| #include<windows.h> |
| #include<stdio.h> |
| |
| #define FILEPATH "C:\\Documents and Settings\\Administrator\\桌面\\PE练习素材\\练习素材\\NOTEPAD.EXE" |
| |
| |
| LPVOID ReadPEFile(LPSTR lpszFile); |
| VOID PrintNTHeaders(); |
| |
| int main(){ |
| PrintNTHeaders(); |
| return 0; |
| } |
| |
| LPVOID ReadPEFile(LPSTR lpszFile) |
| { |
| FILE *pFile = NULL; |
| DWORD fileSize = 0; |
| LPVOID pFileBuffer = NULL; |
| |
| |
| pFile = fopen(lpszFile, "rb"); |
| if(!pFile) |
| { |
| printf(" 无法打开 EXE 文件! "); |
| return NULL; |
| } |
| |
| |
| fseek(pFile, 0, SEEK_END); |
| fileSize = ftell(pFile); |
| |
| |
| fseek(pFile, 0, SEEK_SET); |
| |
| |
| pFileBuffer = malloc(fileSize); |
| |
| if(!pFileBuffer) |
| { |
| printf(" 分配空间失败! "); |
| fclose(pFile); |
| return NULL; |
| } |
| |
| |
| size_t n = fread(pFileBuffer, fileSize, 1, pFile); |
| if(!n) |
| { |
| printf(" 读取数据失败! "); |
| free(pFileBuffer); |
| fclose(pFile); |
| return NULL; |
| } |
| |
| |
| fclose(pFile); |
| return pFileBuffer; |
| } |
| |
| VOID PrintNTHeaders() |
| { |
| LPVOID pFileBuffer = NULL; |
| PIMAGE_DOS_HEADER pDosHeader = NULL; |
| PIMAGE_NT_HEADERS pNTHeader = NULL; |
| PIMAGE_FILE_HEADER pPEHeader = NULL; |
| PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL; |
| PIMAGE_SECTION_HEADER pSectionHeader = NULL; |
| |
| |
| pFileBuffer = ReadPEFile(FILEPATH); |
| if(!pFileBuffer) |
| { |
| printf("文件读取失败\n"); |
| return ; |
| } |
| |
| |
| |
| |
| if(*((PWORD)pFileBuffer) != IMAGE_DOS_SIGNATURE) |
| { |
| printf("不是有效的MZ标志\n"); |
| free(pFileBuffer); |
| return ; |
| } |
| |
| pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer; |
| |
| |
| printf("********************DOS头********************\n\n"); |
| printf("_IMAGE_DOS_HEADERMZ->e_magic MZ标志:0x%x\n",pDosHeader->e_magic); |
| printf("_IMAGE_DOS_HEADERMZ->e_lfanew指向PE标志:0x%x\n",pDosHeader->e_lfanew); |
| printf("\n"); |
| |
| |
| if(*((PDWORD)((DWORD)pFileBuffer+pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE) |
| { |
| printf("不是有效的PE标志\n"); |
| free(pFileBuffer); |
| return ; |
| } |
| |
| |
| pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer+pDosHeader->e_lfanew); |
| |
| |
| printf("********************NT头********************\n\n"); |
| printf("_IMAGE_NT_HEADERS->Signature文件PE标识:0x%x\n",pNTHeader->Signature); |
| printf("\n"); |
| |
| |
| pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader) + 4); |
| int NumberOfSections = pPEHeader->NumberOfSections; |
| printf("********************PE头********************\n\n"); |
| printf("_IMAGE_FILE_HEADER->Machine支持的CPU:0x%x\n",pPEHeader->Machine); |
| printf("_IMAGE_FILE_HEADER->NumberOfSections节的数量:0x%x\n",pPEHeader->NumberOfSections); |
| printf("_IMAGE_FILE_HEADER->SizeOfOptionalHeader可选PE头的大小:0x%x\n",pPEHeader->SizeOfOptionalHeader); |
| printf("\n"); |
| |
| |
| pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader+IMAGE_SIZEOF_FILE_HEADER); |
| printf("********************OPTIOIN_PE头********************\n\n"); |
| printf("_IMAGE_OPTIONAL_HEADER->Magic分辨系统位数:0x%x\n",pOptionHeader->Magic); |
| printf("_IMAGE_OPTIONAL_HEADER->AddressOfEntryPoint程序入口:0x%x\n",pOptionHeader->AddressOfEntryPoint); |
| printf("_IMAGE_OPTIONAL_HEADER->ImageBase内存镜像基址:0x%x\n",pOptionHeader->ImageBase); |
| printf("_IMAGE_OPTIONAL_HEADER->SectionAlignment内存对齐大小:0x%x\n",pOptionHeader->SectionAlignment); |
| printf("_IMAGE_OPTIONAL_HEADER->FileAlignment文件对齐大小:0x%x\n",pOptionHeader->FileAlignment); |
| printf("_IMAGE_OPTIONAL_HEADER->SizeOfImage内存中PE的大小(SectionAlignment整数倍):0x%x\n",pOptionHeader->SizeOfImage); |
| printf("_IMAGE_OPTIONAL_HEADER->SizeOfHeaders头+节表按照文件对齐的大小:0x%x\n",pOptionHeader->SizeOfImage); |
| printf("_IMAGE_OPTIONAL_HEADER->NumberOfRvaAndSizes目录项数目:0x%x\n",pOptionHeader->NumberOfRvaAndSizes); |
| |
| printf("\n"); |
| |
| |
| printf("********************节表********************\n\n"); |
| |
| pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + IMAGE_SIZEOF_NT_OPTIONAL_HEADER); |
| for(int i=1;i<=NumberOfSections;i++){ |
| char SectionName[9] ={0}; |
| strcpy(SectionName,(char *)pSectionHeader->Name); |
| printf("_IMAGE_SECTION_HEADER->Name:%s\n",SectionName); |
| printf("_IMAGE_SECTION_HEADER->VirtualSize:0x%x\n",pSectionHeader->Misc); |
| printf("_IMAGE_SECTION_HEADER->VirtualAddress:0x%x\n",pSectionHeader->VirtualAddress); |
| printf("_IMAGE_SECTION_HEADER->SizeOfRawData:0x%x\n",pSectionHeader->SizeOfRawData); |
| printf("_IMAGE_SECTION_HEADER->PointerToRawData:0x%x\n",pSectionHeader->PointerToRawData); |
| printf("_IMAGE_SECTION_HEADER->Characteristics:0x%x\n",pSectionHeader->Characteristics); |
| pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader +IMAGE_SIZEOF_SECTION_HEADER); |
| printf("\n"); |
| } |
| |
| free(pFileBuffer); |
| } |
| |

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY