一些PE文件操作的函数集合DLL库

这篇博客汇总了作者在程序中经常使用的PE相关函数,并整合到一个DLL库中,便于日后开发时调用。
摘要由CSDN通过智能技术生成

把前面一些程序中用到的PE相关函数集合在一个DLL中方便使用

#ifndef PE32_K_H
#define PE32_K_H

#ifdef __cplusplus
#define EXPORT extern "C" __declspec (dllexport)
#else
#define EXPORT __declspec (dllexport)
#endif

//指定
#define ADD_LAST_SECTION 1	//添加代码到最后一个区段	
#define ADD_NEW_SECTION  2  //添加代码到一个新建的区段
#define ADD_PE_HEADER	 3  //添加代码到PE头部



//重置,重置后可继续用文件初始化此DLL
EXPORT BOOL _stdcall Reset(TCHAR szFileName[]);


//使用函数前必须调用此函数初始化
//参数---szFileName:文件名
EXPORT BOOL _stdcall InitPE32(TCHAR szFileName[]);


//取得原文件数据指针,只读属性
EXPORT CONST PBYTE _stdcall GetFileBuffer();


//取得文件名
EXPORT CONST PTCHAR _stdcall GetFileName();


//添加代码到目标文件
//参数---szNewFile:添加代码后新文件的名字	lpCOdeStart:指向代码起始处	
//		 dwCodeSize:添加代码的大小			dwTypeOfAdd:添加方法类型
EXPORT BOOL _stdcall AddCode(TCHAR szNewFile[], PBYTE lpCodeStart, DWORD dwCodeSize, DWORD dwTypeOfAdd);


//获得目标文件的CRC32校验值
EXPORT DWORD _stdcall GetCRC32(TCHAR szFileName[] );


//检测是否为PE文件
//参数---szFileName:文件名
EXPORT BOOL _stdcall IsPeFile(TCHAR szFileName[]);


//将RVA偏移转换成文件偏移,失败返回-1
EXPORT DWORD _stdcall RvaToOffset (IMAGE_DOS_HEADER *lpFileHead, DWORD dwRva);


//将RVA偏移转成文件指针偏移,失败返回NULL
EXPORT PBYTE _stdcall RvaToPointer(IMAGE_DOS_HEADER *lpFileHead,DWORD dwRva);


//将虚拟地址转成文件指针偏移,失败返回NULL
EXPORT PBYTE _stdcall VirtualAddressToPointer(IMAGE_DOS_HEADER *lpFileHead,DWORD dwVirtualAddress);


//获得RVA偏移处的节区名称,失败返回NULL
EXPORT CONST PBYTE _stdcall GetRvaSection (IMAGE_DOS_HEADER *lpFileHead, DWORD dwRva);


//获得指定RVA所处节区的节表头,失败返回NULL
EXPORT PIMAGE_SECTION_HEADER _stdcall GetSectionOfRva (IMAGE_DOS_HEADER *lpFileHead, char* secName);


//文件偏移转换成RVA,失败返回-1
EXPORT DWORD _stdcall OffsetToRVA(IMAGE_DOS_HEADER *lpFileHead, DWORD dwOffset);


//文件偏移转换成内存指针,失败返回NULL
EXPORT PBYTE _stdcall OffsetToPointer(IMAGE_DOS_HEADER *lpFileHead, DWORD dwOffset);


//提取图标数据,参数指定文件名
EXPORT BOOL _stdcall GetIcon (TCHAR	szIconFileName[]);

#endif


 

#include <windows.h>
#include "PE32_K.H"


TCHAR		g_szFileName[MAX_PATH] = { 0 };
HINSTANCE	g_hInstDll	= NULL;		//DLL模块句柄
PBYTE		g_lpBuffer	= NULL;		//存储文件数据
DWORD		g_dwFileSize= 0;		//文件数据大小
PBYTE		g_lpNewFile = NULL;		//存储添加代码后的数据
BOOL		PE	= FALSE;  //指示是否是PE文件


void _stdcall DllClean();

///

BOOL WINAPI DllMain(HINSTANCE hInstDll, DWORD fdwReason, PVOID fImpLoad) {

   switch (fdwReason) {

      case DLL_PROCESS_ATTACH:
         // DLL is attaching to the address space of the current process.
         g_hInstDll = hInstDll;
         break;

      case DLL_THREAD_ATTACH:
         // A new thread is being created in the current process.
         break;

      case DLL_THREAD_DETACH:
         // A thread is exiting cleanly.
         break;

      case DLL_PROCESS_DETACH:
         // The calling process is detaching the DLL from its address space.
         DllClean();
		 break;
   }
   return(TRUE);
}

///



///将RVA偏移转换成文件偏移,失败返回-1

