mingw-bundledlls – Automatically bundle DLLs for Windows deployment

Download the script – https://github.com/mpreisler/mingw-bundledlls

I recently had to build an application with mingw32 on Fedora 21 and then prepare the binaries for usage on Windows without any external dependencies.

In the past I used to look at the list of dependencies using depends32.exe or similar tools on Windows and then copy all the DLLs manually. Needless to say that is very repetitive work and gets annoying quickly. Googling for existing solutions did not yield any useful results so I decided to solve this myself.

The solution I came up with is a small Python 3 script that uses objdump  to recursively gather all dependencies of an executable file (WinPE EXE) or a dynamic loaded library (DLL). I published the script on GitHub – https://github.com/mpreisler/mingw-bundledlls.

The script can be run from Linux and only depends on python3 and objdump from binutils. It is very convenient to just run:

mingw32-configure && make && mingw-bundledlls --copy $EXE

After this invocation all the necessary DLLs will be right next to the EXE so you can just pack it all up and upload the release.

Practical example

I will show how I build SCAP Workbench for Windows from scratch on Fedora 21.

git clone https://github.com/OpenSCAP/scap-workbench.git
cd scap-workbench
mkdir build
cd build
mingw32-cmake ../
make -j 4

After the previous command finishes build/scap-workbench contains all the necessary resources including scap-workbench.exe. You however cannot run it on Windows without getting an error message about missing DLLs. Let us now run the script to solve that 🙂

$ mingw-bundledlls ./scap-workbench/scap-workbench.exe

Found the following dependencies:

/usr/i686-w64-mingw32/sys-root/mingw/bin/libstdc++-6.dll
/usr/i686-w64-mingw32/sys-root/mingw/bin/libpng16-16.dll
/usr/i686-w64-mingw32/sys-root/mingw/bin/zlib1.dll
/usr/i686-w64-mingw32/sys-root/mingw/bin/libcurl-4.dll
/usr/i686-w64-mingw32/sys-root/mingw/bin/libwinpthread-1.dll
/usr/i686-w64-mingw32/sys-root/mingw/bin/libxslt-1.dll
/usr/i686-w64-mingw32/sys-root/mingw/bin/QtGui4.dll
/usr/i686-w64-mingw32/sys-root/mingw/bin/iconv.dll
/usr/i686-w64-mingw32/sys-root/mingw/bin/libxml2-2.dll
/usr/i686-w64-mingw32/sys-root/mingw/bin/libidn-11.dll
/usr/i686-w64-mingw32/sys-root/mingw/bin/libintl-8.dll
/usr/i686-w64-mingw32/sys-root/mingw/bin/libopenscap-8.dll
/usr/i686-w64-mingw32/sys-root/mingw/bin/libcrypto-10.dll
/usr/i686-w64-mingw32/sys-root/mingw/bin/QtNetwork4.dll
/usr/i686-w64-mingw32/sys-root/mingw/bin/libexslt-0.dll
/usr/i686-w64-mingw32/sys-root/mingw/bin/libssh2-1.dll
/usr/i686-w64-mingw32/sys-root/mingw/bin/QtXmlPatterns4.dll
/usr/i686-w64-mingw32/sys-root/mingw/bin/libgcc_s_sjlj-1.dll
/usr/i686-w64-mingw32/sys-root/mingw/bin/libpcre-1.dll
/usr/i686-w64-mingw32/sys-root/mingw/bin/QtCore4.dll
/usr/i686-w64-mingw32/sys-root/mingw/bin/libssl-10.dll

After confirming that the script did not find anything crazy we can proceed to copy the dependencies next to the exe. Use –copy as an option to accomplish that.

$ mingw-bundledlls --copy ./scap-workbench/scap-workbench.exe

Copying enabled, will now copy all dependencies next to the exe_file.

