从可执行文件中提取静态链接库

10

我不确定这是否可能,但是有一个可执行文件(foo.exe),其中包含许多已静态链接的库。

是否有软件可以从该文件中提取内部的.lib(或.a)文件?

谢谢。

3个回答

15
极不可能,因为通常你不会将整个库的内容注入到可执行文件中。你只会得到足够满足所有未定义符号的部分。实际上这可能只是库的一小部分。库通常由一组对象文件组成,只有需要的文件才会链接到可执行文件中。
例如,如果你在 C 运行时库中调用的唯一函数是 `exit()`,那么你很可能不会在可执行文件中有 `printf()` 函数族。
如果你直接链接对象文件,则有机会,因为它们将包含在内,无论是否使用(除非你的链接器是智能的)。
但即使如此,这也是一项艰巨的任务,因为可执行文件中可能没有关于哪些代码段来自特定对象文件的信息。虽然理论上可行,但如果有其他方法,我会优先考虑那种方式。
让我澄清一下典型的过程:
1.四个对象文件 a.o, b.o, c.o 和 d.o 分别包含函数 a(), b(), c() 和 d()。它们全部被添加到 abcd.a 存档中。
2.除了 b() 调用 c() 的事实之外,它们都是独立的(没有依赖关系)。
3.你有一个主程序调用 a() 和 b(),然后编译它并将其与 abcd.a 库链接起来。
4.链接器从库中提取 a.o 和 b.o 并将其放入你的可执行文件中,满足对 a() 和 b() 的需求,但引入了对 c() 的需求,因为 b() 需要它。链接器然后从库中提取 c.o 并将其添加到您的可执行文件中,满足对 c() 的需求。现在所有未定义的符号都已满足,可执行文件已完成,您可以在准备好时运行它。
在该过程的任何阶段中, d.o 都没有被添加到您的可执行文件中,因此您无法获取它。
更新:关于上面我提到“如果有其他方法,我会优先考虑”的评论,你在对其他答案的评论中刚刚表示你拥有生成需要提取的库的源代码。我需要问的是:为什么您不能使用该源代码重新构建库?这对于试图从一堆可执行代码中重新创建库来说似乎是一个更简单的解决方案。

该场景包括多个自定义对象文件,将它们链接成一个自定义库文件,并在可执行文件中静态链接这些库文件。如果所有库都是自定义的,那么它们不是已经完全嵌入到可执行文件中了吗?实际上,我不想获取源代码,我只想获取库文件。 - HyLian
如果每个库中的目标文件都需要满足所有未定义符号,那么是的,它们都会在那里。但这并不一定是情况。 - paxdiablo
除非你的链接器非常聪明,比如自2002年以来的Visual C++;使用/Gy编译并使用/OPT:REF链接进行函数级别链接。 - MSalters
但可以肯定的是,静态链接库的相关部分在可执行文件中,否则可执行文件将无法工作。 - Andomar
是的,@Andomar,你说得对。将它们取出仍然不是一件容易的事情,而且可能会因为OP已经声明他们拥有制作库的源代码而变得无意义。 - paxdiablo
显示剩余2条评论

1

想象一下,你手头有10本你不懂语言的书,没有封面、题目页、页码和章节。其中一些书可能不完整。所有页面都被混在一起,因此不可能找出每本书的开头和结尾(每页都是一个函数调用)。现在试着找到第5本书的第123页(假设它在上面提到了函数Exit())。

好吧,这是可能的...


你有第5本书的原始手稿。从手稿中重新印刷第5本书肯定更简单。 - deft_code

-1

看起来你正在寻求反编译器。这样的工具难以使用(对于稍微复杂一些的 C++ 可能是不可能的),如果有其他解决问题的方法,包括花几个月时间重写库,我建议采取那种行动方案。

正如 pax 指出的那样,即使你使用了反编译器,你也只会得到可执行文件调用的库函数。


但我不想完全反编译可执行文件,我不需要源代码,我需要的是链接在该可执行文件中的库文件,并将另一个不同的可执行文件与这些库文件链接起来。 - HyLian
你有这个库的头文件吗? - Dan Hook
是的,我有,实际上我拥有生成这些库的所有源代码。 - HyLian
3
如果您有源代码,为什么不重新制作库? - paxdiablo
1
我有源代码和最终的可执行文件。构建所有的库需要很长时间,而我只想更改最终应用程序的一小部分。此外,我对链接器的工作原理很感兴趣 :) - HyLian

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