【逆向】用代码实现合并节操作和打印数据目录结构,以及记录踩过的坑

说来惭愧,这一节课的作业写了超级久,原因是听完课就感觉,就这??那么简单,直接上手写!然后调试了一天才发现难绷,原来一开始就错了。

先讲讲合并节的步骤吧,我的实验是将第一个节表复制到最后一个节表后面,节表数量不变。

具体的做法步骤为:

合并节:

  • 拉伸到内存

  • 将第一个节的内存大小,文件大小改成一样的 Max=VirtualSize和SizeOfRawdata的较大者按照内存对齐后的大小 则合并后的节的大小为VirtualAddress+Max-SizeofHeader按照内存对齐后的大小

  • 将第一个节的属性改成包含所有节的属性

  • 改SizeOfImage的大小

  • 修改节的数量为1

但我发现这也似乎不太行,修改结束后,节表数目变成一个,但是得到的exe文件甚至连图标都没有了,当我把节的数目改回来时,惊奇的发现图标又出现了。由此我提出一个疑问,难道某些节不能动????

所以我尝试了下只把最后一个节和新增节合并,还是可以的
代码如下:
 

void PE::Combine_Section(char* filename, Data& my_data)
{

	int Max = MAX(my_data.my_section[my_data.my_file->NumberOfSections - 1]->SizeOfRawData, my_data.my_section[my_data.my_file->NumberOfSections - 1]->Misc.VirtualSize);
	int Size = my_data.my_section[my_data.my_file->NumberOfSections - 1]->VirtualAddress + Section_Align(Max, my_data) - Section_Align(my_data.my_optional->SizeOfHeaders, my_data)+ MAX(my_data.my_section[0]->SizeOfRawData, my_data.my_section[0]->Misc.VirtualSize);
	Data Comebine_Data;
	int temp_size = _msize(my_data.Stretch_Data)+Max;
	Comebine_Data.Stretch_Data = (void*)malloc(temp_size);
	memset(Comebine_Data.Stretch_Data, 0, Size);

	temp_size = _msize(my_data.Stretch_Data);
	memcpy_s(Comebine_Data.Stretch_Data, temp_size, my_data.Stretch_Data, temp_size);
	Analyze_PE(Comebine_Data, 2);

	void* temp_ptr = (char*)Comebine_Data.Stretch_Data + Max+ my_data.my_section[my_data.my_file->NumberOfSections - 1]->VirtualAddress;
	memcpy_s(temp_ptr, MAX(my_data.my_section[0]->SizeOfRawData, my_data.my_section[0]->Misc.VirtualSize),my_data.my_section[0]->VirtualAddress+(char*)my_data.Stretch_Data, MAX(my_data.my_section[0]->SizeOfRawData, my_data.my_section[0]->Misc.VirtualSize));

	Comebine_Data.my_optional->SizeOfImage += Section_Align(MAX(my_data.my_section[0]->SizeOfRawData, my_data.my_section[0]->Misc.VirtualSize),my_data);

	Comebine_Data.my_section[my_data.my_file->NumberOfSections - 1]->SizeOfRawData += File_Align(MAX(my_data.my_section[0]->SizeOfRawData, my_data.my_section[0]->Misc.VirtualSize), my_data);
	Comebine_Data.my_section[my_data.my_file->NumberOfSections - 1]->Misc.VirtualSize = Section_Align(Comebine_Data.my_section[my_data.my_file->NumberOfSections - 1]->Misc.VirtualSize,my_data)+ Section_Align(MAX(my_data.my_section[0]->SizeOfRawData, my_data.my_section[0]->Misc.VirtualSize),my_data);

	FILE* my_file;
	if (fopen_s(&my_file, filename, "wb") != 0)
	{
		cout << "打开文件失败" << endl;
		return;
	}

	Shrink_PE(Comebine_Data);
	Analyze_PE(Comebine_Data, 3);

	fwrite(Comebine_Data.Shrink_Data, 1, _msize(Comebine_Data.Shrink_Data), my_file);
	cout << "写入成功!" << endl;

	fclose(my_file);
}

期间我还遇到一个bug,就是堆损坏
61ad439c4a9d4afda7d9cab8d36b85a3.png

就像这个样子
百思不得其解,百度了好久,也没得到一个答案,最后问题解决了,原来是申请空间太小了,都进去的东西太多,可能覆盖掉了不该覆盖的东西,进而报错。。。。。哎,浪费好多时间

