ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/RomCheater/trunk/Win32/Sojaner.MemoryScanner/MemoryScanner.cs
Revision: 247
Committed: Sun Jun 3 15:27:23 2012 UTC (11 years, 8 months ago) by william
File size: 15280 byte(s)
Log Message:
+ catch, log and throw errors

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