/[RomCheater]/trunk/Win32/Sojaner.MemoryScanner/MemoryScanner.cs
ViewVC logotype

Contents of /trunk/Win32/Sojaner.MemoryScanner/MemoryScanner.cs

Parent Directory Parent Directory | Revision Log Revision Log


Revision 351 - (show annotations) (download)
Sat Jun 9 20:52:19 2012 UTC (9 years, 3 months ago) by william
File size: 18930 byte(s)

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

  ViewVC Help
Powered by ViewVC 1.1.22