| #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,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· C++代码改造为UTF-8编码问题的总结
· DeepSeek 解答了困扰我五年的技术问题
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
· DeepSeek智能编程
· 精选4款基于.NET开源、功能强大的通讯调试工具
· [翻译] 为什么 Tracebit 用 C# 开发
· 腾讯ima接入deepseek-r1,借用别人脑子用用成真了~
· DeepSeek崛起:程序员“饭碗”被抢,还是职业进化新起点?