ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/RomCheater/trunk/Win32/Sojaner.MemoryScanner/MemoryScanner.cs
Revision: 200
Committed: Thu May 31 07:29:44 2012 UTC (11 years, 6 months ago) by william
File size: 14889 byte(s)
Log Message:

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