您的位置:首页 > 其它

PE结构是那一类!获取导入表和导出表的类

2008-05-16 08:09 225 查看
//--------------------------------------PNExeInfo.h----------------------------------------------------

//加载调试辅助:
#include "IMAGEHLP.H"
#pragma comment(lib,"ImageHlp.lib")

#include "tlhelp32.h"
#pragma comment(lib,"th32.lib")

class CPNExeInfo
{
public:
CPNExeInfo();
virtual ~CPNExeInfo();
public:
BOOL Release();
int LoadPE(DWORD pId); //进程装载
int LoadPE(DWORD pId,DWORD mId); //模块装载
int LoadPE(LPCTSTR path); //文件装载
DWORD GetSize(){return dwFileSize;}

//文件头函数:
PIMAGE_DOS_HEADER GetDosHeader(){return _dosHeader;}
PIMAGE_NT_HEADERS GetNTHeaders(){return _ntHeader;}
PIMAGE_SECTION_HEADER GetSection(DWORD dwRVA=NULL);
//输入表函数:
PIMAGE_IMPORT_DESCRIPTOR GetImportModule(DWORD *dwSize=NULL,LPCTSTR *name=NULL);
PIMAGE_THUNK_DATA GetProcOfModule(LPCTSTR name,DWORD *dwSize=NULL,
LPCTSTR *ProcName=NULL,DWORD *Hint=NULL,
DWORD *Offset=NULL,DWORD *Value=NULL,DWORD *Rva=NULL);
PIMAGE_THUNK_DATA GetProcOfModule(int count,DWORD *dwSize=NULL,
LPCTSTR *ProcName=NULL,DWORD *Hint=NULL,
DWORD *Offset=NULL,DWORD *Value=NULL,DWORD *Rva=NULL);
//输出表函数:
PIMAGE_EXPORT_DIRECTORY GetExportInfo(DWORD *dwSize=NULL,LPCTSTR *strFun=NULL,DWORD *dwAddr=NULL,
DWORD *dwOrdin=NULL,DWORD *dwOffset=NULL,LPTSTR DllName=NULL);
protected:
LPCTSTR m_path; //路径

HANDLE hFile; //打开文件句柄
DWORD dwFileSize; //文件大小
private:
HANDLE hMapping; //映射句柄
LPVOID m_pData;

PIMAGE_DOS_HEADER _dosHeader;
PIMAGE_NT_HEADERS _ntHeader;
};

//-----------------------------------------PNExeInfo.cpp

//装载文件:
int CPNExeInfo::LoadPE(LPCTSTR path)
{
DWORD dwRead=NULL;
//保存路径:
m_path=path;

//以只读方式,其他进程对文件有读写权,打开文件:
hFile=CreateFile(m_path,GENERIC_READ,FILE_SHARE_WRITE|FILE_SHARE_READ,
NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if(hFile==INVALID_HANDLE_VALUE){return -10;} //-10代表打开文件失败;

//获取文件大小:
dwFileSize=GetFileSize(hFile,NULL);
if(dwFileSize <= 0){CloseHandle(hFile);return -11;} //-11代表获取文件大小失败;

/*
//创建镜像:
hMapping=::CreateFileMapping(hFile,NULL,PAGE_READONLY,0,0,NULL);
if(hMapping==NULL){
CloseHandle(hFile);return -20;} //-20创建镜像出错;

//映射地址:
m_pData=::MapViewOfFile(hMapping,FILE_MAP_READ,0,0,0);
if(m_pData==NULL){CloseHandle(hFile);return -21;} //-21代表影射地址出错;
*/

//方便以后销毁,采用分配内存方式:
m_pData=(DWORD*)::VirtualAlloc(NULL,dwFileSize,MEM_COMMIT,PAGE_READWRITE);

ReadFile(hFile,m_pData,dwFileSize,&dwRead,NULL);
//方便其他函数调用,初始化函数头:
_dosHeader =(PIMAGE_DOS_HEADER)m_pData;
_ntHeader =(PIMAGE_NT_HEADERS)((LONG)_dosHeader+(LONG)_dosHeader->e_lfanew);

//关闭文件:
CloseHandle(hFile);
return 0;
}

//装载其它进程,方便获得导出,和导入表:
int CPNExeInfo::LoadPE(DWORD pId)
{
DWORD dwRead=NULL;
HANDLE hModule=NULL;
MODULEENTRY32* minfo=new MODULEENTRY32;

if((int)pId<=0){return -10;}

hModule=CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,pId);
if((DWORD)hModule<=0){return -11;}
Module32First(hModule, minfo);

HANDLE hOpenProcess=::OpenProcess(PROCESS_VM_READ|PROCESS_VM_WRITE,FALSE,pId);

//创建地址:
m_pData=(DWORD*)::VirtualAlloc(NULL,minfo->modBaseSize,MEM_COMMIT,PAGE_READWRITE);
//读取进程:
::ReadProcessMemory(hOpenProcess,minfo->modBaseAddr,m_pData,minfo->modBaseSize,&dwRead);

_dosHeader =(PIMAGE_DOS_HEADER)m_pData;
_ntHeader =(PIMAGE_NT_HEADERS)((LONG)_dosHeader+(LONG)_dosHeader->e_lfanew);

//释放:
if(hModule!=NULL){CloseHandle(hModule);}
if(hOpenProcess!=NULL){CloseHandle(hOpenProcess);}
return 0;
}

