Reputation: 360
I would like to read value from the Android runtime shared library in my application.
Since Android 5, when the new runtime was introduced and libart.so
has first appeared, I am doing it successfully with this code:
std::unique_ptr<void, int(*)(void*)> handle {
dlopen("libart.so", RTLD_NOW | RTLD_GLOBAL),
&dlclose
};
constexpr char THREAD_KEY_NAME[] = "_ZN3art6Thread17pthread_key_self_E";
key_ = static_cast<pthread_key_t *>(dlsym(handle.get(), THREAD_KEY_NAME));
LOG("Current thread: ", key_);
I'm testing this code on Android N simulator, and it fails! dlsym
returns:
undefined symbol: _ZN3art6Thread17pthread_key_self_E
I think "OK, there is no symbol now", so I pull the libart.so from simulator and see:
% ./i686-linux-android-nm ~/Desktop/libart.so | grep pthread_key
00736ea0 B _ZN3art6Thread17pthread_key_self_E
hmm...
% ./i686-linux-android-objdump -T ~/Desktop/libart.so | grep pthread_key
00736ea0 g DO .bss 00000004 Base .protected _ZN3art6Thread17pthread_key_self_E
hmm..
% ./i686-linux-android-readelf -a ~/Desktop/libart.so | grep pthread_key_self
%
OK, empty there :(
So, while I'm not fully expert in these things, i have some questions:
readelf
output is empty? There is some flags i forgot?.protected
means in objdump output? I have read some things about it but don't really understand. May be you can get good explanation?dlsym
returns error on new versions of Android? What the difference?BTW, I dumped /proc/self/maps
file for my application on both Android versions and grep libart.so
gives me:
Android L (which works fine):
b40f3000-b45f3000 r-xp 00000000 1f:00 777 /system/lib/libart.so
b45f3000-b45fb000 r--p 004ff000 1f:00 777 /system/lib/libart.so
b45fb000-b45fc000 rw-p 00507000 1f:00 777 /system/lib/libart.so
Android N (does not work):
aaef1000-aaef2000 r-xp 00000000 fd:00 729 /system/fake-libs/libart.so
aaef2000-aaef3000 r--p 00000000 fd:00 729 /system/fake-libs/libart.so
aaef3000-aaef4000 rw-p 00001000 fd:00 729 /system/fake-libs/libart.so
abc53000-ac373000 r-xp 00000000 fd:00 1034 /system/lib/libart.so
ac374000-ac37c000 r--p 00720000 fd:00 1034 /system/lib/libart.so
ac37c000-ac37e000 rw-p 00728000 fd:00 1034 /system/lib/libart.so
Thanks for any information!
upd: I see there is two libart.so on Android N, and /system/fake-libs/libart.so is empty. I suppose there is a problem, but dlopen("/system/lib/libart.so", ...) does not works :(
Upvotes: 4
Views: 2616
Reputation: 669
In Android N you can not open some private so file(https://developer.android.com/about/versions/nougat/android-7.0-changes.html#ndk)
But you can open libart.so for Android-N use this: https://github.com/crmulliner/adbi/blob/master/hijack/hijack.c or https://github.com/avs333/Nougat_dlfunctions
Upvotes: 1