ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/RomCheater/trunk/Win32/Sojaner.MemoryScanner/MemoryScanner.cs
Revision: 167
Committed: Mon May 28 08:31:56 2012 UTC (11 years, 4 months ago) by william
File size: 9949 byte(s)
Log Message:
+ fix memory dump when bytes to read is less than buffer amount

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 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 public bool DumpMemory(string filename, uint MemoryAddress, uint bytesToRead, out int bytesRead)
73 {
74 bytesRead = 0;
75 uint byte_alignment = 102400; // write to file in 100mb chunks
76 uint address = MemoryAddress;
77 uint _bytesToRead = bytesToRead;
78 byte[] buffer = new byte[] { };
79 try
80 {
81 FileInfo fi = new FileInfo(filename);
82 if (fi.Exists)
83 fi.Delete();
84 using (FileStream fs = new FileStream(filename, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.ReadWrite))
85 {
86 BinaryWriter bw = new BinaryWriter(fs);
87 //foreach (byte b in data) { bw.Write(b); }
88
89 for (uint i = 0; i <= bytesToRead;)
90 {
91 if (_bytesToRead < byte_alignment)
92 {
93 _bytesToRead = bytesToRead;
94 buffer = new byte[_bytesToRead];
95 }
96 else
97 {
98 _bytesToRead = byte_alignment;
99 buffer = new byte[byte_alignment];
100 }
101 IntPtr ptrBytesRead;
102 ProcessMemoryReaderApi.ReadProcessMemory(m_hProcess, (UIntPtr)address, buffer, _bytesToRead, out ptrBytesRead);
103 bytesRead = ptrBytesRead.ToInt32();
104 bw.Write(buffer);
105 bw.Flush();
106
107 if (_bytesToRead < byte_alignment)
108 {
109 i += _bytesToRead;
110 address += _bytesToRead;
111 }
112 else
113 {
114 i += byte_alignment;
115 address += byte_alignment;
116 }
117
118
119 }
120 bw.Close();
121 }
122 return true;
123 }
124 catch (OutOfMemoryException ex)
125 {
126 logger.Error.WriteLine("DumpMemory(): OutOfMemoryException");
127 logger.Error.WriteLine(ex.ToString());
128 }
129 catch (Exception ex)
130 {
131 logger.Error.WriteLine("DumpMemory(): Exception");
132 logger.Error.WriteLine(ex.ToString());
133 }
134 return false;
135 }
136
137 public byte[] ReadProcessMemory(uint MemoryAddress, uint bytesToRead, out int bytesRead)
138 {
139 bytesRead = 0;
140 uint address = MemoryAddress;
141 List<byte[]> aligned_array_list = new List<byte[]>();
142 try
143 {
144 uint byte_alignment = 512; // 4mb alignment
145
146
147 for (uint i = 0; i <= bytesToRead; i += byte_alignment)
148 {
149 byte[] buffer = new byte[byte_alignment];
150 uint bytes_to_read = byte_alignment;
151 IntPtr ptrBytesRead;
152 ProcessMemoryReaderApi.ReadProcessMemory(m_hProcess, (UIntPtr)address, buffer, bytes_to_read, out ptrBytesRead);
153 bytesRead = ptrBytesRead.ToInt32();
154 aligned_array_list.Add(buffer);
155 address += byte_alignment;
156 }
157
158 //List<byte> big_array = new List<byte>();
159 //foreach (byte[] aligned_array in aligned_array_list) { foreach (byte b in aligned_array) { big_array.Add(b); } }
160
161 return new byte[] { };
162 }
163 catch (OutOfMemoryException ex)
164 {
165 logger.Error.WriteLine("ReadProcessMemory(): OutOfMemoryException");
166 logger.Error.WriteLine(ex.ToString());
167 }
168 catch (Exception ex)
169 {
170 logger.Error.WriteLine("ReadProcessMemory(): Exception");
171 logger.Error.WriteLine(ex.ToString());
172 }
173 return new byte[] { };
174 }
175
176 public void WriteProcessMemory(UIntPtr MemoryAddress, byte[] bytesToWrite, out int bytesWritten)
177 {
178 IntPtr ptrBytesWritten;
179 ProcessMemoryReaderApi.WriteProcessMemory(m_hProcess, MemoryAddress, bytesToWrite, (uint)bytesToWrite.Length, out ptrBytesWritten);
180
181 bytesWritten = ptrBytesWritten.ToInt32();
182 }
183
184
185 /// <summary>
186 /// ProcessMemoryReader is a class that enables direct reading a process memory
187 /// </summary>
188 class ProcessMemoryReaderApi
189 {
190 // constants information can be found in <winnt.h>
191 [Flags]
192 public enum ProcessAccessType
193 {
194 PROCESS_TERMINATE = (0x0001),
195 PROCESS_CREATE_THREAD = (0x0002),
196 PROCESS_SET_SESSIONID = (0x0004),
197 PROCESS_VM_OPERATION = (0x0008),
198 PROCESS_VM_READ = (0x0010),
199 PROCESS_VM_WRITE = (0x0020),
200 PROCESS_DUP_HANDLE = (0x0040),
201 PROCESS_CREATE_PROCESS = (0x0080),
202 PROCESS_SET_QUOTA = (0x0100),
203 PROCESS_SET_INFORMATION = (0x0200),
204 PROCESS_QUERY_INFORMATION = (0x0400)
205 }
206
207 // function declarations are found in the MSDN and in <winbase.h>
208
209 // HANDLE OpenProcess(
210 // DWORD dwDesiredAccess, // access flag
211 // BOOL bInheritHandle, // handle inheritance option
212 // DWORD dwProcessId // process identifier
213 // );
214 [DllImport("kernel32.dll")]
215 public static extern IntPtr OpenProcess(UInt32 dwDesiredAccess, Int32 bInheritHandle, UInt32 dwProcessId);
216
217 // BOOL CloseHandle(
218 // HANDLE hObject // handle to object
219 // );
220 [DllImport("kernel32.dll")]
221 public static extern Int32 CloseHandle(IntPtr hObject);
222
223 // BOOL ReadProcessMemory(
224 // HANDLE hProcess, // handle to the process
225 // LPCVOID lpBaseAddress, // base of memory area
226 // LPVOID lpBuffer, // data buffer
227 // SIZE_T nSize, // number of bytes to read
228 // SIZE_T * lpNumberOfBytesRead // number of bytes read
229 // );
230 [DllImport("kernel32.dll")]
231 public static extern Int32 ReadProcessMemory(IntPtr hProcess, UIntPtr lpBaseAddress, [In, Out] byte[] buffer, UInt32 size, out IntPtr lpNumberOfBytesRead);
232
233 // BOOL WriteProcessMemory(
234 // HANDLE hProcess, // handle to process
235 // LPVOID lpBaseAddress, // base of memory area
236 // LPCVOID lpBuffer, // data buffer
237 // SIZE_T nSize, // count of bytes to write
238 // SIZE_T * lpNumberOfBytesWritten // count of bytes written
239 // );
240 [DllImport("kernel32.dll")]
241 public static extern Int32 WriteProcessMemory(IntPtr hProcess, UIntPtr lpBaseAddress, [In, Out] byte[] buffer, UInt32 size, out IntPtr lpNumberOfBytesWritten);
242
243
244 }
245 }
246 #endregion
247 }