//好了,我们只要能加载了,什么都好说:

输出表:

PIMAGE_EXPORT_DIRECTORY CPNExeInfo::GetExportInfo(DWORD *dwSize,LPCTSTR *strFun,DWORD *dwAddr,
DWORD *dwOrdin,DWORD *dwOffset,LPTSTR DllName)
{
PIMAGE_EXPORT_DIRECTORY _exportDir=NULL;
_exportDir=(PIMAGE_EXPORT_DIRECTORY)_ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;

if(_exportDir==NULL){return NULL;}

_exportDir=(PIMAGE_EXPORT_DIRECTORY)ImageRvaToVa(_ntHeader,_dosHeader,(DWORD)_exportDir,NULL);

//数量初始化:
DWORD dwNum=_exportDir->NumberOfNames;
if(dwNum<_exportDir->NumberOfFunctions){dwNum=_exportDir->NumberOfFunctions;}
if(dwSize!=NULL){*dwSize=dwNum;}

//名称初始化:
DWORD **ppdwNames = (DWORD **)_exportDir->AddressOfNames;
ppdwNames = (PDWORD*)ImageRvaToVa(_ntHeader,_dosHeader,(DWORD)ppdwNames,NULL);
if(!ppdwNames){return NULL;}

//地址初始化:
DWORD **ppdwAddr = (DWORD **)_exportDir->AddressOfFunctions;
ppdwAddr = (PDWORD*)ImageRvaToVa(_ntHeader,_dosHeader,(DWORD)ppdwAddr,NULL);
if(!ppdwAddr){return NULL;}

//序号初始化:
DWORD *ppdwOrdin=(DWORD*)ImageRvaToVa(_ntHeader,_dosHeader,(DWORD)_exportDir->AddressOfNameOrdinals,NULL);
if(!ppdwOrdin){return NULL;}

//获取文件名:
if(DllName!=NULL){
char *szdllName=(PSTR)ImageRvaToVa(_ntHeader,_dosHeader,(DWORD)_exportDir->Name,NULL);
//DllName=szdllName;
strcpy(DllName,szdllName);
}

for(DWORD i=0;i<dwNum;i++)
{
char* szFun=(PSTR)ImageRvaToVa(_ntHeader,_dosHeader,(DWORD)*ppdwNames,NULL);
if(strFun!=NULL){strFun[i]=szFun;}
if(dwAddr!=NULL){dwAddr[i]=(DWORD)*ppdwAddr;}
if(dwOffset!=NULL){
dwOffset[i]=(DWORD)ImageRvaToVa(_ntHeader,_dosHeader,(DWORD)*ppdwAddr,NULL);
dwOffset[i]=dwOffset[i]-(DWORD)_dosHeader;
}
if(dwOrdin!=NULL){dwOrdin[i]=(WORD)*ppdwOrdin;}

ppdwOrdin=(DWORD*)((DWORD)ppdwOrdin+2);
ppdwAddr++;
ppdwNames++;
}

return _exportDir;
}

