从Linux/Android上的另一个共享库检查加载的共享库
是否可以检查调用进程从另一个共享库(.so)加载的共享库?我知道那里有命令行工具,但是可以在C++代码中执行这样的检查吗?从Linux/Android上的另一个共享库检查加载的共享库
我需要以某种方式获取由Android应用程序加载的本机共享库列表,但它似乎不可能从Java代码。
对于调用进程,您可以使用/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()
来获得。
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();
}
}
}
不幸的是,标准(未修改的)Android系统中没有'ldd'命令。 – 2012-01-05 15:33:34
'nm'如何? – ajshower 2012-01-05 15:37:30
也没有'nm'。甚至没有'grep'或'find'或大多数其他标准的UNIX工具。你可以在模拟器中检查它。 – 2012-01-05 15:40:56
但我该如何在代码中使用它?它看起来像调用一个命令行工具... – vitakot 2012-01-05 15:01:14
不,你不需要任何命令行工具。我更新了我的答案。 – 2012-01-05 15:26:13
很好的例子!但它显示了一个错误:方法myPid()是未定义类型的进程... – vitakot 2012-01-05 15:39:37