• 理解别人写的简单的重定位程序


    看了下看雪的一篇文章,加深下对重定位的理解,其实这是一个程序

    https://bbs.pediy.com/thread-76638.htm

    这个程序需要用户输入的是加载基址,还有文件的路径

    开始首先通过MZ头,还有e_lfanew偏移是否是PEx00x00 来判断这是否是一个PE文件

    BOOL VerifyPE( PVOID pFile ) 
    { 
        PIMAGE_DOS_HEADER pDosHeader; 
        PIMAGE_NT_HEADERS pNtHeader; 
     
        pDosHeader = (PIMAGE_DOS_HEADER)pFile; 
        if ( pDosHeader->e_magic != 0x5A4D )   // compare with 'MZ' 
            return FALSE; 
     
        pNtHeader = (PIMAGE_NT_HEADERS)((PCHAR)pFile + pDosHeader->e_lfanew);   // e_lfanew + 0x3c  
        if ( pNtHeader->Signature != 0x00004550 ) // compare with 'PE' 
            return FALSE; 
     
        return TRUE; 
    }
    

    重定位

    计算镜像基址与真正加载基址的差值

    pDosHeader = (PIMAGE_DOS_HEADER)pFile;  
    pNtHeader = (PIMAGE_NT_HEADERS)((PCHAR)pFile + pDosHeader->e_lfanew);   // e_lfanew + 0x3c   
    
    dwImageBase = pNtHeader->OptionalHeader.ImageBase;  
    dwDiffer = dwImageBase - BaseAddr;  // pay attention to the order 
    

    获取重定位表RVA,并计算出File Offset

     // Get reloc table RVA  
    PIMAGE_DATA_DIRECTORY pRelocTable = (PIMAGE_DATA_DIRECTORY)pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;   
    
    // Get reloc table File Offset  
    pRelocBlock = (PIMAGE_RELOCATION)( (PCHAR)pFile + RvaToFileOff( pFile, (DWORD)pRelocTable ) ); // the pRelocTable is file offset?  
    

    之后根据重定位表循环计算真正的地址,具体如下

    1、一次获取一条记录,获取其RVA,算出File Offset
    2、通过与pRelocAddr相加得到储存原始地址的地方(即要修正的地址)
    3、将这个要修正的地址减去之前算出来的基址的差别即可
    4、最后将结果写回文件即可

    pRelocAddr = pRelocBlock->VirtualAddress + (*pType & 0x0fff);     
    // pRelocAddr += dwImageBase;  
    
    // Get reloc address's File Offset  
    pRelocAddr = RvaToFileOff( pFile, pRelocAddr );  
    
    //  DWORD test = pRelocAddr;  
    
    // Go to the Buffer offset  
    pRelocAddr += (DWORD)pFile;  
    
    // Get the reloc address  
    dwRelocAddr = *(PDWORD)pRelocAddr;  
    
    // Calculate the new address  
    dwRelocAddr -= dwDiffer;  
    
    // Copy to the file  
    *(PDWORD)pRelocAddr = dwRelocAddr;
    
  • 相关阅读:
    toj 2819 Travel
    toj 2807 Number Sort
    zoj 2818 Prairie dogs IV
    zoj 1276 Optimal Array Multiplication Sequence
    toj 2802 Tom's Game
    toj 2798 Farey Sequence
    toj 2815 Searching Problem
    toj 2806 Replace Words
    toj 2794 Bus
    css截取字符
  • 原文地址:https://www.cnblogs.com/cnsec/p/13286477.html
Copyright © 2020-2023  润新知