2012-01-05 187 views
0

是否可以檢查調用進程從另一個共享庫(.so)加載的共享庫?我知道那裏有命令行工具,但是可以在C++代碼中執行這樣的檢查嗎?從Linux/Android上的另一個共享庫檢查加載的共享庫

我需要以某種方式獲取由Android應用程序加載的本機共享庫列表,但它似乎不可能從Java代碼。

回答

2

對於調用進程,您可以使用/proc/<pid>/maps文件或只使用/proc/self/maps:以'.so'結尾的行用於鏈接的共享庫。這是一個黑客,但應該工作。請注意,一個庫可能被映射多次,因此您需要跳過重複。

好消息:你可以從java中完成。下面的代碼片段將當前進程的共享庫打印到logcat。

try { 
    Set<String> libs = new HashSet<String>(); 
    String mapsFile = "/proc/self/maps"; 
    BufferedReader reader = new BufferedReader(new FileReader(mapsFile)); 
    String line; 
    while ((line = reader.readLine()) != null) { 
     if (line.endsWith(".so")) { 
      int n = line.lastIndexOf(" "); 
      libs.add(line.substring(n + 1)); 
     } 
    } 
    Log.d("Ldd", libs.size() + " libraries:"); 
    for (String lib : libs) { 
     Log.d("Ldd", lib); 
    } 
} catch (FileNotFoundException e) { 
    // Do some error handling... 
} catch (IOException e) { 
    // Do some error handling... 
} 

設備上的輸出是:

D/Ldd  (11286): 55 libraries: 
D/Ldd  (11286): /system/lib/libc.so 
D/Ldd  (11286): /system/lib/libdbus.so 
D/Ldd  (11286): /system/lib/librpc.so 
D/Ldd  (11286): /system/lib/libEGL.so 
D/Ldd  (11286): /system/lib/libstagefright_color_conversion.so 
D/Ldd  (11286): /system/lib/libmedia.so 
D/Ldd  (11286): /system/lib/libemoji.so 
D/Ldd  (11286): /system/lib/libcrypto.so 
D/Ldd  (11286): /system/lib/libstagefright_avc_common.so 
D/Ldd  (11286): /system/lib/libnativehelper.so 
D/Ldd  (11286): /system/lib/libskiagl.so 
D/Ldd  (11286): /system/lib/libopencore_player.so 
D/Ldd  (11286): /system/lib/libjpeg.so 
D/Ldd  (11286): /system/lib/libsurfaceflinger_client.so 
D/Ldd  (11286): /system/lib/libstagefright.so 
D/Ldd  (11286): /system/lib/libdrm1.so 
D/Ldd  (11286): /system/lib/libdvm.so 
D/Ldd  (11286): /system/lib/libwebcore.so 
D/Ldd  (11286): /system/lib/libGLESv1_CM.so 
D/Ldd  (11286): /system/lib/libhardware.so 
D/Ldd  (11286): /system/lib/libexif.so 
D/Ldd  (11286): /system/lib/libgps.so 
D/Ldd  (11286): /system/lib/liblog.so 
D/Ldd  (11286): /system/lib/libexpat.so 
D/Ldd  (11286): /system/lib/libopencore_common.so 
D/Ldd  (11286): /system/lib/libbluedroid.so 
D/Ldd  (11286): /system/lib/libm.so 
D/Ldd  (11286): /system/lib/libicui18n.so 
D/Ldd  (11286): /system/lib/libomx_amrenc_sharedlibrary.so 
D/Ldd  (11286): /system/lib/libwpa_client.so 
D/Ldd  (11286): /system/lib/libstdc++.so 
D/Ldd  (11286): /system/lib/libandroid_runtime.so 
D/Ldd  (11286): /system/lib/libz.so 
D/Ldd  (11286): /system/lib/libETC1.so 
D/Ldd  (11286): /system/lib/libsonivox.so 
D/Ldd  (11286): /system/lib/libstlport.so 
D/Ldd  (11286): /system/lib/libutils.so 
D/Ldd  (11286): /system/lib/libicudata.so 
D/Ldd  (11286): /system/lib/libsqlite.so 
D/Ldd  (11286): /system/lib/libhardware_legacy.so 
D/Ldd  (11286): /system/lib/libpixelflinger.so 
D/Ldd  (11286): /system/lib/libvorbisidec.so 
D/Ldd  (11286): /system/lib/libstagefright_amrnb_common.so 
D/Ldd  (11286): /system/lib/libcutils.so 
D/Ldd  (11286): /system/lib/libui.so 
D/Ldd  (11286): /system/lib/libmedia_jni.so 
D/Ldd  (11286): /system/lib/libomx_sharedlibrary.so 
D/Ldd  (11286): /system/lib/libcamera_client.so 
D/Ldd  (11286): /system/lib/libskia.so 
D/Ldd  (11286): /system/lib/libopencore_net_support.so 
D/Ldd  (11286): /system/lib/libnetutils.so 
D/Ldd  (11286): /system/lib/libbinder.so 
D/Ldd  (11286): /system/lib/libssl.so 
D/Ldd  (11286): /system/lib/libicuuc.so 
D/Ldd  (11286): /system/lib/libGLESv2.so 

此外,如果必要PID可以通過android.os.Process.myPid()來獲得。

+0

但我該如何在代碼中使用它?它看起來像調用一個命令行工具... – vitakot 2012-01-05 15:01:14

+0

不,你不需要任何命令行工具。我更新了我的答案。 – 2012-01-05 15:26:13

+0

很好的例子!但它顯示了一個錯誤:方法myPid()是未定義類型的進程... – vitakot 2012-01-05 15:39:37

0

WRT java,啓動一個進程,在有問題的.so上調用ldd。捕獲來自標準輸出的輸出,並處理輸出:

Process process = Runtime.getRuntime().exec("ldd a.so"); 
StreamGobbler outputGobbler = new StreamGobbler(process.getInputStream()); 
outputGobbler.start(); 
process.waitFor(); 
String result = outputGobbler.buffer; 

參考開創性的崗位上StreamGobbler一類定義。我添加了一個String buffer變量,並將此行0123FF替換爲上一個鏈接的類定義中的buffer = buffer + line+"\n";。顯然,我也將第二個參數丟給了構造函數。

class StreamGobbler extends Thread 
{ 
    InputStream is; 
    String buffer; 

    StreamGobbler(InputStream is) 
    { 
     this.is = is; 
     this.buffer = ""; 
    } 

    public void run() 
    { 
     try 
     { 
      InputStreamReader isr = new InputStreamReader(is); 
      BufferedReader br = new BufferedReader(isr); 
      String line=null; 
      while ((line = br.readLine()) != null) 
       buffer += line+"\n";  
      } catch (IOException ioe) 
       { 
       ioe.printStackTrace(); 
       } 
    } 
} 
+0

不幸的是,標準(未修改的)Android系統中沒有'ldd'命令。 – 2012-01-05 15:33:34

+0

'nm'如何? – ajshower 2012-01-05 15:37:30

+0

也沒有'nm'。甚至沒有'grep'或'find'或大多數其他標準的UNIX工具。你可以在模擬器中檢查它。 – 2012-01-05 15:40:56