diff options
| author | Dmitry Kuzkin <bio@ktaspb.ru> | 2012-07-13 18:53:40 +0000 | 
|---|---|---|
| committer | Dmitry Kuzkin <bio@ktaspb.ru> | 2012-07-13 18:53:40 +0000 | 
| commit | bc5de7df3d29bc8afd8f757cccd0719f37aa4933 (patch) | |
| tree | b84d5c94751cfb1275429de3185a5cf1192b8e4c | |
| parent | f888115632a98c68d859be34395a572ac81b3d09 (diff) | |
- relocation tables processing for compatibility with rebaser
(only for x86 builds)
git-svn-id: http://svn.miranda-ng.org/main/trunk@953 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
| -rw-r--r-- | tools/checksum/checksum.cpp | 252 | ||||
| -rw-r--r-- | tools/checksum/checksum.exe | bin | 11264 -> 53760 bytes | |||
| -rw-r--r-- | tools/checksum/make.bat | 3 | 
3 files changed, 203 insertions, 52 deletions
diff --git a/tools/checksum/checksum.cpp b/tools/checksum/checksum.cpp index 13d13eb9ae..744805a694 100644 --- a/tools/checksum/checksum.cpp +++ b/tools/checksum/checksum.cpp @@ -2,11 +2,13 @@  // Checksum Tool 
  // By Bio (C) 2012
 -#define _VERSION_ "2.0"
 +#define _VERSION_ "2.99"
  #include "commonheaders.h"
 +
  //#define DEBUG_SECTIONS	1
 +//#define DEBUG_REALLOCS	1
  // Return codes
  #define RESULT_OK			0
 @@ -18,6 +20,9 @@  #define RESULT_NONE			100
 +#define DEFAULT_BASE		0x10000000
 +
 +
  int PEChecksum( TCHAR *filename, mir_md5_byte_t digest[16] )
  {
  	HANDLE hFile = INVALID_HANDLE_VALUE;
 @@ -77,23 +82,24 @@ int PEChecksum( TCHAR *filename, mir_md5_byte_t digest[16] )  		else
  		{
  			machine = pINTH->FileHeader.Machine;
 -/*
 +
 +#ifdef DEBUG_SECTIONS
  			switch(machine) 
  			{
  				case IMAGE_FILE_MACHINE_I386:
 -					_ftprintf( stderr, _T("(x86) ") );
 +					_ftprintf( stderr, _T("Build: x86\n") );
  					break;
  				case IMAGE_FILE_MACHINE_AMD64:
 -					_ftprintf( stderr, _T("(x64) ") );
 +					_ftprintf( stderr, _T("Build: x64\n") );
  					break;
  				case IMAGE_FILE_MACHINE_IA64:
 -					_ftprintf( stderr, _T("(IA64 :-) ") );
 +					_ftprintf( stderr, _T("Build: IA64 :-)\n") );
  						break;
  				default:
 -					_ftprintf( stderr, _T("(unknown) ") );
 +					_ftprintf( stderr, _T("Build: unknown :-(\n") );
  					break;
  			}
 -*/
 +#endif
  			sections = pINTH->FileHeader.NumberOfSections;
  			if ( !sections )
 @@ -105,12 +111,21 @@ int PEChecksum( TCHAR *filename, mir_md5_byte_t digest[16] )  				DWORD dbgvaddr = 0; 
  				DWORD expsize = 0;
  				DWORD expvaddr = 0; 
 -			
 +				PBYTE pRealloc = 0;
 +				DWORD realvaddr = 0;
 +				DWORD realsize = 0;
 +				DWORD offset;
 +				__int64 base = 0;
 +
 +				// try to found correct offset independent of architectures 
 +				offset = pIDH->e_lfanew + pINTH->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_NT_HEADERS) - sizeof(IMAGE_OPTIONAL_HEADER);
 +
  				if ( ( machine == IMAGE_FILE_MACHINE_I386 ) && 
  					( pINTH->FileHeader.SizeOfOptionalHeader >= sizeof(IMAGE_OPTIONAL_HEADER32) ) &&
  					( pINTH->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC ) )
  				{
  				    pIDD = (PIMAGE_DATA_DIRECTORY)( (PBYTE)pINTH + offsetof( IMAGE_NT_HEADERS32, OptionalHeader.DataDirectory ) );
 +				    base = *(DWORD*)( (PBYTE)pINTH + offsetof( IMAGE_NT_HEADERS32, OptionalHeader.ImageBase ) );
  				}
  			   	else 
  				if ( ( machine == IMAGE_FILE_MACHINE_AMD64 ) && 
 @@ -118,10 +133,15 @@ int PEChecksum( TCHAR *filename, mir_md5_byte_t digest[16] )  					( pINTH->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC ) )
  				{
 -				    pIDD = (PIMAGE_DATA_DIRECTORY)( (PBYTE)pINTH + offsetof( IMAGE_NT_HEADERS64, OptionalHeader.DataDirectory ) );					
 +				    pIDD = (PIMAGE_DATA_DIRECTORY)( (PBYTE)pINTH + offsetof( IMAGE_NT_HEADERS64, OptionalHeader.DataDirectory ) );
 +				    base = *(__int64*)( (PBYTE)pINTH + offsetof( IMAGE_NT_HEADERS64, OptionalHeader.ImageBase ) );
  				}
  				else 
  					res = RESULT_CORRUPTED;
 +					                                     
 +#ifdef DEBUG_REALLOCS
 +				_ftprintf( stderr, _T("Image base is 0x%I64x \n"), base );
 +#endif
  				if ( pIDD )
  				{	
 @@ -132,64 +152,39 @@ int PEChecksum( TCHAR *filename, mir_md5_byte_t digest[16] )  					// Export information entry
  					expvaddr = pIDD[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
  					expsize = pIDD[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
 -				}
 -			 
 -			    if ( res == RESULT_OK )
 -			    {
 -					PIMAGE_SECTION_HEADER pISH = 0;
 -		            DWORD offset;
 -					DWORD idx = 0;
 -					mir_md5_state_t pms;
 -								
 -					mir_md5_init( &pms );
 -					// try to found correct offset independent of architectures 
 -					offset = pIDH->e_lfanew + pINTH->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_NT_HEADERS) - sizeof(IMAGE_OPTIONAL_HEADER);
 +					// Reallocation information entry
 +					realvaddr = pIDD[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
 +					realsize = pIDD[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
 +				}					
 +
 +				if ( dbgsize || expsize || realsize )
 +				{
 +					DWORD idx = 0;
 +					PIMAGE_SECTION_HEADER pISH = 0;
  					while ( idx < sections )
  					{
  						pISH = (PIMAGE_SECTION_HEADER)( ptr + offset + idx * sizeof(IMAGE_SECTION_HEADER) );
 -						if ( (PBYTE)pISH + sizeof(IMAGE_SECTION_HEADER) > ptr + filesize )
 -						{
 -   							res = RESULT_CORRUPTED;
 -   							break;
 -						}
 -
 -						if ( pISH->PointerToRawData + pISH->SizeOfRawData > filesize )
 -						{
 -   							res = RESULT_CORRUPTED;
 -   							break;
 -						}
 -
 -#ifdef DEBUG_SECTIONS
 -						_ftprintf( stderr, _T("%s - %08X - %d "), pISH->Name, pISH->PointerToRawData, pISH->SizeOfRawData);
 -
 +						if ( ( (PBYTE)pISH + sizeof(IMAGE_SECTION_HEADER) > ptr + filesize ) || ( pISH->PointerToRawData + pISH->SizeOfRawData > filesize ) )
  						{
 -							int i;			
 -							mir_md5_byte_t digest2[16];
 -							mir_md5_state_t pms2;
 -								
 -							mir_md5_init( &pms2 );
 -							mir_md5_append( &pms2, ptr + pISH->PointerToRawData, pISH->SizeOfRawData );
 -							mir_md5_finish( &pms2, digest2 );
 -		
 -							for ( i = 0; i < sizeof( digest2 ) / sizeof( digest2[0] ); i++ )
 -								_ftprintf( stderr, _T("%02X"), digest2[i] );
 -							_ftprintf( stderr, _T("\n") );
 +							res = RESULT_CORRUPTED;
 +							break;
  						}
 -#endif
 +	
  						// erase timestamp and debug information
  						if (( dbgsize >= sizeof( IMAGE_DEBUG_DIRECTORY ) ) && 
  							( dbgvaddr >= pISH->VirtualAddress ) && 
 -							( dbgvaddr + dbgsize <= pISH->VirtualAddress + pISH->SizeOfRawData ) )
 +							( dbgvaddr + dbgsize <= pISH->VirtualAddress + pISH->SizeOfRawData ) 
 +							)
  						{
  						    DWORD shift = dbgvaddr - pISH->VirtualAddress;
  						    PIMAGE_DEBUG_DIRECTORY pDBG = (PIMAGE_DEBUG_DIRECTORY)( ptr + shift + pISH->PointerToRawData ); 
  							pDBG->TimeDateStamp = 0;
  #ifdef DEBUG_SECTIONS
 -							_ftprintf( stderr, _T("found debug section entry %08X ( %d ), data %08X ( %d ) \n"), pISH->PointerToRawData + shift, dbgsize, pDBG->PointerToRawData, pDBG->SizeOfData );
 +							_ftprintf( stderr, _T("Found debug section entry at 0x%08X (%d), data at 0x%08X (%d)\n"), pISH->PointerToRawData + shift, dbgsize, pDBG->PointerToRawData, pDBG->SizeOfData );
  #endif							
  							if ( pDBG->SizeOfData > 0 && 
  								( pDBG->PointerToRawData >= pISH->PointerToRawData ) && 
 @@ -211,9 +206,164 @@ int PEChecksum( TCHAR *filename, mir_md5_byte_t digest[16] )  							pEXP->TimeDateStamp = 0;
  #ifdef DEBUG_SECTIONS
 -							_ftprintf( stderr, _T("found export section entry %08X\n"), pISH->PointerToRawData + shift );
 +							_ftprintf( stderr, _T("Found export section entry at 0x%08X\n"), pISH->PointerToRawData + shift );
 +#endif
 +						}
 +
 +						// find realocation table
 +						if (( realsize >= sizeof( IMAGE_BASE_RELOCATION ) ) && 
 +							( realvaddr >= pISH->VirtualAddress ) && 
 +							( realvaddr + realsize <= pISH->VirtualAddress + pISH->SizeOfRawData ) )
 +						{
 +						    DWORD shift = realvaddr - pISH->VirtualAddress;
 +							pRealloc = ptr + shift + pISH->PointerToRawData; 
 +#ifdef DEBUG_SECTIONS
 +							_ftprintf( stderr, _T("Found reallocation table entry at 0x%08X (%d)\n"), pISH->PointerToRawData + shift, realsize );
 +#endif
 +
 +							// correct base address
 +							base = DEFAULT_BASE - base; 
 +#ifdef DEBUG_REALLOCS
 +							if ( base >= 0) 
 +								_ftprintf( stderr, _T("Image base correction 0x%I64x\n"), base );
 +							else
 +								_ftprintf( stderr, _T("Image base correction -0x%I64x\n"), -base );
 +#endif
 +						}
 +	
 +                        idx++;
 +					}
 +
 +				}
 +			 
 +			    if ( res == RESULT_OK )
 +			    {
 +					PIMAGE_SECTION_HEADER pISH = 0;
 +					DWORD idx = 0;
 +
 +					INT64 rebase = DEFAULT_BASE - base;
 +
 +					mir_md5_state_t pms;
 +								
 +					mir_md5_init( &pms );
 +
 +					while ( idx < sections )
 +					{
 +						pISH = (PIMAGE_SECTION_HEADER)( ptr + offset + idx * sizeof(IMAGE_SECTION_HEADER) );
 +
 +						if ( ( (PBYTE)pISH + sizeof(IMAGE_SECTION_HEADER) > ptr + filesize ) || ( pISH->PointerToRawData + pISH->SizeOfRawData > filesize ) )
 +						{
 +   							res = RESULT_CORRUPTED;
 +   							break;
 +						}
 +
 +						// Rebase to default address
 +						if ( pRealloc ) 
 +						{
 +							PIMAGE_BASE_RELOCATION pIBR = 0;
 +
 +						    DWORD blocklen = realsize;
 +						    PWORD pw;
 +						    DWORD type;
 +						    int len;
 +						    PBYTE pAddr;
 +						    DWORD shift;
 +						    DWORD addr;
 +
 +							pIBR = (PIMAGE_BASE_RELOCATION)pRealloc;
 +
 +							while( pIBR )
 +							{
 +								if ( ( pIBR->VirtualAddress >= pISH->VirtualAddress ) && 
 +									( pIBR->VirtualAddress < pISH->VirtualAddress + pISH->SizeOfRawData ) && 
 +									( pIBR->SizeOfBlock <= blocklen ) )
 +								{
 +									shift = pIBR->VirtualAddress - pISH->VirtualAddress + pISH->PointerToRawData;
 +								    
 +								    len = pIBR->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION);
 +
 +								    pw = (PWORD)( (PBYTE)pIBR + sizeof(IMAGE_BASE_RELOCATION) );
 +#ifdef DEBUG_REALLOCS
 +									_ftprintf( stderr, _T("Realloc block at %08X (%d)\n"), pIBR->VirtualAddress, pIBR->SizeOfBlock );
 +#endif
 +
 +								   	while( len > 0 )
 +								   	{
 +									    type = *pw >> 12;
 +
 +									    addr = ( *pw & 0x0FFF );
 +
 +									    pAddr = ptr + shift + addr;
 +
 +										switch( type )
 +										{
 +											case IMAGE_REL_BASED_HIGHLOW:
 +											    if ( addr + pIBR->VirtualAddress + sizeof(DWORD) >= pISH->VirtualAddress + pISH->SizeOfRawData )
 +											    {
 +											    	len = 0;
 +													break;
 +												}
 +												*(PDWORD)pAddr = (DWORD)( (__int64)(*(PDWORD)pAddr) + base );
 +												break;
 +
 +
 +											case IMAGE_REL_BASED_DIR64:
 +#ifdef DEBUG_REALLOCS
 +												_ftprintf( stderr, _T("REL_BASED_DIR64\n"));
 +#endif
 +                                                // FIXME
 +												break;
 +
 +											case IMAGE_REL_BASED_ABSOLUTE:
 +												// stop processing
 +												len = 0;
 +												break;	
 +		        	
 +											case IMAGE_REL_BASED_HIGH:
 +											case IMAGE_REL_BASED_LOW:
 +											case IMAGE_REL_BASED_HIGHADJ:
 +#ifdef DEBUG_REALLOCS
 +												_ftprintf( stderr, _T("Unexpected block type %d\n"), type );
 +#endif
 +												break;
 +
 +											default:
 +#ifdef DEBUG_REALLOCS
 +												_ftprintf( stderr, _T("Unknown block type %d\n"), type );
  #endif
 +												break;	
 +										}
 +
 +
 +										len -= sizeof(WORD);
 +										pw++;
 +									}
 +								}
 +
 +								blocklen -= pIBR->SizeOfBlock; 
 +								if ( blocklen > sizeof(IMAGE_BASE_RELOCATION) )
 +									pIBR = (PIMAGE_BASE_RELOCATION)( (PBYTE)pIBR + pIBR->SizeOfBlock );
 +								else
 +									break;
 +							}
  						}
 +#ifdef DEBUG_SECTIONS
 +						_ftprintf( stderr, _T("%s - %08X - %d "), pISH->Name, pISH->PointerToRawData, pISH->SizeOfRawData);
 +
 +						{
 +							int i;			
 +							mir_md5_byte_t digest2[16];
 +							mir_md5_state_t pms2;
 +								
 +							mir_md5_init( &pms2 );
 +							mir_md5_append( &pms2, ptr + pISH->PointerToRawData, pISH->SizeOfRawData );
 +							mir_md5_finish( &pms2, digest2 );
 +		
 +							for ( i = 0; i < sizeof( digest2 ) / sizeof( digest2[0] ); i++ )
 +								_ftprintf( stderr, _T("%02X"), digest2[i] );
 +							_ftprintf( stderr, _T("\n") );
 +						}
 +#endif
  	                	mir_md5_append( &pms, ptr + pISH->PointerToRawData, pISH->SizeOfRawData );
 diff --git a/tools/checksum/checksum.exe b/tools/checksum/checksum.exe Binary files differindex 50ba53f7af..6b9e9ef7ea 100644 --- a/tools/checksum/checksum.exe +++ b/tools/checksum/checksum.exe diff --git a/tools/checksum/make.bat b/tools/checksum/make.bat index 07e3402278..d4da86645f 100644 --- a/tools/checksum/make.bat +++ b/tools/checksum/make.bat @@ -1 +1,2 @@ -@cl /MD /O2 /GL /Fe../../bin10/checksum.exe md5.cpp checksum.cpp /link /filealign:512
 +rem @cl /MT /O2 /GL /Fe../../bin10/checksum.exe md5.cpp checksum.cpp /link /filealign:512
 +@cl /MT /O2 /GL /Fe./checksum.exe md5.cpp checksum.cpp /link /filealign:512
\ No newline at end of file  | 