DWORD _stdcall RvaToOffset (IMAGE_DOS_HEADER *lpFileHead, DWORD dwRva)
{
	::IMAGE_NT_HEADERS		*lpPEHead;
	::IMAGE_SECTION_HEADER	*lpSectionHead;
	DWORD i;
	lpPEHead		= (IMAGE_NT_HEADERS*)( (BYTE*)lpFileHead + lpFileHead->e_lfanew);
	i	= lpPEHead->FileHeader.NumberOfSections;
	lpSectionHead	= (IMAGE_SECTION_HEADER*)(++lpPEHead); 
	for ( ; i > 0 ; i--, lpSectionHead++)
	{
		if ( (dwRva >= lpSectionHead->VirtualAddress) && (dwRva < (lpSectionHead->VirtualAddress + lpSectionHead->SizeOfRawData) ) )
		{
			dwRva	= dwRva - lpSectionHead->VirtualAddress + lpSectionHead->PointerToRawData;
			return dwRva;
		}
	}
	return -1;
}





将RVA偏移转成文件指针偏移,失败返回NULL

PBYTE _stdcall RvaToPointer(IMAGE_DOS_HEADER *lpFileHead,DWORD dwRva)
{
	DWORD	Offset	= RvaToOffset(lpFileHead, dwRva);
	if(Offset == -1)
		return NULL;
	return	(PBYTE)(lpFileHead) + Offset;
}





将虚拟地址转成文件指针偏移,失败返回NULL

PBYTE _stdcall VirtualAddressToPointer(IMAGE_DOS_HEADER *lpFileHead,DWORD dwVirtualAddress)
{
	::IMAGE_NT_HEADERS		*lpPEHead;
	lpPEHead		= (IMAGE_NT_HEADERS*)( (BYTE*)lpFileHead + lpFileHead->e_lfanew);
	
	return (PBYTE)RvaToPointer(lpFileHead, dwVirtualAddress - lpPEHead->OptionalHeader.ImageBase);
}





获得RVA偏移处的节区名称

CONST PBYTE _stdcall GetRvaSection (IMAGE_DOS_HEADER *lpFileHead, DWORD dwRva)
{
	IMAGE_NT_HEADERS		*lpPEHead;
	IMAGE_SECTION_HEADER	*lpSectionHead;
	DWORD i;
	lpPEHead		= (IMAGE_NT_HEADERS*)( (BYTE*)lpFileHead + lpFileHead->e_lfanew);
	i	= lpPEHead->FileHeader.NumberOfSections;
	lpSectionHead	= (IMAGE_SECTION_HEADER*)(++lpPEHead); 
	for ( ; i > 0 ; i--, lpSectionHead++)
	{
		if ( (dwRva >= lpSectionHead->VirtualAddress) && (dwRva < (lpSectionHead->VirtualAddress + lpSectionHead->SizeOfRawData) ) )
		{
			return (PBYTE)lpSectionHead;
		}
	}
	return NULL;
}





///获得指定RVA所处节区的节表头,失败返回NULL/

PIMAGE_SECTION_HEADER _stdcall GetSectionOfRva (IMAGE_DOS_HEADER *lpFileHead, char* secName)
{
	::PIMAGE_NT_HEADERS lpNtHead		= (PIMAGE_NT_HEADERS)( (BYTE*)lpFileHead + lpFileHead->e_lfanew);
	DWORD dwSec = lpNtHead->FileHeader.NumberOfSections;
	IMAGE_SECTION_HEADER* lpSection	= (PIMAGE_SECTION_HEADER) (lpNtHead + 1);
	
	for (DWORD i=0; i < dwSec; i++)
	{
		if(!strncmp((char*)lpSection->Name, secName, IMAGE_SIZEOF_SHORT_NAME) )
			return lpSection;
		lpSection++;
	}
	return NULL;
}





文件偏移转换成RVA///

DWORD _stdcall OffsetToRVA(IMAGE_DOS_HEADER *lpFileHead, DWORD dwOffset)
{
	::IMAGE_NT_HEADERS		*lpPEHead;
	::IMAGE_SECTION_HEADER	*lpSectionHead;
	DWORD i;
	lpPEHead		= (IMAGE_NT_HEADERS*)( (BYTE*)lpFileHead + lpFileHead->e_lfanew);
	i	= lpPEHead->FileHeader.NumberOfSections;
	lpSectionHead	= (IMAGE_SECTION_HEADER*)(++lpPEHead); 

	for ( ; i > 0; i--, lpSectionHead++)
	{
		if ( (dwOffset >= lpSectionHead->PointerToRawData) && (dwOffset < (lpSectionHead->PointerToRawData + lpSectionHead->SizeOfRawData) ) )
		{
			dwOffset	= dwOffset - lpSectionHead->PointerToRawData + lpSectionHead->VirtualAddress;
			return dwOffset;
		}
	}
	return -1;
}





文件偏移转换成内存指针///

PBYTE _stdcall OffsetToPointer(IMAGE_DOS_HEADER *lpFileHead, DWORD dwOff
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值