Sté*_*ane 15 linux android gcc compilation android-ndk
如何从/混淆编译的二进制文件中删除字符串?目标是避免让人们阅读里面的函数/方法的名称.
它是一个动态库(.so),使用NDK工具(包括GCC)从Android的C++代码编译
我编译-O3
并已经用于arm-eabi-strip -g mylib.so
删除调试符号,但是当我这样做时,strings mylib.so
所有函数/方法的名称仍然可读.
jch*_*chl 25
这些字符串位于动态符号表中,在运行时加载库时使用. readelf -p .dynstr mylib.so
将显示这些条目.
strip -g
将删除调试符号,但它无法从动态符号表中删除条目,因为在运行时可能需要这些条目.您的问题是您在动态符号表中有条目,用于永远不会从库外部调用的函数.除非您说明,否则编译器/链接器无法知道哪些函数构成外部API的一部分(因此需要动态符号表中的条目)以及哪些函数对您的库是私有的(因此不需要输入动态符号表),因此它只为所有非静态函数创建动态符号表条目.
有两种主要方法可以告知编译器哪些函数是私有的.
标记私人功能static
.显然,这仅适用于单个编译单元中仅需要的函数,但对于某些库,此技术可能就足够了.
使用gcc"visibility"属性将函数标记为可见或隐藏.您有两个选项:将所有私有函数标记为隐藏,或使用-fvisibility=hidden
编译器选项将默认可见性更改为隐藏,并将所有公共函数标记为可见.后者可能是您的最佳选择,因为这意味着您不必担心意外添加功能而忘记将其标记为隐藏.
如果你有一个功能:
int foo(int a, int b);
Run Code Online (Sandbox Code Playgroud)
然后隐藏标记的语法是:
int foo(int a, int b) __attribute__((visibility("hidden")));
Run Code Online (Sandbox Code Playgroud)
并将其标记为可见的语法是:
int foo(int a, int b) __attribute__((visibility("default")));
Run Code Online (Sandbox Code Playgroud)
有关详细信息,请参阅此文档,该文档是有关此主题的绝佳信息来源.
有一些商业混淆器可以实现这一目标.基本上,他们在旅途中重写所有符号.像这样的东西:
void foo()
Run Code Online (Sandbox Code Playgroud)
变
void EEhj_y33() // usually much, much longer and clobbered
Run Code Online (Sandbox Code Playgroud)
变量名也被给予相同的处理,结构/联合的成员(取决于您设置的混淆级别).
他们中的大多数都是通过扫描你的代码库,建立一个字典,然后在输出中用乱码混乱代替符号名称,然后可以照常编译.
我不建议使用它们,但它们可用.简单地模糊有意义的符号名称并不会阻止那些决心发现你的图书馆/程序如何工作的人.此外,您无法对跟踪系统调用的人员执行任何操作.真的,重点是什么?有人认为这有助于让"随意的观察者"陷入困境,我认为有人跑步ltrace
strace
并且strings
通常不是偶然的.
除非你的意思是字符串文字,而不是符号?关于它们没有什么可以做的,除非你以加密的格式存储文字,你编码在使用之前必须解密.这不仅仅是一种浪费,而是一种令人生畏的浪费,它不会带来任何好处.
归档时间: |
|
查看次数: |
11912 次 |
最近记录: |