逆向-打印重定向表

admin 2023年9月21日19:00:37评论10 views字数 6526阅读21分45秒阅读模式

课后3.25作业,打印所有重定向表:


逆向-打印重定向表

实现代码:

// 滴水三期3.25.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。//
#include <iostream>#include <Windows.h>#include <iomanip>using namespace std;
//得到PE文件大小long GetSize(char* fileName) { FILE* file = NULL; errno_t err = fopen_s(&file, fileName, "rb"); if (err != 0) { cout << "文件打开失败!" << endl; fclose(file); return 0; } long fileSize = 0; fseek(file, 0, SEEK_END); fileSize = ftell(file); fseek(file, 0, SEEK_SET); fclose(file); return fileSize;}
//RVA转FOADWORD RVA_TO_FOA(char* fileName, long long RVAaddress) { //先得到大小 long fileSize = GetSize(fileName); //得到大小后,再申请内存 char* fileBuffer = (char*)malloc(fileSize); if (!fileBuffer) { cout << "RVA_TO_FOA---->fileBuffer内存申请失败!" << endl; free(fileBuffer); return 0; } //如果内存申请成功,那么就要读fileBuffer,读之前,先打开文件 FILE* file = NULL; errno_t err = fopen_s(&file, fileName, "rb"); if (err != 0) { cout << "文件打开失败!" << endl; free(fileBuffer); fclose(file); return 0; } //如果打开也没问题,那么就需要真正的开始读了 fread(fileBuffer, 1, fileSize, file); if ((*(PWORD)fileBuffer) != IMAGE_DOS_SIGNATURE) { cout << "PE文件格式错误!" << endl;; free(fileBuffer); fclose(file); return 0; } PIMAGE_DOS_HEADER fileDosHeader = (PIMAGE_DOS_HEADER)fileBuffer;
PIMAGE_NT_HEADERS fileNTHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)fileBuffer + fileDosHeader->e_lfanew); if (fileNTHeader->Signature != IMAGE_NT_SIGNATURE) { cout << "PE的NT头错误!" << endl; free(fileBuffer); fclose(file); return 0; } PIMAGE_FILE_HEADER fileFileHeader = &(fileNTHeader->FileHeader); PIMAGE_OPTIONAL_HEADER fileOptionHeader = &(fileNTHeader->OptionalHeader); PIMAGE_SECTION_HEADER fileSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD_PTR)fileOptionHeader + fileFileHeader->SizeOfOptionalHeader); int sectionNum = 0; for (int i = 0; i < fileFileHeader->NumberOfSections; i++) { if (RVAaddress >= (fileSectionHeader + i)->VirtualAddress && RVAaddress < (fileSectionHeader + i)->VirtualAddress + (fileSectionHeader + i)->Misc.VirtualSize) { sectionNum = i; break; } } long long offsetSize = RVAaddress - (fileSectionHeader + sectionNum)->VirtualAddress; DWORD fileAdderss = (DWORD)((fileSectionHeader + sectionNum)->PointerToRawData + offsetSize); //cout << hex <<"RVAaddress:"<< RVAaddress<<"转换====》" << "文件地址:" << fileAdderss << endl; free(fileBuffer); fclose(file); return fileAdderss;
}

