读取exe程序,并输出字段信息
# define _CRT_SECURE_NO_WARNINGS # include <stdio.h> # include <stdlib.h> # include <string.h> typedef unsigned char BYTE; typedef unsigned short WORD; typedef unsigned int DWORD; typedef struct _Dos_Header { WORD e_magic; WORD e_cblp; WORD e_cp; WORD e_crlc; WORD e_aparhdr; WORD e_minalloc; WORD e_maxalloc; WORD e_ss; WORD e_sp; WORD e_csum; WORD e_ip; WORD e_cs; WORD e_lfarlc; WORD e_ovno; WORD e_res[4]; WORD e_oeminfo; WORD e_res2[10]; DWORD e_lfanew; } Dos_Header; typedef struct _File_Header { WORD Machine; WORD NumberOfSections; DWORD TimeDateStamp; DWORD PointerToSymbolTable; DWORD NumberOfSymbols; WORD SizeOfOptionalHeader; WORD Characteristics; }File_Header; typedef struct _Optional_Header { WORD Magic; BYTE MajorLinkerVersion; BYTE MinorLinkerVersion; DWORD SizeOfCode; DWORD SizeOfInitializedData; DWORD SizeOfUninitializedData; DWORD AddressOfEntryPoint; DWORD BaseOfCode; DWORD BaseOfData; DWORD ImageBase; DWORD SectionAlignment; DWORD FileAlignment; WORD MajorOperatingSystemVersion; WORD MinorOperatingSystemVersion; WORD MajorImageVersion; WORD MinorImageVersion; WORD MajorSubsystemVersion; WORD MinorSubsystemVersion; DWORD Win32VersionValue; DWORD SizeOfImage; DWORD SizeOfHeaders; DWORD CheckSum; WORD Subsystem; WORD DllCharacteristics; DWORD SizeOfStackReserve; DWORD SizeOfStackCommit; DWORD SizeOfHeapReserve; DWORD SizeOfHeapCommit; DWORD LoaderFlags; DWORD NumberOfRvaAndSizes; }Optional_Header; typedef struct _NT_Header { DWORD Signature; File_Header FileHeader; Optional_Header OptionalHeader; }NT_Header; //计算文件长度 int File_Lenth(FILE* pf) { fseek(pf, 0, SEEK_END);//指向文件结尾 int num = ftell(pf);//首尾间的距离 fseek(pf, 0, SEEK_SET);//恢复 return num; } //FillBuffer char* File_Read(const char* p) { FILE* pf = fopen(p, "rb"); int len = File_Lenth(pf); char* pb = (char*)malloc(sizeof(char) * len); fread(pb, len, 1, pf); return pb; } Dos_Header* Dos_Read(char* p) { Dos_Header* Dos = (Dos_Header*)malloc(sizeof(Dos_Header));分配dos头需要的内存 memcpy(Dos, p, sizeof(Dos_Header));//内存复制 return Dos; }
//打印DOS头 int Dos_Print(Dos_Header* Dos) { printf("Dos->e_magic:%X\n", Dos->e_magic); printf("Dos->e_lfanew:%X\n", Dos->e_lfanew); int offset = Dos->e_lfanew; return offset; } NT_Header* NT_Read(char* p, int offset) { NT_Header* NT = (NT_Header*)malloc(sizeof(NT_Header));//分配nt头需要的内存 memcpy(NT, p + offset, sizeof(NT_Header));//内存复制 return NT; } void File_Print(File_Header* File) { printf("File->Machine:%X\n", File->Machine); } void Optional_Print(Optional_Header* Optional) { printf("Optional->Magic:%X\n", Optional->Magic); printf("Optional->ImageBase:%X\n", Optional->ImageBase); }
//打印NT头 void NT_Print(NT_Header* NT) { printf("NT->Signature:%X\n", NT->Signature); File_Print(&NT->FileHeader); Optional_Print(&NT->OptionalHeader); } int main() { char* pfb = File_Read("C:/Windows/System32/notepad.exe"); Dos_Header* Dos = Dos_Read(pfb); int offset = Dos_Print(Dos); NT_Header* NT = NT_Read(pfb, offset); NT_Print(NT); return 0; }
用fopen函数打开notepad.exe是,发现有一字节数据丢失,将参数“r”改成“rb”时,问题解决。
用16进制编辑器查看note.exe
![]()
当参数为“r“时,fopen函数将0D0A转换为0A,而“rb”都会读取,所以使用时尽可能使用“rb”比较好

浙公网安备 33010602011771号