2013-12-13 19 views
3

我想在Android上从ptaced子进程(/ proc/pid/mem)读取和写入内存。在读/写之前,我使用ptrace(Status = 4991,WIFSTOPPED(Status)= true)连接到进程。从Android平台上的Java代码读取/写入/ proc/<pid>/mem

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

你的问题似乎跟ptrace完全没有关系。知道如何帮助你但对ptrace没有兴趣的人会忽略你的问题,而那些知道ptrace(一种Java,我认为不支持C的概念),但不是Java随机访问文件的人会遇到你的问题和浪费他们的时间,直到他们意识到他们无法帮助你。有效的沟通/描述你的问题是至关重要的,你似乎在第一次尝试时失败了。我强烈建议您编辑您的问题,并根据您的需求合理清晰地设置标题和内容。 – mah

+1

@mah:这个问题似乎对我来说足够合理,特别是考虑到英语显然不是他们的第一语言。将/ dev/X/mem与ptrace结合是一种完全标准的技术。此外,像'失败悲惨'这样的短语可能不是建设性的...... –

+0

@DavidGiven我想我同意“失败悲惨”有点苛刻。尽管如此,我仍然觉得问题的标题至少需要与匹配其中的内容和预编辑的内容相匹配,但在此情况并非如此。虽然ptrace和读取/ dev/X/mem确实是相关的,但是表达的问题不仅与ptrace无关,除了偶然的(我想要读取的过程是ptraced)语句之外,ptrace甚至不会出现在它中。我不清楚(直到去海报的​​档案)英语是次要的,但这不是与Q. – mah

回答

1

当试图从内存中读取子进程没有映射的内容时(例如,NULL附近的任何内容),您将得到EIO。这很正常。 (有关更多信息,请参见the mem man page)。因此,如果您在孩子的地址空间中关注破碎的指针,则需要能够处理此问题。

如果当您期望子进程的内存实际存在时发生IO错误,那有点怪异。当子进程停止时,/dev/X/mem和ptrace之间可能会有一些奇怪的相互作用。我建议调查PTRACE_PEEKDATA作为读取子进程内存的替代方法。它慢得多,但可能更可靠---如果/dev/X/mem失败,请尝试PTRACE_PEEKDATA并查看它说的是什么。我假设你有ptrace的Java绑定。

+0

Thx正交的标题作为答案的借口。是的,PTRACE_PEEKDATA和PTRACE_POKEDATA工作得很好,但对于大数据来说太慢了。我正在尝试优化该方法。 [scanmem](https://code.google.com/p/scanmem/source/browse/trunk/ptrace.c)源代码包含以下内容:/ * TODO:may use/proc//mem here */ bool write_array(pid_t target,void * addr,const void * data,int len)...(这促使我修改代码)。我理解了这个问题。谢谢。 – Aleksandr