rewind(fp);
fread(&DOS_header, sizeof(struct _IMAGE_DOS_HEADER), 1, fp);
fseek(fp, DOS_header.e_lfanew, 0);
fread(&nt_header, sizeof(struct _IMAGE_NT_HEADERS), 1, fp);
psection_header = new IMAGE_SECTION_HEADER[nt_header.FileHeader.NumberOfSections];
fread(psection_header, nt_header.FileHeader.NumberOfSections * sizeof(struct _IMAGE_SECTION_HEADER), 1, fp);
PIMAGE_NT_HEADERS64 pNTHeader = (PIMAGE_NT_HEADERS64)&nt_header;
int nSectionNum = pNTHeader->FileHeader.NumberOfSections;
DWORD Addr = pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
DWORD Size = pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size - sizeof(IMAGE_IMPORT_DESCRIPTOR);
while (Size > 0)
{
int nImportOffset = rva_to_raw(psection_header, nSectionNum, Addr);
if (!nImportOffset) {
break;
}
printf("%p--%p--%p", nSectionNum,Addr, nImportOffset);
fseek(fp, nImportOffset, SEEK_SET);
IMAGE_IMPORT_DESCRIPTOR import_table = { 0 };
fread(&import_table, sizeof(IMAGE_IMPORT_DESCRIPTOR), 1, fp);
fseek(fp, rva_to_raw(psection_header, nSectionNum, import_table.Name), SEEK_SET);
char dll_name[300] = { 0 };
fread(dll_name, 300, 1, fp);
printf("%s\r\n", dll_name);
Addr += sizeof(IMAGE_IMPORT_DESCRIPTOR);
Size -= sizeof(IMAGE_IMPORT_DESCRIPTOR);
}
// 内存偏移转文件偏移
int rva_to_raw(PIMAGE_SECTION_HEADER pSection, int nSectionNum, int nRva)
{
int nRet = 0;
// 遍历节区
for (int i = 0; i < nSectionNum; i++) {
// 导出表地址在这个节区内
if (pSection[i].VirtualAddress <= nRva && nRva < pSection[i + 1].VirtualAddress) {
// 文件偏移 = 该段的 PointerToRawData + (内存偏移 - 该段起始的RVA(VirtualAddress))
nRet = nRva - pSection[i].VirtualAddress + pSection[i].PointerToRawData;
break;
}
}
return nRet;
}
这段代码无法正常输出导入表的dll名称,但是我看Addr 的地址是对的,而且同样的逻辑读取x86文件可以成功获取