剥离符号的最佳方法

问题描述 投票:0回答:3

上周我发布了一个应用程序的 Linux 和 Windows 版本。

发布后,我们意识到符号没有被剥离,我的经理认为(我不同意)这可能会让用户理解我们的算法。

无论如何,现在我必须清理符号并重新发布应用程序。

我的问题,

  1. 在 Linux 中去除符号的最佳方法是什么?
  2. 在 Windows 中去除符号的最佳方法是什么?
c++ c visual-c++ gcc symbols
3个回答
32
投票

对于 Windows 上的 Visual C++(和其他 Microsoft 编译器),符号不是二进制文件的一部分。 相反,它们存储在称为“程序数据库”文件(.pdb 文件)的单独文件中。 只是不要提供 .pdb 文件。

使用 GNU 工具链,您可以使用

strip
从二进制文件中删除符号。


26
投票

对于 GNU 工具链,有一个很酷的技巧:

objcopy --only-keep-debug yourprogram ../somepath/yourprogram.dbg
strip yourprogram
objcopy --add-gnu-debuglink=../somepath/yourprogram.dbg yourprogram

现在您可以压缩程序所在的文件夹(或将其打包到安装程序或其他文件中),其中将不再有调试符号。
但是:如果您启动调试器或者运行像

addr2line
obdump
这样的工具,该工具将(感谢调试链接信息)自动知道在哪里找到符号并加载它们。

这太棒了,因为这意味着您可以享受拥有符号的好处,而无需将它们分发给用户。


0
投票

在 Windows 上,没有 PDB 的交付还不够好! 如果 DLL 中有与安全相关的函数,并且 DLL 是使用按名称导出的外部函数构建的,那么这些名称仍将在 calling EXE 的二进制文件中显示为文本字符串。

很容易看到这一点...只需使用“字符串”或任何十六进制编辑器并在 EXE 中搜索一些可能的字符串(如“许可证”等),然后它们就会出现。

在 EXE 上使用“Dependency Walker for Win64”等免费实用程序...即使没有 PDB 并且您正在调用的 DLL 也找不到...Dependency Walker 仍然会构建一个包含名称和序数的表对于 DLL 的所有导出函数。

因此,除了不带 PDB 进行交付(当然)之外,您还需要构建不带任何导出名称的 DLL。请参阅:按序数而不是按名称从 DLL 导出函数。基本上,您需要创建一个 .DEF 文件,该文件用于构建 EXE,但就像 PDB 一样,不会发布。还可以按照此处所述使用 NONAME:使用 DEF 文件从 DLL 导出

完成后,请务必使用字符串等测试运输文件,以验证是否存在有用的符号文本。

© www.soinside.com 2019 - 2024. All rights reserved.