这是从数据目录中获取每个表的地址
- 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
- #include
- #include
- #include
- #include
- 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,搞了好久,最后经过高人指点才知道,原来堆也是需要有运行权限的,貌似堆貌似没有运行权限。哎,搞死了,呜呜。