打印数据目录结构代码:
 

void PE:: Print_IMAGE_DATA_DIRECTORY(Data& my_data)
{
	my_data.my_Data_Directory = nullptr;
	my_data.my_Data_Directory = (PIMAGE_DATA_DIRECTORY*)malloc(16 * sizeof(PIMAGE_DATA_DIRECTORY));
	void* Temp_ptr = my_data.my_optional->DataDirectory;
	for (int i = 0; i < 16; i++)
	{
		my_data.my_Data_Directory[i] = (PIMAGE_DATA_DIRECTORY)Temp_ptr;
		Temp_ptr = (char*)Temp_ptr + 0x8;
	}
	char arr[16][40] = {
	"IMAGE_DIRECTORY_ENTRY_EXPORT",
	"IMAGE_DIRECTORY_ENTRY_IMPORT",
	"IMAGE_DIRECTORY_ENTRY_RESOURCE",
	"IMAGE_DIRECTORY_ENTRY_EXCEPTION",
	"IMAGE_DIRECTORY_ENTRY_SECURITY",
	"IMAGE_DIRECTORY_ENTRY_BASERELOC",
	"IMAGE_DIRECTORY_ENTRY_DEBUG",
	"IMAGE_DIRECTORY_ENTRY_COPYRIGHT",
	"IMAGE_DIRECTORY_ENTRY_GLOBALPTR",
	"IMAGE_DIRECTORY_ENTRY_TLS",
	"IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG",
	"IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT",
	"IMAGE_DIRECTORY_ENTRY_IAT",
	"IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT",
	"IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR",
	"RESERVED"
	};

	for (int i = 0; i < 16; i++)
	{
		cout << arr[i] << " :" << endl;
		cout << "Size: " <<hex<< my_data.my_Data_Directory[i]->Size << endl;
		cout << "Virtual_Address: " << my_data.my_Data_Directory[i]->VirtualAddress << endl;
		cout << "------------------------------------------------------------------------" << endl;
	}
	return;
}

完整代码:

#include <windows.h>
#include <iostream>
#include <string>

#include <malloc.h>
using namespace std;

int MAX(int a, int b)
{
	return a >= b ? a : b;
}

class Data
{
public:
	PIMAGE_DOS_HEADER my_dos;//dos头结构
	PIMAGE_FILE_HEADER my_file;//file结构
	PIMAGE_OPTIONAL_HEADER32 my_optional;//可选PE头结构
	PIMAGE_SECTION_HEADER* my_section;//节表结构
	PIMAGE_DATA_DIRECTORY*	my_Data_Directory;//数据目录结构


	void* Before_Stretch_Data; //指向拉伸前的内容
	void* Stretch_Data; //指向拉伸后的内容
	void* Shrink_Data; //指向缩小PE结构的内容


	Data()
	{
		my_dos = nullptr;//dos头结构
		my_file = nullptr;//file结构
		my_optional = nullptr;//可选PE头结构
		my_section = nullptr;//节表结构
		my_Data_Directory = nullptr;


		Before_Stretch_Data = nullptr; //指向拉伸前的内容
		Stretch_Data = nullptr; //指向拉伸后的内容
		Shrink_Data = nullptr; //指向缩小PE结构的内容
	}

	~Data()
	{
		if (Before_Stretch_Data != nullptr)
		{
			free(Before_Stretch_Data);
			Before_Stretch_Data = nullptr;
		}

		if (Stretch_Data != nullptr)
		{
			free(Stretch_Data);
			Stretch_Data = nullptr;
		}

		if (Shrink_Data != nullptr)
		{
			free(Shrink_Data);
			Shrink_Data = nullptr;
		}
	}


	void Copy_Before_Strectch_Data(Data my_data); //只深拷贝Before_Strectch_Data
};

void Data::Copy_Before_Strectch_Data(Data my_data)
{
	int size = _msize(my_data.Before_Stretch_Data);
	memcpy_s(this->Before_Stretch_Data, size, my_data.Before_Stretch_Data, size);
}



class PE
{
public:




public:
	void Readfile(char* filename, Data& my_data);  //读取pe文件

	void Analyze_PE(Data& my_data, int num);  //分析pe结构

	void Stretch_PE(Data& my_data);  //拉伸pe结构

	void Shrink_PE(Data& my_data); //缩小pe结构

