ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/RomCheater/trunk/Win32/Sojaner.MemoryScanner/MemoryScanner.cs
Revision: 286
Committed: Tue Jun 5 02:19:13 2012 UTC (10 years, 11 months ago) by william
File size: 16327 byte(s)
Log Message:
+ more wip

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")]
143 public static extern Int32 ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [In, Out] byte[] buffer, UInt32 size, out IntPtr lpNumberOfBytesRead);
144
145 // BOOL WriteProcessMemory(
146 // HANDLE hProcess, // handle to process
147 // LPVOID lpBaseAddress, // base of memory area
148 // LPCVOID lpBuffer, // data buffer
149 // SIZE_T nSize, // count of bytes to write
150 // SIZE_T * lpNumberOfBytesWritten // count of bytes written
151 // );
152 [DllImport("kernel32.dll")]
153 public static extern Int32 WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [In, Out] byte[] buffer, UInt32 size, out IntPtr lpNumberOfBytesWritten);
154
155
156 }
157
158 #region IMemoryReader Members
159 #region public bool ReadFirstNonZeroByte(uint MemoryAddress, uint bytesToRead, out int address)
160 public bool ReadFirstNonZeroByte(int MemoryAddress, uint bytesToRead, out int address)
161 {
162 //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));
163 address = 0;
164 uint byte_alignment = 1;
165 // get common init parameters
166 //InitMemoryDump(out byte_alignment);
167 int mem_address = MemoryAddress;
168 uint _bytesToRead = bytesToRead;
169 byte[] buffer = new byte[] { };
170 try
171 {
172 //using (MemoryStream ms = new MemoryStream())
173 //{
174 // //BinaryWriter bw = new BinaryWriter(ms);
175 // //foreach (byte b in data) { bw.Write(b); }
176 for (uint i = 0; i <= bytesToRead; )
177 {
178 if (_bytesToRead < byte_alignment)
179 {
180 _bytesToRead = bytesToRead;
181 buffer = new byte[_bytesToRead];
182 }
183 else
184 {
185 _bytesToRead = byte_alignment;
186 buffer = new byte[byte_alignment];
187 }
188 int bytesRead = 0;
189 ReadProcessMemory(mem_address, _bytesToRead, out bytesRead, out buffer);
190 if (buffer.Length == 0 && bytesRead == 0)
191 {
192 throw new Exception(string.Format("Failed to read memory from process: {0}", ReadProcess.ToString()));
193 }
194 //bw.Write(buffer);
195 //bw.Flush();
196 if (_bytesToRead < byte_alignment)
197 {
198 i += _bytesToRead;
199 mem_address += (int)_bytesToRead;
200 }
201 else
202 {
203 i += byte_alignment;
204 mem_address += (int)byte_alignment;
205 }
206 for (uint j = 0; j < buffer.Length; j++)
207 {
208 if (buffer[j] != 0)
209 {
210 address = mem_address;
211 break;
212 }
213 }
214 if (address != 0)
215 break;
216 }
217 // bw.Close();
218 //}
219 //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));
220 return true;
221 }
222 catch (SEHException ex)
223 {
224 logger.Error.WriteLine("ReadFirstNonZeroByte() SEHException was thrown: (0x{0:x8}) - {1}", ex.ErrorCode, ex.Message);
225 logger.Error.WriteLine(ex.ToString());
226 throw ex;
227 }
228 catch (OutOfMemoryException ex)
229 {
230 logger.Error.WriteLine("ReadFirstNonZeroByte(): OutOfMemoryException");
231 logger.Error.WriteLine(ex.ToString());
232 }
233 catch (Exception ex)
234 {
235 logger.Error.WriteLine("ReadFirstNonZeroByte(): Exception");
236 logger.Error.WriteLine(ex.ToString());
237 throw ex;
238 }
239 return false;
240 }
241 #endregion
242 #region public void ReadProcessMemory(int MemoryAddress, uint bytesToRead, out int bytesRead, out byte[] data)
243 public void ReadProcessMemory(int MemoryAddress, uint bytesToRead, out int bytesRead, out byte[] data)
244 {
245 try
246 {
247 byte[] buffer = new byte[bytesToRead];
248 IntPtr ptrBytesRead;
249 ProcessMemoryReader.ProcessMemoryReaderApi.ReadProcessMemory(m_hProcess, (IntPtr)MemoryAddress, buffer, bytesToRead, out ptrBytesRead);
250 bytesRead = ptrBytesRead.ToInt32();
251 data = buffer;
252 }
253 catch (SEHException ex)
254 {
255 logger.Error.WriteLine("ReadProcessMemory() SEHException was thrown: (0x{0:x8}) - {1}", ex.ErrorCode, ex.Message);
256 logger.Error.WriteLine(ex.ToString());
257 throw ex;
258 }
259 catch (Exception ex)
260 {
261 logger.Error.WriteLine("ReadProcessMemory(): Exception");
262 logger.Error.WriteLine(ex.ToString());
263 throw ex;
264 }
265 }
266 #endregion
267 #endregion
268
269 #region IMemoryWriter Members
270 #region public void WriteProcessMemory(uint MemoryAddress, byte byteToWrite, out int bytesWritten)
271 public void WriteProcessMemory(int MemoryAddress, byte byteToWrite, out int bytesWritten)
272 {
273 WriteProcessMemory(MemoryAddress, new byte[] { byteToWrite }, out bytesWritten);
274 }
275 #endregion
276 #region public void WriteProcessMemory(uint MemoryAddress, byte[] bytesToWrite, out int bytesWritten)
277 public void WriteProcessMemory(int MemoryAddress, byte[] bytesToWrite, out int bytesWritten)
278 {
279 try
280 {
281 IntPtr ptrBytesWritten;
282 ProcessMemoryReaderApi.WriteProcessMemory(m_hProcess, (IntPtr)MemoryAddress, bytesToWrite, (uint)bytesToWrite.Length, out ptrBytesWritten);
283 bytesWritten = ptrBytesWritten.ToInt32();
284 }
285 catch (SEHException ex)
286 {
287 logger.Error.WriteLine("WriteProcessMemory() SEHException was thrown: (0x{0:x8}) - {1}", ex.ErrorCode, ex.Message);
288 logger.Error.WriteLine(ex.ToString());
289 throw ex;
290 }
291 catch (Exception ex)
292 {
293
294 logger.Error.WriteLine("WriteProcessMemory() Exception");
295 logger.Error.WriteLine(ex.ToString());
296 bytesWritten = 0;
297 throw ex;
298 }
299 }
300 #endregion
301 #endregion
302
303 #region IFileWriter Members
304 #region public bool WriteProcessMemoryToFile(string filename, uint MemoryAddress, uint bytesToRead, out int bytesRead)
305 public bool WriteProcessMemoryToFile(string filename, int MemoryAddress, uint bytesToRead, out int bytesRead)
306 {
307 //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));
308 bytesRead = 0;
309 uint byte_alignment = 102400;
310 int address = MemoryAddress;
311 uint _bytesToRead = bytesToRead;
312 byte[] buffer = new byte[] { };
313 try
314 {
315 FileInfo fi = new FileInfo(filename);
316 if (fi.Exists)
317 fi.Delete();
318 using (FileStream fs = new FileStream(filename, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.ReadWrite))
319 {
320 BinaryWriter bw = new BinaryWriter(fs);
321 //foreach (byte b in data) { bw.Write(b); }
322
323 for (uint i = 0; i <= bytesToRead; )
324 {
325 if (_bytesToRead < byte_alignment)
326 {
327 _bytesToRead = bytesToRead;
328 buffer = new byte[_bytesToRead];
329 }
330 else
331 {
332 _bytesToRead = byte_alignment;
333 buffer = new byte[byte_alignment];
334 }
335 ReadProcessMemory(address, _bytesToRead, out bytesRead, out buffer);
336 bw.Write(buffer);
337 bw.Flush();
338
339 if (_bytesToRead < byte_alignment)
340 {
341 i += _bytesToRead;
342 address += (int)_bytesToRead;
343 }
344 else
345 {
346 i += byte_alignment;
347 address += (int)byte_alignment;
348 }
349
350
351 }
352 bw.Close();
353 }
354 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));
355 return true;
356 }
357 catch (SEHException ex)
358 {
359 logger.Error.WriteLine("WriteProcessMemoryToFile() SEHException was thrown: (0x{0:x8}) - {1}", ex.ErrorCode, ex.Message);
360 logger.Error.WriteLine(ex.ToString());
361 throw ex;
362 }
363 catch (OutOfMemoryException ex)
364 {
365 logger.Error.WriteLine("WriteProcessMemoryToFile(): Exception");
366 logger.Error.WriteLine(ex.ToString());
367 }
368 catch (Exception ex)
369 {
370 logger.Error.WriteLine("WriteProcessMemoryToFile(): Exception");
371 logger.Error.WriteLine(ex.ToString());
372 throw ex;
373 }
374 return false;
375 }
376 #endregion
377 #endregion
378 }
379 #endregion
380 }