【问题标题】:How to strip symbols from Android NDK .so file?如何从 Android NDK .so 文件中去除符号?
【发布时间】:2018-11-11 01:26:48
【问题描述】:

如何从 Android .so 本机代码库中去除符号?

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

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

C:\AndroidProject.apk\lib\armeabi-v7a>arm-linux-androideabi-strings.exe libMeow.so | findstr _ZN11SecretClass14SecretFunctionERKS_
_ZN11SecretClass14SecretFunctionERKS_

C:\AndroidProject.apk\lib\armeabi-v7a>arm-linux-androideabi-nm.exe libMeow.so
arm-linux-androideabi-nm.exe: libMeow.so: no symbols

C:\AndroidProject.apk\lib\armeabi-v7a>copy /y libMeow.so libMeow-test.so
        1 file(s) copied.

C:\AndroidProject.apk\lib\armeabi-v7a>sha1sum libMeow.so libMeow-test.so
0a36701ba44b4cfb31e6f6506349493d5466cd70 *libMeow.so
0a36701ba44b4cfb31e6f6506349493d5466cd70 *libMeow-test.so

C:\AndroidProject.apk\lib\armeabi-v7a>arm-linux-androideabi-strip.exe libMeow-test.so

C:\AndroidProject.apk\lib\armeabi-v7a>sha1sum libMeow.so libMeow-test.so
0a36701ba44b4cfb31e6f6506349493d5466cd70 *libMeow.so
0a36701ba44b4cfb31e6f6506349493d5466cd70 *libMeow-test.so

C:\AndroidProject.apk\lib\armeabi-v7a>arm-linux-androideabi-strip.exe -g libMeow-test.so

C:\AndroidProject.apk\lib\armeabi-v7a>sha1sum libMeow.so libMeow-test.so
0a36701ba44b4cfb31e6f6506349493d5466cd70 *libMeow.so
0a36701ba44b4cfb31e6f6506349493d5466cd70 *libMeow-test.so

为了保护罪犯而改名。

【问题讨论】:

    标签: android android-ndk debug-symbols


    【解决方案1】:

    您可能拥有的是 BSD nm,而不是 GNU。试试objdump -TC ......

    【讨论】:

    • 我从示例中删除了路径名,以便于阅读。实际上,我是专门在 Android NDK 目录中运行的。
    【解决方案2】:

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

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

    要隐藏内部符号,您可以阅读https://gcc.gnu.org/wiki/Visibility 了解全文。大致而言,您的选择是:

    • 在您不想在库外看到的每个符号上使用__attribute__ ((visibility ("hidden")))。 (这可能是相当多的,要追踪每一个都需要大量的工作。)
    • 使用-fvisibility=hidden 构建,它在每个外部符号上隐式设置它,并在您实际需要导出的符号上添加__attribute__ ((visibility ("default")))(可能要少得多)
    • 使用“版本脚本”来限制要导出到选择列表的函数。链接时,传递-Wl,-version-script -Wl,mylib.ver

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

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

    【讨论】:

    • -D 选项,不管它是什么,最终让我看到了符号。
    • 您还应该考虑-fvisibility-inlines-hidden,因为您提到了可见性。如果链接到其他库,-Wl,--exclude-libs,ALL 是必须的。如果没有-Wl,--exclude-libs,ALL,即使使用-fvisibility=hidden -fvisibility-inlines-hidden,我们的共享对象也会重新导出数百个符号。另见How to apply gcc -fvisibility option to symbols in static libraries?
    • 另一组可能有助于减小大小和符号的选项是编译器标志-ffunction-sections -fdata-sections 和链接器标志-Wl,--gc-sections
    • JNIEXPORT 允许您标记您的 JNI 函数并使用 -fvisibility=hidden。更多详情:stackoverflow.com/a/21452277/164089
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-30
    • 1970-01-01
    • 2014-01-01
    • 2010-09-07
    • 2013-10-12
    • 2015-03-02
    • 1970-01-01
    相关资源
    最近更新 更多