	void New_Section(char* filename, Data& my_data);//新增节,非扩大节,并写入新的exe文件中

	void Expand_Section(Data& my_data, char* filename);  //扩大节

	int Section_Align(int temp, Data& my_data); //返回内存对齐后的大小

	int File_Align(int temp, Data& my_data); //返回文件对齐后的大小

	void Combine_Section(char* filename, Data& my_data);

	void Copy_Data(Data& my_data);

	void Print_IMAGE_DATA_DIRECTORY(Data& my_data);
};


void PE:: Print_IMAGE_DATA_DIRECTORY(Data& my_data)
{
	my_data.my_Data_Directory = nullptr;
	my_data.my_Data_Directory = (PIMAGE_DATA_DIRECTORY*)malloc(16 * sizeof(PIMAGE_DATA_DIRECTORY));
	void* Temp_ptr = my_data.my_optional->DataDirectory;
	for (int i = 0; i < 16; i++)
	{
		my_data.my_Data_Directory[i] = (PIMAGE_DATA_DIRECTORY)Temp_ptr;
		Temp_ptr = (char*)Temp_ptr + 0x8;
	}
	char arr[16][40] = {
	"IMAGE_DIRECTORY_ENTRY_EXPORT",
	"IMAGE_DIRECTORY_ENTRY_IMPORT",
	"IMAGE_DIRECTORY_ENTRY_RESOURCE",
	"IMAGE_DIRECTORY_ENTRY_EXCEPTION",
	"IMAGE_DIRECTORY_ENTRY_SECURITY",
	"IMAGE_DIRECTORY_ENTRY_BASERELOC",
	"IMAGE_DIRECTORY_ENTRY_DEBUG",
	"IMAGE_DIRECTORY_ENTRY_COPYRIGHT",
	"IMAGE_DIRECTORY_ENTRY_GLOBALPTR",
	"IMAGE_DIRECTORY_ENTRY_TLS",
	"IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG",
	"IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT",
	"IMAGE_DIRECTORY_ENTRY_IAT",
	"IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT",
	"IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR",
	"RESERVED"
	};

	for (int i = 0; i < 16; i++)
	{
		cout << arr[i] << " :" << endl;
		cout << "Size: " <<hex<< my_data.my_Data_Directory[i]->Size << endl;
		cout << "Virtual_Address: " << my_data.my_Data_Directory[i]->VirtualAddress << endl;
		cout << "------------------------------------------------------------------------" << endl;
	}
	return;
}


void PE::Combine_Section(char* filename, Data& my_data)
{

	int Max = MAX(my_data.my_section[my_data.my_file->NumberOfSections - 1]->SizeOfRawData, my_data.my_section[my_data.my_file->NumberOfSections - 1]->Misc.VirtualSize);
	int Size = my_data.my_section[my_data.my_file->NumberOfSections - 1]->VirtualAddress + Section_Align(Max, my_data) - Section_Align(my_data.my_optional->SizeOfHeaders, my_data)+ MAX(my_data.my_section[0]->SizeOfRawData, my_data.my_section[0]->Misc.VirtualSize);
	Data Comebine_Data;
	int temp_size = _msize(my_data.Stretch_Data)+Max;
	Comebine_Data.Stretch_Data = (void*)malloc(temp_size);
	memset(Comebine_Data.Stretch_Data, 0, Size);

	temp_size = _msize(my_data.Stretch_Data);
	memcpy_s(Comebine_Data.Stretch_Data, temp_size, my_data.Stretch_Data, temp_size);
	Analyze_PE(Comebine_Data, 2);

	void* temp_ptr = (char*)Comebine_Data.Stretch_Data + Max+ my_data.my_section[my_data.my_file->NumberOfSections - 1]->VirtualAddress;
	memcpy_s(temp_ptr, MAX(my_data.my_section[0]->SizeOfRawData, my_data.my_section[0]->Misc.VirtualSize),my_data.my_section[0]->VirtualAddress+(char*)my_data.Stretch_Data, MAX(my_data.my_section[0]->SizeOfRawData, my_data.my_section[0]->Misc.VirtualSize));

	Comebine_Data.my_optional->SizeOfImage += Section_Align(MAX(my_data.my_section[0]->SizeOfRawData, my_data.my_section[0]->Misc.VirtualSize),my_data);

	Comebine_Data.my_section[my_data.my_file->NumberOfSections - 1]->SizeOfRawData += File_Align(MAX(my_data.my_section[0]->SizeOfRawData, my_data.my_section[0]->Misc.VirtualSize), my_data);
	Comebine_Data.my_section[my_data.my_file->NumberOfSections - 1]->Misc.VirtualSize = Section_Align(Comebine_Data.my_section[my_data.my_file->NumberOfSections - 1]->Misc.VirtualSize,my_data)+ Section_Align(MAX(my_data.my_section[0]->SizeOfRawData, my_data.my_section[0]->Misc.VirtualSize),my_data);

	FILE* my_file;
	if (fopen_s(&my_file, filename, "wb") != 0)
	{
		cout << "打开文件失败" << endl;
		return;
	}

	Shrink_PE(Comebine_Data);
	Analyze_PE(Comebine_Data, 3);

	fwrite(Comebine_Data.Shrink_Data, 1, _msize(Comebine_Data.Shrink_Data), my_file);
	cout << "写入成功!" << endl;

	fclose(my_file);
}


