Saturday, April 30, 2005

image checksums

When modifying images, it is a good idea to change the checksum as well. There is an API in imagehlp.dll for calculating the checksum from the image bytes.

If you change the image bytes, you should re-calculate the checksum and store in in the image header.

Since I couldn't find a command line tool that could show the original checksum in the header as well as the computed checksum, I wrote this little tool.

Complile this with cl /Zi checksum.cpp /link imagehlp.lib
Usage checksum.exe image_name

ex:
D:\temp>checksum c:\WINDOWS\system32\kerberos.dll
checksum orig 0x00051f00 computed 0x00051f00

D:\temp>

#include <windows.h>
#include <imagehlp.h>
#include <stdio.h>


int __cdecl main(int argc, char** argv){
argc; argv;
if (argc < 2){
printf("Usage: checksum filename\n");
return 1;
}

const char* fn = argv[1];
HANDLE hFile = CreateFile(fn, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if (hFile == INVALID_HANDLE_VALUE)
{
printf("culdn't find %s\n", fn);
return 1;
}

DWORD fileSize = GetFileSize(hFile, 0);
if (INVALID_FILE_SIZE == fileSize)
{
printf("couldn't find size of %s\n", fn);
return 1;
}

HANDLE hFileMap = CreateFileMapping(hFile, 0, PAGE_READONLY, 0, 0, 0);
if (hFileMap == 0)
{
printf("culdn't create mapping for %s\n", fn);
return 1;
}
PVOID hBaseFile = MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 0);
if (hBaseFile == 0)
{
printf("culdn't map %s\n", fn);
return 1;
}

DWORD hdr_checksum;
DWORD checksum;
PIMAGE_NT_HEADERS ntHeaders = CheckSumMappedFile(hBaseFile, fileSize, &hdr_checksum, &checksum);
if (!ntHeaders)
{
printf("checksum api failed\n");
return 1;
}

printf("checksum orig 0x%08x computed 0x%08x\n", hdr_checksum, checksum);
return 0;
}

Sunday, April 17, 2005

Inside look into Microsoft TCP/IP connection limit workaround

I couldn't find out any information on how this was hacked. I assume that a binary differ was used against the orginal tcpip.sys vs the patched one. Halvar Flake's bindiff plugin with IDA-Pro, quite probably.

However, after analyzing the fix, I found it instructive to disassemble tcpip.sys to find out what the hack accomplished.

Basically, tcpip.sys (XP SP2) introduces a pointer value in the image that points to the maximum number of concurrent connections. In a couple of places in the code a check is made to see if the current number of connections exceed this value.

The maximum number of connections is set with this instruction:

mov dword ptr [_ActiveOpenProgressThreshold], 0Ah

The hack changes this to:

mov dword ptr [_ActiveOpenProgressThreshold], 0FFFFFEh

The disassembly makes more sense if you have symbols for tcpip.sys. You can obtain this by setting the symbol path to Microsoft public symbol servers:

set _NT_SYMBOL_PATH=SRV*c:\symbols*http://msdl.microsoft.com/download/symbols

Microsoft Windows TCP/IP security limits

Windows XP SP2 introduced a limit on concurrent half-open TCP/IP connections that can be a problem in using P2P apps like eMule, BitTorrent.

http://forum.emule-project.net/lofiversion/index.php/t56016.html describes the general method of dealing with this.

However, there is at least one other version of tcpip.sys that is different. I believe this is part of a more recent windows update. The same hack can be applied but in two different places.

First check if your tcpip.sys has a size of 359,808. If so apply this patch:

Modify tcpip.sys offset 0x130 from C8 27 06 00 to BC 28 06 00

Modify tcpip.sys offset 0x0004f5a2 from 0A 00 00 00 to FE FF FF 00

An automated fix for this is found in http://www.lvllord.de/

I will post a more general description of what we're modifying later in this blog.