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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 231 - (hide annotations) (download)
Sun Jun 3 12:36:47 2012 UTC (8 years, 7 months ago) by william
File size: 17701 byte(s)
+ overhaul memory scanner

1 william 88 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 william 156 using RomCheater.Logging;
8 william 162 using System.IO;
9 william 231 using Sojaner.MemoryScanner.MemoryProviers;
10 william 88
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 william 231 internal class ProcessMemoryReader : IMemoryReader, IMemoryWriter, IFileWriter
18 william 88 {
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 william 198 private static IntPtr m_hProcess = IntPtr.Zero;
42 william 88
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 william 162
72 william 231
73     #region RamDumper
74     //private interface IRamDumper
75 william 229 //{
76 william 231 // 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 william 229 //}
79 william 231 private class RamDumper
80 william 203 {
81 william 231 public RamDumper() { }
82 william 198 #region IRamDumper members
83     #region DumpMemoryToByteArray
84 william 229 public void DumpMemoryToByteArray(Process ppid, uint MemoryAddress, uint bytesToRead, out int bytesRead, out byte[] data)
85 william 162 {
86 william 229 data = new byte[] { };
87 william 200 //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 william 198 bytesRead = 0;
89 william 204 uint byte_alignment = 1;
90 william 198 // get common init parameters
91 william 204 //InitMemoryDump(out byte_alignment);
92 william 198 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 william 88
102 william 198 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 william 229 data = ms.ToArray();
135 william 198 }
136 william 200 //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 william 198 }
138     catch (OutOfMemoryException ex)
139 william 162 {
140 william 198 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 william 162 }
144 william 198 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 william 156 }
151 william 198 #endregion
152     #endregion
153 william 88 }
154 william 198 #endregion
155 william 88 /// <summary>
156     /// ProcessMemoryReader is a class that enables direct reading a process memory
157     /// </summary>
158 william 231 private class ProcessMemoryReaderApi
159 william 88 {
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 william 164 public static extern Int32 ReadProcessMemory(IntPtr hProcess, UIntPtr lpBaseAddress, [In, Out] byte[] buffer, UInt32 size, out IntPtr lpNumberOfBytesRead);
202 william 88
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 william 164 public static extern Int32 WriteProcessMemory(IntPtr hProcess, UIntPtr lpBaseAddress, [In, Out] byte[] buffer, UInt32 size, out IntPtr lpNumberOfBytesWritten);
212 william 88
213    
214     }
215 william 231
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 william 88 }
384     #endregion
385     }

  ViewVC Help
Powered by ViewVC 1.1.22