void PE::Expand_Section(Data& my_data, char* filename)
{
	this->Stretch_PE(my_data);
	unsigned Size = 0;//扩大节后新的文件大小
	Size = my_data.my_optional->ImageBase + Section_Align(MAX(my_data.my_section[0]->SizeOfRawData, my_data.my_section[0]->Misc.VirtualSize), my_data);

	Data Expand_Data;
	Expand_Data.Stretch_Data = (void*)malloc(Size);
	memset(Expand_Data.Stretch_Data, 0, Size);
	memcpy_s(Expand_Data.Stretch_Data, _msize(my_data.Stretch_Data), my_data.Stretch_Data, _msize(my_data.Stretch_Data));

	Analyze_PE(Expand_Data, 2);

	Expand_Data.my_section[my_data.my_file->NumberOfSections - 1]->SizeOfRawData = Section_Align(MAX(my_data.my_section[0]->SizeOfRawData, my_data.my_section[0]->Misc.VirtualSize), my_data) + Section_Align(MAX(my_data.my_section[my_data.my_file->NumberOfSections - 1]->SizeOfRawData, my_data.my_section[my_data.my_file->NumberOfSections - 1]->Misc.VirtualSize), my_data);
	Expand_Data.my_section[my_data.my_file->NumberOfSections - 1]->Misc.VirtualSize = Expand_Data.my_section[my_data.my_file->NumberOfSections - 1]->SizeOfRawData;

	Expand_Data.my_optional->SizeOfImage += Section_Align(MAX(my_data.my_section[0]->SizeOfRawData, my_data.my_section[0]->Misc.VirtualSize), my_data);

	void* Temp_Ptr = (char*)Expand_Data.Stretch_Data + Expand_Data.my_section[Expand_Data.my_file->NumberOfSections - 1]->VirtualAddress + Section_Align(MAX(my_data.my_section[Expand_Data.my_file->NumberOfSections - 1]->SizeOfRawData, my_data.my_section[Expand_Data.my_file->NumberOfSections - 1]->Misc.VirtualSize), my_data);
	int temp_size = Section_Align(MAX(my_data.my_section[0]->SizeOfRawData, my_data.my_section[0]->Misc.VirtualSize), my_data);
	void* Temp_Ptr2 = (char*)my_data.Stretch_Data + my_data.my_section[0]->VirtualAddress;

	memcpy_s(Temp_Ptr, temp_size, Temp_Ptr2, temp_size);


	Shrink_PE(Expand_Data);

	FILE* my_file;
	if (fopen_s(&my_file, filename, "wb") != 0)
	{
		cout << "打开文件失败!" << endl;

	}
	else
	{
		Size = _msize(Expand_Data.Shrink_Data);
		fwrite(Expand_Data.Shrink_Data, 1, Size, my_file);
		cout << "写入成功!" << endl;
	}
	fclose(my_file);
}


int PE::Section_Align(int temp, Data& my_data)
{
	int i = 0;
	while (temp > i * my_data.my_optional->SectionAlignment)
	{
		i++;
	}
	return i * my_data.my_optional->SectionAlignment;

}

int PE::File_Align(int temp, Data& my_data)
{
	int i = 0;
	while (temp > i * my_data.my_optional->FileAlignment)
	{
		i++;
	}
	return i * my_data.my_optional->FileAlignment;
}

