【逆向】导出表:1.编写程序打印所有的导出表信息2.编写GetFunctionAddrByName3.编写Get
- IT业界
- 2025-08-17 07:42:01

这是从数据目录中获取每个表的地址
void PE::Analyze_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; } }打印所有导出表的信息:
void PE::Print_ExportTable(Data& my_data) { PIMAGE_EXPORT_DIRECTORY my_export_directory_ptr = (PIMAGE_EXPORT_DIRECTORY)((DWORD)my_data.my_Data_Directory[0]->VirtualAddress + (DWORD)my_data.Stretch_Data); my_data.my_Export_Directory = my_export_directory_ptr; DWORD AddressOfFunctions_ptr = (DWORD)((DWORD)my_export_directory_ptr->AddressOfFunctions + (DWORD)my_data.Stretch_Data); DWORD AddressOfNames_ptr = (DWORD)((DWORD)my_export_directory_ptr->AddressOfNames + (DWORD)my_data.Stretch_Data); DWORD AddressOfNameOrdinals_ptr = (DWORD)((DWORD)my_export_directory_ptr->AddressOfNameOrdinals + (DWORD)my_data.Stretch_Data); cout << "---------------AddressOfFunctions------------------" << endl; int number = my_export_directory_ptr->NumberOfFunctions; for (int i = 0; i < number; i++) { cout << i << ": " << "0x" << hex << *((DWORD*)AddressOfFunctions_ptr) << endl; my_data.Export_AddressOfFunction[i] = *((DWORD*)AddressOfFunctions_ptr); AddressOfFunctions_ptr += 0x4; while (*((DWORD*)AddressOfFunctions_ptr) == 0) { AddressOfFunctions_ptr += 0x4; } } cout << "---------------------Names------------------" << endl; number = my_export_directory_ptr->NumberOfNames; for (int i = 0; i < number; i++) { strcpy_s(my_data.my_Export_Name[i], (PCHAR)(*(DWORD*)AddressOfNames_ptr + (DWORD)my_data.Stretch_Data)); cout << i << ": " << (PCHAR)(*(DWORD*)AddressOfNames_ptr + (DWORD)my_data.Stretch_Data) << endl; AddressOfNames_ptr += 0x4; } cout << "----------------------NameOrdinals---------------" << endl; cout << "base: " << my_export_directory_ptr->Base << endl; for (int i = 0; i < number; i++) { cout << i << ": " << *(WORD*)AddressOfNames_ptr << endl; AddressOfNames_ptr += 0x2; } }通过函数名称获取函数在DLL的偏移:
VOID PE::GetFunctionAddrByName(Data& my_data, char* name) { int i = 0; for (i = 0; i < my_data.my_Export_Directory->NumberOfNames; i++) { if (!strcmp(name, my_data.my_Export_Name[i])) { cout << "成功通过函数名匹配到函数!" << endl; break; } if (i == my_data.my_Export_Directory->NumberOfNames - 1) { cout << "没有匹配到函数名!" << endl; return ; } } cout << "0x" << hex << my_data.Export_AddressOfFunction[i] << endl; }通过函数的序号获取函数在DLL的偏移
VOID PE::GetFunctionAddrByOrdinal(Data& my_data, int ordinal) { DWORD AddressOfNames_ptr = (DWORD)((DWORD)my_data.my_Export_Directory->AddressOfNameOrdinals + (DWORD)my_data.Stretch_Data); for (int i = 0; i < my_data.my_Export_Directory->NumberOfNames; i++) { if (*(WORD*)AddressOfNames_ptr + my_data.my_Export_Directory->Base == ordinal) { cout << "成功通过函数的序号找到函数地址!" << endl; cout << "0x" << hex << my_data.Export_AddressOfFunction[i] << endl; return; } AddressOfNames_ptr = (DWORD)((char*)AddressOfNames_ptr + 2); } cout << "没有匹配上!" << endl; }完整的代码如下,可以直接改DLL名字完美运行:
#include <windows.h> #include <iostream> #include <string> #include <cstring> #include <malloc.h> using namespace std; #pragma comment(lib,"Dll1.lib") extern __declspec(dllimport) void Print(); 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;//数据目录结构 //0.导出表 1.导入表 2.资源表 3.异常信息表 4.安全证书表 5.重定位表 6.调试信息表 7.版权所以表 //8.全局指针表 9.TLS表 10.加载配置表 11.绑定导入表 12.IAT表 13.延迟绑定表 14.COM信息表 15.未使用 CHAR my_Export_Name[50][30];//导出表的名字 PIMAGE_EXPORT_DIRECTORY my_Export_Directory; //指向导出表结构的指针 DWORD Export_AddressOfFunction[50]; 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: 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 Analyze_Data_Directory(Data& my_data); DWORD Rva_To_Foa(DWORD Rva_Offset, Data& my_data); VOID Print_ExportTable(Data& my_data); VOID GetFunctionAddrByName(Data& my_data, char* name); VOID GetFunctionAddrByOrdinal(Data& my_data, int ordinal); }; VOID PE::GetFunctionAddrByOrdinal(Data& my_data, int ordinal) { DWORD AddressOfNames_ptr = (DWORD)((DWORD)my_data.my_Export_Directory->AddressOfNameOrdinals + (DWORD)my_data.Stretch_Data); for (int i = 0; i < my_data.my_Export_Directory->NumberOfNames; i++) { if (*(WORD*)AddressOfNames_ptr + my_data.my_Export_Directory->Base == ordinal) { cout << "成功通过函数的序号找到函数地址!" << endl; cout << "0x" << hex << my_data.Export_AddressOfFunction[i] << endl; return; } AddressOfNames_ptr = (DWORD)((char*)AddressOfNames_ptr + 2); } cout << "没有匹配上!" << endl; } VOID PE::GetFunctionAddrByName(Data& my_data, char* name) { int i = 0; for (i = 0; i < my_data.my_Export_Directory->NumberOfNames; i++) { if (!strcmp(name, my_data.my_Export_Name[i])) { cout << "成功通过函数名匹配到函数!" << endl; break; } if (i == my_data.my_Export_Directory->NumberOfNames - 1) { cout << "没有匹配到函数名!" << endl; return ; } } cout << "0x" << hex << my_data.Export_AddressOfFunction[i] << endl; } void PE::Print_ExportTable(Data& my_data) { PIMAGE_EXPORT_DIRECTORY my_export_directory_ptr = (PIMAGE_EXPORT_DIRECTORY)((DWORD)my_data.my_Data_Directory[0]->VirtualAddress + (DWORD)my_data.Stretch_Data); my_data.my_Export_Directory = my_export_directory_ptr; DWORD AddressOfFunctions_ptr = (DWORD)((DWORD)my_export_directory_ptr->AddressOfFunctions + (DWORD)my_data.Stretch_Data); DWORD AddressOfNames_ptr = (DWORD)((DWORD)my_export_directory_ptr->AddressOfNames + (DWORD)my_data.Stretch_Data); DWORD AddressOfNameOrdinals_ptr = (DWORD)((DWORD)my_export_directory_ptr->AddressOfNameOrdinals + (DWORD)my_data.Stretch_Data); cout << "---------------AddressOfFunctions------------------" << endl; int number = my_export_directory_ptr->NumberOfFunctions; for (int i = 0; i < number; i++) { cout << i << ": " << "0x" << hex << *((DWORD*)AddressOfFunctions_ptr) << endl; my_data.Export_AddressOfFunction[i] = *((DWORD*)AddressOfFunctions_ptr); AddressOfFunctions_ptr += 0x4; while (*((DWORD*)AddressOfFunctions_ptr) == 0) { AddressOfFunctions_ptr += 0x4; } } cout << "---------------------Names------------------" << endl; number = my_export_directory_ptr->NumberOfNames; for (int i = 0; i < number; i++) { strcpy_s(my_data.my_Export_Name[i], (PCHAR)(*(DWORD*)AddressOfNames_ptr + (DWORD)my_data.Stretch_Data)); cout << i << ": " << (PCHAR)(*(DWORD*)AddressOfNames_ptr + (DWORD)my_data.Stretch_Data) << endl; AddressOfNames_ptr += 0x4; } cout << "----------------------NameOrdinals---------------" << endl; cout << "base: " << my_export_directory_ptr->Base << endl; for (int i = 0; i < number; i++) { cout << i << ": " << *(WORD*)AddressOfNames_ptr << endl; AddressOfNames_ptr += 0x2; } } DWORD PE::Rva_To_Foa(DWORD Rva_Offset, Data& my_data) { int index = 0; if (Rva_Offset <= my_data.my_optional->SizeOfHeaders) { return Rva_Offset; } else { while (Rva_Offset > my_data.my_section[index]->VirtualAddress) { index++; } index--; //计算在节的偏移 DWORD Section_Offset = Rva_Offset - my_data.my_section[index]->VirtualAddress; return my_data.my_section[index]->PointerToRawData + Section_Offset; } } void PE::Analyze_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; } } void PE::Print_IMAGE_DATA_DIRECTORY(Data& my_data) { 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] = "Dll1.dll"; 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); my_pe.Analyze_Data_Directory(my_data); my_pe.Print_IMAGE_DATA_DIRECTORY(my_data); my_pe.Print_ExportTable(my_data); cout << "转化的文件偏移是" << hex << my_pe.Rva_To_Foa(0x3100, my_data) << endl; //((void(*)())addr)();//调用 HMODULE hDll = GetModuleHandleA("Dll1.dll"); my_pe.GetFunctionAddrByName(my_data, (char*)"Print"); my_pe.GetFunctionAddrByOrdinal(my_data, 14); return 0; }注意注意:有个踩过的坑我想分享给大家。 就是我本来想这样搞: 申请一个堆,里面存Dll的数据,通过分析可以找到Dll文件中函数的偏移嘛,然后我就想着,这个偏移,加上堆的基地址,赋值给一个函数指针,那不是直接就可以调用吗? 结果我试了半天,最后获得函数的真正地址也是正确的,结果就是运行不起来,tnnd,搞了好久,最后经过高人指点才知道,原来堆也是需要有运行权限的,貌似堆貌似没有运行权限。哎,搞死了,呜呜。
【逆向】导出表:1.编写程序打印所有的导出表信息2.编写GetFunctionAddrByName3.编写Get由讯客互联IT业界栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“【逆向】导出表:1.编写程序打印所有的导出表信息2.编写GetFunctionAddrByName3.编写Get”