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.
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:
__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.)-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)-Wl,-version-script -Wl,mylib.ver
.For the version script case, mylib.ver
should look like this:
{ global:
PublicFunction1;
PublicFunction2;
local: *; };
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With