void PE::New_Section(char* filename, Data& my_data)
{
	unsigned int Size; //Size是新文件的大小,是原来的文件大小加上.VirtualSize和SizeOfRawData较大的那个
	Size = my_data.my_optional->SizeOfHeaders;
	for (int i = 0; i < my_data.my_file->NumberOfSections; i++)
	{
		Size += my_data.my_section[i]->SizeOfRawData;
	}
	Size += my_data.my_section[0]->SizeOfRawData;//这是最终新的文件的大小

	Data New_Data;
	New_Data.Before_Stretch_Data = (void*)malloc(Size * 1);
	memset(New_Data.Before_Stretch_Data, 0, Size);
	memcpy_s(New_Data.Before_Stretch_Data, Size, my_data.Before_Stretch_Data, Size - my_data.my_section[0]->SizeOfRawData);//将原来的文件复制过来

	Analyze_PE(New_Data, 1);//让New_Data的dos,file,optional,section有数据

	//复制新的节表
	void* Temp_ptr1 = (char*)my_data.Before_Stretch_Data + 0x98 + my_data.my_file->SizeOfOptionalHeader;
	void* Temp_ptr2 = (char*)New_Data.Before_Stretch_Data + 0x98 + my_data.my_file->SizeOfOptionalHeader + my_data.my_file->NumberOfSections * 0x28;
	memcpy_s(Temp_ptr2, 0x28, Temp_ptr1, 0x28);
	//复制新的节
	Temp_ptr1 = (char*)my_data.Before_Stretch_Data + my_data.my_optional->SizeOfHeaders;//指向.text段
	Temp_ptr2 = (char*)New_Data.Before_Stretch_Data + Size - my_data.my_section[0]->SizeOfRawData;

	memcpy_s(Temp_ptr2, my_data.my_section[0]->SizeOfRawData, Temp_ptr1, my_data.my_section[0]->SizeOfRawData);//复制完.text段作为新增节

	//接下来要改Header的各项数据
	New_Data.my_file->NumberOfSections++;
	New_Data.my_optional->SizeOfImage += my_data.my_section[0]->SizeOfRawData;

	Analyze_PE(New_Data, 1);
	New_Data.my_section[New_Data.my_file->NumberOfSections - 1]->PointerToRawData = New_Data.my_section[New_Data.my_file->NumberOfSections - 2]->PointerToRawData + New_Data.my_section[New_Data.my_file->NumberOfSections - 2]->SizeOfRawData;
	int size;
	if (New_Data.my_section[New_Data.my_file->NumberOfSections - 2]->Misc.VirtualSize >= New_Data.my_section[New_Data.my_file->NumberOfSections - 2]->SizeOfRawData)
	{
		size = New_Data.my_section[New_Data.my_file->NumberOfSections - 2]->Misc.VirtualSize;
	}
	else
	{
		size = New_Data.my_section[New_Data.my_file->NumberOfSections - 2]->SizeOfRawData;
	}
	size = size / my_data.my_optional->SectionAlignment + my_data.my_optional->SectionAlignment;
	New_Data.my_section[New_Data.my_file->NumberOfSections - 1]->VirtualAddress = New_Data.my_section[New_Data.my_file->NumberOfSections - 2]->VirtualAddress + size;

	FILE* my_file;
	if (fopen_s(&my_file, filename, "wb") == 0)
	{
		fwrite(New_Data.Before_Stretch_Data, 1, Size, my_file);
		cout << "写入成功!" << endl;
		return;
	}
	else
	{
		cout << "打开文件失败" << endl;
		return;
	}
	fclose(my_file);
}


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


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

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

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

}

