PE文件操作类

以前看雪发的老贴,挪一波。。。

代码:

//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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值