// helloworld1.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <windows.h>
DWORD RVA2OffSet(DWORD dwRVA, PIMAGE_NT_HEADERS32 pNt)
{
DWORD dwOffset = 0;
// 1. 获取第一个区段结构体
PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION(pNt);
// 2. 获取区段数量
DWORD dwSectionCount = pNt->FileHeader.NumberOfSections;
// 3. 遍历区段信息表
for (DWORD i = 0; i < dwSectionCount; i++)
{
// 4. 匹配RVA所在的区段
if (dwRVA >= pSection[i].VirtualAddress &&
dwRVA < (pSection[i].VirtualAddress + pSection[i].Misc.VirtualSize)
)
{ // 计算对应的文件偏移
dwOffset = dwRVA - pSection[i].VirtualAddress +
pSection[i].PointerToRawData;
return dwOffset;
}
}
return dwOffset;
}
void ShowReloc(PVOID lpImage, DWORD dwSize)
{
// 1. 获取DOS头
PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)lpImage;
// 2. 获取NT头
PIMAGE_NT_HEADERS32 pNt = (PIMAGE_NT_HEADERS32)((DWORD)lpImage + pDos->e_lfanew);
// 3. 获取数据目录表
PIMAGE_DATA_DIRECTORY pRelocDir = pNt->OptionalHeader.DataDirectory;
pRelocDir = &(pRelocDir[IMAGE_DIRECTORY_ENTRY_BASERELOC]);
DWORD dwOffset = RVA2OffSet(pRelocDir->VirtualAddress, pNt);
// 4. 获取重定位目录
PIMAGE_BASE_RELOCATION pReloc = (PIMAGE_BASE_RELOCATION)((DWORD)lpImage + dwOffset);
typedef struct {
WORD Offset : 12; // (1) 大小为12Bit的重定位偏移
WORD Type : 4; // (2) 大小为4Bit的重定位信息类型值
}TypeOffset, *PTypeOffset; // 这个结构体是A1Pass总结的
while (pReloc->VirtualAddress)
{
printf("重定位RVA基址:%p \n", pReloc->VirtualAddress);
PTypeOffset pTypeOffset = (PTypeOffset)(pReloc + 1);
DWORD dwSize = sizeof(IMAGE_BASE_RELOCATION);
// DWORD dwCount = (pReloc->SizeOfBlock - dwSize) / 2 - 1;
DWORD dwCount = (pReloc->SizeOfBlock - dwSize) / 2 - 1;
for (DWORD i = 0; i < dwCount; i++)
{
DWORD dwRVA = pReloc->VirtualAddress + pTypeOffset[i].Offset;
printf("->重定位RVA:%p,重定位文件偏移:%p,需要重定位的代码:%p\n",
dwRVA,
RVA2OffSet(dwRVA, pNt),
*(PDWORD)((DWORD)lpImage + RVA2OffSet(dwRVA, pNt)));
}
pReloc = (PIMAGE_BASE_RELOCATION)((DWORD)pReloc + pReloc->SizeOfBlock);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hFile = nullptr;
DWORD dwSize = 0;
PVOID lpFileImage = nullptr;
LPCTSTR strInPath = L"C:\\Users\\Denny\\Desktop\\(手动查找导入导出表)\\(手动查找导入导出表)\\MFCLibrary1Dll.dll";
//LPCTSTR strInPath = L"E:\\第八期\\2.第八期项目\\05.安全卫士\\1 郭晓勃 111\\Realse\\SAFE.exe";
if (INVALID_HANDLE_VALUE == (hFile = CreateFile(strInPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL)))
return false;
if (INVALID_FILE_SIZE == (dwSize = GetFileSize(hFile, NULL)))
{
CloseHandle(hFile);
return false;
}
if (!(lpFileImage = VirtualAlloc(NULL, dwSize, MEM_COMMIT, PAGE_READWRITE)))
{
CloseHandle(hFile);
return false;
}
DWORD dwRet;
if (!ReadFile(hFile, lpFileImage, dwSize, &dwRet, NULL))
{
CloseHandle(hFile);
VirtualFree(lpFileImage, 0, MEM_RELEASE);
return false;
}
ShowReloc(lpFileImage, dwSize);
//ShowImport(lpFileImage, dwSize);
return 0;
}
PE总结15--PE文件结构之 解析资源表
最新推荐文章于 2023-09-08 09:37:23 发布