从Android平台上的java代码读/写/ proc / <pid> / mem </pid>

时间:2013-12-13 12:24:53

标签: java android c bytebuffer ptrace

我想在Android上从ptaced子进程(/ proc / pid / mem)读取和写入内存。在读/写之前我使用ptrace附加到进程(Status = 4991,WIFSTOPPED(Status)= true)。

int lSize = (int) (pAddressEnd - pAddressStart);
ByteBuffer lByteBuffer = ByteBuffer.allocate(lSize);
RandomAccessFile lRandomAccessFile = null;
try {
    lRandomAccessFile = new RandomAccessFile(mFileName, "r");
    lRandomAccessFile.getChannel().read(lByteBuffer, pAddressStart);

    lRandomAccessFile.close();
} catch (FileNotFoundException e) {
    throw new RuntimeException(e);
} catch (IOException e) {
    throw new RuntimeException(e);
}
...

有时内存访问会正确传递,但有时它会抛出异常:

java.lang.RuntimeException: java.io.IOException: pread failed: EIO (I/O error)
        ...
        at java.lang.Thread.run(Thread.java:841)
Caused by: java.io.IOException: pread failed: EIO (I/O error)
        at java.nio.FileChannelImpl.readImpl(FileChannelImpl.java:315)
        at java.nio.FileChannelImpl.read(FileChannelImpl.java:283)
        at test.Process$Mem.readByteBuffer(Process.java:285)
        ... 33 more
Caused by: libcore.io.ErrnoException: pread failed: EIO (I/O error)
        at libcore.io.Posix.preadBytes(Native Method)
        at libcore.io.Posix.pread(Posix.java:99)
        at libcore.io.BlockGuardOs.pread(BlockGuardOs.java:124)
        at java.nio.FileChannelImpl.readImpl(FileChannelImpl.java:305)
        ... 35 more

尝试写内存总是抛出异常。

我可以使用RandomAccessFile.getChannel()。read()方法来读取内存吗?和RandomAccessFile.getChannel()。write()用于写入内存?如何正确使用它?

1 个答案:

答案 0 :(得分:1)

当你尝试从内存中读取子进程没有映射的内容时,你会得到EIO--例如,NULL周围的任何东西。那是完全正常的。 (有关详细信息,请参阅the mem man page。)因此,如果您在子地址空间中关注了破碎的指针,则需要能够处理此问题。

如果您在预期子进程的内存实际存在时遇到IO错误,那就有点怪异了。当子进程停止时,/dev/X/mem和ptrace之间可能会有一些奇怪的交互。我建议调查PTRACE_PEEKDATA作为阅读子进程记忆的替代方法。它慢得多但可能更可靠 - 如果/dev/X/mem失败,请尝试PTRACE_PEEKDATA并查看其内容。我假设你有ptrace的Java绑定。