【逆向】(c++)分析pe结构,拉伸pe结构,缩小pe结构

建议大家认认真真写一遍,收获蛮大的,是可以加深对pe结构的理解,尤其是对指针的使用,和对win32的一些宏的定义的理解和使用。

cpp 复制代码
#include <windows.h>
#include <iostream>
#include <string>

using namespace std;

PIMAGE_DOS_HEADER my_dos=nullptr;//dos头结构
PIMAGE_FILE_HEADER my_file=nullptr;//file结构
PIMAGE_OPTIONAL_HEADER32 my_optional=nullptr;//可选PE头结构
PIMAGE_SECTION_HEADER* my_section=nullptr;//节表结构
void* Before_Stretch_Data = nullptr; //指向拉伸前的内容
void* Stretch_Data = nullptr; //指向拉伸后的内容
void* Shrink_data = nullptr; //指向缩小PE结构的内容

//获取
void* Readfile(char* filename)
{
	unsigned int size;
	FILE* datafile;
	void* data;
	//打开文件
	if (fopen_s(&datafile, filename, "rb") != 0)
	{
		cout << "打开文件失败" << endl;
		return nullptr;
	}


	else
	{
		//获取文件的大小
		cout << "打开文件成功!" << endl;
		fseek(datafile, 0, SEEK_END);
		size = ftell(datafile);
		fseek(datafile, 0, SEEK_SET);
		if (size == -1L)
		{
			cout << "文件大小判断失败!" << endl;
			return nullptr;
		}

		//申请内存空间把文件内容保存下来
		data = (void*)malloc(size * sizeof(char));

		if (fread_s(data, size, sizeof(char), size, datafile) == 0)
		{
			cout << "写入数据失败!" << endl;
			return nullptr;
		}
		cout << "写入数据成功,成功获取Data!" << endl;
		return data;
	}

}




//分析PE结构
void Analyze_PE(char*& Data, PIMAGE_DOS_HEADER& my_dos, PIMAGE_FILE_HEADER& my_file, PIMAGE_OPTIONAL_HEADER32& my_optional, PIMAGE_SECTION_HEADER*& my_section)
{
	DWORD* Temp_ptr = (DWORD*)Data;
	my_dos = (PIMAGE_DOS_HEADER)Temp_ptr;
	
	Temp_ptr = (DWORD*)((char*)&Data[my_dos->e_lfanew]);
	Temp_ptr++;
	my_file = (PIMAGE_FILE_HEADER)Temp_ptr;

	Temp_ptr = (DWORD*)((char*)Temp_ptr + 0x14);
	my_optional = (PIMAGE_OPTIONAL_HEADER)Temp_ptr;

	Temp_ptr = (DWORD*)((char*)my_optional+my_file->SizeOfOptionalHeader);
	my_section = (PIMAGE_SECTION_HEADER*)malloc(sizeof(IMAGE_SECTION_HEADER) * my_file->NumberOfSections);
	for (int i = 0; i < my_file->NumberOfSections; i++)
	{
		my_section[i] = (PIMAGE_SECTION_HEADER)Temp_ptr;
		Temp_ptr = (DWORD*)((char*)Temp_ptr + 0x28);
	}
}


//复制节表的内容
//void Copy_Section_Content()
//{
//	void* temp_ptr=nullptr;
//	for (int i = 0; i < my_file->NumberOfSections; i++)
//	{
//		temp_ptr = (void*)((char*)Before_Stretch_Data + my_section[i]->PointerToRawData);
//		
//	}
//}


