c语言怎么使用pe文件结构,PE文件结构分析

// ShowPE.c

// Show The Main Structures Of the PE file

// Author: thinker

// Date: 11/28/2008

// E-Mail: cnhnyu@gmail.com

// QQ: 94483026

/*********************************************************

PE File Format

-------------------------------   |     MZ  MS-DOS Header       |    |

-------------------------------    |  Dos Headers

|     MS DOS Stub             |    |

-------------------------------   |        PE00                 |    |

-------------------------------    |

|                             |    |

|  IMAGE_FILE_HEADER          |    | IMAGE_NT_HEADERS32

-------------------------------    |

|                             |    |

|  IMAGE_OPTIONAL_HEADER32    |    |

|                             |    |

-------------------------------   |   Section Header 1          |    |

|-----------------------------|    |

|   Section Header 2          |    |

-------------------------------    |  Section Headers

|     ..............          |    |

|-----------------------------|    |

|   Section Header N          |    |

-------------------------------   |   Section Data 1            |    |

|-----------------------------|    |

|   Section Data 2            |    |

-------------------------------    |  Section Datas

|     ...............         |    |

-------------------------------    |

|   Section Data N            |    |

-------------------------------

**********************************************************/

#include

#include

#include

// Data Directory Description

char szDataDirectory[16][64] = {

"Export Directory",

"Import Directory",

"Resource Directory",

"Exception Directory",

"Security Directory",

"Base Relocation Table",

"Debug Directory",

"Architecture Specific Data",

"RVA of GP",

"TLS Directory",

"Load Configuration Directory",

"Bound Import Directory in headers",

"Import Address Table",

"Delay Load Import Descriptors",

"COM Runtime descriptor"

};

HANDLE hFile = NULL;

HANDLE hFileMapping = NULL;

void* pFileBase = NULL;

IMAGE_DOS_HEADER *pDosHeader = NULL;

IMAGE_NT_HEADERS *pNTHeader = NULL;

IMAGE_SECTION_HEADER *pSectionHeader = NULL;

DWORD RVA2FileOffset(DWORD dwRVA);

int main(int argc, char **argv)

{

struct tm* ptm;

DWORD dwIndex;

IMAGE_IMPORT_DESCRIPTOR *pImportDescriptor = NULL;

IMAGE_THUNK_DATA *pThunkData = NULL;

IMAGE_IMPORT_BY_NAME *pImportByName = NULL;

IMAGE_EXPORT_DIRECTORY *pExportDirectory = NULL;

DWORD *pdw;

WORD *pw;

if ( argc != 2 )

{

printf("Usage:\n\t%s PEFile\n", argv[0]);

return -1;

}

/*********************** Map the file to memory *************************/

hFile = CreateFile(argv[1], GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, NULL);

if ( hFile == INVALID_HANDLE_VALUE )

{

printf("Open File Error.\n");

return -1;

}

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

if ( !hFileMapping )

{

CloseHandle(hFile);

printf("Create File Mapping Error.\n");

return -1;

}

pFileBase = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);

if ( !pFileBase )

{

CloseHandle(hFileMapping);

CloseHandle(hFile);

printf("Map View Of File Error.\n");

return -1;

}

/*********************** Map end *****************************************/

// get the dos heaader pointer

pDosHeader = (IMAGE_DOS_HEADER*)pFileBase;

if ( pDosHeader->e_magic != IMAGE_DOS_SIGNATURE )

{

printf("Unknow File Format.\n");

goto End;

}

printf("%-35s%s\n\n", "FileName:", argv[1]);

printf("%-35s%#010x\n", "Dos Stub Size:", pDosHeader->e_lfanew - sizeof(IMAGE_DOS_HEADER));

printf("%-35s%#010x\n", "NT File RVA:", pDosHeader->e_lfanew);

// get the nt header pointer

pNTHeader = (IMAGE_NT_HEADERS*)((char*)pFileBase + pDosHeader->e_lfanew);

if ( pNTHeader->Signature != IMAGE_NT_SIGNATURE )

