在这里插入
#include <Windows.h>
#include <stdio.h>
#include <winnt.h>
PIMAGE_DOS_HEADER dos_header;
HANDLE handle;
PIMAGE_NT_HEADERS ntheader;
DWORD bytesRead;
DWORD lfanew;
PIMAGE_FILE_HEADER fileheader;
PIMAGE_SECTION_HEADER sectionheader;
PIMAGE_DATA_DIRECTORY data_directory;
// 导出表
PIMAGE_EXPORT_DIRECTORY Export;
// 导入表
PIMAGE_IMPORT_DESCRIPTOR import;
DWORD VirtualAddress;
DWORD exportVirtualAddress;
DWORD exportsize;
DWORD importVirtualAddress;
DWORD importsize;
DWORD *name;
DWORD FirstThunkfileRVA;
DWORD OriginalFirstThunkfileRVA;
PIMAGE_IMPORT_BY_NAME funcname;
WORD Machine;
WORD NumberOfSections;
DWORD SizeOfOptionalHeader;
DWORD getRWA(DWORD RVA, PIMAGE_SECTION_HEADER sectionheader)
{
DWORD RWA = 0;
for (int i = 0; i < 16; i++)
{
if (RVA >= sectionheader->VirtualAddress && RVA < sectionheader->VirtualAddress + sectionheader->SizeOfRawData)
{
RWA = (RVA - sectionheader->VirtualAddress) + sectionheader->PointerToRawData;
return RWA;
}
sectionheader = PIMAGE_SECTION_HEADER((BYTE *)sectionheader + (sizeof(IMAGE_SECTION_HEADER)));
}
return RWA;
}
void getImport(char *pFileBuf, int i)
{
if (i)
{
PIMAGE_THUNK_DATA32 FirstThunk;
PIMAGE_THUNK_DATA32 OriginalFirstThunk;
importVirtualAddress = data_directory[1].VirtualAddress;
importsize = data_directory[1].Size;
if (importVirtualAddress != 0 || importsize != 0)
{
printf("=======================导入表======================\n\n");
import = (PIMAGE_IMPORT_DESCRIPTOR)((char *)dos_header + getRWA(importVirtualAddress, sectionheader));
while (import->Name)
{
name = (DWORD *)(pFileBuf + getRWA(import->Name, sectionheader));
// printf("%s \n",name);
FirstThunkfileRVA = getRWA(import->FirstThunk, sectionheader);
FirstThunk = (PIMAGE_THUNK_DATA32)(pFileBuf + FirstThunkfileRVA);
OriginalFirstThunkfileRVA = getRWA(import->OriginalFirstThunk, sectionheader);
OriginalFirstThunk = (PIMAGE_THUNK_DATA32)(pFileBuf + OriginalFirstThunkfileRVA);
while (OriginalFirstThunk->u1.Ordinal != 0)
{
if (OriginalFirstThunk->u1.AddressOfData & 0x80000000)
{
printf("模块名: %s 序号导出 %x \n", name, OriginalFirstThunk->u1.AddressOfData);
}
else
{
funcname = (PIMAGE_IMPORT_BY_NAME)(pFileBuf + getRWA(OriginalFirstThunk->u1.Function, sectionheader));
// printf("%x", getRWA(0x3c1b0, sectionheader2));
printf("------------------\n");
printf("模块名:%s ", name);
printf("函数名:%s ", funcname->Name);
printf("OriginalFirstThunk RVA:%x ", OriginalFirstThunk->u1.Function);
printf("FirstThunk RVA:%x \n", import->FirstThunk);
}
OriginalFirstThunk++;
}
import++;
}
}
else
{
printf("没有导出表 \n");
}
}
else
{
PIMAGE_THUNK_DATA64 FirstThunk;
PIMAGE_THUNK_DATA64 OriginalFirstThunk;
importVirtualAddress = data_directory[1].VirtualAddress;
importsize = data_directory[1].Size;
if (importVirtualAddress != 0 || importsize != 0)
{
printf("=======================导入表======================\n\n");
import = (PIMAGE_IMPORT_DESCRIPTOR)((char *)dos_header + getRWA(importVirtualAddress, sectionheader));
while (import->Name)
{
name = (DWORD *)(pFileBuf + getRWA(import->Name, sectionheader));
// printf("%s \n",name);
FirstThunkfileRVA = getRWA(import->FirstThunk, sectionheader);
FirstThunk = (PIMAGE_THUNK_DATA64)(pFileBuf + FirstThunkfileRVA);
OriginalFirstThunkfileRVA = getRWA(import->OriginalFirstThunk, sectionheader);
OriginalFirstThunk = (PIMAGE_THUNK_DATA64)(pFileBuf + OriginalFirstThunkfileRVA);
while (OriginalFirstThunk->u1.Ordinal != 0)
{
if (OriginalFirstThunk->u1.AddressOfData & 0x80000000)
{
printf("模块名: %s 序号导出 %x \n", name, OriginalFirstThunk->u1.AddressOfData);
}
else
{
funcname = (PIMAGE_IMPORT_BY_NAME)(pFileBuf + getRWA(OriginalFirstThunk->u1.Function, sectionheader));
printf("------------------\n");
printf("模块名:%s ", name);
printf("函数名:%s ", funcname->Name);
printf("OriginalFirstThunk RVA:%x ", OriginalFirstThunk->u1.Function);
printf("FirstThunk RVA:%x \n", import->FirstThunk);
}
OriginalFirstThunk++;
}
import++;
}
}
else
{
printf("没有导入表 \n");
}
}
}
void getexport(char *pFileBuf)
{
DWORD sum = 1;
DWORD *fliename;
DWORD NumberOfNames;
// 输出函数地址的RVA
DWORD *AddressOfFunctionsRVA;
DWORD *AddressOfFunctions;
// 输出函数名字的RVA
DWORD *AddressOfNamesRVA;
DWORD *AddressOfNames;
// 指向输出函数序号的RVA
WORD *AddressOfNameOrdinalsRVA;
DWORD base;
exportVirtualAddress = data_directory[0].VirtualAddress;
exportsize = data_directory[0].Size;
if (exportVirtualAddress || exportsize)
{
DWORD exportfileVAR;
// 导出表文件偏移地址
exportfileVAR = getRWA(exportVirtualAddress, sectionheader);
printf("=======================导出表======================\n\n");
Export = PIMAGE_EXPORT_DIRECTORY(pFileBuf + exportfileVAR);
base = Export->Base;
// 文件名
fliename = (DWORD *)(pFileBuf + getRWA(Export->Name, sectionheader));
// 导出函数的总数
NumberOfNames = Export->NumberOfNames;
AddressOfNamesRVA = (DWORD *)(pFileBuf + getRWA(Export->AddressOfNames, sectionheader));
// 函数名
AddressOfNames = (DWORD *)(pFileBuf + getRWA(*AddressOfNamesRVA, sectionheader));
// 函数名的RVA
AddressOfFunctionsRVA = (DWORD *)(pFileBuf + getRWA(Export->AddressOfFunctions, sectionheader));
AddressOfNameOrdinalsRVA = (WORD *)(pFileBuf + getRWA(Export->AddressOfNameOrdinals, sectionheader));
for (int i = 0; i < NumberOfNames; i++)
{
int index = 0;
index = (base + *AddressOfNameOrdinalsRVA);
AddressOfFunctionsRVA = (DWORD *)((BYTE *)AddressOfFunctionsRVA + (index - sum) * sizeof(DWORD));
printf("\n函数名称:%s ", AddressOfNames);
printf("RVA: %x ", *AddressOfFunctionsRVA);
printf("文件偏移: %x \n", getRWA(*AddressOfFunctionsRVA, sectionheader));
AddressOfNames++;
AddressOfFunctionsRVA++;
}
}
else
{
printf("没有导出表 \n");
}
}
void printfsectionheader()
{
printf("\n");
for (int i = 0; i < NumberOfSections; i++)
{
printf("\n");
printf("区块名称 :%s ", sectionheader[i].Name);
printf("真实长度 :%x ", sectionheader[i].Misc.VirtualSize);
printf("RVA 地址 :%x ", sectionheader[i].VirtualAddress);
printf("按照0x200对齐后的长度 :%x ", sectionheader[i].SizeOfRawData);
printf("磁盘文件的偏移 :%x ", sectionheader[i].PointerToRawData);
printf("\n");
}
printf("\n");
}
void printdata_directroy()
{
for (int i = 0; i < 16; i++)
{
printf("data_directroy[%d]: %x\n", i, data_directory[i].VirtualAddress);
printf("data_directroy[%d]: %x\n", i, data_directory[i].Size);
}
}
int main()
{
do{
handle = CreateFileA(".\\01.dll",
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (handle == INVALID_HANDLE_VALUE)
{
printf("文件加载失败");
break;
}
DWORD dwFileSize = GetFileSize(handle, NULL);
if (dwFileSize==0){
break;
}
CHAR *pFileBuf = new CHAR[dwFileSize];
ReadFile(handle, pFileBuf, dwFileSize, &bytesRead, NULL);
dos_header = (PIMAGE_DOS_HEADER)pFileBuf;
// printf("dos_headr %x ",dos_header);
if (!dos_header->e_magic == 0x5a4d)
{
printf("不是PE文件");
break;
}
printf("dos_haendr->e_magic = %x \n", dos_header->e_magic);
lfanew = dos_header->e_lfanew;
printf("dos_header->e_lfanew %X \n", dos_header->e_lfanew);
ntheader = (PIMAGE_NT_HEADERS)((BYTE *)dos_header + lfanew);
if (!ntheader == 0x4550)
{
printf("不是PE文件");
break;
}
printf("ntheader->Signature: %x\n", ntheader->Signature);
fileheader = &(ntheader->FileHeader);
SizeOfOptionalHeader = fileheader->SizeOfOptionalHeader;
NumberOfSections = fileheader->NumberOfSections;
Machine = fileheader->Machine;
if (Machine == IMAGE_FILE_MACHINE_I386)
{
printf("\n=================32位================");
PIMAGE_NT_HEADERS32 ntheader32;
ntheader32 = (PIMAGE_NT_HEADERS32)((BYTE *)dos_header + lfanew);
PIMAGE_OPTIONAL_HEADER32 opheader32;
opheader32 = (PIMAGE_OPTIONAL_HEADER32) & (ntheader32->OptionalHeader);
sectionheader = PIMAGE_SECTION_HEADER((BYTE *)opheader32 + SizeOfOptionalHeader);
printfsectionheader();
data_directory = opheader32->DataDirectory;
printdata_directroy();
getexport(pFileBuf);
printf("\n");
getImport(pFileBuf, 0);
}
else
{
printf("\n=================64位================");
PIMAGE_NT_HEADERS64 ntheader64;
ntheader64 = (PIMAGE_NT_HEADERS64)((BYTE *)dos_header + lfanew);
PIMAGE_OPTIONAL_HEADER64 opheader64;
opheader64 = &(ntheader64->OptionalHeader);
sectionheader = PIMAGE_SECTION_HEADER((BYTE *)opheader64 + SizeOfOptionalHeader);
printfsectionheader();
data_directory = opheader64->DataDirectory;
printdata_directroy();
printf("\n");
getexport(pFileBuf);
printf("\n");
getImport(pFileBuf, 0);
}
getchar();
}while(0);
CloseHandle(handle);
return 0;
}
代码片
最近在学习PE 文件格式 。