[滴水逆向]03-12 pe头字段说明课后作业,输出pe结构

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

相关推荐
SRY122404192 小时前
javaSE面试题
java·开发语言·面试
李元豪3 小时前
【智鹿空间】c++实现了一个简单的链表数据结构 MyList,其中包含基本的 Get 和 Modify 操作,
数据结构·c++·链表
无尽的大道3 小时前
Java 泛型详解:参数化类型的强大之处
java·开发语言
ZIM学编程3 小时前
Java基础Day-Sixteen
java·开发语言·windows
放逐者-保持本心,方可放逐3 小时前
react 组件应用
开发语言·前端·javascript·react.js·前端框架
UestcXiye3 小时前
《TCP/IP网络编程》学习笔记 | Chapter 9:套接字的多种可选项
c++·计算机网络·ip·tcp
一丝晨光4 小时前
编译器、IDE对C/C++新标准的支持
c语言·开发语言·c++·ide·msvc·visual studio·gcc
阮少年、4 小时前
java后台生成模拟聊天截图并返回给前端
java·开发语言·前端
代码小鑫4 小时前
A027-基于Spring Boot的农事管理系统
java·开发语言·数据库·spring boot·后端·毕业设计
丶Darling.4 小时前
Day40 | 动态规划 :完全背包应用 组合总和IV(类比爬楼梯)
c++·算法·动态规划·记忆化搜索·回溯