我正在尝试编写一个代码,该代码应该通过使用 exe 的 .idata 部分中的 IMAGE_IMPORT_DESCRIPTOR 结构的“名称”字段打印出 exe 中所有导入的 dll 的名称,但程序似乎陷入无限循环。谁能告诉我如何正确打印出名字...
#include<iostream>
#include<Windows.h>
#include<stdio.h>
#include<WinNT.h>
int main()
{
FILE *fp;
int i;
if((fp = fopen("c:\\Linked List.exe","rb"))==NULL)
std::cout<<"unable to open";
IMAGE_DOS_HEADER imdh;
fread(&imdh,sizeof(imdh),1,fp);
fseek(fp,imdh.e_lfanew,0);
IMAGE_NT_HEADERS imnth;
fread(&imnth,sizeof(imnth),1,fp);
IMAGE_SECTION_HEADER *pimsh;
pimsh = (IMAGE_SECTION_HEADER *)malloc(sizeof(IMAGE_SECTION_HEADER) * imnth.FileHeader.NumberOfSections);
long t;
fread(pimsh,sizeof(IMAGE_SECTION_HEADER),imnth.FileHeader.NumberOfSections,fp);
for(i=0;i<imnth.FileHeader.NumberOfSections;i++)
{
if(!strcmp((char *)pimsh->Name,".idata"))
t = pimsh->PointerToRawData;
pimsh++;
}
fseek(fp,t,0);
IMAGE_IMPORT_DESCRIPTOR iid;
char c;
while(1)
{
fread(&iid,sizeof(iid),1,fp);
if(iid.Characteristics == NULL)
break;
t = ftell(fp);
fseek(fp,(long)iid.Name,0);
while(c=fgetc(fp))
printf("%c",c);
printf("\n");
fseek(fp,t,0);
}
}
最佳答案
有几个问题。
您不能假定导入部分名为“.idata”。您应该使用
IMAGE_OPTIONAL_HEADER.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]
找到导入。PE 文件中的大多数偏移量是相对虚拟地址 (RVA),而不是文件偏移量。要将 RVA 转换为偏移量,您需要确定虚拟地址位于哪个部分,然后根据该部分在文件中的位置计算偏移量。具体来说,
IMAGE_IMPORT_DESCRIPTOR.Name
字段包含 RVA,而不是文件偏移量。如果您使用内存映射文件而不是文件 I/O,您的代码会更简单(也更快)。
This MSDN article解释了 RVA、数据目录等。它还包括 pedump
,一个具有完整源代码的用于转储 PE 文件的应用程序,这是一个有用的引用。
关于windows - 从可移植可执行文件的 .idata 部分打印出隐式链接的 dll 的名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9656147/