【逆向】导出表:1.编写程序打印所有的导出表信息 2.编写GetFunctionAddrByName 3.编写GetFunctionAddrByOrdinal

这是从数据目录中获取每个表的地址

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缩小//复制Headsmemcpy_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*& sectionmy_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,搞了好久,最后经过高人指点才知道,原来堆也是需要有运行权限的,貌似堆貌似没有运行权限。哎,搞死了,呜呜。
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/102594.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【技术干货】如何快速创建商用照明 OEM APP?

本文介绍了如何在涂鸦 IoT 平台的 App 工作台上创建一款体验版商照 App、正式版 OEM App、上架 App、以及完成通用配置。 OEM App 开发 创建 App 登录 涂鸦 IoT 平台的 App 页面。 单击 创建APP&#xff0c;选择 商照 APP 进行创建。 在提示框里&#xff0c;完善 App 信息…

通过Node.js获取高德的省市区数据并插入数据库

通过Node.js获取高德的省市区数据并插入数据库 1 创建秘钥1.1 登录高德地图开放平台1.2 创建应用1.3 绑定服务创建秘钥 2 获取数据并插入2.1 创建数据库连接工具2.2 请求数据2.3 数据处理2.4 全部代码 3 还可以打印文件到本地 1 创建秘钥 1.1 登录高德地图开放平台 打开开放平…

Java基础面试-面向对象

什么是面向对象&#xff1f; 对比面向过程&#xff0c;是两种不同的处理问题角度 面向过程更注重事情的每一个步骤及顺序&#xff0c;面向对象更注重事情有哪些参与者&#xff08;对象&#xff09;&#xff0c;及各自需要做什么 比如洗衣机洗衣服 面向过程会将任务拆解成一系…

11面向对象编程例子 月饼可以访问模子 模子不能访问月饼

类就好比是一个模子&#xff0c;然后各种对象就是月饼&#xff0c;印的月饼太多了&#xff0c;于是找不到月饼了&#xff0c;但是月饼只有一个模子&#xff0c;所以可以向上找到自己的模子 先上代码&#xff1a; class Person:age 0def shilifangfa(self):print(self)print(…

多列等高实现

预期效果 多列等高,左右两列高度自适应且一样,分别设置不同背景色效果预览: 分别由6种方法实现 1、使用padding + margin + overflow 实现多列等高效果,具有良好的兼容性; 2、border实现多列等高,左边框宽度为200px,左列浮动,伪元素清除浮动; 3、父元素线性渐变背景色…

基于web的酒店客房管理系统

目录 前言 一、技术栈 二、系统功能介绍 用户信息管理 会员信息管理 客房信息管理 收藏客房管理 用户入住管理 客房清扫管理 三、核心代码 1、登录模块 2、文件上传模块 3、代码封装 前言 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施…

【数据结构】算法效率的度量方法

&#x1f984;个人主页:修修修也 &#x1f38f;所属专栏:数据结构 ⚙️操作环境:Visual Studio 2022 目录 &#x1f38f;事后统计方法 &#x1f38f;事前分析估算方法 &#x1f38f;函数的渐进式增长 结语 在上篇文章中我们提到了算法的设计要求中我们要尽量满足时间效率高…

10架构管理之公司整体技术架构

一句话导读 公司的整体技术架构一般是公司的架构组、架构管理部、技术委员会等部门负责&#xff0c;需要对公司整体的技术架构进行把控和管理&#xff0c;确保信息系统的稳定性和可靠性&#xff0c;避免因技术架构不合理而导致的系统崩溃和数据丢失等问题&#xff0c;为公司的业…

Tomcat和HPPT协议

1.介绍 1.Java EE 规范 JavaEE&#xff08;java Enterprise Edition&#xff09;&#xff1a;java企业版 JavaEE 规范是很多的java开发技术的总称。这些技术规范都是沿用自J2EE的。一共包括了13个技术规范 2.WEB概述 WEB在计算机领域中代表的是网络 像我们之前所用的WWW&…

Excel往Word复制表格时删除空格