Copying '/usr/i686-w64-mingw32/sys-root/mingw/bin/libidn-11.dll' to './scap-workbench/libidn-11.dll'
Copying '/usr/i686-w64-mingw32/sys-root/mingw/bin/libssh2-1.dll' to './scap-workbench/libssh2-1.dll'
Copying '/usr/i686-w64-mingw32/sys-root/mingw/bin/libwinpthread-1.dll' to './scap-workbench/libwinpthread-1.dll'
Copying '/usr/i686-w64-mingw32/sys-root/mingw/bin/libxml2-2.dll' to './scap-workbench/libxml2-2.dll'
Copying '/usr/i686-w64-mingw32/sys-root/mingw/bin/QtNetwork4.dll' to './scap-workbench/QtNetwork4.dll'
Copying '/usr/i686-w64-mingw32/sys-root/mingw/bin/libstdc++-6.dll' to './scap-workbench/libstdc++-6.dll'
Copying '/usr/i686-w64-mingw32/sys-root/mingw/bin/zlib1.dll' to './scap-workbench/zlib1.dll'
Copying '/usr/i686-w64-mingw32/sys-root/mingw/bin/libopenscap-8.dll' to './scap-workbench/libopenscap-8.dll'
Copying '/usr/i686-w64-mingw32/sys-root/mingw/bin/libpcre-1.dll' to './scap-workbench/libpcre-1.dll'
Copying '/usr/i686-w64-mingw32/sys-root/mingw/bin/libgcc_s_sjlj-1.dll' to './scap-workbench/libgcc_s_sjlj-1.dll'
Copying '/usr/i686-w64-mingw32/sys-root/mingw/bin/QtXmlPatterns4.dll' to './scap-workbench/QtXmlPatterns4.dll'
Copying '/usr/i686-w64-mingw32/sys-root/mingw/bin/libexslt-0.dll' to './scap-workbench/libexslt-0.dll'
Copying '/usr/i686-w64-mingw32/sys-root/mingw/bin/libcurl-4.dll' to './scap-workbench/libcurl-4.dll'
Copying '/usr/i686-w64-mingw32/sys-root/mingw/bin/libpng16-16.dll' to './scap-workbench/libpng16-16.dll'
Copying '/usr/i686-w64-mingw32/sys-root/mingw/bin/QtCore4.dll' to './scap-workbench/QtCore4.dll'
Copying '/usr/i686-w64-mingw32/sys-root/mingw/bin/libssl-10.dll' to './scap-workbench/libssl-10.dll'
Copying '/usr/i686-w64-mingw32/sys-root/mingw/bin/libxslt-1.dll' to './scap-workbench/libxslt-1.dll'
Copying '/usr/i686-w64-mingw32/sys-root/mingw/bin/libcrypto-10.dll' to './scap-workbench/libcrypto-10.dll'
Copying '/usr/i686-w64-mingw32/sys-root/mingw/bin/QtGui4.dll' to './scap-workbench/QtGui4.dll'
Copying '/usr/i686-w64-mingw32/sys-root/mingw/bin/iconv.dll' to './scap-workbench/iconv.dll'
Copying '/usr/i686-w64-mingw32/sys-root/mingw/bin/libintl-8.dll' to './scap-workbench/libintl-8.dll'

The script also runs upx on all the binaries if –upx is supplied. That is useful for minimizing installed size of your application.

At this point I just zip build/scap-workbench and test it on Windows.

Runtime loaded DLLs

The script will not find any runtime loaded dependencies. Doing that would be possible by looking for LoadLibrary, LoadLibraryEx, … calls but probably not worth it. Bundling runtime loaded DLLs is a potential nightmare depending on whether relative or absolute paths are used when calling LoadLibrary. Inevitably the script would have to alter the EXE itself or any of the DLLs that is calling LoadLibrary.

Since I did not need this I decided to ignore this issue 🙂

SCAP Workbench 1.1.0

The new SCAP Workbench is out! This is the biggest release to date. We focused on improving the typical use-case of tailoring and remote scanning. This is also the first release to have Windows and MacOS X support!

Update: Thanks to the great work of Jakub Jelen, we now have a testing release for Windows that supports remote scan! Give it a try, report any issues: scap-workbench-1.1.0-win32-remote-scan-testing.zip. SCAP Workbench 1.1.1 will be released some time soon and will have remote scanning from Windows included.

Fedora updates for F22, F21 and F20 are pending. Testing and karma would be greatly appreciated! This release brings so many fixes and does not break existing use-cases that I decided to push it to older Fedoras as well. Even though it is a major release.

Screenshots

sw-1.1.0_1 sw-1.1.0_2

sw-1.1.0_3 sw-1.1.0_4

What’s new?