//拉伸PE结构   注意看PIMAGE_XXX_HEADER的定义,它们本就是指向结构体的指针
void Stretch_PE()
{
	unsigned Memory_Size = 0;
	Memory_Size = my_optional->SizeOfImage;
	Stretch_Data = (void*)malloc(sizeof(char) * Memory_Size);
	memset(Stretch_Data, 0, Memory_Size);
	void* temp_before_stretch_data_ptr = Before_Stretch_Data;
	int size_of_dos = 0x40;
	int size_of_junk = 0x40;
	int size_of_file = 0x18;
	unsigned Size_Of_Optional = my_file->SizeOfOptionalHeader;
	unsigned Size_Of_Section = 0x28;
	unsigned Size_Of_Header = size_of_dos + size_of_file + size_of_junk + Size_Of_Optional + Size_Of_Section * my_file->NumberOfSections;//还未对齐
	memcpy_s(Stretch_Data, Memory_Size, Before_Stretch_Data, Size_Of_Header);
	void* temp_stretch_data = Stretch_Data;
	//现在计算head头对齐后的大小
	int Size = Size_Of_Header % my_optional->SectionAlignment;
	Size_Of_Header = my_optional->SectionAlignment * Size;

	
	for (int i = 0; i < my_file->NumberOfSections; i++)
	{
		temp_stretch_data = (void*)((char*)Stretch_Data+my_section[i]->VirtualAddress);
		temp_before_stretch_data_ptr = (void*)((char*)Before_Stretch_Data+my_section[i]->PointerToRawData);
		memcpy_s(temp_stretch_data, my_section[i]->SizeOfRawData, temp_before_stretch_data_ptr, my_section[i]->SizeOfRawData);
	}
	cout << "拉伸成功" << endl;
}

void Shrink_PE()
{
	unsigned int Size = 0;
	Size = my_section[my_file->NumberOfSections - 1]->PointerToRawData + my_section[my_file->NumberOfSections - 1]->SizeOfRawData;
	Shrink_data = (void*)malloc(Size);

	//从Stretch_Data缩小
	
	//复制Heads
	memcpy_s(Shrink_data, my_optional->SizeOfHeaders, Stretch_Data, my_optional->SizeOfHeaders);

	//复制节
	void* temp_shrink_data_ptr = Shrink_data;
	void* temp_stretch_data_ptr = Stretch_Data;
	for (int i = 0; i < my_file->NumberOfSections; i++)
	{
		temp_shrink_data_ptr = (void*)((char*)Shrink_data + my_section[i]->PointerToRawData);
		temp_stretch_data_ptr= (void*)((char*)Stretch_Data + my_section[i]->VirtualAddress);
		memcpy_s(temp_shrink_data_ptr, my_section[i]->SizeOfRawData, temp_stretch_data_ptr, my_section[i]->SizeOfRawData);
	}
	cout << "缩小成功" << endl;
	return;

}


int main()
{
	
	char filename[100]= "ceshi.exe";
	Before_Stretch_Data =Readfile(filename);
	Analyze_PE((char*&)Before_Stretch_Data, my_dos, my_file, my_optional, my_section);
	cout << my_dos->e_lfanew << endl;
	cout << my_file->Characteristics << endl;
	cout << my_optional->ImageBase << endl;
	cout << my_section[1]->Name<< endl;
	Stretch_PE();
	cout << my_section[3]->Name << endl;
	Shrink_PE();
	Analyze_PE((char*&)Shrink_data, my_dos, my_file, my_optional, my_section);
	cout << my_dos->e_lfanew << endl;
	cout << my_file->Characteristics << endl;
	cout << my_optional->ImageBase << endl;
	cout << my_section[1]->Name << endl;
	return 0;
}
相关推荐
代码小鑫2 分钟前
A032-基于Spring Boot的健康医院门诊在线挂号系统
java·开发语言·spring boot·后端·spring·毕业设计
训山9 分钟前
4000字浅谈Java网络编程
java·开发语言·网络
API快乐传递者11 分钟前
除了网页标题,还能用爬虫抓取哪些信息?
开发语言·爬虫·python
hutaotaotao1 小时前
c语言用户不同命令调用不同函数实现
c语言·开发语言
huangjiazhi_1 小时前
QTcpSocket 服务端和客户端
开发语言·qt
ac-er88881 小时前
ThinkPHP中的MVC分层是什么
开发语言·php·mvc
槿花Hibiscus1 小时前
C++基础:Pimpl设计模式的实现
c++·设计模式
shinelord明2 小时前
【再谈设计模式】建造者模式~对象构建的指挥家
开发语言·数据结构·设计模式
黑不拉几的小白兔2 小时前
PTA部分题目C++重练
开发语言·c++·算法
写bug的小屁孩2 小时前
websocket身份验证
开发语言·网络·c++·qt·websocket·网络协议·qt6.3