#include <iostream>
#include <windows.h>
using namespace std;
#pragma warning(disable:4996)
//DOC结构
typedef struct _DOC_HEADER
{WORD  e_magic;WORD  e_cblp;WORD  e_cp;WORD  e_crlc;WORD  e_cparhar;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_oemid;WORD  e_oeminfo;WORD  e_res2[10];DWORD e_lfanew;
}PeDoc;
//FILE结构
typedef struct _STANDARD_PE_HEADER
{WORD Machine;WORD NumberOfSections;DWORD TimeDateStamp;DWORD PointerToSymbolTable;DWORD NumberOfSymbols;WORD SizeOfOptionalHeader;WORD Characteristics;
}StandardPeHeader;
//OPTIONAL结构
typedef struct _OPTIONAL_PE_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;
}OptionalPeHeader;//输出doc数据
void printDoc(PeDoc* doc)
{printf(">>>> DOC <<<<\n");printf("e_magic    = %x\n", doc->e_magic);printf("e_cblp     = %x\n", doc->e_cblp);printf("e_cp       = %x\n", doc->e_cp);printf("e_crlc     = %x\n", doc->e_crlc);printf("e_cparhar  = %x\n", doc->e_cparhar);printf("e_minalloc = %x\n", doc->e_minalloc);printf("e_maxalloc = %x\n", doc->e_maxalloc);printf("e_ss       = %x\n", doc->e_ss);printf("e_sp       = %x\n", doc->e_ss);printf("e_csum     = %x\n", doc->e_csum);printf("e_ip       = %x\n", doc->e_ip);printf("e_cs       = %x\n", doc->e_cs);printf("e_lfarlc   = %x\n", doc->e_lfarlc);printf("e_ovno     = %x\n", doc->e_ovno);printf("e_res      = %x%x%x%x\n", doc->e_res[0], doc->e_res[1], doc->e_res[2], doc->e_res[3]);printf("e_oemid    = %x\n", doc->e_oemid);printf("e_oeminfo  = %x\n", doc->e_oeminfo);printf("e_res2[10] = %x%x%x%x%x%x%x%x%x%x\n", doc->e_res2[0], doc->e_res2[1], doc->e_res2[2], doc->e_res2[3], doc->e_res2[4], doc->e_res2[5], doc->e_res2[6], doc->e_res2[7], doc->e_res2[8], doc->e_res2[9]);printf("e_lfanew   = %x\n", doc->e_lfanew);printf(">>>> DOC <<<<\n\n\n");
}
//输出file数据
void printStandar(StandardPeHeader* standard)
{printf(">>>> STANDARD <<<<\n");printf("Machine               = %x\n", standard->Machine);printf("NumberOfSections      = %x\n", standard->NumberOfSections);printf("TimeDateStamp         = %x\n", standard->TimeDateStamp);printf("PointerToSymbolTable  = %x\n", standard->PointerToSymbolTable);printf("NumberOfSymbols	      = %x\n", standard->NumberOfSymbols);printf("SizeOfOptionalHeader  = %x\n", standard->SizeOfOptionalHeader);printf("Characteristics       = %x\n", standard->Characteristics);printf(">>>> STANDARD <<<<\n\n\n");
}
//输出optional数据
void printOptional(OptionalPeHeader* optional)
{printf(">>>> OPTIONAL <<<<\n");printf("Magic                       = %x\n", optional->Magic);printf("MajorLinkerVersion          = %x\n", optional->MajorLinkerVersion);printf("MinorLinkerVersion          = %x\n", optional->MinorLinkerVersion);printf("SizeOfCode                  = %x\n", optional->SizeOfCode);printf("SizeOfInitializedData       = %x\n", optional->SizeOfInitializedData);printf("SizeOfUninitializedData     = %x\n", optional->SizeOfUninitializedData);printf("AddressOfEntryPoint         = %x\n", optional->AddressOfEntryPoint);printf("BaseOfCode                  = %x\n", optional->BaseOfCode);printf("BaseOfData                  = %x\n", optional->BaseOfData);printf("ImageBase                   = %x\n", optional->ImageBase);printf("SectionAlignment            = %x\n", optional->SectionAlignment);printf("FileAlignment               = %x\n", optional->FileAlignment);printf("MajorOperatingSystemVersion = %x\n", optional->MajorOperatingSystemVersion);printf("MinorOperatingSystemVersion = %x\n", optional->MinorOperatingSystemVersion);printf("MajorImageVersion           = %x\n", optional->MajorImageVersion);printf("MinorImageVersion           = %x\n", optional->MinorImageVersion);printf("MajorSubsystemVersion	    = %x\n", optional->MajorSubsystemVersion);printf("MinorSubsystemVersion	    = %x\n", optional->MinorSubsystemVersion);printf("Win32VersionValue           = %x\n", optional->Win32VersionValue);printf("SizeOfImage                 = %x\n", optional->SizeOfImage);printf("SizeOfHeaders               = %x\n", optional->SizeOfHeaders);printf("CheckSum                    = %x\n", optional->CheckSum);printf("Subsystem                   = %x\n", optional->Subsystem);printf("DllCharacteristics          = %x\n", optional->DllCharacteristics);printf("SizeOfStackReserve          = %x\n", optional->SizeOfStackReserve);printf("SizeOfStackCommit           = %x\n", optional->SizeOfStackCommit);printf("SizeOfHeapReserve           = %x\n", optional->SizeOfHeapReserve);printf("SizeOfHeapCommit            = %x\n", optional->SizeOfHeapCommit);printf("LoaderFlags                 = %x\n", optional->LoaderFlags);printf("NumberOfRvaAndSizes         = %x\n", optional->NumberOfRvaAndSizes);printf(">>>> OPTIONAL <<<<\n\n\n");
}char* ReadPeFile(const char* peFIle)
{FILE* peFile = fopen(peFIle, "rb");  //pe文件对象unsigned int peSize = 0;  //pe文件大小char* peData = nullptr;   //指向pe的二进制数据if (peFile == NULL){cout << "文件打开失败" << endl;goto END;}if (fseek(peFile, 0, SEEK_END) != 0){cout << "指针移动失败" << endl;goto END;}peSize = ftell(peFile);if (peSize == 0){cout << "程序没有任何数据" << endl;goto END;}if (fseek(peFile, 0, SEEK_SET) != 0){printf("指针移动失败!(%d)\n", __LINE__);goto END;}//根据PE文件的大小开辟内存存放PE数据peData = (char*)malloc(peSize);if (peData != NULL){memset(peData, '0', peSize);//读取pe数据fread(peData, sizeof(char), peSize, peFile);}END:if (peFile){fclose(peFile);}return peData;}void ReadPeData(char* peData, PeDoc*& doc, StandardPeHeader*& standard, OptionalPeHeader*& optional)
{doc = (PeDoc*)peData;peData = &peData[doc->e_lfanew + 4];standard = (StandardPeHeader*)peData;peData = &peData[20];optional = (OptionalPeHeader*)peData;
}void printPeHeaderInfo(const char* peFile)
{char* peData = ReadPeFile(peFile);PeDoc* doc = { NULL };StandardPeHeader* peStandard = { NULL };OptionalPeHeader* peOptional = { NULL };ReadPeData(peData, doc, peStandard, peOptional);printDoc(doc);printStandar(peStandard);printOptional(peOptional);free(peData);
}int main()
{printPeHeaderInfo("Afkayas.1.Exe");getchar();return 0;
} 

有个问题,因为我认为前面一个已经判断指针移动失败了,于是我把第二个注释了,发现少了第二个fseek就会输出错误的答案
正在解决。。。。
喵的,解决了
fseek : 重新设置文件内部指针的位置 ;
#include <stdio.h> int fseek(FILE *stream, long offset, int fromwhere);设置的指针的位置是 起始位置 + 偏移量 ;
其中的
int fromwhere参数就是 起始位置 , 有以下三种选择 :
文件头
SEEK_SET0当前位置
SEEK_CUR1文件尾
SEEK_END2
long offset偏移量参数 , 可以为正数 , 也可以为负数 ;如果执行成功 , 则返回 0 , 失败返回非 0 , 并设置 error 错误代码 ;
所以重点来了:用完ftell()这个函数,就会将文件内部指针的位置移动到最末尾(如果设置的是SEEK_END),所以需要重新使用一下fseek重新设置文件内部指针的一个位置