2016-09-05 59 views
2

dlopen()在API-23中工作正常,但對於Android-N,當我試圖用dlopen打開任何軟件時,它返回一個soinfo結構類型指針。但是當我試圖訪問這個結構的任何變量時,應用程序就會崩潰。dlopen()與android-n不兼容

si = (soinfo*) dlopen("/data/app/com.xxx.xxx.sampleapp.android-1/lib/x86/libtest.so", RTLD_GLOBAL); 

if (si == NULL) 
    return; 

LOGI("value of dlopen [%d]", si->size); 

在Android-N中是否有任何dlopen()功能的變化?

回答

2

developer documentation(強調):

開始在安卓7.0,系統防止對非NDK庫,這可能會導致應用程序崩潰動態鏈接的應用程序。這種行爲變化旨在通過平臺更新和不同設備創建一致的應用體驗。
...
所有應用程序在調用既不公開也不臨時訪問的API時會生成運行時錯誤。 結果是System.loadLibrary和dlopen(3)都返回NULL,並可能導致您的應用程序崩潰。

+0

在提問中,提問者指出'dlopen'事實上並不返回NULL。還有其他事情必須在這裏發生,你同意嗎? –

+0

是的。它不會返回NULL。它返回一個無法訪問的內存指針。這就是爲什麼我感到驚訝。 – vinit

+0

它實際上並不是一個_pointer_,它是一個_handle._含義:不要試圖通過它訪問內存。 –

7

dlopen()指針不回一些soinfo結構,它返回void*,標準的Linux手冊頁是非常具體的關於這一點:

函數dlopen()的加載動態共享對象(共享庫)文件,該文件由以null結尾的字符串filename命名,併爲加載的對象返回一個不透明的「句柄」。該句柄與dlopen API中的其他函數一起使用,例如dlsym(3),dladdr(3),dlinfo(3)和dlclose()。

,這樣你可以以某種方式譯作返回值的事實是非標準,現在谷歌僅僅是執行與this change

commit ae74e8750b9dae51b24a22fdb4b0e0a2d84f37b9 
author Dimitry Ivanov <[email protected]> 
... 
linker: hide the pointer to soinfo 

Handle no longer is a pointer to soinfo of 
a corresponding library. This is done to 
prevent access to linker internal fields. 

Bug: http://b/25593965 
Change-Id: I62bff0d0e5b2dc842e6bf0babb30fcc4c000be24 
(cherry picked from commit d88e1f350111b3dfd71c6492321f0503cb5540db) 

所以,除非你的應用程序的目標是SDK版本23或更低(請參閱soinfo::to_handle()),您現在正在獲取只能轉換回soinfo*的手柄,並帶有內部仿生soinfo_from_handle()

+0

是的,我同意它返回無效*抱歉的錯誤.. – vinit

1

對於返回不透明句柄而不是指向soinfo的指針的Android版本,函數dl_iterate_phdr()可用。這可以讓你找到所有.so's的Elf標題,而Elf標題包含大量與soinfo結構相同的信息。

相關問題