[代码]重定位文件程序

  1. // 11-Nov-2008 Create by Benyanwk 
  2. // Enviroment: Windows all platfrom. 
  3. // Note: (1) Do not support x64 
  4. //       (2) Do not support file large than 4GB. 
  5. //       (3) Do not use SEH. 
  6. // Revision:  
  7. //  11-Nov-2008 ver1.0 
  8. #define UNICODE
  9. #include <windows.h> 
  10. #include <winnt.h>  // include PE file header definition. 
  11. #include <stdio.h> 
  12. LPCTSTR GetErrMsg(void); 
  13. DWORD 
  14. GetSectionsInfo(  
  15.         PVOID pFile, 
  16.         PIMAGE_SECTION_HEADER *pSections 
  17.         ); 
  18. DWORD Reloc( HANDLE hFile, ULONG BaseAddr ); 
  19. BOOL RelocFile( PVOID pFile, ULONG BaseAddr ); 
  20. DWORD RvaToFileOff( PVOID pFile, DWORD Rva ); 
  21. BOOL VerifyPE( PVOID pFile ); 
  22. ULONG char2ul(char *lpUlNum); 
  23. int main( int argc, char *argv[] ) 
  24.     LPCTSTR lpErrMsg; 
  25.     HANDLE hFile; 
  26.     // 
  27.     // Check the arguments 
  28.     // 
  29.     if( argc != 4 ) 
  30.     { 
  31.          
  32.         wprintf( L"Usage: /n" ); 
  33.         wprintf( L"rebase -b baseaddr filepath /n"); 
  34.         return 1;   // indicate argument error 
  35.     }    
  36.     if( strcmp( argv[1], "-b" ) != 0 ) 
  37.     { 
  38.          
  39.         wprintf( L"Usage: /n" ); 
  40.         wprintf( L"rebase -b baseaddr filepath /n"); 
  41.         return 1; 
  42.     } 
  43.      
  44.     // 
  45.     // Check the File (existence) 
  46.     // 
  47.     char *lpFilePath = argv[3]; 
  48.     hFile =  CreateFileA(  
  49.                     lpFilePath, 
  50.                     GENERIC_READ|GENERIC_WRITE, 
  51.                     FILE_SHARE_READ|FILE_SHARE_WRITE, 
  52.                     (LPSECURITY_ATTRIBUTES)NULL, 
  53.                     OPEN_EXISTING, 
  54.                     FILE_ATTRIBUTE_NORMAL, 
  55.                     (HANDLE)NULL ); 
  56.     if( hFile == INVALID_HANDLE_VALUE ) 
  57.     { 
  58.         lpErrMsg = GetErrMsg(); 
  59.         wsprintf( L"CreateFile Failed!errorcode = %s", lpErrMsg ); 
  60.         LocalFree( (HLOCAL)lpErrMsg ); 
  61.         return 2;   // indicate open file error 
  62.     } 
  63.      
  64.     //  
  65.     // Get the base address 
  66.     // 
  67.     ULONG ulBaseAddr = char2ul( argv[2] ); 
  68.      
  69.     // 
  70.     // Reloc the file 
  71.     // 
  72.     if( Reloc( hFile, ulBaseAddr ) != 0 ) 
  73.     { 
  74.         wprintf( L" Reloc file failed! I'm sorry /n" ); 
  75.         CloseHandle( hFile ); 
  76.         return 3;   // indicate reloc error 
  77.     } 
  78.     return 0;   // indicate success 
  79. LPCTSTR GetErrMsg(void
  80.     DWORD dwErrCode;  
  81.     LPCTSTR lpErrMsg; 
  82.     dwErrCode = GetLastError(); 
  83.      
  84.     FormatMessage(  
  85.         FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, 
  86.         (LPCVOID)NULL, 
  87.         dwErrCode, 
  88.         MAKELANGID( LANG_NEUTRAL, SUBLANG_NEUTRAL ), 
  89.         (LPWSTR)&lpErrMsg, 
  90.         0,
  91.         NULL ); 
  92.     return lpErrMsg; 
  93. DWORD Reloc( HANDLE hFile, ULONG BaseAddr ) 
  94.     DWORD dwFileSize; 
  95.     HGLOBAL pFile;  // HGLOBAL = HANDLE = void* = LPVOID 
  96.     DWORD dwReturnBytes; 
  97.     LPCTSTR lpErrMsg; 
  98.     // 
  99.     // Read the File to memory 
  100.     // 
  101.     dwFileSize = GetFileSize( hFile, NULL ); 
  102.     pFile = GlobalAlloc( GMEM_FIXED, (SIZE_T)dwFileSize ); 
  103.     if( ReadFile(    
  104.              hFile, 
  105.              pFile, 
  106.              dwFileSize, 
  107.              &dwReturnBytes, 
  108.              (LPOVERLAPPED)NULL 
  109.             ) == 0 ) 
  110.     { 
  111.         lpErrMsg = GetErrMsg(); 
  112.         wprintf( L"ReadFile failed! error message = %s", lpErrMsg ); 
  113.         GlobalFree( hFile ); 
  114.         // 
  115.         // indicate read file error. 
  116.         // 
  117.         return 1; 
  118.     } 
  119.                  
  120.                  
  121.     // 
  122.     // Verify PE file 
  123.     //  
  124.     if( VerifyPE( pFile ) == FALSE ) 
  125.     { 
  126.         wprintf( L" this is not a PE file /n"); 
  127.         GlobalFree( pFile ); 
  128.         return 1;   // indicate not pe file 
  129.     } 
  130.      
  131.     // 
  132.     // Reloc PE file 
  133.     // 
  134.     if( RelocFile( pFile, BaseAddr ) != TRUE ) 
  135.     { 
  136.         wprintf( L" reloc PE file failed!/n"); 
  137.         GlobalFree( pFile ); 
  138.         return 2; // indicate reloc pe file failed; 
  139.     } 
  140.     //
  141.     // Jmp to the begining of the PE file
  142.     //
  143.     SetFilePointer(
  144.         hFile,
  145.         0,
  146.         (PLONG)NULL,
  147.         FILE_BEGIN
  148.         );
  149.      
  150.     // 
  151.     // Write back the file 
  152.     // 
  153.     if( WriteFile(  
  154.             hFile, 
  155.             pFile, 
  156.             dwFileSize, 
  157.             &dwReturnBytes, 
  158.             (LPOVERLAPPED)NULL 
  159.             ) == 0 ) 
  160.     { 
  161.         lpErrMsg = GetErrMsg(); 
  162.         wprintf( L" WriteFile failed! %s/n", lpErrMsg ); 
  163.         GlobalFree( pFile ); 
  164.         CloseHandle( hFile ); 
  165.         return 3; // indicate write file failed! 
  166.     } 
  167.     GlobalFree( pFile ); 
  168.     CloseHandle( hFile ); 
  169.     printf(" Yes you get it/n" ); 
  170.     return 0;   // indicate success 
  171.      
  172. DWORD RvaToFileOff( PVOID pFile,  DWORD Rva ) 
  173. /*++ 
  174. Routine Name: 
  175.     RvaToFileOffset 
  176. Description: 
  177.     Translate the Relative Virtual Address to Raw File Offset 
  178. Arugments: 
  179.     File Map; Rva; 
  180. Return: 
  181.     File Offset 
  182. --*/ 
  183.     static DWORD dwSections; 
  184.     DWORD i; 
  185.     static PIMAGE_SECTION_HEADER pSections; 
  186.     ULONG ulDiffer = 0;          
  187.     static BOOL bFunExecute = FALSE;    // GetSectionInfo should only execute once.(?) 
  188.      
  189.     if( bFunExecute == FALSE ) 
  190.     { 
  191.         dwSections = GetSectionsInfo( pFile, &pSections ); 
  192.         bFunExecute = TRUE; 
  193.     } 
  194.     for ( i = 0; i < dwSections; i++ ) 
  195.     { 
  196.         if( (Rva >= pSections[i].VirtualAddress) &&  
  197.                 (Rva <= (pSections[i].VirtualAddress + pSections[i].Misc.VirtualSize)) )     
  198.         { 
  199.             // 
  200.             // indicate in the this section. 
  201.             // 
  202.             ulDiffer = pSections[i].VirtualAddress - pSections[i].PointerToRawData; 
  203.             break
  204.         } 
  205.     } 
  206.      
  207.     return (Rva - ulDiffer); 
  208. DWORD 
  209. GetSectionsInfo(  
  210.         PVOID pFile, 
  211.         PIMAGE_SECTION_HEADER *pSections 
  212.         ) 
  213. /*  
  214.     Return number of sections  
  215.     Return pointer to sections table 
  216. */ 
  217.     DWORD dwSections; 
  218.     PIMAGE_SECTION_HEADER hSections; 
  219.     // 
  220.     // Jump to section table 
  221.     // 
  222.      
  223.     PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pFile; 
  224.     PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((PCHAR)pFile + pDosHeader->e_lfanew); // e_lfanew + 0x3c  
  225.     dwSections = pNtHeader->FileHeader.NumberOfSections; // NumberOfSections + 0x02  
  226.     //  
  227.     // Allocate the memory for section table 
  228.     // 
  229.     hSections = (PIMAGE_SECTION_HEADER)GlobalAlloc( GMEM_FIXED, dwSections*sizeof(IMAGE_SECTION_HEADER) ); 
  230.      
  231.     // 
  232.     // Copy the section table information 
  233.     // 
  234.     PIMAGE_SECTION_HEADER pSectionHeader = (PIMAGE_SECTION_HEADER)(++pNtHeader); 
  235.      
  236.     memcpy( (PVOID)hSections, (PVOID)pSectionHeader, (SIZE_T)dwSections*sizeof(IMAGE_SECTION_HEADER) ); 
  237.     *pSections = hSections; 
  238.     return dwSections; 
  239. BOOL VerifyPE( PVOID pFile ) 
  240.     PIMAGE_DOS_HEADER pDosHeader; 
  241.     PIMAGE_NT_HEADERS pNtHeader; 
  242.     pDosHeader = (PIMAGE_DOS_HEADER)pFile; 
  243.     if ( pDosHeader->e_magic != 0x5A4D )   // compare with 'MZ' 
  244.         return FALSE; 
  245.     pNtHeader = (PIMAGE_NT_HEADERS)((PCHAR)pFile + pDosHeader->e_lfanew);   // e_lfanew + 0x3c  
  246.     if ( pNtHeader->Signature != 0x00004550 ) // compare with 'PE/0/0' 
  247.         return FALSE; 
  248.     return TRUE; 
  249. ULONG char2ul(char* lpUlNum) 
  250.     ULONG ulSum = 0; 
  251.     while(*lpUlNum) 
  252.     { 
  253.         if(*lpUlNum>='0' && *lpUlNum<='9'
  254.             *lpUlNum = *lpUlNum - '0'
  255.         else if(*lpUlNum>='A' && *lpUlNum<='F'
  256.             *lpUlNum = *lpUlNum - 'A' + 10; 
  257.         else 
  258.             *lpUlNum = *lpUlNum - 'a' + 10; 
  259.         ulSum = ulSum*16 + *lpUlNum; 
  260.         lpUlNum++; 
  261.     } 
  262.     return ulSum; 
  263. BOOL RelocFile( PVOID pFile, ULONG BaseAddr ) 
  264.     PIMAGE_NT_HEADERS pNtHeader; 
  265.     PIMAGE_DOS_HEADER pDosHeader; 
  266.     DWORD dwImageBase; 
  267.     DWORD pRelocAddr,dwRelocAddr; 
  268.     DWORD dwDiffer; 
  269.     PWORD  pType; 
  270.     PIMAGE_RELOCATION pRelocBlock; 
  271.      
  272.     pDosHeader = (PIMAGE_DOS_HEADER)pFile; 
  273.     pNtHeader = (PIMAGE_NT_HEADERS)((PCHAR)pFile + pDosHeader->e_lfanew);   // e_lfanew + 0x3c  
  274.     dwImageBase = pNtHeader->OptionalHeader.ImageBase; 
  275.     dwDiffer = dwImageBase - BaseAddr;  // pay attention to the order 
  276.     // Get reloc table RVA 
  277.     PIMAGE_DATA_DIRECTORY pRelocTable = (PIMAGE_DATA_DIRECTORY) 
  278.         pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;  
  279.     // Get reloc table File Offset 
  280.     pRelocBlock = (PIMAGE_RELOCATION)( (PCHAR)pFile + RvaToFileOff( pFile, (DWORD)pRelocTable ) ); // the pRelocTable is file offset? 
  281.     do 
  282.     { 
  283.         pType = &pRelocBlock->Type; 
  284.         do 
  285.         { 
  286.              
  287.             // Get reloc address's RVA 
  288.             if( ( *pType && 0x3000) == 0 ) 
  289.             { 
  290.                 if( ( *pType && 0xf000) == 0 ) 
  291.                     continue
  292.                 return TRUE; 
  293.             } 
  294.             pRelocAddr = pRelocBlock->VirtualAddress + (*pType & 0x0fff);    
  295.             // pRelocAddr += dwImageBase; 
  296.             // Get reloc address's File Offset 
  297.             pRelocAddr = RvaToFileOff( pFile, pRelocAddr ); 
  298.         //  DWORD test = pRelocAddr; 
  299.             // Go to the Buffer offset 
  300.             pRelocAddr += (DWORD)pFile; 
  301.             // Get the reloc address 
  302.             dwRelocAddr = *(PDWORD)pRelocAddr; 
  303.             // Calculate the new address 
  304.             dwRelocAddr -= dwDiffer; 
  305.              
  306.             // Copy to the file 
  307.             *(PDWORD)pRelocAddr = dwRelocAddr; 
  308.         } while( ++pType < (PWORD)((PCHAR)pRelocBlock + pRelocBlock->SymbolTableIndex) ); 
  309.              
  310.         pRelocBlock = (PIMAGE_RELOCATION)((PCHAR)pRelocBlock + pRelocBlock->SymbolTableIndex ); 
  311.         }   while( pRelocBlock->VirtualAddress != 0 );// loop the reloc block entry 
  312.      
  313.     pNtHeader->OptionalHeader.ImageBase = BaseAddr;
  314.     return TRUE; 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值