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, 5 months ago) by william
File size: 17207 byte(s)
Log Message:
+redeclaration

File Contents

# Content
1 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 using RomCheater.Logging;
8 using System.IO;
9 using Sojaner.MemoryScanner.MemoryProviers;
10 using Microsoft.Win32.SafeHandles;
11
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 internal class ProcessMemoryReader : IMemoryReader, IMemoryWriter, IFileWriter
19 {
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
42 //SafeWaitHandle handle;
43 private static IntPtr m_hProcess = IntPtr.Zero;
44
45 public void OpenProcess()
46 {
47 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 }
68
69 public void CloseHandle()
70 {
71 try
72 {
73 SafeWaitHandle handle = new SafeWaitHandle(m_hProcess, false);
74 if (handle.IsInvalid) { return; }
75 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 }
85 catch (SEHException ex)
86 {
87 logger.Error.WriteLine("WriteProcessMemoryToFile() SEHException was thrown: (0x{0:x8}) - {1}", ex.ErrorCode, ex.Message);
88 logger.Error.WriteLine(ex.ToString());
89 throw ex;
90 }
91 catch (Exception ex)
92 {
93 logger.Error.WriteLine(ex.ToString());
94 throw ex;
95 }
96 }
97 /// <summary>
98 /// ProcessMemoryReader is a class that enables direct reading a process memory
99 /// </summary>
100 private class ProcessMemoryReaderApi
101 {
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 [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
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 [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
166
167 }
168
169 #region IMemoryReader Members
170 #region public bool ReadFirstNonZeroByte(uint MemoryAddress, uint bytesToRead, out int address)
171 public bool ReadFirstNonZeroByte(int MemoryAddress, uint bytesToRead, out int address)
172 {
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 uint byte_alignment = 1;
176 // get common init parameters
177 //InitMemoryDump(out byte_alignment);
178 int mem_address = MemoryAddress;
179 uint _bytesToRead = bytesToRead;
180 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 for (uint i = 0; i <= bytesToRead; )
188 {
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 if (buffer.Length == 0 && bytesRead == 0)
202 {
203 throw new Exception(string.Format("Failed to read memory from process: {0}", ReadProcess.ToString()));
204 }
205 //bw.Write(buffer);
206 //bw.Flush();
207 if (_bytesToRead < byte_alignment)
208 {
209 i += _bytesToRead;
210 mem_address += (int)_bytesToRead;
211 }
212 else
213 {
214 i += byte_alignment;
215 mem_address += (int)byte_alignment;
216 }
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 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 catch (OutOfMemoryException ex)
240 {
241 logger.Error.WriteLine("ReadFirstNonZeroByte(): OutOfMemoryException");
242 logger.Error.WriteLine(ex.ToString());
243 }
244 catch (Exception ex)
245 {
246 logger.Error.WriteLine("ReadFirstNonZeroByte(): Exception");
247 logger.Error.WriteLine(ex.ToString());
248 throw ex;
249 }
250 return false;
251 }
252 #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 {
256 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 try
261 {
262 byte[] buffer = new byte[bytesToRead];
263 ProcessMemoryReader.ProcessMemoryReaderApi.ReadProcessMemory(m_hProcess, (IntPtr)MemoryAddress, buffer, bytesToRead, out bytesRead);
264 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 }
279 #endregion
280 #endregion
281
282 #region IMemoryWriter Members
283 #region public void WriteProcessMemory(uint MemoryAddress, byte byteToWrite, out int bytesWritten)
284 public void WriteProcessMemory(int MemoryAddress, byte byteToWrite, out int bytesWritten)
285 {
286 WriteProcessMemory(MemoryAddress, new byte[] { byteToWrite }, out bytesWritten);
287 }
288 public void WriteProcessMemory(uint MemoryAddress, byte byteToWrite, out uint bytesWritten)
289 {
290 WriteProcessMemory(MemoryAddress, new byte[] { byteToWrite }, out bytesWritten);
291 }
292 #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 {
296 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 try
303 {
304 UIntPtr ptrBytesWritten;
305 ProcessMemoryReaderApi.WriteProcessMemory(m_hProcess, (IntPtr)MemoryAddress, bytesToWrite, (uint)bytesToWrite.Length, out ptrBytesWritten);
306 bytesWritten = ptrBytesWritten.ToUInt32();
307 }
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 }
323 #endregion
324 #endregion
325
326 #region IFileWriter Members
327 #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 {
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 uint byte_alignment = 102400;
333 int address = MemoryAddress;
334 uint _bytesToRead = bytesToRead;
335 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 for (uint i = 0; i <= bytesToRead; )
347 {
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 address += (int)_bytesToRead;
366 }
367 else
368 {
369 i += byte_alignment;
370 address += (int)byte_alignment;
371 }
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 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 catch (OutOfMemoryException ex)
387 {
388 logger.Error.WriteLine("WriteProcessMemoryToFile(): Exception");
389 logger.Error.WriteLine(ex.ToString());
390 }
391 catch (Exception ex)
392 {
393 logger.Error.WriteLine("WriteProcessMemoryToFile(): Exception");
394 logger.Error.WriteLine(ex.ToString());
395 throw ex;
396 }
397 return false;
398 }
399 #endregion
400 #endregion
401 }
402 #endregion
403 }