#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重新设置文件内部指针的一个位置