ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/RomCheater/trunk/Win32/Sojaner.MemoryScanner/MemoryScanner.cs
Revision: 245
Committed: Sun Jun 3 14:50:09 2012 UTC (11 years ago) by william
File size: 13779 byte(s)
Log Message:
+ add exception logic to ensure provider is open

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