// PE.cpp : 定义控制台应用程序的入口点。 //DOS版PE工具制作 #include "stdafx.h" #include <windows.h> #include <winnt.h> int filelength(FILE *fp); int _tmain(int argc, _TCHAR* argv[]) { FILE *Fp; int FpSize = 0; short e_lfanew = 0; fopen_s(&Fp, "C:\Users\Administrator\Desktop\MSG.exe", "rb"); FpSize = filelength(Fp);//获取文件大小 char * TempBuffer = (char *)malloc(FpSize);//申请存放文件的内存空间 if (TempBuffer == NULL) { fclose(Fp); free(TempBuffer); return 0; } fread_s(TempBuffer, FpSize + 1, 1, FpSize, Fp);//将文件读入内存中 TempBuffer = (char *)(TempBuffer + *(int *)(TempBuffer + 0x3c));//获取PE标志地址 PIMAGE_FILE_HEADER MyFileHeader; printf("---------------------------------------------- "); printf("PE标记:%08x ", *(int *)TempBuffer); printf("---------------------------------------------- "); TempBuffer = TempBuffer + 0x4;//指针指向标准PE头首地址 MyFileHeader = (PIMAGE_FILE_HEADER)TempBuffer; printf("IMAGE_FILE_HEADER结构: "); printf("---------------------------------------------- "); printf("Machine : %04X ", MyFileHeader->Machine);//运行平台 printf("NumberOfSections : %04X ", MyFileHeader->NumberOfSections);//区块数目 printf("TimeDateStamp : %08X ", MyFileHeader->TimeDateStamp);//文件日期时间戳 printf("PointerToSymbolTable : %08X ", MyFileHeader->PointerToSymbolTable);//指向符号表 printf("NumberOfSymbols : %08X ", MyFileHeader->NumberOfSymbols);//符号表中的符号数量 printf("SizeOfOptionalHeader : %04X ", MyFileHeader->SizeOfOptionalHeader);//映像可选头结构的大小 printf("Characteristics : %04X ", MyFileHeader->Characteristics);//文件特征值 printf("---------------------------------------------- "); TempBuffer = TempBuffer + 0x14;//指针指向可选PE头首地址 PIMAGE_OPTIONAL_HEADER MyOptionalHeader; MyOptionalHeader = (PIMAGE_OPTIONAL_HEADER)TempBuffer; printf("IMAGE_OPTIONAL_HEADER结构: "); printf("---------------------------------------------- "); printf("Magic : %04X ", MyOptionalHeader->Magic);//幻数,32位pe文件总为010bh printf("MajorLinkerVersion : %02X ", MyOptionalHeader->MajorLinkerVersion);//连接器主版本号 printf("MinorLinkerVersion : %02X ", MyOptionalHeader->MinorLinkerVersion);//连接器副版本号 printf("SizeOfCode : %08X ", MyOptionalHeader->SizeOfCode);//代码段总大小 printf("SizeOfInitializedData : %08X ", MyOptionalHeader->SizeOfInitializedData);//已初始化数据段总大小 printf("SizeOfUninitializedData : %08X ", MyOptionalHeader->SizeOfUninitializedData);//未初始化数据段总大小 printf("AddressOfEntryPoint : %08X ", MyOptionalHeader->AddressOfEntryPoint);//程序执行入口地址(RVA) printf("BaseOfCode : %08X ", MyOptionalHeader->BaseOfCode);//代码段起始地址(RVA) printf("BaseOfData : %08X ", MyOptionalHeader->BaseOfData);//数据段起始地址(RVA) printf("ImageBase : %08X ", MyOptionalHeader->ImageBase);//程序默认的装入起始地址 printf("SectionAlignment : %08X ", MyOptionalHeader->SectionAlignment);//内存中区块的对齐单位 printf("FileAlignment : %08X ", MyOptionalHeader->FileAlignment);//文件中区块的对齐单位 printf("MajorOperatingSystemVersion : %04X ", MyOptionalHeader->MajorOperatingSystemVersion);//所需操作系统主版本号 printf("MinorOperatingSystemVersion : %04X ", MyOptionalHeader->MinorOperatingSystemVersion);//所需操作系统副版本号 printf("MajorImageVersion : %04X ", MyOptionalHeader->MajorImageVersion);//自定义主版本号 printf("MinorImageVersion : %04X ", MyOptionalHeader->MinorImageVersion);//自定义副版本号 printf("MajorSubsystemVersion : %04X ", MyOptionalHeader->MajorSubsystemVersion);//所需子系统主版本号 printf("MinorSubsystemVersion : %04X ", MyOptionalHeader->MinorSubsystemVersion);//所需子系统副版本号 printf("Win32VersionValue : %08X ", MyOptionalHeader->Win32VersionValue);//总是0 printf("SizeOfImage : %08X ", MyOptionalHeader->SizeOfImage);//pe文件在内存中的映像总大小 printf("SizeOfHeaders : %08X ", MyOptionalHeader->SizeOfHeaders);//从pe文件开始到节表(包含节表)的总大小 printf("CheckSum : %08X ", MyOptionalHeader->CheckSum);//pe文件CRC校验和 printf("Subsystem : %04X ", MyOptionalHeader->Subsystem);//用户界面使用的子系统类型 printf("DllCharacteristics : %04X ", MyOptionalHeader->DllCharacteristics);//为0 printf("SizeOfStackReserve : %08X ", MyOptionalHeader->SizeOfStackReserve);//为线程的栈初始保留的虚拟内存的默认值 printf("SizeOfStackCommit : %08X ", MyOptionalHeader->SizeOfStackCommit);//为线程的栈初始提交的虚拟内存的大小 printf("SizeOfHeapReserve : %08X ", MyOptionalHeader->SizeOfHeapReserve);//为进程的堆保留的虚拟内存的大小 printf("SizeOfHeapCommit : %08X ", MyOptionalHeader->SizeOfHeapCommit);//为进程的堆初始提交的虚拟内存的大小 printf("LoaderFlags : %08X ", MyOptionalHeader->LoaderFlags);//为0 printf("NumberOfRvaAndSizes : %08X ", MyOptionalHeader->NumberOfRvaAndSizes);//数据目录结构数组的项数,总为 00000010h TempBuffer = TempBuffer + MyFileHeader->SizeOfOptionalHeader;//指针指向区块首地址 printf("---------------------------------------------- "); printf("节表信息: "); printf("---------------------------------------------- "); PIMAGE_SECTION_HEADER MySectionHeader; MySectionHeader = (PIMAGE_SECTION_HEADER)TempBuffer; for (int i = 0; i < MyFileHeader->NumberOfSections; i++) { printf("Name : %s ", MySectionHeader->Name);//区块名字 printf("Misc : %08X ", MySectionHeader->Misc);//在没有对齐前的真实大小 printf("VirtualAddress : %08X ", MySectionHeader->VirtualAddress);//节区在内存中的偏移地址 printf("SizeOfRawData : %08X ", MySectionHeader->SizeOfRawData);//节在文件中对齐后的大小 printf("PointerToRawData : %08X ", MySectionHeader->PointerToRawData);//节区在文件中的偏移 printf("PointerToRelocations : %08X ", MySectionHeader->PointerToRelocations);//在OBJ文件中使用 无意义 printf("PointerToLinenumbers : %08X ", MySectionHeader->PointerToLinenumbers);//行号表的位置 调试的时候用 printf("NumberOfRelocations : %04X ", MySectionHeader->NumberOfRelocations);//在OBJ文件中使用 对EXE无意义 printf("NumberOfLinenumbers : %04X ", MySectionHeader->NumberOfLinenumbers);//行号表中行号的数量 调试的时候用 printf("Characteristics : %08X ", MySectionHeader->Characteristics);//节的属性 printf("---------------------------------------------- "); MySectionHeader++; } fclose(Fp); getchar(); free(TempBuffer); return 0; } //获取文件大小 int filelength(FILE *fp) { int num; fseek(fp, 0, SEEK_END); num = ftell(fp); fseek(fp, 0, SEEK_SET); return num; }