How to strip symbols from Android NDK .so file?

2019-04-14 06:12发布

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

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.

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

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

Names have been changed to protect the guilty.

2条回答
地球回转人心会变
2楼-- · 2019-04-14 06:41

You have probably the BSD nm not the GNU one. Try objdump -TC ......

查看更多
迷人小祖宗
3楼-- · 2019-04-14 06:59

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.

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.

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

  • 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.

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

{ global:
PublicFunction1;
PublicFunction2;
local: *; };
查看更多
登录 后发表回答