以前看雪发的老贴,挪一波。。。
代码:
//PeReadWrite.h 文件
#pragma once
class PeReadWrite
{
private:
HANDLE hFile;
HANDLE hMapping;
PVOID pBaseAddr;
public:
//构造函数
PeReadWrite();
//加载文件
bool loadFile(CString filePath);
//返回载入的地址
DWORD getBaseAddr();
//判断是否是PE文件
bool isPeFile();
//获取DOS头
IMAGE_DOS_HEADER *getDosHeader();
//获取NT头
IMAGE_NT_HEADERS *getNtHeader();
//获取节表起始
IMAGE_SECTION_HEADER *getSectionStart();
//获取导入表
IMAGE_IMPORT_DESCRIPTOR *getImport();
//获取导出表
IMAGE_EXPORT_DIRECTORY *getExport();
//获取重定位
IMAGE_BASE_RELOCATION *getReLocation();
//获取资源
IMAGE_RESOURCE_DIRECTORY *getResource();
//计算RvaToVa
DWORD RvaToVa(DWORD rva);
//关闭一系列操作
void UnFile();
};
cpp文件
代码:
//PeReadWrite.cpp 文件
#include "stdafx.h"
#include "PeReadWrite.h"
#include "windows.h"
//默认构造函数
PeReadWrite::PeReadWrite(){}
bool PeReadWrite::loadFile(CString filePath){
hFile = CreateFile(filePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, 0);
if (hFile == INVALID_HANDLE_VALUE)
{
return FALSE;
}
//创建内存映射文件
if (!(hMapping = CreateFileMapping(hFile, 0, PAGE_READWRITE | SEC_COMMIT, 0, 0, 0)))
{
CloseHandle(hFile);
return FALSE;
}
//把文件映像存入pBaseAddr
if (!(pBaseAddr = MapViewOfFile(hMapping, FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, 0)))
{
CloseHandle(hMapping);
CloseHandle(hFile);
return FALSE;
}
return TRUE;
}
//返回载入地址
DWORD PeReadWrite::getBaseAddr(){
return (DWORD)pBaseAddr;
}
//获取NT头
IMAGE_NT_HEADERS* PeReadWrite::getNtHeader(){
IMAGE_DOS_HEADER* dosHead = (IMAGE_DOS_HEADER*)pBaseAddr;
return (IMAGE_NT_HEADERS *)((DWORD)pBaseAddr + dosHead->e_lfanew);
}
//获取DOS头
IMAGE_DOS_HEADER* PeReadWrite::getDosHeader(){
return (IMAGE_DOS_HEADER *)pBaseAddr;
}
//获取节表起始
IMAGE_SECTION_HEADER* PeReadWrite::getSectionStart(){
return (IMAGE_SECTION_HEADER*)((DWORD)getNtHeader() + sizeof(IMAGE_NT_HEADERS));
}
//获取导入表
IMAGE_IMPORT_DESCRIPTOR* PeReadWrite::getImport(){
DWORD importTable = RvaToVa(getNtHeader()->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
return (IMAGE_IMPORT_DESCRIPTOR *)importTable;
}
//获取导出表
IMAGE_EXPORT_DIRECTORY* PeReadWrite::getExport(){
DWORD exportTable = RvaToVa(getNtHeader()->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
return (IMAGE_EXPORT_DIRECTORY*)exportTable;
}
//获取重定位
IMAGE_BASE_RELOCATION* PeReadWrite::getReLocation(){
DWORD reLocation = RvaToVa(getNtHeader()->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
return (IMAGE_BASE_RELOCATION*)reLocation;
}
//获取资源表
IMAGE_RESOURCE_DIRECTORY *PeReadWrite::getResource(){
DWORD source = RvaToVa(getNtHeader()->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress);
return (IMAGE_RESOURCE_DIRECTORY *)source;
}
//计算 RvaToVa
DWORD PeReadWrite::RvaToVa(DWORD rva){
IMAGE_SECTION_HEADER *sectionHeader;
int secNum = getNtHeader()->FileHeader.NumberOfSections;
sectionHeader = getSectionStart();
for (int i = 0; i<secNum; i++)
{
if ((sectionHeader->VirtualAddress <= rva)&& rva<(sectionHeader->VirtualAddress + sectionHeader->SizeOfRawData))
return (rva - sectionHeader->VirtualAddress + sectionHeader->PointerToRawData) + (DWORD)pBaseAddr;
sectionHeader++;
}
return 0;
}
//清除内存映射和关闭文件
void PeReadWrite::UnFile(){
if (pBaseAddr!=NULL)
{
UnmapViewOfFile(pBaseAddr);
}
if (hMapping!=NULL)
{
CloseHandle(hMapping);
}
if (hFile!=NULL)
{
CloseHandle(hFile);
}
}
//验证是否是PE文件
bool PeReadWrite::isPeFile(){
if (getDosHeader()->e_magic != IMAGE_DOS_SIGNATURE)
{
return FALSE;
}
if (getNtHeader()->Signature != IMAGE_NT_SIGNATURE)
{
return FALSE;
}
return TRUE;
}