2013-12-13 51 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