ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/RomCheater/trunk/Win32/Sojaner.MemoryScanner/MemoryScanner.cs
Revision: 231
Committed: Sun Jun 3 12:36:47 2012 UTC (11 years, 6 months ago) by william
File size: 17701 byte(s)
Log Message:
+ overhaul memory scanner

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