Assembly 不带导入查找表的64位PE文件

Assembly 不带导入查找表的64位PE文件,assembly,64-bit,portable-executable,fasm,Assembly,64 Bit,Portable Executable,Fasm,我有一个用于windows的64位hello world应用程序。它是使用平面汇编程序(fasm)创建的。我不再有源代码,但这是一个非常简单的示例,它调用: MessageBoxA() 退出程序() 我在PE编辑器(CFF浏览器)中打开了该文件,看到“导入目录表”中“导入查找表”的RVA为0x0。尽管如此,“导入地址表”RVA仍然存在,包含指向API名称的指针,并且Windows 10可以毫无怨言地启动程序 我的问题是:是否存在定义这种二进制文件的PE规范?其他编译器有相同的行为吗?这是体育+的

我有一个用于windows的64位hello world应用程序。它是使用平面汇编程序(fasm)创建的。我不再有源代码,但这是一个非常简单的示例,它调用:

  • MessageBoxA()
  • 退出程序()
  • 我在PE编辑器(CFF浏览器)中打开了该文件,看到“导入目录表”中“导入查找表”的RVA为0x0。尽管如此,“导入地址表”RVA仍然存在,包含指向API名称的指针,并且Windows 10可以毫无怨言地启动程序

    我的问题是:是否存在定义这种二进制文件的PE规范?其他编译器有相同的行为吗?这是体育+的东西吗


    从技术上讲,缺少“导入查找表”并没有什么大不了的,因为“导入地址表”中有相同的数据(尽管被PE加载程序覆盖)。但是Microsoft文档()没有涵盖这种.idata部分。

    我正在编写一些分析.EXE文件的工具,我也看到过类似的.EXE文件

    您链接的Microsoft文档中暗示了此类文件存在的原因:

    导入查找表的RVA。。。(Winnt.h中使用了名称“Characteristics”,但不再描述此字段。)

    对我来说,括号中的句子和“不再”一词意味着较旧的Windows版本使用“导入查找表的RVA”字段来存储不同类型的信息,因此为这些Windows版本编写的.EXE文件没有导入查找表

    而且,因为较新的Windows版本应该能够运行旧的可执行文件,所以最近的Windows版本似乎仍然接受将该字段用作其他信息的可执行文件

    另一方面,一些链接器或编译器似乎仍然用零填充此字段,因为Windows仍然接受零值

    然而,据我所知,只有32位版本的Windows使用此字段存储不同类型的信息。如果这是真的,则只有此字段设置为零的32位.EXE文件(为旧Windows版本编写)才有效


    这意味着Microsoft可能会在将来禁用对64位.EXE文件的支持,这些文件的此字段设置为零。这意味着64位链接器或编译器将此字段设置为零是错误的。

    您可能正在查看本机映像(仅导入ntdll)、绑定导入或延迟加载所有内容。或者您正在使用一个不处理PE32+的查看器,该查看器在可选标题中缺少一个字段


    编辑:我重读了这个问题。如果查看导入表条目中的时间戳,它可能不是零,表示绑定的导入。

    从技术上讲,可以通过名称或序号(简单的数字)定义导入。使用序数时,不需要查找表。这是不寻常的,但是你不能再给我们看你的导入语句了,并且对链接器只字未提。最好不要纠缠于此。澄清一下:这不是“按名称导入”与“按顺序导入”。“导入查找表”和“导入地址表”中的每个条目都可以是指向名称或序号的指针(取决于是否设置了最后一位)。我的问题是:应该有两个具有相同值的表(根据MS文档),但只有“导入地址表”在那里。我怀疑您弄错了,或者CFF Explorer向您显示了错误的数据。导入目录表中应该有三个条目,一个用于USER32.DLL,一个用于KERNEL32.DLL,一个为空,所有零值表示表的结束。这三个条目中的每一个都有自己的“导入查找表RVA”和“导入地址表RVA”值。Thx,很高兴知道我不是唯一一个看到此类文件的人:)不,该字段绝对可以为零。这只是随着链接器/加载器中添加的功能而改变的含义。