微软Visual Studio导入库的格式

3
已知Visual Studio库*.lib文件是一个Unix "ar"存档,其中包含COFF格式的目标模块。但我发现用于导入DLL的库是一系列小块(或存根)的存档,而不是COFF对象。例如,库VS15\lib\ucrt\ucrt.lib。这些块包含函数名称和定义该函数的DLL库的引用。以下是“puts”函数存根的示例(十六进制转储):
00-00-FF-FF-00-00-4C-01-39-E9-80-55-26-00-00-00 ......L.9..U&...
93-00-08-00-5F-70-75-74-73-00-61-70-69-2D-6D-73 “..._puts.api-ms
2D-77-69-6E-2D-63-72-74-2D-73-74-64-69-6F-2D-6C -win-crt-stdio-l
31-2D-31-2D-30-2E-64-6C-6C-00                   1-1-0.dll.

这绝对不是COFF对象(尽管它包含特定于COFF的386架构签名0x14C)。我找不到关于这些导入对象格式的任何文档。有人知道这个格式吗?

可能是非官方规范?

可能有一些可以处理此格式的源代码?


这个有帮助吗:https://blogs.msdn.microsoft.com/ronpih/2006/10/28/new-version-of-the-microsoft-pecoff-spec/? - Richard Critten
我很熟悉这份文档,这是我的手册。可惜,它只描述了传统的COFF目标模块,而没有导入存根。 - Serge Goncharov
1
请注意,ucrt导入库比普通导入库更特殊:它们可能包含特殊逻辑以加载特定版本的dll。请参见https://mingwpy.github.io/ucrt.html,了解为什么仅为ucrt dll生成导入库会产生错误的结果。 - rubenvb
@rubenvb 在检查 ucrt.lib 时,我没有注意到除了枚举模块而不是名称之外的任何特殊逻辑。从技术角度来看,它是一个普通的库,但 COFF 模块被这些块所取代。有一种简单的方法可以获得类似的结果 - 只需将 DLL(通过 DEF)转换为库即可。我制作了一个包含单个函数定义的简单 test.def 并创建了 *.lib。结果相当相似。 - Serge Goncharov
@Serge 好的。那么链接中描述的问题可能出在其他地方。也许是从ucrt dll生成def文件并链接到从中生成的导入库不起作用。但我认为这与你的问题无关。 - rubenvb
1个回答

3
这是所谓的微软“短导入”对象。基本上,它由20个字节的头部(与常规COFF头部相同大小)组成,后面跟着两个以零结尾的字符串:导入符号名称和DLL名称。
“短导入”头与常规COFF头在前四个签名字节上不同:0x00 0x00 0xFF 0xFF(没有常规COFF可以以此开头,因为它会被读作“未知机器,65535节”,这是无意义的)。
“短导入”头的格式在这里完全描述:MSDN PE Format
因此,在上面的示例中,我们有:

0x00 0x00 0xFF 0xFF --> "short import" 签名
0x00 0x00 --> 版本 0 (未使用)
0x4C 0x01 --> 机器 I386
0x39 0xE9 0x80 0x55 --> 时间/日期戳记 (2015年6月17日,协调世界时6:27:53)
0x26 0x00 0x00 0x00 --> 标头后面字符串的大小(38字节)
0x93 0x00 --> 序数/提示 (147)
0x08 0x00 --> 位域 ("代码",按名称导入)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接