通過這個p在C#調用ReadProcessMemory
時,我遇到了一些非常怪異的行爲被設置爲空/調用簽名:引起參考奇怪的行爲時調用ReadProcessMemory
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool ReadProcessMemory(
IntPtr hProcess,
IntPtr lpBaseAddress,
[Out] byte[] lpBuffer,
int dwSize,
out int lpNumberOfBytesRead
);
在我的應用程序」 m掃描具有讀取和寫入權限的內存區域的整個內存(以及應用了一些更多的過濾器,但這是另一部分)。
在掃描部分的代碼是這樣的:
int numberOfBytes;
if (!NativeMethods.ReadProcessMemory(handle, region.StartAddress,
buffer, (int)region.RegionSize, out numberOfBytes))
// The handle, region (custom struct containing some fields from the
// MEMORY_BASIC_INFORMATION struct), and buffer come from parameters.
和代碼完美的作品。它會掃描整個內存中的一系列字節。那裏沒有問題。
遠一點我的程序的流程我有這樣的代碼:
注:它使用相同的處理的IntPtr爲前面的代碼(選中它),它在同一個線程中運行
int bytesRead;
byte[] buffer = new byte[128]; // In my real app this is some calculated value
// however that irrelevant. It's calculated 128.
if (!NativeMethods.ReadProcessMemory(handle, location.Location,
buffer, buffer.Length, out bytesRead))
continue; // Error while reading
// At this point buffer == null, so the next line causes an exception
if (bytesRead != buffer.Length) continue;
代碼非常相似,但由於某些原因,對緩衝區的引用丟失並且緩衝區設置爲空。如果它不是一個外部電話,我會100%確定它是一個錯誤,因爲緩衝區不作爲ref
或out
參數傳遞。但是我知道.NET在外部調用時會做一些vodoo的東西(例如編組)。
是什麼讓,甚至怪異的情況是,當我替換代碼:
int bytesRead;
byte[] buffer = new byte[128];
byte[] bufferRef = buffer;
if (!NativeMethods.ReadProcessMemory(handle, location.Location,
buffer, buffer.Length, out bytesRead))
continue; // Error while reading
buffer = bufferRef;
if (bytesRead != buffer.Length) continue;
只簡單的工作。內存讀取和所有!所以發生的只是由於某種原因,buffer
變量失去了對實際緩衝區的引用。它讓我感到困惑。
這種行爲的東西,我做錯了的結果(例如錯誤的P/Invoke),它是危險(內存泄露?),和解釋的?
我的配置:
- 的.NET Framework 4.0
- 的Visual Studio 2012專業版(版本11.0.51106.01更新1)
- 安裝了.NET Framework 4.5.50709
- 運行作爲管理員
- 在發行版和調試版本中均發生,兩者均在visual studio host ex ecutable和常規的構建可執行文件。
- 視窗7 64位
- 過程我讀存儲器從是32位
- 構建配置:平臺:任何CPU
編輯:完整NativeMethods I類使用可以在這裏找到:http://paste2.org/p/2770271
編輯2:我添加了我遵循的簡單步驟編輯解決問題作爲答案,可以發現here。
旁註:Marshal.GetLastWin32Error()返回1008,它在啓動時返回相同的代碼。 – Aidiakapi
您的MEMORY_BASIC_INFORMATION聲明是錯誤的,RegionSize是一個UIntPtr,而不是ulong。不知道如何可以破壞堆棧。 –
@HansPassant謝謝,這指出我在解決問題的方向:)! – Aidiakapi