ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/RomCheater/trunk/Win32/Sojaner.MemoryScanner/MemoryScanner.cs
Revision: 247
Committed: Sun Jun 3 15:27:23 2012 UTC (11 years, 6 months ago) by william
File size: 15280 byte(s)
Log Message:
+ catch, log and throw errors

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 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 public bool ReadFirstNonZeroByte(uint MemoryAddress, uint bytesToRead, out uint address)
153 {
154 //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));
155 address = 0;
156 uint byte_alignment = 1;
157 // get common init parameters
158 //InitMemoryDump(out byte_alignment);
159 uint mem_address = MemoryAddress;
160 uint _bytesToRead = bytesToRead;
161 byte[] buffer = new byte[] { };
162 try
163 {
164 //using (MemoryStream ms = new MemoryStream())
165 //{
166 // //BinaryWriter bw = new BinaryWriter(ms);
167 // //foreach (byte b in data) { bw.Write(b); }
168 for (uint i = 0; i <= bytesToRead; )
169 {
170 if (_bytesToRead < byte_alignment)
171 {
172 _bytesToRead = bytesToRead;
173 buffer = new byte[_bytesToRead];
174 }
175 else
176 {
177 _bytesToRead = byte_alignment;
178 buffer = new byte[byte_alignment];
179 }
180 int bytesRead = 0;
181 ReadProcessMemory(mem_address, _bytesToRead, out bytesRead, out buffer);
182 if (buffer.Length == 0 && bytesRead == 0)
183 {
184 throw new Exception(string.Format("Failed to read memory from process: {0}", ReadProcess.ToString()));
185 }
186 //bw.Write(buffer);
187 //bw.Flush();
188 if (_bytesToRead < byte_alignment)
189 {
190 i += _bytesToRead;
191 mem_address += (uint)_bytesToRead;
192 }
193 else
194 {
195 i += byte_alignment;
196 mem_address += (uint)byte_alignment;
197 }
198 for (uint j = 0; j < buffer.Length; j++)
199 {
200 if (buffer[j] != 0)
201 {
202 address = mem_address;
203 break;
204 }
205 }
206 if (address != 0)
207 break;
208 }
209 // bw.Close();
210 //}
211 //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));
212 return true;
213 }
214 catch (SEHException ex)
215 {
216 logger.Error.WriteLine("ReadFirstNonZeroByte() SEHException was thrown: (0x{0:x8}) - {1}", ex.ErrorCode, ex.Message);
217 logger.Error.WriteLine(ex.ToString());
218 throw ex;
219 }
220 catch (OutOfMemoryException ex)
221 {
222 logger.Error.WriteLine("ReadFirstNonZeroByte(): OutOfMemoryException");
223 logger.Error.WriteLine(ex.ToString());
224 }
225 catch (Exception ex)
226 {
227 logger.Error.WriteLine("ReadFirstNonZeroByte(): Exception");
228 logger.Error.WriteLine(ex.ToString());
229 throw ex;
230 }
231 return false;
232 }
233 public void ReadProcessMemory(uint MemoryAddress, uint bytesToRead, out int bytesRead, out byte[] data)
234 {
235 try
236 {
237 byte[] buffer = new byte[] { };
238 IntPtr ptrBytesRead;
239 ProcessMemoryReader.ProcessMemoryReaderApi.ReadProcessMemory(m_hProcess, (IntPtr)MemoryAddress, buffer, bytesToRead, out ptrBytesRead);
240 bytesRead = ptrBytesRead.ToInt32();
241 data = buffer;
242 }
243 catch (SEHException ex)
244 {
245 logger.Error.WriteLine("ReadProcessMemory() SEHException was thrown: (0x{0:x8}) - {1}", ex.ErrorCode, ex.Message);
246 logger.Error.WriteLine(ex.ToString());
247 throw ex;
248 }
249 catch (Exception ex)
250 {
251 logger.Error.WriteLine("ReadProcessMemory(): Exception");
252 logger.Error.WriteLine(ex.ToString());
253 throw ex;
254 }
255 }
256 #endregion
257
258 #region IMemoryWriter Members
259 public void WriteProcessMemory(uint MemoryAddress, byte byteToWrite, out int bytesWritten)
260 {
261 WriteProcessMemory(MemoryAddress, new byte[] { byteToWrite }, out bytesWritten);
262 }
263 public void WriteProcessMemory(uint MemoryAddress, byte[] bytesToWrite, out int bytesWritten)
264 {
265 try
266 {
267 IntPtr ptrBytesWritten;
268 ProcessMemoryReaderApi.WriteProcessMemory(m_hProcess, (IntPtr)MemoryAddress, bytesToWrite, (uint)bytesToWrite.Length, out ptrBytesWritten);
269 bytesWritten = ptrBytesWritten.ToInt32();
270 }
271 catch (SEHException ex)
272 {
273 logger.Error.WriteLine("WriteProcessMemory() SEHException was thrown: (0x{0:x8}) - {1}", ex.ErrorCode, ex.Message);
274 logger.Error.WriteLine(ex.ToString());
275 throw ex;
276 }
277 catch (Exception ex)
278 {
279
280 logger.Error.WriteLine("WriteProcessMemory() Exception");
281 logger.Error.WriteLine(ex.ToString());
282 bytesWritten = 0;
283 throw ex;
284 }
285 }
286 #endregion
287
288 #region IFileWriter Members
289
290 public bool WriteProcessMemoryToFile(string filename, uint MemoryAddress, uint bytesToRead, out int bytesRead)
291 {
292 //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));
293 bytesRead = 0;
294 uint byte_alignment = 102400;
295 uint address = MemoryAddress;
296 uint _bytesToRead = bytesToRead;
297 byte[] buffer = new byte[] { };
298 try
299 {
300 FileInfo fi = new FileInfo(filename);
301 if (fi.Exists)
302 fi.Delete();
303 using (FileStream fs = new FileStream(filename, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.ReadWrite))
304 {
305 BinaryWriter bw = new BinaryWriter(fs);
306 //foreach (byte b in data) { bw.Write(b); }
307
308 for (uint i = 0; i <= bytesToRead; )
309 {
310 if (_bytesToRead < byte_alignment)
311 {
312 _bytesToRead = bytesToRead;
313 buffer = new byte[_bytesToRead];
314 }
315 else
316 {
317 _bytesToRead = byte_alignment;
318 buffer = new byte[byte_alignment];
319 }
320 ReadProcessMemory(address, _bytesToRead, out bytesRead, out buffer);
321 bw.Write(buffer);
322 bw.Flush();
323
324 if (_bytesToRead < byte_alignment)
325 {
326 i += _bytesToRead;
327 address += (uint)_bytesToRead;
328 }
329 else
330 {
331 i += byte_alignment;
332 address += (uint)byte_alignment;
333 }
334
335
336 }
337 bw.Close();
338 }
339 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));
340 return true;
341 }
342 catch (SEHException ex)
343 {
344 logger.Error.WriteLine("WriteProcessMemoryToFile() SEHException was thrown: (0x{0:x8}) - {1}", ex.ErrorCode, ex.Message);
345 logger.Error.WriteLine(ex.ToString());
346 throw ex;
347 }
348 catch (OutOfMemoryException ex)
349 {
350 logger.Error.WriteLine("WriteProcessMemoryToFile(): Exception");
351 logger.Error.WriteLine(ex.ToString());
352 }
353 catch (Exception ex)
354 {
355 logger.Error.WriteLine("WriteProcessMemoryToFile(): Exception");
356 logger.Error.WriteLine(ex.ToString());
357 throw ex;
358 }
359 return false;
360 }
361
362 #endregion
363 }
364 #endregion
365 }