ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/RomCheater/trunk/Win32/Sojaner.MemoryScanner/MemoryScanner-r204.cs
Revision: 251
Committed: Sun Jun 3 16:32:58 2012 UTC (11 years ago) by william
File size: 19577 byte(s)
Log Message:
+ add variant classes that use MemoryScanner from r204

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