//FOA转RVA//这里的FOA要减去fileBufferDWORD FOA_TO_RVA(char* fileName, long long FOAaddress) { //先得到大小 long fileSize = GetSize(fileName); //得到大小后,再申请内存 char* fileBuffer = (char*)malloc(fileSize); if (!fileBuffer) { cout << "FOA_TO_FOA---->fileBuffer内存申请失败!" << endl; free(fileBuffer); return 0; } //如果内存申请成功,那么就要读fileBuffer,读之前,先打开文件 FILE* file = NULL; errno_t err = fopen_s(&file, fileName, "rb"); if (err != 0) { cout << "文件打开失败!" << endl; free(fileBuffer); fclose(file); return 0; } //如果打开也没问题,那么就需要真正的开始读了 fread(fileBuffer, 1, fileSize, file); if ((*(PWORD)fileBuffer) != IMAGE_DOS_SIGNATURE) { cout << "PE文件格式错误!" << endl;; free(fileBuffer); fclose(file); return 0; } PIMAGE_DOS_HEADER fileDosHeader = (PIMAGE_DOS_HEADER)fileBuffer;
PIMAGE_NT_HEADERS fileNTHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)fileBuffer + fileDosHeader->e_lfanew); if (fileNTHeader->Signature != IMAGE_NT_SIGNATURE) { cout << "PE的NT头错误!" << endl; free(fileBuffer); fclose(file); return 0; } PIMAGE_FILE_HEADER fileFileHeader = &(fileNTHeader->FileHeader); PIMAGE_OPTIONAL_HEADER fileOptionHeader = &(fileNTHeader->OptionalHeader); PIMAGE_SECTION_HEADER fileSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD_PTR)fileOptionHeader + fileFileHeader->SizeOfOptionalHeader); int sectionNum = 0; for (int i = 0; i < fileFileHeader->NumberOfSections; i++) { if (FOAaddress >= (fileSectionHeader + i)->PointerToRawData && FOAaddress < (fileSectionHeader + i)->PointerToRawData + (fileSectionHeader + i)->SizeOfRawData) { sectionNum = i; break; } } long long offsetSize = FOAaddress - (fileSectionHeader + sectionNum)->PointerToRawData; DWORD fileAdderss = (DWORD)((fileSectionHeader + sectionNum)->VirtualAddress + offsetSize); //cout << hex <<"RVAaddress:"<< RVAaddress<<"转换====》" << "文件地址:" << fileAdderss << endl; free(fileBuffer); fclose(file); return fileAdderss;
}
void PrintAllBaseReloc(char* fileName) { //先得到大小 long fileSize = GetSize(fileName); //得到大小后,再申请内存 char* fileBuffer = (char*)malloc(fileSize); if (!fileBuffer) { cout << "RVA_TO_FOA---->fileBuffer内存申请失败!" << endl; free(fileBuffer); return; } //如果内存申请成功,那么就要读fileBuffer,读之前,先打开文件 FILE* file = NULL; errno_t err = fopen_s(&file, fileName, "rb"); if (err != 0) { cout << "文件打开失败!" << endl; free(fileBuffer); fclose(file); return; } //如果打开也没问题,那么就需要真正的开始读了 fread(fileBuffer, 1, fileSize, file); if ((*(PWORD)fileBuffer) != IMAGE_DOS_SIGNATURE) { cout << "PE文件格式错误!" << endl;; free(fileBuffer); fclose(file); return; } PIMAGE_DOS_HEADER fileDosHeader = (PIMAGE_DOS_HEADER)fileBuffer;
PIMAGE_NT_HEADERS fileNTHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)fileBuffer + fileDosHeader->e_lfanew); if (fileNTHeader->Signature != IMAGE_NT_SIGNATURE) { cout << "PE的NT头错误!" << endl; free(fileBuffer); fclose(file); return; } PIMAGE_FILE_HEADER fileFileHeader = &(fileNTHeader->FileHeader); PIMAGE_OPTIONAL_HEADER fileOptionHeader = &(fileNTHeader->OptionalHeader); PIMAGE_SECTION_HEADER fileSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD_PTR)fileOptionHeader + fileFileHeader->SizeOfOptionalHeader);
//找到重定位表的RVA DWORD BaseRelocTableRVA = fileOptionHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress; long BaseRelocTableSize = fileOptionHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
//将重定位表的RVA转换成 DWORD BaseRelocTableFOA = RVA_TO_FOA(fileName, BaseRelocTableRVA);
DWORD fileBaseRelocTable = (DWORD_PTR)fileBuffer + BaseRelocTableFOA;
DWORD BlockSize = *((PDWORD)fileBaseRelocTable + 1);

bool tmp = true; while (tmp) {
if (*((PDWORD)fileBaseRelocTable) != 0x00 && *((PDWORD)fileBaseRelocTable + 1) != 0x00) { DWORD PageRVA = *((PDWORD)fileBaseRelocTable); DWORD BlockSize = *((PDWORD)fileBaseRelocTable + 1); DWORD Offset = fileBaseRelocTable - (DWORD)fileBuffer+ 8 + i*2; cout << hex<<left << "重定向表:" << setw(10) << "Offset:" << setw(10) << Offset << setw(10) << "PageRVA:" << setw(10) << PageRVA << setw(10) << "BlockSize:" << setw(8) << BlockSize << setw(15) << "Entries Count:" << (BlockSize - 8) / 2 << endl;
for (int i = 0; i < (BlockSize - 8) / 2; i++) { unsigned value = *((PWORD)fileBaseRelocTable + 4 + i); unsigned short high4Bits = (value >> 12) & 0xF; unsigned short low12Bits = value & 0xFFF; Offset = fileBaseRelocTable - (DWORD)fileBuffer + 2; if (high4Bits == 3) { cout << left << "YES:" << setw(8) << "Offset:" << setw(8) << Offset << setw(8) << "Value:" << setw(8) << value << setw(8) << "Type:" << "32bit" << setw(20) << " low12Bits(真实偏移):" << setw(8) << low12Bits << setw(12) << "RVA偏移:" << PageRVA + low12Bits << endl;
} else { cout << left << "NO:" << setw(8) << "Offset:" << setw(8) << Offset << setw(8) << "Value:" << setw(8) << value << setw(8) << "Type:" << "32bit" << setw(20) << " low12Bits(真实偏移):" << setw(8) << low12Bits << setw(12) << "RVA偏移:" << PageRVA + low12Bits << endl;

} } cout << "============================================" << endl; //循环 fileBaseRelocTable = fileBaseRelocTable + BlockSize; tmp = true; } else { tmp = false; }
}


free(fileBuffer); fclose(file);}
int main(){ char fileName[] = "C:\Users\zyjsuper\Desktop\test\dll.dll"; PrintAllBaseReloc(fileName);}

逆向-打印重定向表


原文始发于微信公众号(loochSec):逆向-打印重定向表

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年9月21日19:00:37
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   逆向-打印重定向表https://cn-sec.com/archives/2055902.html

发表评论

匿名网友 填写信息