2015-09-04 28 views
0

我的P/Invoke WriteProcessMemory方法目前看起來是這樣的:發送空值終止字符串通過P字節數組WriteProcessMemory的()/調用

 [DllImport("kernel32", SetLastError = true)] 
     [return : MarshalAs(UnmanagedType.Bool)] 
     static extern bool WriteProcessMemory(
      IntPtr hProcess, 
      IntPtr baseAddress, 
      byte[] bufferToWrite, 
      uint numBytesToWrite, 
      out IntPtr numBytesWritten 
      ); 

我需要一個字符串發送到bufferToWrite參數,但它需要byte[]所以我把它轉換成byte[]之前通過它。

我的問題是,因爲.NET字符串不是空終止,它不會寫入終止null到遠程內存。如果我在非託管代碼中執行此操作,我將分配字符串的長度+終止空值,並將所有內容放入分配的內存中,因爲我正在讀取的「字符串」包含空值。但是託管字符串不包含它。也許我可以分配一個足夠大的緩衝區來包含終止空值,然後再次調用WriteProcessMemory來寫入空值;或者我可以創建一個足以容納字符串+ null的byte[],寫入數組並將其傳入。

但是,有沒有一個更優雅的解決這個問題?

回答

2

聲明超載這樣的:

[DllImport("kernel32", SetLastError = true)] 
[return : MarshalAs(UnmanagedType.Bool)] 
static extern bool WriteProcessMemory(
    IntPtr hProcess, 
    IntPtr baseAddress, 
    string bufferToWrite, 
    uint numBytesToWrite, 
    out uint numBytesWritten 
); 

這樣,你強迫編組爲空終止字符串。

您可以將數據傳遞爲IntPtr並使用Marshal.StringToPtrAnsi。但是,你需要管理內存。

如果文本是Unicode,請使用CharSet.Unicode選項。

+0

如果我這樣做,應該'numBytesToWrite'考慮終止空字節,儘管目前很多字節不會存在於clr字符串中? – eurotrash

+0

編組器會將'string'編組爲一個指向以null結尾的字符數組的指針。你可以並且應該在numBytesToWrite –

+0

中說明空終止符。好極了,這正是我正在尋找的解決方案。 – eurotrash

0

您還可以分配字符串加上一個空終止符。例如。如果你想要寫的字符串

string szToWrite = "This is what I want to write"; 

我有它通過例如轉換爲byte[]使用ASCII轉換

byte[] aBytes = Encoding.ASCII.GetBytes(szToWrite); 

然後,只需把它與一個額外的空字節加入。

aBytes = aBytes.Concat(new byte[] { 0x00 }).ToArray(); 

如果你想,創建自己的功能WriteProcessMemoryString,有它接受一個string而不是byte[]並使用相同的概念之上。另請注意,您可能希望使用與ASCII不同的編碼,例如UTF7/UTF8,或者任何您本地需要的東西(例如寬字符字符串)。

+0

是的,這基本上是我考慮過的選項之一,我只是希望有一個比faff少一點的東西比手動追加一個null。我想如你所說我可以創建一個函數,並讓它處理字符串轉換+追加空值。我稍等一下,看看其他人是否還有其他想法...... – eurotrash