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


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

    1. void PE::Analyze_Data_Directory(Data& my_data)
    2. {
    3. my_data.my_Data_Directory = nullptr;
    4. my_data.my_Data_Directory = (PIMAGE_DATA_DIRECTORY*)malloc(16 * sizeof(PIMAGE_DATA_DIRECTORY));
    5. void* Temp_ptr = my_data.my_optional->DataDirectory;
    6. for (int i = 0; i < 16; i++)
    7. {
    8. my_data.my_Data_Directory[i] = (PIMAGE_DATA_DIRECTORY)Temp_ptr;
    9. Temp_ptr = (char*)Temp_ptr + 0x8;
    10. }
    11. }

     打印所有导出表的信息:
     

    1. void PE::Print_ExportTable(Data& my_data)
    2. {
    3. PIMAGE_EXPORT_DIRECTORY my_export_directory_ptr = (PIMAGE_EXPORT_DIRECTORY)((DWORD)my_data.my_Data_Directory[0]->VirtualAddress + (DWORD)my_data.Stretch_Data);
    4. my_data.my_Export_Directory = my_export_directory_ptr;
    5. DWORD AddressOfFunctions_ptr = (DWORD)((DWORD)my_export_directory_ptr->AddressOfFunctions + (DWORD)my_data.Stretch_Data);
    6. DWORD AddressOfNames_ptr = (DWORD)((DWORD)my_export_directory_ptr->AddressOfNames + (DWORD)my_data.Stretch_Data);
    7. DWORD AddressOfNameOrdinals_ptr = (DWORD)((DWORD)my_export_directory_ptr->AddressOfNameOrdinals + (DWORD)my_data.Stretch_Data);
    8. cout << "---------------AddressOfFunctions------------------" << endl;
    9. int number = my_export_directory_ptr->NumberOfFunctions;
    10. for (int i = 0; i < number; i++)
    11. {
    12. cout << i << ": " << "0x" << hex << *((DWORD*)AddressOfFunctions_ptr) << endl;
    13. my_data.Export_AddressOfFunction[i] = *((DWORD*)AddressOfFunctions_ptr);
    14. AddressOfFunctions_ptr += 0x4;
    15. while (*((DWORD*)AddressOfFunctions_ptr) == 0)
    16. {
    17. AddressOfFunctions_ptr += 0x4;
    18. }
    19. }
    20. cout << "---------------------Names------------------" << endl;
    21. number = my_export_directory_ptr->NumberOfNames;
    22. for (int i = 0; i < number; i++)
    23. {
    24. strcpy_s(my_data.my_Export_Name[i], (PCHAR)(*(DWORD*)AddressOfNames_ptr + (DWORD)my_data.Stretch_Data));
    25. cout << i << ": " << (PCHAR)(*(DWORD*)AddressOfNames_ptr + (DWORD)my_data.Stretch_Data) << endl;
    26. AddressOfNames_ptr += 0x4;
    27. }
    28. cout << "----------------------NameOrdinals---------------" << endl;
    29. cout << "base: " << my_export_directory_ptr->Base << endl;
    30. for (int i = 0; i < number; i++)
    31. {
    32. cout << i << ": " << *(WORD*)AddressOfNames_ptr << endl;
    33. AddressOfNames_ptr += 0x2;
    34. }
    35. }

    通过函数名称获取函数在DLL的偏移:

    1. VOID PE::GetFunctionAddrByName(Data& my_data, char* name)
    2. {
    3. int i = 0;
    4. for (i = 0; i < my_data.my_Export_Directory->NumberOfNames; i++)
    5. {
    6. if (!strcmp(name, my_data.my_Export_Name[i]))
    7. {
    8. cout << "成功通过函数名匹配到函数!" << endl;
    9. break;
    10. }
    11. if (i == my_data.my_Export_Directory->NumberOfNames - 1)
    12. {
    13. cout << "没有匹配到函数名!" << endl;
    14. return ;
    15. }
    16. }
    17. cout << "0x" << hex << my_data.Export_AddressOfFunction[i] << endl;
    18. }

    通过函数的序号获取函数在DLL的偏移

    1. VOID PE::GetFunctionAddrByOrdinal(Data& my_data, int ordinal)
    2. {
    3. DWORD AddressOfNames_ptr = (DWORD)((DWORD)my_data.my_Export_Directory->AddressOfNameOrdinals + (DWORD)my_data.Stretch_Data);
    4. for (int i = 0; i < my_data.my_Export_Directory->NumberOfNames; i++)
    5. {
    6. if (*(WORD*)AddressOfNames_ptr + my_data.my_Export_Directory->Base == ordinal)
    7. {
    8. cout << "成功通过函数的序号找到函数地址!" << endl;
    9. cout << "0x" << hex << my_data.Export_AddressOfFunction[i] << endl;
    10. return;
    11. }
    12. AddressOfNames_ptr = (DWORD)((char*)AddressOfNames_ptr + 2);
    13. }
    14. cout << "没有匹配上!" << endl;
    15. }

    完整的代码如下,可以直接改DLL名字完美运行:

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. using namespace std;
    7. #pragma comment(lib,"Dll1.lib")
    8. extern __declspec(dllimport) void Print();
    9. int MAX(int a, int b)
    10. {
    11. return a >= b ? a : b;
    12. }
    13. class Data
    14. {
    15. public:
    16. PIMAGE_DOS_HEADER my_dos;//dos头结构
    17. PIMAGE_FILE_HEADER my_file;//file结构
    18. PIMAGE_OPTIONAL_HEADER32 my_optional;//可选PE头结构
    19. PIMAGE_SECTION_HEADER* my_section;//节表结构
    20. PIMAGE_DATA_DIRECTORY* my_Data_Directory;//数据目录结构
    21. //0.导出表 1.导入表 2.资源表 3.异常信息表 4.安全证书表 5.重定位表 6.调试信息表 7.版权所以表
    22. //8.全局指针表 9.TLS表 10.加载配置表 11.绑定导入表 12.IAT表 13.延迟绑定表 14.COM信息表 15.未使用
    23. CHAR my_Export_Name[50][30];//导出表的名字
    24. PIMAGE_EXPORT_DIRECTORY my_Export_Directory; //指向导出表结构的指针
    25. DWORD Export_AddressOfFunction[50];
    26. void* Before_Stretch_Data; //指向拉伸前的内容
    27. void* Stretch_Data; //指向拉伸后的内容
    28. void* Shrink_Data; //指向缩小PE结构的内容
    29. Data()
    30. {
    31. my_dos = nullptr;//dos头结构
    32. my_file = nullptr;//file结构
    33. my_optional = nullptr;//可选PE头结构
    34. my_section = nullptr;//节表结构
    35. my_Data_Directory = nullptr;
    36. Before_Stretch_Data = nullptr; //指向拉伸前的内容
    37. Stretch_Data = nullptr; //指向拉伸后的内容
    38. Shrink_Data = nullptr; //指向缩小PE结构的内容
    39. }
    40. ~Data()
    41. {
    42. if (Before_Stretch_Data != nullptr)
    43. {
    44. free(Before_Stretch_Data);
    45. Before_Stretch_Data = nullptr;
    46. }
    47. if (Stretch_Data != nullptr)
    48. {
    49. free(Stretch_Data);
    50. Stretch_Data = nullptr;
    51. }
    52. if (Shrink_Data != nullptr)
    53. {
    54. free(Shrink_Data);
    55. Shrink_Data = nullptr;
    56. }
    57. }
    58. VOID Copy_Before_Strectch_Data(Data my_data); //只深拷贝Before_Strectch_Data
    59. };
    60. VOID Data::Copy_Before_Strectch_Data(Data my_data)
    61. {
    62. int size = _msize(my_data.Before_Stretch_Data);
    63. memcpy_s(this->Before_Stretch_Data, size, my_data.Before_Stretch_Data, size);
    64. }
    65. class PE
    66. {
    67. public:
    68. VOID Readfile(char* filename, Data& my_data); //读取pe文件
    69. VOID Analyze_PE(Data& my_data, int num); //分析pe结构
    70. VOID Stretch_PE(Data& my_data); //拉伸pe结构
    71. VOID Shrink_PE(Data& my_data); //缩小pe结构
    72. VOID New_Section(char* filename, Data& my_data);//新增节,非扩大节,并写入新的exe文件中
    73. VOID Expand_Section(Data& my_data, char* filename); //扩大节
    74. int Section_Align(int temp, Data& my_data); //返回内存对齐后的大小
    75. int File_Align(int temp, Data& my_data); //返回文件对齐后的大小
    76. VOID Combine_Section(char* filename, Data& my_data);
    77. VOID Copy_Data(Data& my_data);
    78. VOID Print_IMAGE_DATA_DIRECTORY(Data& my_data);
    79. VOID Analyze_Data_Directory(Data& my_data);
    80. DWORD Rva_To_Foa(DWORD Rva_Offset, Data& my_data);
    81. VOID Print_ExportTable(Data& my_data);
    82. VOID GetFunctionAddrByName(Data& my_data, char* name);
    83. VOID GetFunctionAddrByOrdinal(Data& my_data, int ordinal);
    84. };
    85. VOID PE::GetFunctionAddrByOrdinal(Data& my_data, int ordinal)
    86. {
    87. DWORD AddressOfNames_ptr = (DWORD)((DWORD)my_data.my_Export_Directory->AddressOfNameOrdinals + (DWORD)my_data.Stretch_Data);
    88. for (int i = 0; i < my_data.my_Export_Directory->NumberOfNames; i++)
    89. {
    90. if (*(WORD*)AddressOfNames_ptr + my_data.my_Export_Directory->Base == ordinal)
    91. {
    92. cout << "成功通过函数的序号找到函数地址!" << endl;
    93. cout << "0x" << hex << my_data.Export_AddressOfFunction[i] << endl;
    94. return;
    95. }
    96. AddressOfNames_ptr = (DWORD)((char*)AddressOfNames_ptr + 2);
    97. }
    98. cout << "没有匹配上!" << endl;
    99. }
    100. VOID PE::GetFunctionAddrByName(Data& my_data, char* name)
    101. {
    102. int i = 0;
    103. for (i = 0; i < my_data.my_Export_Directory->NumberOfNames; i++)
    104. {
    105. if (!strcmp(name, my_data.my_Export_Name[i]))
    106. {
    107. cout << "成功通过函数名匹配到函数!" << endl;
    108. break;
    109. }
    110. if (i == my_data.my_Export_Directory->NumberOfNames - 1)
    111. {
    112. cout << "没有匹配到函数名!" << endl;
    113. return ;
    114. }
    115. }
    116. cout << "0x" << hex << my_data.Export_AddressOfFunction[i] << endl;
    117. }
    118. void PE::Print_ExportTable(Data& my_data)
    119. {
    120. PIMAGE_EXPORT_DIRECTORY my_export_directory_ptr = (PIMAGE_EXPORT_DIRECTORY)((DWORD)my_data.my_Data_Directory[0]->VirtualAddress + (DWORD)my_data.Stretch_Data);
    121. my_data.my_Export_Directory = my_export_directory_ptr;
    122. DWORD AddressOfFunctions_ptr = (DWORD)((DWORD)my_export_directory_ptr->AddressOfFunctions + (DWORD)my_data.Stretch_Data);
    123. DWORD AddressOfNames_ptr = (DWORD)((DWORD)my_export_directory_ptr->AddressOfNames + (DWORD)my_data.Stretch_Data);
    124. DWORD AddressOfNameOrdinals_ptr = (DWORD)((DWORD)my_export_directory_ptr->AddressOfNameOrdinals + (DWORD)my_data.Stretch_Data);
    125. cout << "---------------AddressOfFunctions------------------" << endl;
    126. int number = my_export_directory_ptr->NumberOfFunctions;
    127. for (int i = 0; i < number; i++)
    128. {
    129. cout << i << ": " << "0x" << hex << *((DWORD*)AddressOfFunctions_ptr) << endl;
    130. my_data.Export_AddressOfFunction[i] = *((DWORD*)AddressOfFunctions_ptr);
    131. AddressOfFunctions_ptr += 0x4;
    132. while (*((DWORD*)AddressOfFunctions_ptr) == 0)
    133. {
    134. AddressOfFunctions_ptr += 0x4;
    135. }
    136. }
    137. cout << "---------------------Names------------------" << endl;
    138. number = my_export_directory_ptr->NumberOfNames;
    139. for (int i = 0; i < number; i++)
    140. {
    141. strcpy_s(my_data.my_Export_Name[i], (PCHAR)(*(DWORD*)AddressOfNames_ptr + (DWORD)my_data.Stretch_Data));
    142. cout << i << ": " << (PCHAR)(*(DWORD*)AddressOfNames_ptr + (DWORD)my_data.Stretch_Data) << endl;
    143. AddressOfNames_ptr += 0x4;
    144. }
    145. cout << "----------------------NameOrdinals---------------" << endl;
    146. cout << "base: " << my_export_directory_ptr->Base << endl;
    147. for (int i = 0; i < number; i++)
    148. {
    149. cout << i << ": " << *(WORD*)AddressOfNames_ptr << endl;
    150. AddressOfNames_ptr += 0x2;
    151. }
    152. }
    153. DWORD PE::Rva_To_Foa(DWORD Rva_Offset, Data& my_data)
    154. {
    155. int index = 0;
    156. if (Rva_Offset <= my_data.my_optional->SizeOfHeaders)
    157. {
    158. return Rva_Offset;
    159. }
    160. else
    161. {
    162. while (Rva_Offset > my_data.my_section[index]->VirtualAddress)
    163. {
    164. index++;
    165. }
    166. index--;
    167. //计算在节的偏移
    168. DWORD Section_Offset = Rva_Offset - my_data.my_section[index]->VirtualAddress;
    169. return my_data.my_section[index]->PointerToRawData + Section_Offset;
    170. }
    171. }
    172. void PE::Analyze_Data_Directory(Data& my_data)
    173. {
    174. my_data.my_Data_Directory = nullptr;
    175. my_data.my_Data_Directory = (PIMAGE_DATA_DIRECTORY*)malloc(16 * sizeof(PIMAGE_DATA_DIRECTORY));
    176. void* Temp_ptr = my_data.my_optional->DataDirectory;
    177. for (int i = 0; i < 16; i++)
    178. {
    179. my_data.my_Data_Directory[i] = (PIMAGE_DATA_DIRECTORY)Temp_ptr;
    180. Temp_ptr = (char*)Temp_ptr + 0x8;
    181. }
    182. }
    183. void PE::Print_IMAGE_DATA_DIRECTORY(Data& my_data)
    184. {
    185. char arr[16][40] = {
    186. "IMAGE_DIRECTORY_ENTRY_EXPORT",
    187. "IMAGE_DIRECTORY_ENTRY_IMPORT",
    188. "IMAGE_DIRECTORY_ENTRY_RESOURCE",
    189. "IMAGE_DIRECTORY_ENTRY_EXCEPTION",
    190. "IMAGE_DIRECTORY_ENTRY_SECURITY",
    191. "IMAGE_DIRECTORY_ENTRY_BASERELOC",
    192. "IMAGE_DIRECTORY_ENTRY_DEBUG",
    193. "IMAGE_DIRECTORY_ENTRY_COPYRIGHT",
    194. "IMAGE_DIRECTORY_ENTRY_GLOBALPTR",
    195. "IMAGE_DIRECTORY_ENTRY_TLS",
    196. "IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG",
    197. "IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT",
    198. "IMAGE_DIRECTORY_ENTRY_IAT",
    199. "IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT",
    200. "IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR",
    201. "RESERVED"
    202. };
    203. for (int i = 0; i < 16; i++)
    204. {
    205. cout << arr[i] << " :" << endl;
    206. cout << "Size: " << hex << my_data.my_Data_Directory[i]->Size << endl;
    207. cout << "Virtual_Address: " << my_data.my_Data_Directory[i]->VirtualAddress << endl;
    208. cout << "------------------------------------------------------------------------" << endl;
    209. }
    210. return;
    211. }
    212. void PE::Combine_Section(char* filename, Data& my_data)
    213. {
    214. 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);
    215. 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);
    216. Data Comebine_Data;
    217. int temp_size = _msize(my_data.Stretch_Data) + Max;
    218. Comebine_Data.Stretch_Data = (void*)malloc(temp_size);
    219. memset(Comebine_Data.Stretch_Data, 0, Size);
    220. temp_size = _msize(my_data.Stretch_Data);
    221. memcpy_s(Comebine_Data.Stretch_Data, temp_size, my_data.Stretch_Data, temp_size);
    222. Analyze_PE(Comebine_Data, 2);
    223. void* temp_ptr = (char*)Comebine_Data.Stretch_Data + Max + my_data.my_section[my_data.my_file->NumberOfSections - 1]->VirtualAddress;
    224. 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));
    225. Comebine_Data.my_optional->SizeOfImage += Section_Align(MAX(my_data.my_section[0]->SizeOfRawData, my_data.my_section[0]->Misc.VirtualSize), my_data);
    226. 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);
    227. 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);
    228. FILE* my_file;
    229. if (fopen_s(&my_file, filename, "wb") != 0)
    230. {
    231. cout << "打开文件失败" << endl;
    232. return;
    233. }
    234. Shrink_PE(Comebine_Data);
    235. Analyze_PE(Comebine_Data, 3);
    236. fwrite(Comebine_Data.Shrink_Data, 1, _msize(Comebine_Data.Shrink_Data), my_file);
    237. cout << "写入成功!" << endl;
    238. fclose(my_file);
    239. }
    240. void PE::Expand_Section(Data& my_data, char* filename)
    241. {
    242. this->Stretch_PE(my_data);
    243. unsigned Size = 0;//扩大节后新的文件大小
    244. Size = my_data.my_optional->ImageBase + Section_Align(MAX(my_data.my_section[0]->SizeOfRawData, my_data.my_section[0]->Misc.VirtualSize), my_data);
    245. Data Expand_Data;
    246. Expand_Data.Stretch_Data = (void*)malloc(Size);
    247. memset(Expand_Data.Stretch_Data, 0, Size);
    248. memcpy_s(Expand_Data.Stretch_Data, _msize(my_data.Stretch_Data), my_data.Stretch_Data, _msize(my_data.Stretch_Data));
    249. Analyze_PE(Expand_Data, 2);
    250. 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);
    251. Expand_Data.my_section[my_data.my_file->NumberOfSections - 1]->Misc.VirtualSize = Expand_Data.my_section[my_data.my_file->NumberOfSections - 1]->SizeOfRawData;
    252. Expand_Data.my_optional->SizeOfImage += Section_Align(MAX(my_data.my_section[0]->SizeOfRawData, my_data.my_section[0]->Misc.VirtualSize), my_data);
    253. 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);
    254. int temp_size = Section_Align(MAX(my_data.my_section[0]->SizeOfRawData, my_data.my_section[0]->Misc.VirtualSize), my_data);
    255. void* Temp_Ptr2 = (char*)my_data.Stretch_Data + my_data.my_section[0]->VirtualAddress;
    256. memcpy_s(Temp_Ptr, temp_size, Temp_Ptr2, temp_size);
    257. Shrink_PE(Expand_Data);
    258. FILE* my_file;
    259. if (fopen_s(&my_file, filename, "wb") != 0)
    260. {
    261. cout << "打开文件失败!" << endl;
    262. }
    263. else
    264. {
    265. Size = _msize(Expand_Data.Shrink_Data);
    266. fwrite(Expand_Data.Shrink_Data, 1, Size, my_file);
    267. cout << "写入成功!" << endl;
    268. }
    269. fclose(my_file);
    270. }
    271. int PE::Section_Align(int temp, Data& my_data)
    272. {
    273. int i = 0;
    274. while (temp > i * my_data.my_optional->SectionAlignment)
    275. {
    276. i++;
    277. }
    278. return i * my_data.my_optional->SectionAlignment;
    279. }
    280. int PE::File_Align(int temp, Data& my_data)
    281. {
    282. int i = 0;
    283. while (temp > i * my_data.my_optional->FileAlignment)
    284. {
    285. i++;
    286. }
    287. return i * my_data.my_optional->FileAlignment;
    288. }
    289. void PE::New_Section(char* filename, Data& my_data)
    290. {
    291. unsigned int Size; //Size是新文件的大小,是原来的文件大小加上.VirtualSize和SizeOfRawData较大的那个
    292. Size = my_data.my_optional->SizeOfHeaders;
    293. for (int i = 0; i < my_data.my_file->NumberOfSections; i++)
    294. {
    295. Size += my_data.my_section[i]->SizeOfRawData;
    296. }
    297. Size += my_data.my_section[0]->SizeOfRawData;//这是最终新的文件的大小
    298. Data New_Data;
    299. New_Data.Before_Stretch_Data = (void*)malloc(Size * 1);
    300. memset(New_Data.Before_Stretch_Data, 0, Size);
    301. memcpy_s(New_Data.Before_Stretch_Data, Size, my_data.Before_Stretch_Data, Size - my_data.my_section[0]->SizeOfRawData);//将原来的文件复制过来
    302. Analyze_PE(New_Data, 1);//让New_Data的dos,file,optional,section有数据
    303. //复制新的节表
    304. void* Temp_ptr1 = (char*)my_data.Before_Stretch_Data + 0x98 + my_data.my_file->SizeOfOptionalHeader;
    305. void* Temp_ptr2 = (char*)New_Data.Before_Stretch_Data + 0x98 + my_data.my_file->SizeOfOptionalHeader + my_data.my_file->NumberOfSections * 0x28;
    306. memcpy_s(Temp_ptr2, 0x28, Temp_ptr1, 0x28);
    307. //复制新的节
    308. Temp_ptr1 = (char*)my_data.Before_Stretch_Data + my_data.my_optional->SizeOfHeaders;//指向.text段
    309. Temp_ptr2 = (char*)New_Data.Before_Stretch_Data + Size - my_data.my_section[0]->SizeOfRawData;
    310. memcpy_s(Temp_ptr2, my_data.my_section[0]->SizeOfRawData, Temp_ptr1, my_data.my_section[0]->SizeOfRawData);//复制完.text段作为新增节
    311. //接下来要改Header的各项数据
    312. New_Data.my_file->NumberOfSections++;
    313. New_Data.my_optional->SizeOfImage += my_data.my_section[0]->SizeOfRawData;
    314. Analyze_PE(New_Data, 1);
    315. 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;
    316. int size;
    317. if (New_Data.my_section[New_Data.my_file->NumberOfSections - 2]->Misc.VirtualSize >= New_Data.my_section[New_Data.my_file->NumberOfSections - 2]->SizeOfRawData)
    318. {
    319. size = New_Data.my_section[New_Data.my_file->NumberOfSections - 2]->Misc.VirtualSize;
    320. }
    321. else
    322. {
    323. size = New_Data.my_section[New_Data.my_file->NumberOfSections - 2]->SizeOfRawData;
    324. }
    325. size = size / my_data.my_optional->SectionAlignment + my_data.my_optional->SectionAlignment;
    326. New_Data.my_section[New_Data.my_file->NumberOfSections - 1]->VirtualAddress = New_Data.my_section[New_Data.my_file->NumberOfSections - 2]->VirtualAddress + size;
    327. FILE* my_file;
    328. if (fopen_s(&my_file, filename, "wb") == 0)
    329. {
    330. fwrite(New_Data.Before_Stretch_Data, 1, Size, my_file);
    331. cout << "写入成功!" << endl;
    332. return;
    333. }
    334. else
    335. {
    336. cout << "打开文件失败" << endl;
    337. return;
    338. }
    339. fclose(my_file);
    340. }
    341. void PE::Readfile(char* filename, Data& my_data)
    342. {
    343. unsigned int size;
    344. FILE* datafile;
    345. void* data;
    346. //打开文件
    347. if (fopen_s(&datafile, filename, "rb") != 0)
    348. {
    349. cout << "打开文件失败" << endl;
    350. return;
    351. }
    352. else
    353. {
    354. //获取文件的大小
    355. cout << "打开文件成功!" << endl;
    356. fseek(datafile, 0, SEEK_END);
    357. size = ftell(datafile);
    358. fseek(datafile, 0, SEEK_SET);
    359. if (size == -1L)
    360. {
    361. cout << "文件大小判断失败!" << endl;
    362. return;
    363. }
    364. //申请内存空间把文件内容保存下来
    365. my_data.Before_Stretch_Data = (void*)malloc(size * sizeof(char));
    366. if (fread_s(my_data.Before_Stretch_Data, size, sizeof(char), size, datafile) == 0)
    367. {
    368. cout << "写入数据失败!" << endl;
    369. return;
    370. }
    371. cout << "写入数据成功,成功获取Data!" << endl;
    372. return;
    373. }
    374. }
    375. //分析PE结构
    376. void PE::Analyze_PE(Data& data, int num)
    377. {
    378. if (num == 1)
    379. {
    380. if (data.Before_Stretch_Data != nullptr)
    381. {
    382. DWORD* Temp_ptr = (DWORD*)data.Before_Stretch_Data;
    383. data.my_dos = (PIMAGE_DOS_HEADER)Temp_ptr;
    384. Temp_ptr = (DWORD*)((char*)data.Before_Stretch_Data + data.my_dos->e_lfanew);
    385. Temp_ptr++;
    386. data.my_file = (PIMAGE_FILE_HEADER)Temp_ptr;
    387. Temp_ptr = (DWORD*)((char*)Temp_ptr + 0x14);
    388. data.my_optional = (PIMAGE_OPTIONAL_HEADER)Temp_ptr;
    389. Temp_ptr = (DWORD*)((char*)data.my_optional + data.my_file->SizeOfOptionalHeader);
    390. data.my_section = (PIMAGE_SECTION_HEADER*)malloc(sizeof(PIMAGE_SECTION_HEADER) * data.my_file->NumberOfSections);
    391. memset(data.my_section, 0, sizeof(PIMAGE_SECTION_HEADER) * data.my_file->NumberOfSections);
    392. for (int i = 0; i < data.my_file->NumberOfSections; i++)
    393. {
    394. data.my_section[i] = (PIMAGE_SECTION_HEADER)Temp_ptr;
    395. Temp_ptr = (DWORD*)((char*)Temp_ptr + 0x28);
    396. }
    397. return;
    398. }
    399. cout << "分析PE结构失败!" << endl;
    400. }
    401. if (num == 2)
    402. {
    403. if (data.Stretch_Data != nullptr)
    404. {
    405. DWORD* Temp_ptr = (DWORD*)data.Stretch_Data;
    406. data.my_dos = (PIMAGE_DOS_HEADER)Temp_ptr;
    407. Temp_ptr = (DWORD*)((char*)data.Stretch_Data + data.my_dos->e_lfanew);
    408. Temp_ptr++;
    409. data.my_file = (PIMAGE_FILE_HEADER)Temp_ptr;
    410. Temp_ptr = (DWORD*)((char*)Temp_ptr + 0x14);
    411. data.my_optional = (PIMAGE_OPTIONAL_HEADER)Temp_ptr;
    412. Temp_ptr = (DWORD*)((char*)data.my_optional + data.my_file->SizeOfOptionalHeader);
    413. data.my_section = nullptr;
    414. data.my_section = (PIMAGE_SECTION_HEADER*)malloc(sizeof(PIMAGE_SECTION_HEADER) * data.my_file->NumberOfSections);
    415. for (int i = 0; i < data.my_file->NumberOfSections; i++)
    416. {
    417. data.my_section[i] = (PIMAGE_SECTION_HEADER)Temp_ptr;
    418. Temp_ptr = (DWORD*)((char*)Temp_ptr + 0x28);
    419. }
    420. return;
    421. }
    422. cout << "分析PE结构失败!" << endl;
    423. }
    424. if (num == 3)
    425. {
    426. if (data.Shrink_Data != nullptr)
    427. {
    428. DWORD* Temp_ptr = (DWORD*)data.Shrink_Data;
    429. data.my_dos = (PIMAGE_DOS_HEADER)Temp_ptr;
    430. Temp_ptr = (DWORD*)((char*)data.Shrink_Data + data.my_dos->e_lfanew);
    431. Temp_ptr++;
    432. data.my_file = (PIMAGE_FILE_HEADER)Temp_ptr;
    433. Temp_ptr = (DWORD*)((char*)Temp_ptr + 0x14);
    434. data.my_optional = (PIMAGE_OPTIONAL_HEADER)Temp_ptr;
    435. Temp_ptr = (DWORD*)((char*)data.my_optional + data.my_file->SizeOfOptionalHeader);
    436. data.my_section = (PIMAGE_SECTION_HEADER*)malloc(sizeof(PIMAGE_SECTION_HEADER) * data.my_file->NumberOfSections);
    437. for (int i = 0; i < data.my_file->NumberOfSections; i++)
    438. {
    439. data.my_section[i] = (PIMAGE_SECTION_HEADER)Temp_ptr;
    440. Temp_ptr = (DWORD*)((char*)Temp_ptr + 0x28);
    441. }
    442. return;
    443. }
    444. cout << "分析pe结构失败!" << endl;
    445. }
    446. }
    447. //拉伸PE结构 注意看PIMAGE_XXX_HEADER的定义,它们本就是指向结构体的指针
    448. void PE::Stretch_PE(Data& my_data)
    449. {
    450. unsigned Memory_Size = 0;
    451. Memory_Size = my_data.my_optional->SizeOfImage;
    452. my_data.Stretch_Data = (void*)malloc(sizeof(char) * Memory_Size);
    453. memset(my_data.Stretch_Data, 0, Memory_Size);
    454. void* temp_before_stretch_data_ptr = my_data.Before_Stretch_Data;
    455. int size_of_dos = 0x40;
    456. int size_of_junk = 0x40;
    457. int size_of_file = 0x18;
    458. unsigned Size_Of_Optional = my_data.my_file->SizeOfOptionalHeader;
    459. unsigned Size_Of_Section = 0x28;
    460. unsigned Size_Of_Header = my_data.my_optional->SizeOfHeaders;//还未对齐
    461. memcpy_s(my_data.Stretch_Data, Memory_Size, my_data.Before_Stretch_Data, Size_Of_Header);
    462. void* temp_stretch_data = my_data.Stretch_Data;
    463. //现在计算head头对齐后的大小
    464. int Size = Size_Of_Header % my_data.my_optional->SectionAlignment;
    465. Size_Of_Header = my_data.my_optional->SectionAlignment * Size;
    466. for (int i = 0; i < my_data.my_file->NumberOfSections; i++)
    467. {
    468. temp_stretch_data = (void*)((char*)my_data.Stretch_Data + my_data.my_section[i]->VirtualAddress);
    469. temp_before_stretch_data_ptr = (void*)((char*)my_data.Before_Stretch_Data + my_data.my_section[i]->PointerToRawData);
    470. memcpy_s(temp_stretch_data, my_data.my_section[i]->SizeOfRawData, temp_before_stretch_data_ptr, my_data.my_section[i]->SizeOfRawData);
    471. }
    472. cout << "拉伸成功" << endl;
    473. }
    474. void PE::Shrink_PE(Data& my_data)
    475. {
    476. unsigned int Size = 0;
    477. Size = my_data.my_section[my_data.my_file->NumberOfSections - 1]->PointerToRawData + my_data.my_section[my_data.my_file->NumberOfSections - 1]->SizeOfRawData;
    478. my_data.Shrink_Data = (void*)malloc(Size);
    479. memset(my_data.Shrink_Data, 0, Size);
    480. //从Stretch_Data缩小
    481. //复制Heads
    482. memcpy_s(my_data.Shrink_Data, my_data.my_optional->SizeOfHeaders, my_data.Stretch_Data, my_data.my_optional->SizeOfHeaders);
    483. //复制节
    484. void* temp_shrink_data_ptr = my_data.Shrink_Data;
    485. void* temp_stretch_data_ptr = my_data.Stretch_Data;
    486. for (int i = 0; i < my_data.my_file->NumberOfSections; i++)
    487. {
    488. temp_shrink_data_ptr = (void*)((char*)my_data.Shrink_Data + my_data.my_section[i]->PointerToRawData);
    489. temp_stretch_data_ptr = (void*)((char*)my_data.Stretch_Data + my_data.my_section[i]->VirtualAddress);
    490. memcpy_s(temp_shrink_data_ptr, my_data.my_section[i]->SizeOfRawData, temp_stretch_data_ptr, my_data.my_section[i]->SizeOfRawData);
    491. }
    492. cout << "缩小成功" << endl;
    493. return;
    494. }
    495. int main()
    496. {
    497. char filename[100] = "Dll1.dll";
    498. PE my_pe;
    499. Data my_data;
    500. my_pe.Readfile(filename, my_data);
    501. 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
    502. my_pe.Stretch_PE(my_data);
    503. my_pe.Shrink_PE(my_data);
    504. my_pe.Analyze_Data_Directory(my_data);
    505. my_pe.Print_IMAGE_DATA_DIRECTORY(my_data);
    506. my_pe.Print_ExportTable(my_data);
    507. cout << "转化的文件偏移是" << hex << my_pe.Rva_To_Foa(0x3100, my_data) << endl;
    508. //((void(*)())addr)();//调用
    509. HMODULE hDll = GetModuleHandleA("Dll1.dll");
    510. my_pe.GetFunctionAddrByName(my_data, (char*)"Print");
    511. my_pe.GetFunctionAddrByOrdinal(my_data, 14);
    512. return 0;
    513. }

    注意注意:有个踩过的坑我想分享给大家。
    就是我本来想这样搞:
    申请一个堆,里面存Dll的数据,通过分析可以找到Dll文件中函数的偏移嘛,然后我就想着,这个偏移,加上堆的基地址,赋值给一个函数指针,那不是直接就可以调用吗?
    结果我试了半天,最后获得函数的真正地址也是正确的,结果就是运行不起来,tnnd,搞了好久,最后经过高人指点才知道,原来堆也是需要有运行权限的,貌似堆貌似没有运行权限。哎,搞死了,呜呜。
     

  • 相关阅读:
    【Leetcode】1825. Finding MK Average
    【世界杯】free-api-worldcup2022 免费世界杯API
    【机械仿真】基于matlab打桩机运动学仿真【含Matlab源码 2101期】
    在原生APP中集成Unity容器
    【数据结构】单链表
    一键式文件共享软件Jirafeau
    数据结构与算法之字典: Leetcode 3. 无重复字符的最长子串 (Typescript版)
    【MQTT从入门到提高系列 | 09】WireShark抓包分析MQTT报文
    【记录】打印|用浏览器生成证件照打印PDF,打印在任意尺寸的纸上(简单无损!)
    利用EMQX建立MQTT服务器通讯
  • 原文地址:https://blog.csdn.net/fzucaicai/article/details/133800313