检查从Linux/Android上的另一个共享库加载的共享库

检查从Linux/Android上的另一个共享库加载的共享库,android,linux,android-ndk,Android,Linux,Android Ndk,是否可以检查调用进程从另一个共享库(.so)加载了哪些共享库?我知道有命令行工具,但是在C++代码中执行这种检查是否可能?< /P> 我需要以某种方式获得Android应用程序加载的本机共享库列表,但从Java代码中似乎不可能获得该列表。您可以使用/proc//maps文件,或者只使用/proc/self/maps调用过程:以“.so”结尾的行用于链接共享库。这是一个黑客程序,但应该有效。请注意,一个库可以映射多次,因此您需要跳过重复 好消息是:您可以从java实现它。下面的代码片段将当前进程的

是否可以检查调用进程从另一个共享库(.so)加载了哪些共享库?我知道有命令行工具,但是在C++代码中执行这种检查是否可能?< /P> 我需要以某种方式获得Android应用程序加载的本机共享库列表,但从Java代码中似乎不可能获得该列表。

您可以使用
/proc//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...
}

另外,如果需要,可以通过
android.os.Process.myPid()

WRT java获得pid,启动一个进程来调用.so。从标准输出捕获输出并处理输出:

Process process = Runtime.getRuntime().exec("ldd a.so");  
StreamGobbler outputGobbler = new StreamGobbler(process.getInputStream());  
outputGobbler.start();  
process.waitFor();  
String result = outputGobbler.buffer;  
有关类定义,请参阅上的开创性文章。我添加了一个
stringbuffer
变量并替换了这一行,
System.out.println(type+“>”+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();  
              }
    }
}

不,您不需要任何命令行工具。我更新了我的答案。很好的例子!但是它向我显示了一个错误:类型进程的方法myPid()没有定义……好的,我明白了,只需要调用android.os.Process.myPid()是的,你对
进程的看法是正确的。我(为其他人)更新了答案,以免与
java.lang.Process
混淆。您也可以只使用
/proc/self
,而不必费心处理
Process.myPid()
self
是当前PID的符号链接。不幸的是,标准(未修改)Android系统中没有
ldd
命令。也没有
nm
。甚至没有
grep
find
或大多数其他标准UNIX工具。您可以在emulator中进行检查。对不起,我的回答是基于
linux
标记的。我没有任何android经验或模拟器。
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();  
              }
    }
}