如何从已编译的二进制文件(.so)中删除字符串

18
如何从/混淆编译后的二进制文件中删除字符串?目标是避免让人们读取内部函数和方法的名称。
这是一个使用NDK工具(包括GCC)为Android编译的C++代码的动态库(.so)。
我使用-O3进行编译,并已经使用arm-eabi-strip -g mylib.so来删除调试符号,但是当我运行strings mylib.so时,所有函数/方法的名称仍然可读。
4个回答

32
这些字符串位于动态符号表中,该表在库在运行时加载时使用。可以通过readelf -p .dynstr mylib.so命令查看这些条目。 strip -g会删除调试符号,但它无法删除动态符号表中的条目,因为这些条目可能在运行时需要。你的问题是动态符号表中存在从未在库外部被调用的函数条目。除非你告诉它,否则编译器/链接器没有办法知道哪些函数是外部API的一部分(因此需要在动态符号表中有条目),哪些函数是私有的(因此不需要在动态符号表中有条目),所以它只为所有非静态函数创建动态符号表条目。
您可以通过两种主要方式通知编译器哪些函数是私有的:
1. 将私有函数标记为static。显然,这仅适用于仅需要在单个编译单元内使用的函数,尽管对于某些库,这种技术可能已经足够。 2. 使用gcc的"visibility"属性将函数标记为可见或隐藏。您有两个选项:将所有私有函数标记为隐藏,或者使用-fvisibility = hidden编译器选项更改默认可见性,并将所有公共函数标记为可见。后者可能是最好的选择,因为它意味着您不必担心意外添加函数并忘记将其标记为隐藏。
如果您有一个函数:
int foo(int a, int b);

那么将其标记为隐藏的语法是:

int foo(int a, int b) __attribute__((visibility("hidden")));

并将其标记为可见的语法为:

int foo(int a, int b) __attribute__((visibility("default")));

更多详情请参考这份文档,它是关于此主题的一份卓越的信息来源。


好的答案!我需要测试一下...如何做也很棒,但是需要花费很长时间去阅读。非常感谢! - Stéphane

7

有一些商业混淆器可以实现这个功能,比如C++混淆器,它们会即时重写所有符号。大致就像这样:

void foo()

变成

void EEhj_y33() // usually much, much longer and clobbered

变量名和结构/联合体成员也受到相同的处理,具体取决于您设置的混淆级别。大多数混淆工具通过扫描代码库、建立字典,然后在输出中用混乱的字符替换符号名称来工作,之后可以像平常一样编译。
我不建议使用它们,但它们是可用的。仅仅混淆有意义的符号名称并不能阻止那些决心要发现你的库/程序如何工作的人。此外,你无法对那些跟踪系统调用的人采取任何行动。真的,这有什么意义吗?有人认为这有助于防止“偶然观察者”,但我认为运行ltracestracestrings的人通常都不是偶然的。
除非你指的是字符串字面值而不是符号?对于它们,除非你将字面值存储在代码必须解密后才能使用的加密格式中,否则你无法做任何事情。这不仅浪费时间,而且是一个毫无益处的过度浪费。

谢谢!混淆比什么都不做要好;我的代码主要由复杂算法及其实现和调整组成,这些算法的函数名称有点透露了软件的很多价值。另一方面,保留系统调用的可识别性并不是问题。 - Stéphane

3
假设您已经正确地为所有源文件指定了g ++的隐藏可见性(正如其他帖子所建议的那样),有可能您会遇到这个GCC错误: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38643 尝试转储显示的二进制符号(readelf -Wa mylib.so | c++filt | less); 如果在解缠之后只看到vtable和VTT符号,则gcc错误可能是您的问题。
编辑:如果可以,请尝试使用GCC 4.4.0或更高版本,因为它似乎已在其中修复。

在GCC(V4.4.0)中使用“-fvisibility = hidden” + arm-eabi-strip -s可以起作用。谢谢。 - Stéphane

-2

它们是不可避免的。这些字符串是加载器在运行时链接共享库的手段。


我不是在谈论用于访问库的导出函数,而是内部函数。它们是否不可避免地要展示出来? - Stéphane
1
啊,那你的arm-eabi-gcc命令行让我感到困惑。-g选项通常会“添加”调试符号。 - Marcelo Cantos
抱歉打错了,不是gcc而是strip...让我更正一下。 - Stéphane

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