dlsym:未定义的符号,Android N.

时间:2016-06-07 15:24:55

标签: android c++ linux shared-libraries elf

我想从我的应用程序中的Android运行时共享库​​中读取值。 从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_);

我在Android 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

HMM ..

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

好的,在那里空着:(

所以,虽然我对这些事情并不完全擅长,但我有一些问题:

  1. 为什么readelf输出为空?我忘记了一些旗帜?
  2. .protected在objdump输出中的含义是什么?我已经阅读了一些有关它的内容,但并不是真的理解。你可以得到很好的解释吗?
  3. 为什么dlsym会在新版Android上返回错误?有什么区别?
  4. 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 :我看到Android N上有两个libart.so,而/system/fake-libs/libart.so为空。我想有一个问题,但是dlopen(“/ system / lib / libart.so”,...)不起作用:(

1 个答案:

答案 0 :(得分:1)

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

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