ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/RomCheater/trunk/Win32/Sojaner.MemoryScanner/MemoryScanner.cs
Revision: 235
Committed: Sun Jun 3 12:44:26 2012 UTC (11 years, 5 months ago) by william
File size: 17657 byte(s)
Log Message:
change int in method to uint

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, uint 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 uint byte_alignment = 1;
222 // get common init parameters
223 //InitMemoryDump(out byte_alignment);
224 uint mem_address = MemoryAddress;
225 uint _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 (uint 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, uint bytesToRead, out int bytesRead, out byte[] data)
290 {
291 byte[] buffer = new byte[] { };
292 IntPtr ptrBytesRead;
293 ProcessMemoryReader.ProcessMemoryReaderApi.ReadProcessMemory(m_hProcess, (UIntPtr)MemoryAddress, buffer, bytesToRead, out ptrBytesRead);
294 bytesRead = ptrBytesRead.ToInt32();
295 data = buffer;
296 }
297 #endregion
298
299 #region IMemoryWriter Members
300 public void WriteProcessMemory(uint MemoryAddress, byte byteToWrite, out int bytesWritten)
301 {
302 WriteProcessMemory(MemoryAddress, new byte[] { byteToWrite }, out bytesWritten);
303 }
304 public void WriteProcessMemory(uint MemoryAddress, byte[] bytesToWrite, out int bytesWritten)
305 {
306 IntPtr ptrBytesWritten;
307 ProcessMemoryReaderApi.WriteProcessMemory(m_hProcess, (UIntPtr)MemoryAddress, bytesToWrite, (uint)bytesToWrite.Length, out ptrBytesWritten);
308 bytesWritten = ptrBytesWritten.ToInt32();
309 }
310 #endregion
311
312 #region IFileWriter Members
313
314 public bool WriteProcessMemoryToFile(string filename, uint MemoryAddress, uint bytesToRead, out int bytesRead)
315 {
316 //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));
317 bytesRead = 0;
318 uint byte_alignment = 102400;
319 uint address = MemoryAddress;
320 uint _bytesToRead = bytesToRead;
321 byte[] buffer = new byte[] { };
322 try
323 {
324 FileInfo fi = new FileInfo(filename);
325 if (fi.Exists)
326 fi.Delete();
327 using (FileStream fs = new FileStream(filename, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.ReadWrite))
328 {
329 BinaryWriter bw = new BinaryWriter(fs);
330 //foreach (byte b in data) { bw.Write(b); }
331
332 for (uint i = 0; i <= bytesToRead; )
333 {
334 if (_bytesToRead < byte_alignment)
335 {
336 _bytesToRead = bytesToRead;
337 buffer = new byte[_bytesToRead];
338 }
339 else
340 {
341 _bytesToRead = byte_alignment;
342 buffer = new byte[byte_alignment];
343 }
344 ReadProcessMemory(address, _bytesToRead, out bytesRead, out buffer);
345 bw.Write(buffer);
346 bw.Flush();
347
348 if (_bytesToRead < byte_alignment)
349 {
350 i += _bytesToRead;
351 address += (uint)_bytesToRead;
352 }
353 else
354 {
355 i += byte_alignment;
356 address += (uint)byte_alignment;
357 }
358
359
360 }
361 bw.Close();
362 }
363 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));
364 return true;
365 }
366 catch (OutOfMemoryException ex)
367 {
368 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));
369 logger.Error.WriteLine("DumpMemory(): OutOfMemoryException");
370 logger.Error.WriteLine(ex.ToString());
371 }
372 catch (Exception ex)
373 {
374 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));
375 logger.Error.WriteLine("DumpMemory(): Exception");
376 logger.Error.WriteLine(ex.ToString());
377 }
378 return false;
379 }
380
381 #endregion
382 }
383 #endregion
384 }