1.1.0 is a packed major release, the number of changes is second only to the 0.8.0 C++ rewrite.

  • Windows support – including a native MSI installer
  • MacOS X support – including a native dmg image
  • Complete redesign of the main window, with rich-text rule descriptions
  • Better SCAP Security Guide integration
  • Tailoring window greatly improved – shows relationships between values and rules
  • Opens bzip2 files
  • Performance improvements when loading big SCAP files
  • Countless UX improvements
  • And a lot more, a total of 49 tickets fixed, plus fixes merged from maintenance branches

Where to report issues?

The best place to report issues is the trac bug tracker. However I also accept reports via the mailing list or even comments to this blog post.

OpenSCAP and SCAP Workbench on Windows – part 2

Go to Part 1

Remote scanning

I have made some progress with remote scanning but there still are issues that prevent convenient usage. Right now workbench on Windows can:

  • login to the remote machine
  • query oscap capabilities and parse them
  • copy input content to the remote machine (ssh+tee)
  • start the scan
  • copy remote results back to the local machine

remote-scan-from-windows-1

So it seems remote scan is working fine, right? The issue is that ssh continuously asks for login over and over again. This is not such an issue if you have a private key setup but if you login with username and password this is a major pain. You have to type the password in a dozen of times, each time for one performed action. To make matters worse, setting up ssh private key in cygwin ssh isn’t straightforward at all.

The issue stems from the fact that it seems cygwin ssh does not support ControlMaster and ControlPath options. Right now I am researching alternatives but haven’t found anything suitable yet. Suggestions welcome.

Windows content tailoring

However I also have good news 🙂

NIST has released release candidate of the upcoming USGCB content for Microsoft products. At first workbench failed to open it, claiming there are referenced tests that are non-existent. Turns out openscap had some of the Windows specific OVAL enumeration strings missing and/or wrong. This has been fixed in openscap master branch.

OpenSCAP and SCAP Workbench from master branches can now open the upcoming USGCB content for Windows 7. Furthermore, workbench can customize Windows-specific content and save the result for later use.

windows-tailoring-1 windows-tailoring-2 windows-tailoring-3

I have performed profile customization of the Windows 7 USGCB profile and saved it to a tailoring file, here is how the resulting file looks like:

<?xml version="1.0" encoding="UTF-8"?>
<xccdf:Tailoring xmlns:xccdf="http://checklists.nist.gov/xccdf/1.2" id="xccdf_scap-workbench_tailoring_default">
  <xccdf:benchmark href="C:/Users/mpreisle/Desktop/USGCB-Windows/Win7-2.0.5.1-rc1/scap_gov.nist_USGCB-Windows-7.xml"/>
  <xccdf:version time="2015-03-02T17:28:53">1</xccdf:version>
  <xccdf:Profile id="xccdf_gov.nist_profile_united_states_government_configuration_baseline_version_2.0.5.1_customized" extends="xccdf_gov.nist_profile_united_states_government_configuration_baseline_version_2.0.5.1">
    <xccdf:title xmlns:xhtml="http://www.w3.org/1999/xhtml" xml:lang="en-US">United States Government Configuration Baseline 2.0.5.1 [CUSTOMIZED]</xccdf:title>
    <xccdf:description xmlns:xhtml="http://www.w3.org/1999/xhtml" xml:lang="en-US">This profile represents guidance outlined in United States Government Configuration Baseline for desktop systems with Microsoft Windows 7 installed.</xccdf:description>
    <xccdf:select idref="xccdf_gov.nist_group_security_options_settings" selected="false"/>
    <xccdf:select idref="xccdf_gov.nist_group_system_services_settings" selected="false"/>
    <xccdf:set-value idref="xccdf_gov.nist_value_auto_admin_logon_var">1</xccdf:set-value>
    <xccdf:set-value idref="xccdf_gov.nist_value_router_discovery_var">1</xccdf:set-value>
  </xccdf:Profile>
</xccdf:Tailoring>

Executables for testing

Please keep in mind that this is a preliminary release that is in no way official. It just shows what is possible right now and allows me to outline future plans. You should NOT use this in production!

scap-workbench-win32-prealpha2.zip

You need to edit scap-workbench.bat if you want to try remote scanning. Right now workbench requires absolute path to win-ssh-askpass.exe and I am too much of a Windows scripting newbie to do it automatically 🙂 This will be fixed later. The executable is in the bin folder in the zip file.