Loading... ```bash DWORD RvaToFoa(char* lpImage, DWORD dwRva) { //1 获取区段表的起始位置 PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)lpImage; //获取 NT头 PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)(pDos->e_lfanew + lpImage); PIMAGE_SECTION_HEADER pHeader = IMAGE_FIRST_SECTION(pNt); if (dwRva < pNt->OptionalHeader.SizeOfHeaders) { return dwRva; } //dwrva 是相对于区段头的 //循环判断RVA 落到了那个区块中 for (int i = 0; i < pNt->FileHeader.NumberOfSections; i++) { //首先的出来的是相对于区段的RVA // 区段的起始 这个相当于区段起始的位置 DWORD dwSectionRva = pHeader[i].VirtualAddress; // 文件区段的大小 如果超出文件区段的大小 得出来的结果没有意义 DWORD dwSectionEndRva = dwSectionRva + pHeader[i].SizeOfRawData; //上面得出来是这个位置的大小 // 区段的文件 文件偏移 区段的文件偏移 (起始地址) DWORD dwSectionFOA = pHeader[i].PointerToRawData; if (dwRva >= dwSectionRva && dwRva <= dwSectionEndRva) { pHeader[i].VirtualAddress; DWORD dwFOA = dwRva - dwSectionRva + dwSectionFOA; // 内存中rva 内存起始地址 文件起始地址 //当前已经记录了 FOA的起始基址 需要差值 就可以运算而 rva 必须在段内才是正确数据 //所以得出所在段的时候需要减去这个段的 所在位置 得出目前段的偏移 当前段正好有记载 文件段的位置 //所以加上当前段起始位置就可以了 return dwFOA; } } return -1; } ``` 最后修改:2021 年 02 月 28 日 © 允许规范转载 赞 0 如果觉得我的文章对你有用,请随意赞赏