我想在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()用于写入内存?如何正确使用它?
答案 0 :(得分:1)
当你尝试从内存中读取子进程没有映射的内容时,你会得到EIO--例如,NULL周围的任何东西。那是完全正常的。 (有关详细信息,请参阅the mem man page。)因此,如果您在子地址空间中关注了破碎的指针,则需要能够处理此问题。
如果您在预期子进程的内存实际存在时遇到IO错误,那就有点怪异了。当子进程停止时,/dev/X/mem
和ptrace之间可能会有一些奇怪的交互。我建议调查PTRACE_PEEKDATA
作为阅读子进程记忆的替代方法。它慢得多但可能更可靠 - 如果/dev/X/mem
失败,请尝试PTRACE_PEEKDATA
并查看其内容。我假设你有ptrace的Java绑定。