這是從數(shù)據(jù)目錄中獲取每個(gè)表的地址
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;
}
}
?打印所有導(dǎo)出表的信息:
?
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;
}
}
通過函數(shù)名稱獲取函數(shù)在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 << "成功通過函數(shù)名匹配到函數(shù)!" << endl;
break;
}
if (i == my_data.my_Export_Directory->NumberOfNames - 1)
{
cout << "沒有匹配到函數(shù)名!" << endl;
return ;
}
}
cout << "0x" << hex << my_data.Export_AddressOfFunction[i] << endl;
}
通過函數(shù)的序號(hào)獲取函數(shù)在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 << "成功通過函數(shù)的序號(hào)找到函數(shù)地址!" << endl;
cout << "0x" << hex << my_data.Export_AddressOfFunction[i] << endl;
return;
}
AddressOfNames_ptr = (DWORD)((char*)AddressOfNames_ptr + 2);
}
cout << "沒有匹配上!" << endl;
}
完整的代碼如下,可以直接改DLL名字完美運(yùn)行:文章來源:http://www.zghlxwxcb.cn/news/detail-725703.html
#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頭結(jié)構(gòu)
PIMAGE_FILE_HEADER my_file;//file結(jié)構(gòu)
PIMAGE_OPTIONAL_HEADER32 my_optional;//可選PE頭結(jié)構(gòu)
PIMAGE_SECTION_HEADER* my_section;//節(jié)表結(jié)構(gòu)
PIMAGE_DATA_DIRECTORY* my_Data_Directory;//數(shù)據(jù)目錄結(jié)構(gòu)
//0.導(dǎo)出表 1.導(dǎo)入表 2.資源表 3.異常信息表 4.安全證書表 5.重定位表 6.調(diào)試信息表 7.版權(quán)所以表
//8.全局指針表 9.TLS表 10.加載配置表 11.綁定導(dǎo)入表 12.IAT表 13.延遲綁定表 14.COM信息表 15.未使用
CHAR my_Export_Name[50][30];//導(dǎo)出表的名字
PIMAGE_EXPORT_DIRECTORY my_Export_Directory; //指向?qū)С霰斫Y(jié)構(gòu)的指針
DWORD Export_AddressOfFunction[50];
void* Before_Stretch_Data; //指向拉伸前的內(nèi)容
void* Stretch_Data; //指向拉伸后的內(nèi)容
void* Shrink_Data; //指向縮小PE結(jié)構(gòu)的內(nèi)容
Data()
{
my_dos = nullptr;//dos頭結(jié)構(gòu)
my_file = nullptr;//file結(jié)構(gòu)
my_optional = nullptr;//可選PE頭結(jié)構(gòu)
my_section = nullptr;//節(jié)表結(jié)構(gòu)
my_Data_Directory = nullptr;
Before_Stretch_Data = nullptr; //指向拉伸前的內(nèi)容
Stretch_Data = nullptr; //指向拉伸后的內(nèi)容
Shrink_Data = nullptr; //指向縮小PE結(jié)構(gòu)的內(nèi)容
}
~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結(jié)構(gòu)
VOID Stretch_PE(Data& my_data); //拉伸pe結(jié)構(gòu)
VOID Shrink_PE(Data& my_data); //縮小pe結(jié)構(gòu)
VOID New_Section(char* filename, Data& my_data);//新增節(jié),非擴(kuò)大節(jié),并寫入新的exe文件中
VOID Expand_Section(Data& my_data, char* filename); //擴(kuò)大節(jié)
int Section_Align(int temp, Data& my_data); //返回內(nèi)存對(duì)齊后的大小
int File_Align(int temp, Data& my_data); //返回文件對(duì)齊后的大小
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 << "成功通過函數(shù)的序號(hào)找到函數(shù)地址!" << 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 << "成功通過函數(shù)名匹配到函數(shù)!" << endl;
break;
}
if (i == my_data.my_Export_Directory->NumberOfNames - 1)
{
cout << "沒有匹配到函數(shù)名!" << 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--;
//計(jì)算在節(jié)的偏移
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;//擴(kuò)大節(jié)后新的文件大小
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較大的那個(gè)
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);//將原來的文件復(fù)制過來
Analyze_PE(New_Data, 1);//讓New_Data的dos,file,optional,section有數(shù)據(jù)
//復(fù)制新的節(jié)表
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);
//復(fù)制新的節(jié)
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);//復(fù)制完.text段作為新增節(jié)
//接下來要改Header的各項(xiàng)數(shù)據(jù)
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;
}
//申請(qǐng)內(nèi)存空間把文件內(nèi)容保存下來
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 << "寫入數(shù)據(jù)失??!" << endl;
return;
}
cout << "寫入數(shù)據(jù)成功,成功獲取Data!" << endl;
return;
}
}
//分析PE結(jié)構(gòu)
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結(jié)構(gòu)失??!" << 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結(jié)構(gòu)失??!" << 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結(jié)構(gòu)失敗!" << endl;
}
}
//拉伸PE結(jié)構(gòu) 注意看PIMAGE_XXX_HEADER的定義,它們本就是指向結(jié)構(gòu)體的指針
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;//還未對(duì)齊
memcpy_s(my_data.Stretch_Data, Memory_Size, my_data.Before_Stretch_Data, Size_Of_Header);
void* temp_stretch_data = my_data.Stretch_Data;
//現(xiàn)在計(jì)算head頭對(duì)齊后的大小
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縮小
//復(fù)制Heads
memcpy_s(my_data.Shrink_Data, my_data.my_optional->SizeOfHeaders, my_data.Stretch_Data, my_data.my_optional->SizeOfHeaders);
//復(fù)制節(jié)
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 << "轉(zhuǎn)化的文件偏移是" << hex << my_pe.Rva_To_Foa(0x3100, my_data) << endl;
//((void(*)())addr)();//調(diào)用
HMODULE hDll = GetModuleHandleA("Dll1.dll");
my_pe.GetFunctionAddrByName(my_data, (char*)"Print");
my_pe.GetFunctionAddrByOrdinal(my_data, 14);
return 0;
}
注意注意:有個(gè)踩過的坑我想分享給大家。
就是我本來想這樣搞:
申請(qǐng)一個(gè)堆,里面存Dll的數(shù)據(jù),通過分析可以找到Dll文件中函數(shù)的偏移嘛,然后我就想著,這個(gè)偏移,加上堆的基地址,賦值給一個(gè)函數(shù)指針,那不是直接就可以調(diào)用嗎?
結(jié)果我試了半天,最后獲得函數(shù)的真正地址也是正確的,結(jié)果就是運(yùn)行不起來,tnnd,搞了好久,最后經(jīng)過高人指點(diǎn)才知道,原來堆也是需要有運(yùn)行權(quán)限的,貌似堆貌似沒有運(yùn)行權(quán)限。哎,搞死了,嗚嗚。
?文章來源地址http://www.zghlxwxcb.cn/news/detail-725703.html
到了這里,關(guān)于【逆向】導(dǎo)出表:1.編寫程序打印所有的導(dǎo)出表信息 2.編寫GetFunctionAddrByName 3.編寫GetFunctionAddrByOrdinal的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!