如何从 Android NDK .so 文件中删除符号? [英] How to strip symbols from Android NDK .so file?

查看:46
本文介绍了如何从 Android NDK .so 文件中删除符号?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何从 Android .so 原生代码库中去除符号?

How do you strip symbols from an Android .so native code library?

我构建了一个 .so,它有数千个符号在十六进制编辑器中清晰可见.IDA Pro 会根据可执行文件中的符号使用适当的符号自动反汇编.

I have a .so built that has thousands of symbols clearly visible in a hex editor. IDA Pro automatically disassembles with proper symbols based on the ones in the executable.

但是,如果我要求 nm 转储符号表,它会说没有.stripobjcopy 也没有效果.

However, if I ask nm to dump the symbol table, it says there are none. strip and objcopy also have no effect.

C:AndroidProject.apklibarmeabi-v7a>arm-linux-androideabi-strings.exe libMeow.so | findstr _ZN11SecretClass14SecretFunctionERKS_
_ZN11SecretClass14SecretFunctionERKS_

C:AndroidProject.apklibarmeabi-v7a>arm-linux-androideabi-nm.exe libMeow.so
arm-linux-androideabi-nm.exe: libMeow.so: no symbols

C:AndroidProject.apklibarmeabi-v7a>copy /y libMeow.so libMeow-test.so
        1 file(s) copied.

C:AndroidProject.apklibarmeabi-v7a>sha1sum libMeow.so libMeow-test.so
0a36701ba44b4cfb31e6f6506349493d5466cd70 *libMeow.so
0a36701ba44b4cfb31e6f6506349493d5466cd70 *libMeow-test.so

C:AndroidProject.apklibarmeabi-v7a>arm-linux-androideabi-strip.exe libMeow-test.so

C:AndroidProject.apklibarmeabi-v7a>sha1sum libMeow.so libMeow-test.so
0a36701ba44b4cfb31e6f6506349493d5466cd70 *libMeow.so
0a36701ba44b4cfb31e6f6506349493d5466cd70 *libMeow-test.so

C:AndroidProject.apklibarmeabi-v7a>arm-linux-androideabi-strip.exe -g libMeow-test.so

C:AndroidProject.apklibarmeabi-v7a>sha1sum libMeow.so libMeow-test.so
0a36701ba44b4cfb31e6f6506349493d5466cd70 *libMeow.so
0a36701ba44b4cfb31e6f6506349493d5466cd70 *libMeow-test.so

为了保护罪犯而改名.

推荐答案

由于 .so 是一个动态加载的共享库,它需要有一些外部可用的符号.要查看这些,请使用 nm -D libMeow.so.Strip 不会删除这些,否则会使库无法使用.

Since the .so is a shared library that will be loaded dynamically, it needs to have some amount of symbols available externally. To view these, use nm -D libMeow.so. Strip won't remove these, or it would make the library unusable.

由于某些函数需要从外部加载,所以不能只删除所有动态符号,因为这样就没有人能够与 .so 进行交互了.如果你的 .so 是一个 JNI 库,你需要让 JNI 入口点函数在外部可见,而如果它是另一个 .so 链接的共享库,你至少需要让你的库的公共界面可见.

Since the some functions need to be loaded externally, you can't just remove all dynamic symbols, because then nobody would be able to interface with the .so. If your .so is a JNI library, you need to have the JNI entry point functions visible externally, while if it is a shared library that another .so links against, you need to have at least the public interface of your library visible.

要隐藏内部符号,您可以阅读 https://gcc.gnu.org/wiki/完整故事的可见性.大致而言,您的选择是:

To make the internal symbols hidden, you can read https://gcc.gnu.org/wiki/Visibility for the full story. Roughly, your options are:

  • 在您不希望在库外可见的每个符号上使用 __attribute__ ((visibility ("hidden"))).(这可能是相当多的,要追踪每一个都需要大量的工作.)
  • 使用 -fvisibility=hidden 构建,它在每个外部符号上隐式设置它,并在符号上添加 __attribute__ ((visibility ("default")))您实际需要导出的内容(可能要少得多)
  • 使用版本脚本"来限制要导出到选择列表的函数.链接时,传递 -Wl,-version-script -Wl,mylib.ver.
  • Use __attribute__ ((visibility ("hidden"))) on every symbol you don't want to be visible outside of the library. (This probably is quite a few and it's a lot of work to track down every single one.)
  • Build with -fvisibility=hidden, which implicitly sets this on every single external symbol, and add __attribute__ ((visibility ("default"))) on the ones that you actually need to have exported (probably much fewer)
  • Use a "version script" to limit what functions to export to a select list. When linking, pass -Wl,-version-script -Wl,mylib.ver.

对于版本脚本案例,mylib.ver 应如下所示:

For the version script case, mylib.ver should look like this:

{ global:
PublicFunction1;
PublicFunction2;
local: *; };

这篇关于如何从 Android NDK .so 文件中删除符号?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