ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/RomCheater/trunk/Win32/Sojaner.MemoryScanner/MemoryScanner.cs
Revision: 169
Committed: Mon May 28 08:49:42 2012 UTC (10 years, 10 months ago) by william
File size: 10869 byte(s)
Log Message:
+ add success/failure messages for ram dump

File Contents

# User Rev Content
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     private 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 william 162
72 william 169 public bool DumpMemory(Process ppid, string filename, uint MemoryAddress, uint bytesToRead, out int bytesRead)
73 william 88 {
74 william 169 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));
75 william 162 bytesRead = 0;
76 william 166 uint byte_alignment = 102400; // write to file in 100mb chunks
77 william 162 uint address = MemoryAddress;
78 william 167 uint _bytesToRead = bytesToRead;
79     byte[] buffer = new byte[] { };
80 william 156 try
81     {
82 william 167 FileInfo fi = new FileInfo(filename);
83     if (fi.Exists)
84     fi.Delete();
85     using (FileStream fs = new FileStream(filename, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.ReadWrite))
86 william 162 {
87     BinaryWriter bw = new BinaryWriter(fs);
88     //foreach (byte b in data) { bw.Write(b); }
89 william 88
90 william 167 for (uint i = 0; i <= bytesToRead;)
91 william 162 {
92 william 167 if (_bytesToRead < byte_alignment)
93     {
94     _bytesToRead = bytesToRead;
95     buffer = new byte[_bytesToRead];
96     }
97     else
98     {
99     _bytesToRead = byte_alignment;
100     buffer = new byte[byte_alignment];
101     }
102 william 162 IntPtr ptrBytesRead;
103 william 167 ProcessMemoryReaderApi.ReadProcessMemory(m_hProcess, (UIntPtr)address, buffer, _bytesToRead, out ptrBytesRead);
104 william 162 bytesRead = ptrBytesRead.ToInt32();
105     bw.Write(buffer);
106     bw.Flush();
107 william 167
108     if (_bytesToRead < byte_alignment)
109     {
110     i += _bytesToRead;
111     address += _bytesToRead;
112     }
113     else
114     {
115     i += byte_alignment;
116     address += byte_alignment;
117     }
118    
119    
120 william 162 }
121     bw.Close();
122     }
123 william 169 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));
124 william 162 return true;
125     }
126     catch (OutOfMemoryException ex)
127     {
128 william 169 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));
129 william 162 logger.Error.WriteLine("DumpMemory(): OutOfMemoryException");
130     logger.Error.WriteLine(ex.ToString());
131     }
132     catch (Exception ex)
133     {
134 william 169 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));
135 william 162 logger.Error.WriteLine("DumpMemory(): Exception");
136     logger.Error.WriteLine(ex.ToString());
137     }
138     return false;
139     }
140 william 88
141 william 162 public byte[] ReadProcessMemory(uint MemoryAddress, uint bytesToRead, out int bytesRead)
142     {
143     bytesRead = 0;
144     uint address = MemoryAddress;
145     List<byte[]> aligned_array_list = new List<byte[]>();
146     try
147     {
148     uint byte_alignment = 512; // 4mb alignment
149    
150 william 88
151 william 162 for (uint i = 0; i <= bytesToRead; i += byte_alignment)
152     {
153     byte[] buffer = new byte[byte_alignment];
154     uint bytes_to_read = byte_alignment;
155     IntPtr ptrBytesRead;
156 william 164 ProcessMemoryReaderApi.ReadProcessMemory(m_hProcess, (UIntPtr)address, buffer, bytes_to_read, out ptrBytesRead);
157 william 162 bytesRead = ptrBytesRead.ToInt32();
158     aligned_array_list.Add(buffer);
159     address += byte_alignment;
160     }
161    
162     //List<byte> big_array = new List<byte>();
163     //foreach (byte[] aligned_array in aligned_array_list) { foreach (byte b in aligned_array) { big_array.Add(b); } }
164    
165     return new byte[] { };
166 william 156 }
167     catch (OutOfMemoryException ex)
168     {
169     logger.Error.WriteLine("ReadProcessMemory(): OutOfMemoryException");
170     logger.Error.WriteLine(ex.ToString());
171     }
172     catch (Exception ex)
173     {
174     logger.Error.WriteLine("ReadProcessMemory(): Exception");
175     logger.Error.WriteLine(ex.ToString());
176     }
177     return new byte[] { };
178 william 88 }
179    
180 william 164 public void WriteProcessMemory(UIntPtr MemoryAddress, byte[] bytesToWrite, out int bytesWritten)
181 william 88 {
182     IntPtr ptrBytesWritten;
183     ProcessMemoryReaderApi.WriteProcessMemory(m_hProcess, MemoryAddress, bytesToWrite, (uint)bytesToWrite.Length, out ptrBytesWritten);
184    
185     bytesWritten = ptrBytesWritten.ToInt32();
186     }
187    
188    
189     /// <summary>
190     /// ProcessMemoryReader is a class that enables direct reading a process memory
191     /// </summary>
192     class ProcessMemoryReaderApi
193     {
194     // constants information can be found in <winnt.h>
195     [Flags]
196     public enum ProcessAccessType
197     {
198     PROCESS_TERMINATE = (0x0001),
199     PROCESS_CREATE_THREAD = (0x0002),
200     PROCESS_SET_SESSIONID = (0x0004),
201     PROCESS_VM_OPERATION = (0x0008),
202     PROCESS_VM_READ = (0x0010),
203     PROCESS_VM_WRITE = (0x0020),
204     PROCESS_DUP_HANDLE = (0x0040),
205     PROCESS_CREATE_PROCESS = (0x0080),
206     PROCESS_SET_QUOTA = (0x0100),
207     PROCESS_SET_INFORMATION = (0x0200),
208     PROCESS_QUERY_INFORMATION = (0x0400)
209     }
210    
211     // function declarations are found in the MSDN and in <winbase.h>
212    
213     // HANDLE OpenProcess(
214     // DWORD dwDesiredAccess, // access flag
215     // BOOL bInheritHandle, // handle inheritance option
216     // DWORD dwProcessId // process identifier
217     // );
218     [DllImport("kernel32.dll")]
219     public static extern IntPtr OpenProcess(UInt32 dwDesiredAccess, Int32 bInheritHandle, UInt32 dwProcessId);
220    
221     // BOOL CloseHandle(
222     // HANDLE hObject // handle to object
223     // );
224     [DllImport("kernel32.dll")]
225     public static extern Int32 CloseHandle(IntPtr hObject);
226    
227     // BOOL ReadProcessMemory(
228     // HANDLE hProcess, // handle to the process
229     // LPCVOID lpBaseAddress, // base of memory area
230     // LPVOID lpBuffer, // data buffer
231     // SIZE_T nSize, // number of bytes to read
232     // SIZE_T * lpNumberOfBytesRead // number of bytes read
233     // );
234     [DllImport("kernel32.dll")]
235 william 164 public static extern Int32 ReadProcessMemory(IntPtr hProcess, UIntPtr lpBaseAddress, [In, Out] byte[] buffer, UInt32 size, out IntPtr lpNumberOfBytesRead);
236 william 88
237     // BOOL WriteProcessMemory(
238     // HANDLE hProcess, // handle to process
239     // LPVOID lpBaseAddress, // base of memory area
240     // LPCVOID lpBuffer, // data buffer
241     // SIZE_T nSize, // count of bytes to write
242     // SIZE_T * lpNumberOfBytesWritten // count of bytes written
243     // );
244     [DllImport("kernel32.dll")]
245 william 164 public static extern Int32 WriteProcessMemory(IntPtr hProcess, UIntPtr lpBaseAddress, [In, Out] byte[] buffer, UInt32 size, out IntPtr lpNumberOfBytesWritten);
246 william 88
247    
248     }
249     }
250     #endregion
251     }