//分析PE结构
void PE::Analyze_PE(Data& data, int num)
{
	if (num == 1)
	{
		if (data.Before_Stretch_Data != nullptr)
		{
			DWORD* Temp_ptr = (DWORD*)data.Before_Stretch_Data;
			data.my_dos = (PIMAGE_DOS_HEADER)Temp_ptr;

			Temp_ptr = (DWORD*)((char*)data.Before_Stretch_Data + data.my_dos->e_lfanew);
			Temp_ptr++;
			data.my_file = (PIMAGE_FILE_HEADER)Temp_ptr;

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

			Temp_ptr = (DWORD*)((char*)data.my_optional + data.my_file->SizeOfOptionalHeader);
			data.my_section = (PIMAGE_SECTION_HEADER*)malloc(sizeof(PIMAGE_SECTION_HEADER) * data.my_file->NumberOfSections);
			memset(data.my_section, 0, sizeof(PIMAGE_SECTION_HEADER) * data.my_file->NumberOfSections);
			for (int i = 0; i < data.my_file->NumberOfSections; i++)
			{
				data.my_section[i] = (PIMAGE_SECTION_HEADER)Temp_ptr;
				Temp_ptr = (DWORD*)((char*)Temp_ptr + 0x28);
			}
			return;
		}
		cout << "分析PE结构失败!" << endl;
	}

	if (num == 2)
	{
		if (data.Stretch_Data != nullptr)
		{
			DWORD* Temp_ptr = (DWORD*)data.Stretch_Data;
			data.my_dos = (PIMAGE_DOS_HEADER)Temp_ptr;

			Temp_ptr = (DWORD*)((char*)data.Stretch_Data + data.my_dos->e_lfanew);
			Temp_ptr++;
			data.my_file = (PIMAGE_FILE_HEADER)Temp_ptr;

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

			Temp_ptr = (DWORD*)((char*)data.my_optional + data.my_file->SizeOfOptionalHeader);
			data.my_section = nullptr;
			data.my_section = (PIMAGE_SECTION_HEADER*)malloc(sizeof(PIMAGE_SECTION_HEADER) * data.my_file->NumberOfSections);
			for (int i = 0; i < data.my_file->NumberOfSections; i++)
			{
				data.my_section[i] = (PIMAGE_SECTION_HEADER)Temp_ptr;
				Temp_ptr = (DWORD*)((char*)Temp_ptr + 0x28);
			}
			return;
		}
		cout << "分析PE结构失败!" << endl;
	}

	if (num == 3)
	{
		if (data.Shrink_Data != nullptr)
		{
			DWORD* Temp_ptr = (DWORD*)data.Shrink_Data;
			data.my_dos = (PIMAGE_DOS_HEADER)Temp_ptr;

			Temp_ptr = (DWORD*)((char*)data.Shrink_Data + data.my_dos->e_lfanew);
			Temp_ptr++;
			data.my_file = (PIMAGE_FILE_HEADER)Temp_ptr;

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

			Temp_ptr = (DWORD*)((char*)data.my_optional + data.my_file->SizeOfOptionalHeader);
			data.my_section = (PIMAGE_SECTION_HEADER*)malloc(sizeof(PIMAGE_SECTION_HEADER) * data.my_file->NumberOfSections);
			for (int i = 0; i < data.my_file->NumberOfSections; i++)
			{
				data.my_section[i] = (PIMAGE_SECTION_HEADER)Temp_ptr;
				Temp_ptr = (DWORD*)((char*)Temp_ptr + 0x28);
			}
			return;
		}
		cout << "分析pe结构失败!" << endl;
	}

}

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


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



void PE::Shrink_PE(Data& my_data)
{
	unsigned int Size = 0;
	Size = my_data.my_section[my_data.my_file->NumberOfSections - 1]->PointerToRawData + my_data.my_section[my_data.my_file->NumberOfSections - 1]->SizeOfRawData;
	my_data.Shrink_Data = (void*)malloc(Size);
	memset(my_data.Shrink_Data, 0, Size);
	//从Stretch_Data缩小

	//复制Heads
	memcpy_s(my_data.Shrink_Data, my_data.my_optional->SizeOfHeaders, my_data.Stretch_Data, my_data.my_optional->SizeOfHeaders);

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

}


int main()
{
	char filename[100] = "ceshi.exe";
	PE my_pe;
	Data my_data;
	my_pe.Readfile(filename, my_data);
	my_pe.Analyze_PE(my_data, 1);   //char*& Data, PIMAGE_DOS_HEADER& dos, PIMAGE_FILE_HEADER& file, PIMAGE_OPTIONAL_HEADER32& optional, PIMAGE_SECTION_HEADER*& section
	my_pe.Stretch_PE(my_data);
	my_pe.Shrink_PE(my_data);

	/*char filename2[100] = "666.exe";
	my_pe.New_Section(filename2, my_data);*/

	/*char filename3[100] = "555.exe";
	my_pe.Expand_Section(my_data,filename3);
	return 0;*/

	//char filename4[100] = "333.exe";
	//my_pe.Combine_Section(filename4, my_data);
	//return 0;
	my_pe.Print_IMAGE_DATA_DIRECTORY(my_data);


}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值