dlsym:未定义的符号,Android N

dlsym: undefined symbol, Android N

本文关键字:Android 符号 未定义 dlsym      更新时间:2023-10-16

我想从应用程序中的Android运行时共享库中读取值。自从安卓5推出新的运行时,libart.so首次出现以来,我用以下代码成功地完成了这项工作:

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_);

我正在安卓N模拟器上测试这段代码,但它失败了!dlsym返回:

undefined symbol: _ZN3art6Thread17pthread_key_self_E

我想"好吧,现在没有符号了",所以我从模拟器中提取libart.so,然后看到:

% ./i686-linux-android-nm ~/Desktop/libart.so | grep pthread_key
00736ea0 B _ZN3art6Thread17pthread_key_self_E

嗯。。。

% ./i686-linux-android-objdump -T ~/Desktop/libart.so | grep pthread_key
00736ea0 g    DO .bss   00000004  Base        .protected _ZN3art6Thread17pthread_key_self_E

嗯。。

% ./i686-linux-android-readelf -a ~/Desktop/libart.so | grep pthread_key_self
%

好的,那里是空的:(

所以,虽然我不是这些方面的专家,但我有一些问题:

  1. 为什么readelf输出为空?有一些旗帜我忘了
  2. .protected在objdump输出中意味着什么?我读过一些关于它的东西,但并不真正理解。也许你能得到很好的解释
  3. 为什么dlsym在新版本的Android上返回错误?有什么区别

BTW,我在两个Android版本上都为我的应用程序转储了/proc/self/maps文件,grep libart.so给了我:

  • Android L(运行良好):

    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(不工作):

    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
    

感谢提供任何信息!

upd:我看到安卓N上有两个libart.so,/system/fake-libs/libart.so为空。我想这是有问题的,但dlopen("/system/lib/libart.so",…)不起作用:(

在Android N中,您无法打开一些私人so文件(https://developer.android.com/about/versions/nougat/android-7.0-changes.html#ndk)

但是你可以为Android-N打开libart.so,使用这个:https://github.com/crmulliner/adbi/blob/master/hijack/hijack.c或https://github.com/avs333/Nougat_dlfunctions