昨天闲的蛋疼,一想如果每次完成的作业都需要重新写一次完整的PE结构缩小,放大,写入文件等功能,对于我这个上了年纪的老人来说实在难绷,因此我昨天花了大力气,调试了蛮久的,封装在c++的类里面,结构看起来也清晰,功能我也会按照进度持续更新
顺便谈谈下一步计划,三期结束,想看看内核的编程,和科锐老钱的那本书,叫啥c++反汇编与逆向分析技术解密,接下来就是看看外挂?未来还是蛮想做反挂的一些职业的
扯远了,上代码,代码我有时间进行优化,后悔上学期的c++没学很好,淦
- #include
- #include
- #include
- using namespace std;
-
-
- 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 ;//节表结构
-
-
- 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;//节表结构
-
-
- 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;
- }
- }
- };
-
- class PE
- {
- public:
-
-
-
-
- public:
- void Readfile(char* filename, Data& my_data); //读取pe文件
-
- void Analyze_PE(Data& my_data); //分析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 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);
- 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);//让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);
- 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;
- }
- }
-
-
- 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& my_data)
- {
- DWORD* Temp_ptr = (DWORD*)my_data.Before_Stretch_Data;
- my_data.my_dos = (PIMAGE_DOS_HEADER)Temp_ptr;
-
- Temp_ptr = (DWORD*)((char*)my_data.Before_Stretch_Data+ my_data.my_dos->e_lfanew);
- Temp_ptr++;
- my_data.my_file = (PIMAGE_FILE_HEADER)Temp_ptr;
-
- Temp_ptr = (DWORD*)((char*)Temp_ptr + 0x14);
- my_data.my_optional = (PIMAGE_OPTIONAL_HEADER)Temp_ptr;
-
- Temp_ptr = (DWORD*)((char*)my_data.my_optional + my_data.my_file->SizeOfOptionalHeader);
- my_data.my_section = (PIMAGE_SECTION_HEADER*)malloc(sizeof(IMAGE_SECTION_HEADER) * my_data.my_file->NumberOfSections);
- for (int i = 0; i < my_data.my_file->NumberOfSections; i++)
- {
- my_data.my_section[i] = (PIMAGE_SECTION_HEADER)Temp_ptr;
- Temp_ptr = (DWORD*)((char*)Temp_ptr + 0x28);
- }
- }
-
- //拉伸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 = size_of_dos + size_of_file + size_of_junk + Size_Of_Optional + Size_Of_Section * my_data.my_file->NumberOfSections;//还未对齐
- 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);
-
- //从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); //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);
- return 0;
-
- }
不知道大家看别人代码的时候,会不会很讨厌别人使用一些奇奇怪怪的宏定义,明明非常简单的一些指针,除非是结构体指针,确实蛮好用的,但是有些我实在难以理解,于是我的代码几乎没有那些奇奇怪怪的宏定义,主要是自己看着也舒服(其实是我水平确实不高,对比其他人,开发水平实在低)。所以我的代码应该还是很好读懂的
顺便说下,新增节的功能默认是复制第一个节表和第一个节的内容,如果有需要,可以自己稍加修改,我这只是写了个框架
WARING:注意注意,如果代码有更新,有新的功能的话,点我主页看!