首页
社区
课程
招聘
[原创][分享]PE文件结构之打印重定位表
发表于: 2020-10-8 11:34 3502

[原创][分享]PE文件结构之打印重定位表

2020-10-8 11:34
3502


#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <windows.h>
 
DWORD ReadPEFile(char* filepath,PVOID* pFileBuffer)
{
    PVOID pTempFileBuffer = NULL;
    DWORD Filesize = 0;
 
 
    FILE* pFile = NULL;
    pFile = fopen(filepath,"rb");
    if(!pFile)
    {
        printf("文件打开失败");
        return 0;
    }
    fseek(pFile,0,SEEK_END);
    Filesize = ftell(pFile);
    fseek(pFile,0,SEEK_SET);
 
    pTempFileBuffer = malloc(Filesize);
 
    if(!pTempFileBuffer)
    {
        printf("申请动态内存失败");
        fclose(pFile);
        return 0;
 
    }
 
    size_t n = fread(pTempFileBuffer,Filesize,1,pFile);
    if(!n)
    {
        printf("文件写入文件缓冲区失败");
        free(pTempFileBuffer);
        fclose(pFile);
        return 0;
    }
    *pFileBuffer = pTempFileBuffer;
    pTempFileBuffer = NULL;
    free(pTempFileBuffer);
    fclose(pFile);
 
    return Filesize;
 
}
 
DWORD RvaToFoa(PIMAGE_NT_HEADERS pNTHeader, DWORD dwRVA)
{
    PIMAGE_SECTION_HEADER pSection = (PIMAGE_SECTION_HEADER)((DWORD)pNTHeader + sizeof(IMAGE_NT_HEADERS));
 
    for(int i = 0; i < pNTHeader->FileHeader.NumberOfSections; i++)
    {
        if(dwRVA >= pSection[i].VirtualAddress && dwRVA < (pSection[i].VirtualAddress + pSection[i].SizeOfRawData))
        {
            return pSection[i].PointerToRawData + (dwRVA - pSection[i].VirtualAddress);
        }
    }
 
    return 0;
}
 
 
 
void relocation(PVOID pFileBuffer)
{   
    BYTE secName[9] = {0};
    PIMAGE_DOS_HEADER pDosHeader;
    PIMAGE_NT_HEADERS pNtHeaders;
    PIMAGE_BASE_RELOCATION  pBaseRec;
    PIMAGE_SECTION_HEADER pSectionHeader;
 
    pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
    pNtHeaders = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer+pDosHeader->e_lfanew);
 
    printf("重定位表的相对虚拟地址:%x\n",pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
    printf("重定位表的大小:%x\n",pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size);
 
    DWORD pBaseRecOffset = RvaToFoa(pNtHeaders, pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress); //注意这个VirtualAddress是VA
    pBaseRec = (PIMAGE_BASE_RELOCATION)(pBaseRecOffset+(DWORD)pFileBuffer);
    pSectionHeader = (PIMAGE_SECTION_HEADER)(pNtHeaders+1);
 
    for(int i=0; pBaseRec->SizeOfBlock && pBaseRec->VirtualAddress; i++)
    {
        DWORD FOA = RvaToFoa(pNtHeaders, pBaseRec->VirtualAddress);
        DWORD size = (pBaseRec->SizeOfBlock - 8 )/2; // VirtualAddress SizeOfBlock共占8字节,每个项2字节
 
        //确定该结构所属的节
 
         for(DWORD j=0;j<pNtHeaders->FileHeader.NumberOfSections;j++)
         {
             DWORD lower =RvaToFoa(pNtHeaders, pSectionHeader[j].VirtualAddress);
             DWORD upper =RvaToFoa(pNtHeaders, pSectionHeader[j].VirtualAddress+pSectionHeader[j].Misc.VirtualSize);
 
            if(FOA>=lower && FOA<=upper )
            {
                memcpy(secName,pSectionHeader[j].Name,8);
                break;
            }
         }
         printf("第%d块.Relocation\n VirtualAddress %x(%s)\n SizeOfBlock %x\n", i+1, pBaseRec->VirtualAddress,secName, size); //打印本页的主要信息
         printf("RVA,TYPE\n");
 
         //打印一个页中,所有重定位地址与信息
         WORD * recAddr = (WORD *)((BYTE *)pBaseRec+8); //指向第一个目录项
        //如果高4位是3则取后12位地址加上VirtualAddress才是真正需要修复的数据的Rva
         for(j=0; j<size; j++)
         {
            DWORD offset = (recAddr[j] & 0x0FFF) + FOA ;
            WORD type = recAddr[j] >> 12;
 
            if(type!=0)
            {
                 printf("%08X,  %x\n",offset+pBaseRec->VirtualAddress,type);
            }
         }
        memset(secName, 0, 9);
        pBaseRec = (PIMAGE_BASE_RELOCATION )((BYTE *)pBaseRec + pBaseRec->SizeOfBlock);//移到下一页
    }
}
 
 
 
int main(int argc, char* argv[])
{
    char filepath[] = "F:\\pwn\\test\\TTTT.dll";
    PVOID pFileBuffer = NULL;
 
 
    ReadPEFile(filepath,&pFileBuffer);
    relocation(pFileBuffer);
 
    return 0;
}
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <windows.h>
 
DWORD ReadPEFile(char* filepath,PVOID* pFileBuffer)
{
    PVOID pTempFileBuffer = NULL;
    DWORD Filesize = 0;
 
 
    FILE* pFile = NULL;
    pFile = fopen(filepath,"rb");
    if(!pFile)
    {
        printf("文件打开失败");
        return 0;
    }
    fseek(pFile,0,SEEK_END);
    Filesize = ftell(pFile);
    fseek(pFile,0,SEEK_SET);
 
    pTempFileBuffer = malloc(Filesize);
 
    if(!pTempFileBuffer)
    {
        printf("申请动态内存失败");
        fclose(pFile);
        return 0;
 
    }
 
    size_t n = fread(pTempFileBuffer,Filesize,1,pFile);
    if(!n)
    {
        printf("文件写入文件缓冲区失败");
        free(pTempFileBuffer);
        fclose(pFile);
        return 0;
    }
    *pFileBuffer = pTempFileBuffer;
    pTempFileBuffer = NULL;
    free(pTempFileBuffer);
    fclose(pFile);
 
    return Filesize;
 
}
 
DWORD RvaToFoa(PIMAGE_NT_HEADERS pNTHeader, DWORD dwRVA)
{
    PIMAGE_SECTION_HEADER pSection = (PIMAGE_SECTION_HEADER)((DWORD)pNTHeader + sizeof(IMAGE_NT_HEADERS));
 
    for(int i = 0; i < pNTHeader->FileHeader.NumberOfSections; i++)
    {
        if(dwRVA >= pSection[i].VirtualAddress && dwRVA < (pSection[i].VirtualAddress + pSection[i].SizeOfRawData))
        {
            return pSection[i].PointerToRawData + (dwRVA - pSection[i].VirtualAddress);
        }
    }
 
    return 0;
}
 
 
 
void relocation(PVOID pFileBuffer)

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 1
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//