2010-05-20 88 views
14

如何从/模糊编译的二进制文件中删除字符串?目标是避免让人们阅读里面的函数/方法的名字。如何从编译的二进制文件中删除字符串(.so)

它是一个动态库(的.so)从C++代码编译为Android与NDK工具(包括GCC)

-O3编译和已经使用arm-eabi-strip -g mylib.so删除调试符号,但是当我做strings mylib.so所有函数/方法的名称仍然可读。

回答

22

这些字符串位于动态符号表中,在运行时加载库时使用。 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"))); 

欲了解更多详情,请参阅this document,这是关于此主题的极好信息来源。

+0

很好的回答!我需要测试一下......该方法也很棒,但是阅读起来很长。非常感谢! – 2010-06-02 20:27:13

-2

它们是不可避免的。这些字符串是加载程序在运行时链接共享库的方式。

+0

我不是在谈论导出的函数来访问库,而是内部函数。是不可避免的向他们展示? – 2010-05-20 10:05:13

+1

啊,那么你的'arm-eabi-gcc'命令行让我感到困惑。 '-g'选项通常是_adds_调试符号。 – 2010-05-20 10:17:54

+0

对于错字感到抱歉,它不是'gcc',而是'strip' ...让我纠正这一点。 – 2010-05-20 12:11:54

5

有一些commercial obfuscators完成这一点。基本上,他们在旅途中重新编写所有的符号。事情是这样的:

void foo() 

成为

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

变量名(取决于您所设置的级别混淆)也给予同样的待遇,因为是结构/联合的成员。

其中大部分工作是通过扫描您的代码库,建立一个字典,然后用乱码替换输出中的符号名称,然后可以照常编译。

我不推荐使用它们,但它们都可用。简单地混淆有意义的符号名称是而不是将阻止某个决心发现您的图书馆/程序如何工作的人。此外,您无法对跟踪系统调用的人做任何事情。真的,有什么意义?有人认为,它有助于保持“临时观察员”的身份,我认为有人运行ltracestracestrings通常是非常随意的。

,除非你是字符串文字,不符号?除非您将文字以加密格式存储,并且代码在使用之前必须解密,否则无法对其执行任何操作。这不仅仅是一种浪费,而且是一种极其糟糕的浪费,不会带来任何好处。

+0

谢谢!混淆总比没有好;我的代码主要由复杂的算法组成,它们的实现和调整(这些功能的名称有些不同)使得软件的价值很大。另一方面,让系统调用可识别不是问题。 – 2010-05-27 13:49:23

2

假设正确,指定一个隐藏的知名度,G ++中针对所有的源文件(如其他海报推荐),有可能会在这个GCC错误运行一个机会: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38643

尝试倾销您的二进制文件中显示的符号(readelf -Wa mylib.so | c++filt | less);如果你在demangling之后只看到vtable和VTT符号,那么gcc bug可能是你的问题。

编辑:如果可以,请尝试GCC 4.4.0或更高版本,因为它似乎在那里修复。

+0

-fvisibility =隐藏在GCC(V4.4.0)+ arm-eabi-strip -s工作中。 谢谢 – 2010-07-21 17:29:26