簡體   English   中英

是否可以以編程方式預加載共享庫?

[英]Is it possible to programatically preload a shared library?

我正在構建一個項目,該項目需要修改一些仿生方法(例如 getaddrinfo、__android_print)的行為。 我已經能夠使用獨立編譯器或使用 Cmake 將其直接包含在 Apk 中創建掛鈎庫。 我已經能夠使用 setprop wrap.com.foo.bar 和 LD_PRELOAD 預加載共享庫,並且它正在工作並且我得到了我想要的結果。 但是,我想以編程方式預加載掛鈎庫,因此我不需要每次在重新啟動設備后都執行 LD_PRELOAD(又名禁用 SELinux、root 設備、setprop)的具體步驟。

我嘗試使用

// MainActivity
companion object {
   System.load("/data/data/com.foo.bar/lib/libhookedmethod.so")
}

但我沒有看到該方法被替換。

作為參考,hooked 方法相當簡單。 這是一個極端的簡化:


int __android_print(varargs a) {
   int realmethod(...);
   realmethod = dlsym("__android_print");
   doStuff();
   int res = realmethod(a) ;
   return res;
}

同樣,編譯和使用 LD_PRELOAD 是有效的,但我想在不使用 LD_PRELOAD 的情況下實現它......任何事情都有幫助! 提前致謝

LD_PRELOAD通過要求動態加載器任何其他庫之前加載引用的庫來工作。 加載器通過按加載順序搜索加載的庫來解析對給定符號的引用。

一旦一個符號被解析到一個特定的庫,在這個過程中它不會被重新綁定到其他庫。

上面的解釋應該很明顯為什么在程序已經運行加載libhookedmethod.so沒有任何效果。

關於實現您想要的唯一方法是setenv() (如果尚未設置)並重新exec()當前進程。 像這樣的東西:

int main(int argc, char *argv[])
{
  char *e = getenv("LD_PRELOAD");
  if (e == NULL || /* any other checks that show LD_PRELOAD to not be as we want it */) {
    setenv("LD_PRELOAD", ..., 1);
    execvp(argv[0], argv);
  }
  // LD_PRELOAD is to our liking. Run the actual program.
  ...
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM