#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_SET
0当前位置
SEEK_CUR
1文件尾
SEEK_END
2
long offset
偏移量参数 , 可以为正数 , 也可以为负数 ;如果执行成功 , 则返回 0 , 失败返回非 0 , 并设置 error 错误代码 ;
所以重点来了:用完ftell()这个函数,就会将文件内部指针的位置移动到最末尾(如果设置的是SEEK_END),所以需要重新使用一下fseek重新设置文件内部指针的一个位置