php读取pe文件,C++ 读取PE文件信息(读取PE导入表等)

[C++] 纯文本查看 复制代码// ReadPEInfo.cpp : 定义控制台应用程序的入口点。

//

#include "stdafx.h"

#include

#include

#include

#include

void ReadNTPEInfo(PIMAGE_NT_HEADERS pImageNtPE);

ULONG RvaToOffset(IMAGE_NT_HEADERS * pNtHeader,ULONG Rva);

#define pNtHeaders pImageNtHeaders

int _tmain(int argc, _TCHAR* argv[])

{

char file[]="win32.exe";

//DOS头

PIMAGE_DOS_HEADER pImageDosHeader;

//NT头(包括PE标识+Image_File_Header+OptionHeader)

PIMAGE_NT_HEADERS pImageNtHeaders;

//标准PE头、

PIMAGE_FILE_HEADER pImageFileHeader;

//扩展PE头

IMAGE_OPTIONAL_HEADER32 pImageOptionHeaders;

HANDLE hFile;

HANDLE hMapObject;

//DOS头

PUCHAR uFileMap;

hFile= CreateFile(file,GENERIC_READ,0,NULL,OPEN_EXISTING,0,0);

if(hFile==NULL)

{

printf("打开文件失败\n");

system("pause");

return 0;

}

hMapObject=CreateFileMapping(hFile,NULL,PAGE_READONLY,0,0,NULL);

if(hMapObject==NULL)

{

printf("创建文件映射内核对对象失败\n");

system("pause");

return 0;

}

//PE基址

uFileMap=(PUCHAR)MapViewOfFile(hMapObject,FILE_MAP_READ,0,0,0);

if(uFileMap==NULL)

{

printf("映射到进程地址空间失败\n");

system("pause");

return 0;

}

pImageDosHeader=(PIMAGE_DOS_HEADER)uFileMap;

if(pImageDosHeader->e_magic!=IMAGE_DOS_SIGNATURE)

{

printf("不是PE结构\n");

system("pause");

return 0;

}

//定位到NT PE头

pImageNtHeaders=(PIMAGE_NT_HEADERS)((PUCHAR)uFileMap+pImageDosHeader->e_lfanew);

//导入表的相对虚拟地址(RVA)

ULONG rva_ofimporttable=pImageNtHeaders->OptionalHeader.DataDirectory[1].VirtualAddress;

//根据相对虚拟(rva)地址计算偏移地址(offset)

ULONG offset_importtable=RvaToOffset(pImageNtHeaders,rva_ofimporttable);

if(!offset_importtable)

{

printf("获取导入表偏移地址失败\n");

system("pause");

return 0;

}

PIMAGE_THUNK_DATA s;

//取得导入表的地址

IMAGE_IMPORT_DESCRIPTOR *pImportTable=(IMAGE_IMPORT_DESCRIPTOR *)((char*)uFileMap+offset_importtable);

IMAGE_IMPORT_DESCRIPTOR null_iid;

IMAGE_THUNK_DATA null_thunk;

memset(&null_iid, 0, sizeof(null_iid));

memset(&null_thunk, 0, sizeof(null_thunk));

//每个元素代表了一个引入的DLL。

for(int i=0; memcmp(pImportTable + i, &null_iid, sizeof(null_iid))!=0; i++)

{

char *dllName= (char*)(uFileMap+RvaToOffset(pImageNtHeaders,pImportTable[i].Name));

//拿到了DLL的名字

printf("模块[%d]: %s\n", i, (char*)dllName);

PIMAGE_THUNK_DATA32 pThunk=(PIMAGE_THUNK_DATA32)(uFileMap+RvaToOffset(pImageNtHeaders,pImportTable[i].FirstThunk));

while(pThunk->u1.Ordinal!=NULL)

{

PIMAGE_IMPORT_BY_NAME pname=(PIMAGE_IMPORT_BY_NAME)(uFileMap+RvaToOffset(pImageNtHeaders,pThunk->u1.AddressOfData));

printf("函数编号: %d 名称: %s\n",pname->Hint,pname->Name);

pThunk++;

}

}

system("pause");

return 0;

}

void ReadNTPEInfo(PIMAGE_NT_HEADERS pImageNtPE)

{

printf("运行平台: 0x%04X\n",pImageNtPE->FileHeader.Machine);

printf("节数量: %d\n",pImageNtPE->FileHeader.NumberOfSections);

printf("PE属性: 0x%04X\n",pImageNtPE->FileHeader.Characteristics);

}

//计算Offset

ULONG RvaToOffset(IMAGE_NT_HEADERS * pNtHeader,ULONG Rva)

{

//PE节

IMAGE_SECTION_HEADER *p_section_header;

ULONG sNum,i;

//取得节表项数目

sNum=pNtHeader->FileHeader.NumberOfSections;

//取得第一个节表项

p_section_header=(IMAGE_SECTION_HEADER *)

((BYTE *)pNtHeader+sizeof(IMAGE_NT_HEADERS));

for(i=0;i

{

//printf("PE 节名称: %s\n",p_section_header->Name);

if((p_section_header->VirtualAddress<=Rva)&&RvaVirtualAddress+p_section_header->SizeOfRawData))

{

return Rva-p_section_header->VirtualAddress+p_section_header->PointerToRawData;

}

p_section_header++;

}

return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值