ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/RomCheater/trunk/Win32/Sojaner.MemoryScanner/MemoryScanner.cs
Revision: 350
Committed: Sat Jun 9 20:07:18 2012 UTC (11 years, 8 months ago) by william
File size: 17207 byte(s)
Log Message:
+redeclaration

File Contents

# User Rev Content
1 william 88 using System;
2     using System.Collections.Generic;
3     using System.Text;
4     using System.Diagnostics;
5     using System.Threading;
6     using System.Runtime.InteropServices;
7 william 156 using RomCheater.Logging;
8 william 162 using System.IO;
9 william 231 using Sojaner.MemoryScanner.MemoryProviers;
10 william 284 using Microsoft.Win32.SafeHandles;
11 william 88
12     namespace Sojaner.MemoryScanner
13     {
14     // code borrowed from: http://www.codeproject.com/KB/cs/sojaner_memory_scanner.aspx
15     #region ProcessMemoryReader class
16     //Thanks goes to Arik Poznanski for P/Invokes and methods needed to read and write the Memory
17     //For more information refer to "Minesweeper, Behind the scenes" article by Arik Poznanski at Codeproject.com
18 william 257 internal class ProcessMemoryReader : IMemoryReader, IMemoryWriter, IFileWriter
19 william 88 {
20    
21     public ProcessMemoryReader()
22     {
23     }
24    
25     /// <summary>
26     /// Process from which to read
27     /// </summary>
28     public Process ReadProcess
29     {
30     get
31     {
32     return m_ReadProcess;
33     }
34     set
35     {
36     m_ReadProcess = value;
37     }
38     }
39    
40     private Process m_ReadProcess = null;
41 william 286
42     //SafeWaitHandle handle;
43 william 198 private static IntPtr m_hProcess = IntPtr.Zero;
44 william 88
45     public void OpenProcess()
46     {
47 william 247 try
48     {
49     // m_hProcess = ProcessMemoryReaderApi.OpenProcess(ProcessMemoryReaderApi.PROCESS_VM_READ, 1, (uint)m_ReadProcess.Id);
50     ProcessMemoryReaderApi.ProcessAccessType access;
51     access = ProcessMemoryReaderApi.ProcessAccessType.PROCESS_VM_READ
52     | ProcessMemoryReaderApi.ProcessAccessType.PROCESS_VM_WRITE
53     | ProcessMemoryReaderApi.ProcessAccessType.PROCESS_VM_OPERATION;
54     m_hProcess = ProcessMemoryReaderApi.OpenProcess((uint)access, 1, (uint)m_ReadProcess.Id);
55     }
56     catch (SEHException ex)
57     {
58     logger.Error.WriteLine("WriteProcessMemoryToFile() SEHException was thrown: (0x{0:x8}) - {1}", ex.ErrorCode, ex.Message);
59     logger.Error.WriteLine(ex.ToString());
60     throw ex;
61     }
62     catch (Exception ex)
63     {
64     logger.Error.WriteLine(ex.ToString());
65     throw ex;
66     }
67 william 88 }
68    
69     public void CloseHandle()
70     {
71     try
72     {
73 william 286 SafeWaitHandle handle = new SafeWaitHandle(m_hProcess, false);
74     if (handle.IsInvalid) { return; }
75 william 284 if (handle.IsClosed) { return; }
76     handle.Close();
77     //string stack_trace = System.Environment.StackTrace;
78     //int iRetValue;
79     //iRetValue = ProcessMemoryReaderApi.CloseHandle(m_hProcess);
80     //if (iRetValue == 0)
81     //{
82     // throw new Exception("CloseHandle failed");
83     //}
84 william 88 }
85 william 245 catch (SEHException ex)
86     {
87 william 247 logger.Error.WriteLine("WriteProcessMemoryToFile() SEHException was thrown: (0x{0:x8}) - {1}", ex.ErrorCode, ex.Message);
88     logger.Error.WriteLine(ex.ToString());
89 william 245 throw ex;
90     }
91 william 88 catch (Exception ex)
92     {
93 william 247 logger.Error.WriteLine(ex.ToString());
94 william 88 throw ex;
95     }
96     }
97     /// <summary>
98     /// ProcessMemoryReader is a class that enables direct reading a process memory
99     /// </summary>
100 william 231 private class ProcessMemoryReaderApi
101 william 88 {
102     // constants information can be found in <winnt.h>
103     [Flags]
104     public enum ProcessAccessType
105     {
106     PROCESS_TERMINATE = (0x0001),
107     PROCESS_CREATE_THREAD = (0x0002),
108     PROCESS_SET_SESSIONID = (0x0004),
109     PROCESS_VM_OPERATION = (0x0008),
110     PROCESS_VM_READ = (0x0010),
111     PROCESS_VM_WRITE = (0x0020),
112     PROCESS_DUP_HANDLE = (0x0040),
113     PROCESS_CREATE_PROCESS = (0x0080),
114     PROCESS_SET_QUOTA = (0x0100),
115     PROCESS_SET_INFORMATION = (0x0200),
116     PROCESS_QUERY_INFORMATION = (0x0400)
117     }
118    
119     // function declarations are found in the MSDN and in <winbase.h>
120    
121     // HANDLE OpenProcess(
122     // DWORD dwDesiredAccess, // access flag
123     // BOOL bInheritHandle, // handle inheritance option
124     // DWORD dwProcessId // process identifier
125     // );
126     [DllImport("kernel32.dll")]
127     public static extern IntPtr OpenProcess(UInt32 dwDesiredAccess, Int32 bInheritHandle, UInt32 dwProcessId);
128    
129     // BOOL CloseHandle(
130     // HANDLE hObject // handle to object
131     // );
132     [DllImport("kernel32.dll")]
133     public static extern Int32 CloseHandle(IntPtr hObject);
134    
135     // BOOL ReadProcessMemory(
136     // HANDLE hProcess, // handle to the process
137     // LPCVOID lpBaseAddress, // base of memory area
138     // LPVOID lpBuffer, // data buffer
139     // SIZE_T nSize, // number of bytes to read
140     // SIZE_T * lpNumberOfBytesRead // number of bytes read
141     // );
142 william 350 [DllImport("kernel32.dll", SetLastError = true)]
143     public static extern bool ReadProcessMemory(
144     IntPtr hProcess,
145     IntPtr lpBaseAddress,
146     [Out] byte[] lpBuffer,
147     uint dwSize,
148     out int lpNumberOfBytesRead
149     );
150 william 88
151     // BOOL WriteProcessMemory(
152     // HANDLE hProcess, // handle to process
153     // LPVOID lpBaseAddress, // base of memory area
154     // LPCVOID lpBuffer, // data buffer
155     // SIZE_T nSize, // count of bytes to write
156     // SIZE_T * lpNumberOfBytesWritten // count of bytes written
157     // );
158 william 350 [DllImport("kernel32.dll", SetLastError = true)]
159     public static extern bool WriteProcessMemory(
160     IntPtr hProcess,
161     IntPtr lpBaseAddress,
162     byte[] lpBuffer,
163     uint nSize,
164     out UIntPtr lpNumberOfBytesWritten);
165 william 88
166    
167     }
168 william 231
169     #region IMemoryReader Members
170 william 249 #region public bool ReadFirstNonZeroByte(uint MemoryAddress, uint bytesToRead, out int address)
171     public bool ReadFirstNonZeroByte(int MemoryAddress, uint bytesToRead, out int address)
172 william 231 {
173     //logger.Info.WriteLine("Dumping memory (0x{0:x8}-0x{1:x8}) from pid=({2})", MemoryAddress, MemoryAddress + bytesToRead, string.Format("0x{0:x4} {1}.exe", ppid.Id, ppid.ProcessName));
174     address = 0;
175 william 235 uint byte_alignment = 1;
176 william 231 // get common init parameters
177     //InitMemoryDump(out byte_alignment);
178 william 249 int mem_address = MemoryAddress;
179 william 235 uint _bytesToRead = bytesToRead;
180 william 231 byte[] buffer = new byte[] { };
181     try
182     {
183     //using (MemoryStream ms = new MemoryStream())
184     //{
185     // //BinaryWriter bw = new BinaryWriter(ms);
186     // //foreach (byte b in data) { bw.Write(b); }
187 william 235 for (uint i = 0; i <= bytesToRead; )
188 william 231 {
189     if (_bytesToRead < byte_alignment)
190     {
191     _bytesToRead = bytesToRead;
192     buffer = new byte[_bytesToRead];
193     }
194     else
195     {
196     _bytesToRead = byte_alignment;
197     buffer = new byte[byte_alignment];
198     }
199     int bytesRead = 0;
200     ReadProcessMemory(mem_address, _bytesToRead, out bytesRead, out buffer);
201 william 245 if (buffer.Length == 0 && bytesRead == 0)
202     {
203     throw new Exception(string.Format("Failed to read memory from process: {0}", ReadProcess.ToString()));
204     }
205 william 231 //bw.Write(buffer);
206     //bw.Flush();
207     if (_bytesToRead < byte_alignment)
208     {
209     i += _bytesToRead;
210 william 249 mem_address += (int)_bytesToRead;
211 william 231 }
212     else
213     {
214     i += byte_alignment;
215 william 249 mem_address += (int)byte_alignment;
216 william 231 }
217     for (uint j = 0; j < buffer.Length; j++)
218     {
219     if (buffer[j] != 0)
220     {
221     address = mem_address;
222     break;
223     }
224     }
225     if (address != 0)
226     break;
227     }
228     // bw.Close();
229     //}
230     //logger.Info.WriteLine("Succefully dumped memory (0x{0:x8}-0x{1:x8}) from pid=({2})", MemoryAddress, MemoryAddress + bytesToRead, string.Format("0x{0:x4} {1}.exe", ppid.Id, ppid.ProcessName));
231     return true;
232     }
233 william 247 catch (SEHException ex)
234     {
235     logger.Error.WriteLine("ReadFirstNonZeroByte() SEHException was thrown: (0x{0:x8}) - {1}", ex.ErrorCode, ex.Message);
236     logger.Error.WriteLine(ex.ToString());
237     throw ex;
238     }
239 william 231 catch (OutOfMemoryException ex)
240     {
241 william 247 logger.Error.WriteLine("ReadFirstNonZeroByte(): OutOfMemoryException");
242 william 231 logger.Error.WriteLine(ex.ToString());
243     }
244     catch (Exception ex)
245     {
246 william 247 logger.Error.WriteLine("ReadFirstNonZeroByte(): Exception");
247 william 231 logger.Error.WriteLine(ex.ToString());
248 william 247 throw ex;
249 william 231 }
250     return false;
251     }
252 william 249 #endregion
253     #region public void ReadProcessMemory(int MemoryAddress, uint bytesToRead, out int bytesRead, out byte[] data)
254     public void ReadProcessMemory(int MemoryAddress, uint bytesToRead, out int bytesRead, out byte[] data)
255 william 231 {
256 william 350 ReadProcessMemory((uint)MemoryAddress, bytesToRead, out bytesRead, out data);
257     }
258     public void ReadProcessMemory(uint MemoryAddress, uint bytesToRead, out int bytesRead, out byte[] data)
259     {
260 william 247 try
261     {
262 william 254 byte[] buffer = new byte[bytesToRead];
263 william 350 ProcessMemoryReader.ProcessMemoryReaderApi.ReadProcessMemory(m_hProcess, (IntPtr)MemoryAddress, buffer, bytesToRead, out bytesRead);
264 william 247 data = buffer;
265     }
266     catch (SEHException ex)
267     {
268     logger.Error.WriteLine("ReadProcessMemory() SEHException was thrown: (0x{0:x8}) - {1}", ex.ErrorCode, ex.Message);
269     logger.Error.WriteLine(ex.ToString());
270     throw ex;
271     }
272     catch (Exception ex)
273     {
274     logger.Error.WriteLine("ReadProcessMemory(): Exception");
275     logger.Error.WriteLine(ex.ToString());
276     throw ex;
277     }
278 william 231 }
279     #endregion
280 william 249 #endregion
281 william 231
282     #region IMemoryWriter Members
283 william 249 #region public void WriteProcessMemory(uint MemoryAddress, byte byteToWrite, out int bytesWritten)
284     public void WriteProcessMemory(int MemoryAddress, byte byteToWrite, out int bytesWritten)
285 william 350 {
286     WriteProcessMemory(MemoryAddress, new byte[] { byteToWrite }, out bytesWritten);
287     }
288     public void WriteProcessMemory(uint MemoryAddress, byte byteToWrite, out uint bytesWritten)
289 william 231 {
290     WriteProcessMemory(MemoryAddress, new byte[] { byteToWrite }, out bytesWritten);
291     }
292 william 249 #endregion
293     #region public void WriteProcessMemory(uint MemoryAddress, byte[] bytesToWrite, out int bytesWritten)
294     public void WriteProcessMemory(int MemoryAddress, byte[] bytesToWrite, out int bytesWritten)
295 william 231 {
296 william 350 uint _bytesWritten = 0;
297     WriteProcessMemory((uint)MemoryAddress, bytesToWrite, out _bytesWritten);
298     bytesWritten = (int)_bytesWritten;
299     }
300     public void WriteProcessMemory(uint MemoryAddress, byte[] bytesToWrite, out uint bytesWritten)
301     {
302 william 247 try
303     {
304 william 350 UIntPtr ptrBytesWritten;
305 william 249 ProcessMemoryReaderApi.WriteProcessMemory(m_hProcess, (IntPtr)MemoryAddress, bytesToWrite, (uint)bytesToWrite.Length, out ptrBytesWritten);
306 william 350 bytesWritten = ptrBytesWritten.ToUInt32();
307 william 247 }
308     catch (SEHException ex)
309     {
310     logger.Error.WriteLine("WriteProcessMemory() SEHException was thrown: (0x{0:x8}) - {1}", ex.ErrorCode, ex.Message);
311     logger.Error.WriteLine(ex.ToString());
312     throw ex;
313     }
314     catch (Exception ex)
315     {
316    
317     logger.Error.WriteLine("WriteProcessMemory() Exception");
318     logger.Error.WriteLine(ex.ToString());
319     bytesWritten = 0;
320     throw ex;
321     }
322 william 231 }
323 william 249 #endregion
324 william 231 #endregion
325    
326     #region IFileWriter Members
327 william 249 #region public bool WriteProcessMemoryToFile(string filename, uint MemoryAddress, uint bytesToRead, out int bytesRead)
328     public bool WriteProcessMemoryToFile(string filename, int MemoryAddress, uint bytesToRead, out int bytesRead)
329 william 231 {
330     //logger.Info.WriteLine("Dumping memory (0x{0:x8}-0x{1:x8}) from pid=({3}) to file {2}", MemoryAddress, MemoryAddress + bytesToRead, filename, string.Format("0x{0:x4} {1}.exe", ppid.Id, ppid.ProcessName));
331     bytesRead = 0;
332 william 235 uint byte_alignment = 102400;
333 william 249 int address = MemoryAddress;
334 william 235 uint _bytesToRead = bytesToRead;
335 william 231 byte[] buffer = new byte[] { };
336     try
337     {
338     FileInfo fi = new FileInfo(filename);
339     if (fi.Exists)
340     fi.Delete();
341     using (FileStream fs = new FileStream(filename, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.ReadWrite))
342     {
343     BinaryWriter bw = new BinaryWriter(fs);
344     //foreach (byte b in data) { bw.Write(b); }
345    
346 william 235 for (uint i = 0; i <= bytesToRead; )
347 william 231 {
348     if (_bytesToRead < byte_alignment)
349     {
350     _bytesToRead = bytesToRead;
351     buffer = new byte[_bytesToRead];
352     }
353     else
354     {
355     _bytesToRead = byte_alignment;
356     buffer = new byte[byte_alignment];
357     }
358     ReadProcessMemory(address, _bytesToRead, out bytesRead, out buffer);
359     bw.Write(buffer);
360     bw.Flush();
361    
362     if (_bytesToRead < byte_alignment)
363     {
364     i += _bytesToRead;
365 william 249 address += (int)_bytesToRead;
366 william 231 }
367     else
368     {
369     i += byte_alignment;
370 william 249 address += (int)byte_alignment;
371 william 231 }
372    
373    
374     }
375     bw.Close();
376     }
377     logger.Info.WriteLine("Succefully dumped memory (0x{0:x8}-0x{1:x8}) from pid=({3}) to file {2}", MemoryAddress, MemoryAddress + bytesToRead, filename, string.Format("0x{0:x4} {1}.exe", ReadProcess.Id, ReadProcess.ProcessName));
378     return true;
379     }
380 william 247 catch (SEHException ex)
381     {
382     logger.Error.WriteLine("WriteProcessMemoryToFile() SEHException was thrown: (0x{0:x8}) - {1}", ex.ErrorCode, ex.Message);
383     logger.Error.WriteLine(ex.ToString());
384     throw ex;
385     }
386 william 231 catch (OutOfMemoryException ex)
387     {
388 william 247 logger.Error.WriteLine("WriteProcessMemoryToFile(): Exception");
389 william 231 logger.Error.WriteLine(ex.ToString());
390     }
391     catch (Exception ex)
392     {
393 william 247 logger.Error.WriteLine("WriteProcessMemoryToFile(): Exception");
394 william 231 logger.Error.WriteLine(ex.ToString());
395 william 247 throw ex;
396 william 231 }
397     return false;
398     }
399     #endregion
400 william 249 #endregion
401 william 88 }
402     #endregion
403     }