1.背景 在编写文档&#xff0c;经常需要从Excel往Word里复制表格 但是复制过去的表格前面会出现空格&#xff08;缩进&#xff09; 再WPS中试了很多方法&#xff0c;终于摆脱了挨个删除的困扰 2. WPS排版中删除 选择表格菜单栏-选在【开始】-【排版】选择【更多段落处理】-【段…

ai语音机器人OKCC的空号检测

一、空号检测模块介绍 空号检测的原理&#xff1a;空号检测是利用现代通信技术和互联网技术结合而成&#xff0c;采用批量拨电话号码的方式&#xff0c;过滤空号、停机、无效号码。业内又称空号筛选、空号过滤。空号检测技术的成果是去除号码中的无效号码&#xff0c;包括…

二、BurpSuite Proxy代理

一、配置与基础 配置&#xff1a;配置代理的端口 Forward&#xff1a;将拦截的请求正常发往服务器 Drop&#xff1a;直接将请求丢弃 intercept&#xff1a;开启后才能进行请求拦截 Open brower&#xff1a;在2021版本之后&#xff0c;点击该选项即可开启BurpSuite自带的浏览器…

2023版 STM32实战9 RTC实时时钟/闹钟

RTC简介 实时时钟是一个独立的定时器。RTC模块拥有一组连续计数的计数器&#xff0c;在相应软件配置下&#xff0c;可提供时钟日历的功能。修改计数器的值可以重新设置系统当前的时间和日期。 注意事项 -1- 要手动配置中断寄存器 -2- 需要等待写操作完成 -3- 时钟闹钟中段…

webpack不同环境下使用CSS分离插件mini-css-extract-plugin

1.背景描述 使用mini-css-extract-plugin插件来打包css文件&#xff08;从css文件中提取css代码到单独的文件中&#xff0c;对css代码进行代码压缩等&#xff09;。 本次采用三个配置文件&#xff1a; 公共配置文件&#xff1a;webpack.common.jsdev开发环境配置文件&#x…

视频编解码(七)之FOURCC和YUV关系简介

FOURCC是4字节代码&#xff0c;是一个codec中对压缩格式、颜色、像素格式等的标识。按一个字节8bit&#xff0c;FOURCC通常占4字节32bit。 FOURCC is short for “four character code” - an identifier for a video codec, compression format, color or pixel format used i…

SQL: 索引原理与创建索引的规范

SQL 索引是一种数据结构&#xff0c;用于加速数据库查询操作。它通过在表的列上创建索引&#xff0c;提供了一种快速查找数据的方法&#xff0c;减少了数据库的扫描和比较操作&#xff0c;从而提高了查询性能。索引根据其实现方式可以分为多种类型&#xff0c;如 B-树索引、哈希…

YoloV8改进策略:全新特征融合模块AFPN,更换YoloV8的Neck

文章目录 摘要论文:《AFPN:用于目标检测的渐近特征金字塔网络》1、介绍2、相关工作3、渐进特征金字塔网络4、实验5、结论改进方法测试结果摘要 目标检测中的特征金字塔结构,包括FPN和PAFPN,这两种结构都可以应用于一阶段和二阶段方法中,以提高目标检测的性能。FPN是最常用…

react–antd 实现TreeSelect树形选择组件,实现点开一层调一次接口

效果图: 注意: 当选择“否”&#xff0c;开始调接口&#xff0c;不要把点击调接口写在TreeSelect组件上&#xff0c;这样会导致问题出现&#xff0c;没有层级了 部分代码:

Centos切换yum源

Centos切换yum源 常用命令 #查看内核/操作系统/CPU信息 uname -a #查看yum源 yum list repolist all切换步骤 1.备份yum源文件 cp -a /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak2.下载新的CentOS-Base.repo文件到/etc/yum.repos.d/目录下 …

MYSQL的事务原理

事务基础 事务概念 事务是一组操作的集合&#xff0c;它是一个不可分割的工作单位&#xff0c;事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求&#xff0c;即这些操作要么同时成功&#xff0c;要么同时失败。 事务特性 原子性&#xff08;Atomicity&#xff09…