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: