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

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

#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;
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值