/[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 284 - (show annotations) (download)
Tue Jun 5 01:50:38 2012 UTC (9 years, 3 months ago) by william
File size: 16249 byte(s)
use SafeWaitHandle in when closing process handle

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

  ViewVC Help
Powered by ViewVC 1.1.22