Nmap Development mailing list archives
Ncat on MinGW - report
From: Jacek Wielemborek <wielemborekj1 () gmail com>
Date: Sun, 11 Aug 2013 15:02:08 +0200
Hi, (note that it's not a part of my GSoC project, rather just extra time experiment ;)) Yesterday I tried to compile Ncat under MinGW. I managed to, and there's surprisingly little problems to solve to make it possible. In this e-mail I'll try to explain what I needed to do to cross-compile a working Windows binary. I ran the tests on Fedora 19, using i686-w64-mingw32-gcc compiler. The result was a working Ncat executable built without IPv6 support, but with SSL (currently only compiled in). My attempts were against the latest SVN trunk. In order to compile ncat, you need to first get a working version of nbase and nsock. In both of the libraries there are issues that block compilation by default. As ./configure in Nmap's root directory tries to configure libpcap as well, I decided to just ./configure inside nbase, nsock and ncat and get these three working. First, you're going to need a compilation OpenSSL under MinGW. I downloaded openssl-1.0.1e.tar.gz and compiled it using the following commands: ./Configure mingw #note that mingw64 threw some assembly errors for me make CC=i686-w64-mingw32-gcc \ RANLIB=i686-w64-mingw32-ranlib \ LD=i686-w64-mingw32-ld \ INSTALL_PREFIX=`pwd` make CC=i686-w64-mingw32-gcc \ RANLIB=i686-w64-mingw32-ranlib \ LD=i686-w64-mingw32-ld \ INSTALL_PREFIX=`pwd` install If all went well, we should have libssl.a and libcrypto.a in ./usr/local/ssl/lib. Let's save the path for future reference: export MY_SSL_DIRECTORY=`pwd`/usr/local/ssl/ Now, let's start compiling Nbase Here's the configure command I used - quite likely a bit too bloated: RANLIB=i686-w64-mingw32-ranlib \ AR=i686-w64-mingw32-ar \ LD=i686-w64-mingw32-ld \ CC=i686-w64-mingw32-gcc \ ./configure \ --with-openssl=$MY_SSL_DIRECTORY \ --disable-ipv6 \ --host=i686-w64-mingw32 Our first error to fix will be: nbase_winunix.h:189:22: fatal error: WINCRYPT.H: No such file or directory It turns out that Nbase compiles fine without this include, so I just commented it out. Then, there will be a bunch of this kind of errors: nbase_winconfig.h:177:24: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'int64_t' I figured I'd just comment out these declarations and hope that GCC already has it and it turned out to be good idea. Nbase then gets back to compiling, until it reaches getaddrinfo.c, where it complains: getaddrinfo.c:169:36: error: conflicting types for 'gai_strerrorA' char* WSAAPI gai_strerrorA (int errcode) ^ I saw a bunch of weird __MINGW32__ things that caused to the compilation of gai_strerrorA, so I commented them otu. And next "make" invocation led me to linking libnbase.a. Now, to Nsock. Let's visit nsock/src directory and run the ./configure similar to the last one, but without --disable-ipv6, since it's ignored and with --without-pcap: RANLIB=i686-w64-mingw32-ranlib \ AR=i686-w64-mingw32-ar \ LD=i686-w64-mingw32-ld \ CC="i686-w64-mingw32-gcc -DDISABLE_NSOCK_PCAP" \ ./configure \ --with-openssl=$MY_SSL_DIRECTORY \ --without-pcap \ --host=i686-w64-mingw32 Here's our first error: nsock_internal.h:72:22: fatal error: Winsock2.h: No such file or directory It's easy to fix, we just need to change Winsock2.h to winsock.2 in nsock_internal.h. You'll have to do the same in netutils.c. Now, ncat. Both --disable-ipv6 and --without-pcap are reported to be ignored, so our ./configure will look like this: RANLIB=i686-w64-mingw32-ranlib \ AR=i686-w64-mingw32-ar \ LD=i686-w64-mingw32-ld \ CC="i686-w64-mingw32-gcc -DDISABLE_NSOCK_PCAP" \ ./configure \ --with-openssl=$MY_SSL_DIRECTORY \ --host=i686-w64-mingw32 \ --without-liblua The --without-liblua is related to some compilation error which is a result of defining LUA_USE_POSIX in our ./configure - I thought I'd just skip it for now. If you'd like to work around it, remove -DLUA_USE_POSIX and -DLUA_USE_DLOPEN from LUA_CFLAGS from Makefile (or ./configure). Either way, we'll hit this error: sys_wrap.h:147:20: fatal error: WinDef.h: No such file or directory Again, Linux is case sensitive and the right way to write it is "windef.h". After fixing it, we'll see ncat_posix.c failing to compile: ncat_posix.c:221:16: error: 'SIGPIPE' undeclared (first use in this function) Signal(SIGPIPE, SIG_DFL); ^ I edited the Makefile, replacing ncat_posix.c (and ncat_posix.o) to their ncat_win.o/ncat.win.c and ncat_exec_win.c/ncat_exec_win.o. The next error looks like this: ncat_ssl.c:139:29: fatal error: openssl/applink.c: No such file or directory #include <openssl/applink.c> ^ I removed the include and just moved on. Yay, finally reached the linking phase! i686-w64-mingw32-gcc -DDISABLE_NSOCK_PCAP -o ncat -I/home/d33tah/workspace/ncat/ncat-mingw/openssl-1.0.1e/usr/local/ssl//include -Wall -L../libpcap -L/home/d33tah/workspace/ncat/ncat-mingw/openssl-1.0.1e/usr/local/ssl//lib ncat_main.o ncat_connect.o ncat_core.o ncat_win.o ncat_exec_win.o ncat_listen.o ncat_proxy.o ncat_ssl.o base64.o http.o util.o sys_wrap.o http_digest.o ../nsock/src/libnsock.a ../nbase/libnbase.a -lssl -lcrypto -lpcap /usr/lib64/gcc/i686-w64-mingw32/4.8.1/../../../../i686-w64-mingw32/bin/ld: cannot find -lpcap We remove -lpcap from the Makefile and get the following errors: i686-w64-mingw32-gcc -DDISABLE_NSOCK_PCAP -o ncat -I/home/d33tah/workspace/ncat/ncat-mingw/openssl-1.0.1e/usr/local/ssl//include -Wall -L../libpcap -L/home/d33tah/workspace/ncat/ncat-mingw/openssl-1.0.1e/usr/local/ssl//lib ncat_main.o ncat_connect.o ncat_core.o ncat_win.o ncat_exec_win.o ncat_listen.o ncat_proxy.o ncat_ssl.o base64.o http.o util.o sys_wrap.o http_digest.o ../nsock/src/libnsock.a ../nbase/libnbase.a -lssl -lcrypto ncat_main.o:ncat_main.c:(.text+0xae): undefined reference to `gai_strerrorA' ncat_main.o:ncat_main.c:(.text+0x4b6): undefined reference to `gai_strerrorA' ncat_main.o:ncat_main.c:(.text+0x1089): undefined reference to `gai_strerrorA' ncat_main.o:ncat_main.c:(.text+0x11a1): undefined reference to `gai_strerrorA' ncat_main.o:ncat_main.c:(.text+0x1347): undefined reference to `_imp__htons@4' ncat_main.o:ncat_main.c:(.text+0x1373): undefined reference to `_imp__htons@4' ncat_main.o:ncat_main.c:(.text+0x1409): undefined reference to `in6addr_any' ncat_main.o:ncat_main.c:(.text+0x1413): undefined reference to `in6addr_any' ncat_main.o:ncat_main.c:(.text+0x141d): undefined reference to `in6addr_any' ncat_main.o:ncat_main.c:(.text+0x1427): undefined reference to `in6addr_any' ncat_main.o:ncat_main.c:(.text+0x1447): undefined reference to `_imp__htons@4' ncat_main.o:ncat_main.c:(.text+0x1462): undefined reference to `_imp__htons@4' ncat_main.o:ncat_main.c:(.text+0x178d): undefined reference to `gai_strerrorA' ncat_main.o:ncat_main.c:(.text+0x1806): undefined reference to `gai_strerrorA' /usr/lib64/gcc/i686-w64-mingw32/4.8.1/../../../../i686-w64-mingw32/bin/ld: ncat_main.o: bad reloc address 0x0 in section `.data' collect2: error: ld returned 1 exit status make: *** [ncat] Error 1 Looks like we need some more libs! The ones we're lacking are: -lwsock32 -lgdi32 -lws2_32. Now, the final problem: [d33tah-pc][~/workspace/ncat/ncat-mingw/ncat] $ i686-w64-mingw32-gcc -DDISABLE_NSOCK_PCAP -o ncat -I/home/d33tah/workspace/ncat/ncat-mingw/openssl-1.0.1e/usr/local/ssl//include -Wall -L../libpcap -L/home/d33tah/workspace/ncat/ncat-mingw/openssl-1.0.1e/usr/local/ssl//lib ncat_main.o ncat_connect.o ncat_core.o ncat_win.o ncat_exec_win.o ncat_listen.o ncat_proxy.o ncat_ssl.o base64.o http.o util.o sys_wrap.o http_digest.o ../nsock/src/libnsock.a ../nbase/libnbase.a -lssl -lcrypto -lwsock32 -lgdi32 -lws2_32 ../nbase/libnbase.a(nbase_misc.o): In function `fselect': /home/d33tah/workspace/ncat/ncat-mingw/nbase/nbase_misc.c:506: undefined reference to `win_stdin_ready' /home/d33tah/workspace/ncat/ncat-mingw/nbase/nbase_misc.c:468: undefined reference to `win_stdin_start_thread' Looks like we need to step back and include nbase_winunix.o in the libnbase.o. In order to include it, I edited the Makefile and added nbase_winunix.o to the OBJS list. Run "make" again and Nbase is updated. Then, repeat the Ncat linking and you'll get "ncat" binary, which is finally a Windows executable: [d33tah-pc][~/workspace/ncat/ncat-mingw/ncat] $ file ncat ncat: PE32 executable (console) Intel 80386, for MS Windows I'll run ncat-test.pl on Cygwin and get back to you. For now, I attach the quick "svn diff" patch that includes the changes I made to the source code to get Ncat working. The case-sensitivity patches I'll commit to the trunk in a while, since I believe they're harmless. For the further solution, we'd need some autoconf/automake modifications that would detect that we're running compiling on MinGW and use Windows code instead of POSIX. It shouldn't be that hard, though - as you can see, there's not that many errors to fix. I'll probably create a new branch for my experiments soon. Yours, Jacek Wielemborek
Attachment:
ncat-mingw.diff
Description:
_______________________________________________ Sent through the dev mailing list http://nmap.org/mailman/listinfo/dev Archived at http://seclists.org/nmap-dev/
Current thread:
- Ncat on MinGW - report Jacek Wielemborek (Aug 11)
- Re: Ncat on MinGW - report Gisle Vanem (Aug 11)
- Re: Ncat on MinGW - report Jacek Wielemborek (Aug 11)
- Re: Ncat on MinGW - report Gisle Vanem (Aug 11)