{

printf("Not NT File.\n");

goto End;

}

// get the section header pointer

pSectionHeader = (IMAGE_SECTION_HEADER*)((char*)pNTHeader + sizeof(IMAGE_NT_HEADERS));

printf("\n%-35s%s\n", "nRun Platform:", (pNTHeader->FileHeader.Machine == IMAGE_FILE_MACHINE_I386) ? "Intel 386" : "Other" );

printf("%-35s%d\n", "NumOfSections:", pNTHeader->FileHeader.NumberOfSections);

ptm = localtime(&pNTHeader->FileHeader.TimeDateStamp);

printf("%-35s%02d/%02d/%04d %02d:%02d:%02d\n", "FileCreateTime:", ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_year + 1900,

ptm->tm_hour, ptm->tm_min, ptm->tm_sec);

//printf("%.19s\n", asctime(ptm));

printf("%-35s%#010x\n", "SizeofOptionHdr:", pNTHeader->FileHeader.SizeOfOptionalHeader);

printf("%-35s%s\n", "File Type:", (pNTHeader->FileHeader.Characteristics & IMAGE_FILE_DLL) ? "DLL" : "EXE");

printf("\n%-35s%s\n", "Image Type:", (pNTHeader->OptionalHeader.Magic == 0x10B) ? "Exe Image" : "Other");

printf("%-35s%d.%d\n", "Linker Version:", pNTHeader->OptionalHeader.MajorLinkerVersion, pNTHeader->OptionalHeader.MinorLinkerVersion);

printf("%-35s%#010x\n", "SizeofCode:", pNTHeader->OptionalHeader.SizeOfCode);

printf("%-35s%#010x\n", "AddressOfEntryPoint:", pNTHeader->OptionalHeader.AddressOfEntryPoint);

printf("%-35s%#010x\n", "DefaultLoadAddress:", pNTHeader->OptionalHeader.ImageBase);

printf("%-35s%#010x\n", "SectionAlignment:", pNTHeader->OptionalHeader.SectionAlignment);

printf("%-35s%#010x\n", "FileAlignment:", pNTHeader->OptionalHeader.FileAlignment);

printf("%-35s%d.%d\n", "OS SystemVersion:", pNTHeader->OptionalHeader.MajorOperatingSystemVersion,

pNTHeader->OptionalHeader.MinorOperatingSystemVersion);

printf("%-35s%d.%d\n", "ImageVersion:", pNTHeader->OptionalHeader.MajorImageVersion,

pNTHeader->OptionalHeader.MinorImageVersion);

printf("%-35s%d.%d\n", "SubSystemVersion:", pNTHeader->OptionalHeader.MajorSubsystemVersion,

pNTHeader->OptionalHeader.MinorSubsystemVersion);

printf("%-35s%#010d\n", "SizeOfIamge:", pNTHeader->OptionalHeader.SizeOfImage);

printf("%-35s%#010d\n", "SizeOfHeaders:", pNTHeader->OptionalHeader.SizeOfHeaders);

if ( pNTHeader->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI )

printf("%-35s%s\n", "GUI System:", "Windows GUI");

else if ( pNTHeader->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI)

printf("%-35s%s\n", "GUI System:", "Windows Console");

else

printf("%-35s%s\n", "GUI System:", "Other");

printf("\n-----------------------------Data Directory----------------------------------\n");

printf("#Index\t#Virtual Address\t#Size\t\t#%-32s\n", "Directory Name");

for (dwIndex = 0; dwIndex < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; dwIndex++ )

{

printf("0x%02x\t0x%08x\t0x%08x\t%-50s\n", dwIndex,

pNTHeader->OptionalHeader.DataDirectory[dwIndex].VirtualAddress,

pNTHeader->OptionalHeader.DataDirectory[dwIndex].Size, szDataDirectory[dwIndex]);

}

printf("\n\n-----------------------------Section Headers----------------------------------\n");