//输入模块:
PIMAGE_IMPORT_DESCRIPTOR CPNExeInfo::GetImportModule(DWORD *dwSize,LPCTSTR *name)
{
PIMAGE_IMPORT_DESCRIPTOR _importDesc=NULL;

//获取输入表虚拟地址:
_importDesc=(PIMAGE_IMPORT_DESCRIPTOR)_ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
if(_importDesc==NULL){return NULL;}

//将虚拟地址进行转换:
_importDesc=(PIMAGE_IMPORT_DESCRIPTOR)::ImageRvaToVa(_ntHeader,m_pData,(DWORD)_importDesc,NULL);

DWORD dwRe=(DWORD)_importDesc;
int i=0;
if(name!=NULL)
{
for(;_importDesc->Name!=NULL;i++)
{
char *szName=(PSTR)ImageRvaToVa(_ntHeader, _dosHeader, (DWORD)_importDesc->Name, 0);
name[i]=szName;
_importDesc++;
}
}
if(dwSize!=NULL)memcpy(dwSize,(DWORD*)&i,sizeof(DWORD));
_importDesc=(PIMAGE_IMPORT_DESCRIPTOR)dwRe;

return _importDesc;
}

//获取模块的函数:
PIMAGE_THUNK_DATA CPNExeInfo::GetProcOfModule(LPCTSTR ModuleName,DWORD *dwSize,LPCTSTR *ProcName,
DWORD *Hint,DWORD *Offset,DWORD *Value,DWORD *Rva)
{
DWORD dwThunk=NULL;
PIMAGE_THUNK_DATA _pThunk=NULL;

PIMAGE_IMPORT_DESCRIPTOR _importDesc=NULL;

//获取输入表虚拟地址:
_importDesc=(PIMAGE_IMPORT_DESCRIPTOR)_ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
if(_importDesc==NULL){return NULL;}

//将虚拟地址进行转换:
_importDesc=(PIMAGE_IMPORT_DESCRIPTOR)::ImageRvaToVa(_ntHeader,m_pData,(DWORD)_importDesc,NULL);

for(int i=0;_importDesc->Name!=NULL;i++)
{
char *szName=(PSTR)ImageRvaToVa(_ntHeader, _dosHeader, (DWORD)_importDesc->Name, 0);
if(lstrcmp(ModuleName,szName)==0)
{
if(_importDesc->OriginalFirstThunk!=0)
{
dwThunk=_importDesc->OriginalFirstThunk;
_pThunk=(PIMAGE_THUNK_DATA)ImageRvaToVa(_ntHeader,_dosHeader,
(DWORD)_importDesc->OriginalFirstThunk,NULL);
break;
}
else
{
dwThunk=_importDesc->FirstThunk;
_pThunk=(PIMAGE_THUNK_DATA)ImageRvaToVa(_ntHeader,_dosHeader,
(DWORD)_importDesc->FirstThunk,NULL);
break;
}
}
_importDesc++;
}

DWORD dwRe=(DWORD)_pThunk;

if(ProcName==NULL){return _pThunk;}
for(i=0;_pThunk->u1.AddressOfData!=NULL;i++)
{
char *szFun=(PSTR)ImageRvaToVa(_ntHeader,_dosHeader,(DWORD)_pThunk->u1.AddressOfData->Name, 0);

ProcName[i]=szFun;
if(Hint!=NULL){
if(szFun!=NULL){memcpy(&Hint[i],szFun-2,2);}
else{Hint[i]=-1;}
}
if(Offset!=NULL){
Offset[i]=(DWORD)ImageRvaToVa(_ntHeader,_dosHeader,(DWORD)dwThunk,NULL);
Offset[i]=Offset[i]-(DWORD)m_pData;
}
if(Value!=NULL){
Value[i]=(DWORD)_pThunk->u1.AddressOfData;
if((Value[i]&0x80000000)==0x80000000){Value[i]&=0x7FFFFFFF;}
}
if(Rva!=NULL){
Rva[i]=dwThunk;
}
dwThunk+=4;
_pThunk++;
}

if(dwSize!=NULL)memcpy(dwSize,(DWORD*)&i,sizeof(DWORD));
_pThunk=(PIMAGE_THUNK_DATA)dwRe;
return _pThunk;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: