/[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 204 - (hide annotations) (download)
Thu May 31 09:08:24 2012 UTC (8 years, 9 months ago) by william
File size: 19257 byte(s)
DumpMemoryToByteArray(): set byte_alignment to 1

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

  ViewVC Help
Powered by ViewVC 1.1.22