Nmap Development mailing list archives
Re: Scans failing on Win32 - failures differ depending on args len (maybe)
From: jah <jah () zadkiel plus com>
Date: Sat, 08 Oct 2011 19:38:22 +0100
Hello, The failures I reported stem from the call to GetAdaptersAddresses from _refresh_tables in libdnet-stripped/src/intf-win32.c With the args: -F -v -d -n 195.166.128.231, GetAdaptersAddresses returns ERROR_INVALID_PARAMETER the very first time _refresh_tables is called: nmap.exe!_refresh_tables(intf_handle * intf) Line 216 C nmap.exe!intf_loop(intf_handle * intf, int (const intf_entry *, void *)* callback, void * arg) Line 373 + 0x9 bytes C nmap.exe!getinterfaces_dnet(int * howmany, char * errstr, unsigned int errstrlen) Line 1312 + 0x12 bytes C++ nmap.exe!getinterfaces(int * howmany, char * errstr, unsigned int errstrlen) Line 1335 + 0x12 bytes C++ nmap.exe!sysroutes_dnet_find_interfaces(dnet_collector_route_nfo * dcrn) Line 1490 + 0xd bytes C++ nmap.exe!getsysroutes_dnet(int * howmany, char * errstr, unsigned int errstrlen) Line 1596 + 0x9 bytes C++ nmap.exe!getsysroutes(int * howmany, char * errstr, unsigned int errstrlen) Line 1625 + 0x11 bytes C++ nmap.exe!route_dst_generic(const sockaddr_storage * dst, route_nfo * rnfo, const char * device, const sockaddr_storage * spoofss) Line 3233 + 0x15 bytes C++ nmap.exe!route_dst(const sockaddr_storage * dst, route_nfo * rnfo, const char * device, const sockaddr_storage * spoofss) Line 3329 + 0x15 bytes C++ nmap.exe!nmap_route_dst(const sockaddr_storage * dst, route_nfo * rnfo) Line 2031 + 0x17 bytes C++ nmap.exe!nexthost(HostGroupState * hs, const addrset * exclude_group, scan_lists * ports, int pingtype) Line 359 + 0x13 bytes C++ nmap.exe!nmap_main(int argc, char * * argv) Line 1778 + 0x1e bytes C++ nmap.exe!main(int argc, char * * argv) Line 195 + 0xd bytes C++ nmap.exe!__tmainCRTStartup() Line 278 + 0x19 bytes C nmap.exe!mainCRTStartup() Line 189 C kernel32.dll!_BaseProcessStart@4() + 0x23 bytes With the args -F -v -v -d -n 195.166.128.231, GetAdaptersAddresses returns NO_ERROR the first time _refresh_tables is called and ERROR_INVALID_PARAMETER the second time _refresh_tables is called: nmap.exe!_refresh_tables(intf_handle * intf) Line 216 C nmap.exe!intf_get_pcap_devname(const char * intf_name, char * pcapdev, int pcapdevlen) Line 417 + 0x9 bytes C nmap.exe!eth_get_pcap_devname(const char * intf_name, char * pcapdev, int pcapdevlen) Line 117 + 0x11 bytes C nmap.exe!eth_open(const char * device) Line 39 + 0x15 bytes C nmap.exe!eth_open_cached(const char * device) Line 942 + 0x9 bytes C++ nmap.exe!UltraScanInfo::Init(std::vector<Target *,std::allocator<Target *> > & Targets, scan_lists * pts, stype scantp) Line 1653 + 0x17 bytes C++ nmap.exe!UltraScanInfo::UltraScanInfo(std::vector<Target *,std::allocator<Target *> > & Targets, scan_lists * pts, stype scantype) Line 607 + 0xa3 bytes C++ nmap.exe!ultra_scan(std::vector<Target *,std::allocator<Target *> > & Targets, scan_lists * ports, stype scantype, timeout_info * to) Line 5718 + 0x3a bytes C++ nmap.exe!massping(Target * * hostbatch, int num_hosts, scan_lists * ports) Line 257 + 0x14 bytes C++ nmap.exe!nexthost(HostGroupState * hs, const addrset * exclude_group, scan_lists * ports, int pingtype) Line 465 + 0x16 bytes C++ nmap.exe!nmap_main(int argc, char * * argv) Line 1778 + 0x1e bytes C++ nmap.exe!main(int argc, char * * argv) Line 195 + 0xd bytes C++ nmap.exe!__tmainCRTStartup() Line 278 + 0x19 bytes C nmap.exe!mainCRTStartup() Line 189 C kernel32.dll!_BaseProcessStart@4() + 0x23 bytes GetAdaptersAddresses is called in a loop, first with a 2 byte buffer allocation for the adapter addresses and then again, if it returned ERROR_BUFFER_OVERFLOW, with a larger allocation having the length as updated by GetAdaptersAddresses. In each of the two aforementioned cases GetAdaptersAddresses returns ERROR_INVALID_PARAMETER during the first go round the loop. In the latter of the cases, during the first call to _refresh_tables, it takes two loops to allocate the (assumed) correct buffer size - I've observed that 2940 bytes is allocated. According to the msdn docs for GetAdaptersAddresses [1], this method of determining the buffer size is "Strongly discouraged" (it doesn't say exactly why, but it does say that the function "requires a significant amount of network resources and time to complete since all of the low-level network interface tables must be traversed"). Instead the docs suggest pre-allocating a 15KB buffer which, "on typical computers", "dramatically reduces the chances that the GetAdaptersAddresses function returns ERROR_BUFFER_OVERFLOW, which would require calling GetAdaptersAddresses function multiple times". The msdn docs say this about the reasons why ERROR_INVALID_PARAMETER is returned: "One of the parameters is invalid. This error is returned for any of the following conditions: the SizePointer parameter is NULL, the Address parameter is not AF_INET, AF_INET6, or AF_UNSPEC, or the address information for the parameters requested is greater than ULONG_MAX". For sure, neither of the first two reasons apply and ULONG_MAX, defined in limits.h (included from Visual Studio includes), is 0xffffffff so I don't think that can be it either. I can't find any other clue as to why this might happen. The attached patch implements the suggested method for allocating the adapter addresses buffer and all of the scans which had previously failed on XP SP3 complete successfully with the change. I wasn't able to reproduce the failures on Windows 7 and the patched binary made no difference to the scan results on that OS. I haven't yet discovered why one -v makes such a difference to the code path taken when failure occurs. jah [1] - GetAdaptersAddresses http://msdn.microsoft.com/en-us/library/aa365915%28VS.85%29.aspx#Remarks
Attachment:
libdnet-stripped_intf-win32.patch
Description:
_______________________________________________ Sent through the nmap-dev mailing list http://cgi.insecure.org/mailman/listinfo/nmap-dev Archived at http://seclists.org/nmap-dev/
Current thread:
- Scans failing on Win32 - failures differ depending on args len (maybe) jah (Oct 07)
- Message not available
- Re: Scans failing on Win32 - failures differ depending on args len (maybe) jah (Oct 07)
- Message not available
- Re: Scans failing on Win32 - failures differ depending on args len(maybe) jah (Oct 07)
- Re: Scans failing on Win32 - failures differ depending on args len(maybe) David Fifield (Oct 10)
- Re: Scans failing on Win32 - failures differ depending on args len(maybe) jah (Oct 11)
- Re: Scans failing on Win32 - failures differ depending on args len (maybe) jah (Oct 07)
- Message not available
- Re: Scans failing on Win32 - failures differ depending on args len (maybe) David Fifield (Oct 12)