printf("#VirtualAddress\t#VirtualSize\t#PointerToRawData\t#SizeOfRawData\t#Name\n");

for ( dwIndex = 0; dwIndex < pNTHeader->FileHeader.NumberOfSections; dwIndex++ )

{

printf("0x%08x\t0x%08x\t0x%08x\t\t0x%08x\t%-10s\n", pSectionHeader[dwIndex].VirtualAddress,

pSectionHeader[dwIndex].Misc.VirtualSize, pSectionHeader[dwIndex].PointerToRawData,

pSectionHeader[dwIndex].SizeOfRawData, pSectionHeader[dwIndex].Name);

}

// Import Table

printf("\n\n-------------------------Import Table-------------------------------------\n");

pImportDescriptor = (IMAGE_IMPORT_DESCRIPTOR*)((char*)pFileBase + RVA2FileOffset(pNTHeader->OptionalHeader.DataDirectory[1].VirtualAddress));

for ( ; *(char*)pImportDescriptor ; pImportDescriptor++ )

{

printf("Import Lib: %s\n", (char*)(RVA2FileOffset(pImportDescriptor->Name) + (char*)pFileBase));

pThunkData = (IMAGE_THUNK_DATA*)(RVA2FileOffset(pImportDescriptor->OriginalFirstThunk) + (char*)pFileBase);

for ( ; pThunkData->u1.AddressOfData; pThunkData++ )

{

if ( pThunkData->u1.Ordinal & IMAGE_ORDINAL_FLAG32 ) // import by index

{

printf("\t0x%04x\n", pThunkData->u1.Ordinal & 0xffff);

}

else // import by name

{

pImportByName = (IMAGE_IMPORT_BY_NAME*)(RVA2FileOffset(pThunkData->u1.Ordinal) + (char*)pFileBase);

printf("\t0x%04x\t%s\n", pImportByName->Hint, pImportByName->Name);

}

}

printf("\n");

}

if ( pNTHeader->OptionalHeader.DataDirectory[0].Size == 0 ) // Export Table Not Exist

goto End;

// Export Table

printf("\n\n------------------------Export Table---------------------------------\n");

pExportDirectory = (IMAGE_EXPORT_DIRECTORY*)(RVA2FileOffset(pNTHeader->OptionalHeader.DataDirectory[0].VirtualAddress) + (char*)pFileBase);

printf("Export Lib: \t%s\n", (char*)(RVA2FileOffset(pExportDirectory->Name) + (char*)pFileBase));

printf("\tIndex\tName\t\t\n");

printf("\t------------------------------\n");

for ( dwIndex = 0; dwIndex < pExportDirectory->NumberOfNames; dwIndex++ )

{

pdw = (DWORD*)(RVA2FileOffset(pExportDirectory->AddressOfNames) + (char*)pFileBase);

pw = (WORD*)(RVA2FileOffset(pExportDirectory->AddressOfFunctions) + (char*)pFileBase);

printf("\t0x%04x\t%-20s\n", dwIndex, (char*)(RVA2FileOffset(pdw[dwIndex]) + (char*)pFileBase), pw[dwIndex]);

}

End:

UnmapViewOfFile(pFileBase);

CloseHandle(hFileMapping);

CloseHandle(hFile);

return 0;

}

/*

Convert RVA To File Offset

*/

DWORD RVA2FileOffset(DWORD dwRVA)

{

DWORD dwNum, dwIndex;

if ( pNTHeader == NULL )

return 0;

if ( pSectionHeader == NULL )

return 0;

dwNum = pNTHeader->FileHeader.NumberOfSections;

for ( dwIndex = 0; dwIndex < dwNum; dwIndex++ )

{

if ( dwRVA >= pSectionHeader[dwIndex].VirtualAddress &&

dwRVA <= pSectionHeader[dwIndex].VirtualAddress + pSectionHeader[dwIndex].SizeOfRawData)

{

return dwRVA - pSectionHeader[dwIndex].VirtualAddress + pSectionHeader[dwIndex].PointerToRawData;

}

}

return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值