ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/RomCheater/trunk/Win32/Sojaner.MemoryScanner/MemoryScanner.cs
Revision: 249
Committed: Sun Jun 3 16:09:05 2012 UTC (11 years ago) by william
File size: 15935 byte(s)
Log Message:
change address from uint to int

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