遍历导入表和导出表见另一篇文章
运行效果如下:

代码如下,获取的是主要信息:
#include <stdio.h>
#include <windows.h>
#pragma warning(disable : 4996)
IMAGE_DOS_HEADER DosHeader;
PIMAGE_DOS_HEADER pDosHeader;
IMAGE_NT_HEADERS NtHeader;
PIMAGE_NT_HEADERS pNtHeader;
IMAGE_FILE_HEADER FileHeader;
PIMAGE_FILE_HEADER pFileHeader;
IMAGE_OPTIONAL_HEADER OptionHeader;
PIMAGE_OPTIONAL_HEADER pOptionHeader;
PIMAGE_DATA_DIRECTORY pDataDirectory;
IMAGE_SECTION_HEADER SectionHeader;
char * filepath = "atl.dll"; // 写死
long e_lfanew;
DWORD RvaToRaw(PIMAGE_NT_HEADERS pNtHeader, DWORD Rva){
PIMAGE_SECTION_HEADER pSectionHeader = (PIMAGE_SECTION_HEADER)IMAGE_FIRST_SECTION(pNtHeader);
for (int i = 0; i < pNtHeader->FileHeader.NumberOfSections; i++){
DWORD SectionBeginRva = pSectionHeader[i].VirtualAddress;
DWORD SectionEndRva = pSectionHeader[i].VirtualAddress + pSectionHeader[i].SizeOfRawData;
if (Rva >= SectionBeginRva && Rva <= SectionEndRva){
DWORD Temp = Rva - SectionBeginRva;
DWORD Rwa = Temp + pSectionHeader[i].PointerToRawData;
return Rwa;
}
}
}
void main(int argc, char * agrv[]){
HANDLE hFile = CreateFileA(filepath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, NULL);
HANDLE hMapping = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 0, NULL);
PVOID pbFile = MapViewOfFile(hMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0);
if (hFile == INVALID_HANDLE_VALUE || hMapping == NULL || pbFile == NULL){
printf("\n>>> 文件不存在\n");
if (hFile != INVALID_HANDLE_VALUE){
CloseHandle(hFile);
}
if (hMapping != NULL){
CloseHandle(hMapping);
}
if (pbFile != NULL){
UnmapViewOfFile(pbFile);
}
}
// 获取DOS头信息
puts("=================DOS_HEADER======================");
pDosHeader = (PIMAGE_DOS_HEADER)pbFile;
printf("e_magic(MZ头): %X ", pDosHeader->e_magic);
char arry_dosheader_e_magic[sizeof(pDosHeader->e_magic)]; // 申请一块MZ头字段大小的空间,将MZ头复制到该内存
memcpy(arry_dosheader_e_magic, &pDosHeader->e_magic, sizeof(pDosHeader->e_magic));
for (int i = 0; i < sizeof(pDosHeader->e_magic) && arry_dosheader_e_magic[i] != '\0'; i++){
printf("%c", arry_dosheader_e_magic[i]);
}
printf("\ne_lfanew(NT头位置): %X\n", pDosHeader->e_lfanew);
pNtHeader = (PIMAGE_NT_HEADERS)((DWORD)pbFile + pDosHeader->e_lfanew);
// NT头
puts("\n=================NT_HEADER=======================");
printf("Signature(PE标志): %X ", pNtHeader->Signature);
char arry_nt_Signature[sizeof(pNtHeader->Signature)];
memcpy(arry_nt_Signature, &pNtHeader->Signature, sizeof(pNtHeader->Signature));
for (int i = 0; i < sizeof(pNtHeader->Signature) && arry_nt_Signature[i] != '\0'; i++){
printf("%c", arry_nt_Signature[i]);
}
// 文件头
puts("\n\n==========================NT_FILE_HEADER=========================");
printf("NumberOfSections(节区数): %X\n", pNtHeader->FileHeader.NumberOfSections);
printf("TimeDateStamp(文件编译时间): %X\n", pNtHeader->FileHeader.TimeDateStamp);
printf("SizeOfOptionalHeader(可选头大小): %X\n", pNtHeader->FileHeader.SizeOfOptionalHeader);
printf("Characteristics(文件类型特征值): %X\n", pNtHeader->FileHeader.Characteristics);
// 可选头
puts("\n====================NT_OPTIONAL_HEADER(RVA)======================");
printf("AddressOfEntryPoint(程序执行入口点): %X\n", pNtHeader->OptionalHeader.AddressOfEntryPoint);
printf("BaseOfCode(代码节地址): %X\n", pNtHeader->OptionalHeader.BaseOfCode);
printf("BaseOfData(数据节地址): %X\n", pNtHeader->OptionalHeader.BaseOfData);
printf("ImageBase(文件在内存中的基址): %X\n", pNtHeader->OptionalHeader.ImageBase);
printf("SectionAlignment(文件在内存中的节区对齐大小): %X\n", pNtHeader->OptionalHeader.SectionAlignment);
printf("FileAlignment(文件在磁盘中的节区对齐大小): %X\n", pNtHeader->OptionalHeader.FileAlignment);
printf("SizeOfImage(文件加载到内存中的大小): %X\n", pNtHeader->OptionalHeader.SizeOfImage);
printf("SizeOfHeaders(DOS头+NT头+节区表): %X\n", pNtHeader->OptionalHeader.SizeOfHeaders);
printf("NumberOfRvaAndSizes(数据目录表的个数-bug): %X\n", pNtHeader->OptionalHeader.NumberOfRvaAndSizes);
/*打印数据目录表*/
puts("\n=================PE IMAGE_DATA_DIRECTORY HEADER==================");
pDataDirectory = pNtHeader->OptionalHeader.DataDirectory;
printf("Table Name\t\tVirtualAddress\t\tSize\n\n");
printf("Export Table\t\t%08X\t\t%08X\n", pDataDirectory[0].VirtualAddress, pDataDirectory[0].Size);
printf("Import Table\t\t%08X\t\t%08X\n", pDataDirectory[1].VirtualAddress, pDataDirectory[1].Size);
printf("Resources Table\t\t%08X\t\t%08X\n", pDataDirectory[2].VirtualAddress, pDataDirectory[2].Size);
printf("Exception Table\t\t%08X\t\t%08X\n", pDataDirectory[3].VirtualAddress, pDataDirectory[3].Size);
printf("Security Table\t\t%08X\t\t%08X\n", pDataDirectory[4].VirtualAddress, pDataDirectory[4].Size);
printf("Base relocation Table\t%08X\t\t%08X\n", pDataDirectory[5].VirtualAddress, pDataDirectory[5].Size);
printf("Debug Table\t\t%08X\t\t%08X\n", pDataDirectory[6].VirtualAddress, pDataDirectory[6].Size);
printf("Copyrught Table\t\t%08X\t\t%08X\n", pDataDirectory[7].VirtualAddress, pDataDirectory[7].Size);
printf("Global Ptr Table\t%08X\t\t%08X\n", pDataDirectory[8].VirtualAddress, pDataDirectory[8].Size);
printf("TLS Table\t\t%08X\t\t%08X\n", pDataDirectory[9].VirtualAddress, pDataDirectory[9].Size);
printf("Load config Table\t%08X\t\t%08X\n", pDataDirectory[10].VirtualAddress, pDataDirectory[10].Size);
printf("Bound Import Table\t%08X\t\t%08X\n", pDataDirectory[11].VirtualAddress, pDataDirectory[11].Size);
printf("IAT Table\t\t%08X\t\t%08X\n", pDataDirectory[12].VirtualAddress, pDataDirectory[12].Size);
printf("Delay Import Table\t%08X\t\t%08X\n", pDataDirectory[13].VirtualAddress, pDataDirectory[13].Size);
printf("COM descriptor Table\t%08X\t\t%08X\n", pDataDirectory[14].VirtualAddress, pDataDirectory[14].Size);
printf("Retention Table\t\t%08X\t\t%08X\n", pDataDirectory[15].VirtualAddress, pDataDirectory[15].Size);
/* 打印SECTION头 */
PIMAGE_SECTION_HEADER pSectionHeader = (PIMAGE_SECTION_HEADER)IMAGE_FIRST_SECTION(pNtHeader);
puts("\n=========================SECTION HEADER==========================");
for (int count = 0; count < pNtHeader->FileHeader.NumberOfSections; count++){
// 打印节区标志
printf("\n----------------");
char arry_section_text[sizeof(pSectionHeader->Name)];
memcpy(arry_section_text, &pSectionHeader->Name, sizeof(pSectionHeader->Name));
for (int i = 0; i < sizeof(pSectionHeader->Name) && arry_section_text[i] != '\0'; i++){
printf("%c", arry_section_text[i]);
}
printf("----------------\n");
printf("Name\t\t\t");
for (int i = 0; i < sizeof(pSectionHeader->Name) && arry_section_text[i] != '\0'; i++){
printf("%c", arry_section_text[i]);
}
printf("\nVirtualSize\t\t%08X\n", pSectionHeader->Misc.VirtualSize);
printf("VirtualAddress\t\t%08X\n", pSectionHeader->VirtualAddress);
printf("SizeOfRawData\t\t%08X\n", pSectionHeader->SizeOfRawData);
printf("PointerToRawData\t%08X\n", pSectionHeader->PointerToRawData);
//printf("PointerToRelocation\t%08X\n", pSectionHeader->PointerToRelocations);
//printf("PointerToLinenumbers\t%08X\n", pSectionHeader->PointerToLinenumbers);
//printf("NumberOfRelocations\t%04X\n", pSectionHeader->NumberOfRelocations);
//printf("NumberOfLinenumbers\t%04X\n", pSectionHeader->NumberOfLinenumbers);
printf("Characteristics\t\t%08X\n", pSectionHeader->Characteristics);
pSectionHeader++;
}
system("pause");
}
版本二:
#include <stdio.h>
#include <Windows.h>
#include <tchar.h>
#pragma warning(disable : 4996)
extern void DirectoryString(DWORD dwIndex);
char path[MAX_PATH]; // 文件路径
int _tmain(int argc, _TCHAR* argv[])
{
// 选择Virus文件
OPENFILENAMEA ofn;
memset(path, 0, MAX_PATH);
memset(&ofn, 0, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.lpstrFile = path; // path
ofn.nMaxFile = MAX_PATH;
ofn.lpstrFilter = "*.exe\0*.exe\0";
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
if (!GetOpenFileName(&ofn)) { // 如果打开文件错误
MessageBox(NULL, "Open file failed!", NULL, MB_OK);
exit(0); // 退出所有进程
}
// 获取文件句柄,映射到内存
HANDLE hFile = CreateFileA(path, GENERIC_ALL, 3u, NULL, OPEN_EXISTING, 0x80u, 0); // path,第一个3u表示共享读写
// 获取文件大小
DWORD dwFileSize = GetFileSize(hFile, NULL);
CHAR *pFileBuf = new CHAR[dwFileSize];
// 将文件读取到内存
DWORD ReadSize = 0;
ReadFile(hFile, pFileBuf, dwFileSize, &ReadSize, NULL);
// 判断是否为PE文件
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pFileBuf;
if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
{
// 不是PE
printf("不是PE文件\n");
system("pause");
return 0;
}
PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)(pFileBuf + pDosHeader->e_lfanew);
if (pNtHeader->Signature != IMAGE_NT_SIGNATURE)
{
// 不是PE文件
printf("不是PE文件\n");
system("pause");
return 0;
}
// 获取基本PE头信息
// 获取信息所用到的两个结构体指针 (这两个结构体都属于NT头)
PIMAGE_FILE_HEADER pFileHeader = &(pNtHeader->FileHeader);
PIMAGE_OPTIONAL_HEADER pOptionalHeader = &(pNtHeader->OptionalHeader);
// 输出PE头信息
printf("================== 基 本 P E 头 信 息 ==================\n\n");
printf("入 口 点:\t%08X\t", pOptionalHeader->AddressOfEntryPoint);
printf("子 系 统:\t%04X\n", pOptionalHeader->Subsystem);
printf("镜像基址:\t%08X\t", pOptionalHeader->ImageBase);
printf("区段数目:\t%04X\n", pFileHeader->NumberOfSections);
printf("镜像大小:\t%08X\t", pOptionalHeader->SizeOfImage);
printf("日期时间标志:\t%08X\n", pFileHeader->TimeDateStamp);
printf("代码基址:\t%08X\t", pOptionalHeader->BaseOfCode);
printf("部首大小:\t%08X\n", pOptionalHeader->SizeOfHeaders);
printf("数据基址:\t%08X\t", pOptionalHeader->BaseOfData);
printf("特 征 值:\t%04X\n", pFileHeader->Characteristics);
printf("块 对 齐:\t%08X\t", pOptionalHeader->SectionAlignment);
printf("校 验 和:\t%08X\n", pOptionalHeader->CheckSum);
printf("文件块对齐:\t%08X\t", pOptionalHeader->FileAlignment);
printf("可选头部大小:\t%04X\n", pFileHeader->SizeOfOptionalHeader);
printf("标 志 字:\t%04X\t\t", pOptionalHeader->Magic);
printf("RVA数及大小:\t%08X\n\n", pOptionalHeader->NumberOfRvaAndSizes);
printf("======================= 目 录 表 =======================\n");
// 获取目录表头指针,数据目录表个数宏定义默认为16
PIMAGE_DATA_DIRECTORY pDataDirectory = pOptionalHeader->DataDirectory;
printf("\t\t RAV\t\t 大小\n");
for (DWORD i = 0; i < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; i++)
{
DirectoryString(i);
printf("%08X\t%08X\n",
pDataDirectory[i].VirtualAddress, pDataDirectory[i].Size);
}
printf("======================= 区 段 表 =======================\n");
// 获取区段表头指针
PIMAGE_SECTION_HEADER pSectionHeader = IMAGE_FIRST_SECTION(pNtHeader);
printf("名称 VOffset VSize ROffset RSize 标志\n");
// 获取区段个数
DWORD dwSectionNum = pFileHeader->NumberOfSections;
// 根据区段个数遍历区段信息
for (DWORD i = 0; i < dwSectionNum; i++, pSectionHeader++)
{
for (DWORD j = 0; j < IMAGE_SIZEOF_SHORT_NAME; j++)
{
printf("%c", pSectionHeader->Name[j]);
}
printf(" %08X %08X %08X %08X %08X\n",
pSectionHeader->VirtualAddress,
pSectionHeader->Misc.VirtualSize,
pSectionHeader->PointerToRawData,
pSectionHeader->SizeOfRawData,
pSectionHeader->Characteristics);
}
printf("\n");
system("pause");
return 0;
}
void DirectoryString(DWORD dwIndex)
{
switch (dwIndex)
{
case 0:printf("输出表:\t\t");
break;
case 1:printf("输入表:\t\t");
break;
case 2:printf("资源:\t\t");
break;
case 3:printf("异常:\t\t");
break;
case 4:printf("安全:\t\t");
break;
case 5:printf("重定位:\t\t");
break;
case 6:printf("调试:\t\t");
break;
case 7:printf("版权:\t\t");
break;
case 8:printf("全局指针:\t");
break;
case 9:printf("TLS表:\t\t");
break;
case 10:printf("载入配置:\t");
break;
case 11:printf("输入范围:\t");
break;
case 12:printf("IAT:\t\t");
break;
case 13:printf("延迟输入:\t");
break;
case 14:printf("COM:\t\t");
break;
case 15:printf("保留:\t\t");
break;
}
}
效果:

723

被折叠的 条评论
为什么被折叠?



