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 (10 years, 10 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

# User Rev Content
1 william 88 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 william 156 using RomCheater.Logging;
8 william 162 using RomCheater.Core;
9     using System.IO;
10 william 88
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 william 162
72     public bool DumpMemory(string filename, uint MemoryAddress, uint bytesToRead, out int bytesRead)
73 william 88 {
74 william 162 bytesRead = 0;
75 william 166 uint byte_alignment = 102400; // write to file in 100mb chunks
76 william 162 uint address = MemoryAddress;
77 william 167 uint _bytesToRead = bytesToRead;
78     byte[] buffer = new byte[] { };
79 william 156 try
80     {
81 william 167 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 william 162 {
86     BinaryWriter bw = new BinaryWriter(fs);
87     //foreach (byte b in data) { bw.Write(b); }
88 william 88
89 william 167 for (uint i = 0; i <= bytesToRead;)
90 william 162 {
91 william 167 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 william 162 IntPtr ptrBytesRead;
102 william 167 ProcessMemoryReaderApi.ReadProcessMemory(m_hProcess, (UIntPtr)address, buffer, _bytesToRead, out ptrBytesRead);
103 william 162 bytesRead = ptrBytesRead.ToInt32();
104     bw.Write(buffer);
105     bw.Flush();
106 william 167
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 william 162 }
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 william 88
137 william 162 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 william 88
147 william 162 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 william 164 ProcessMemoryReaderApi.ReadProcessMemory(m_hProcess, (UIntPtr)address, buffer, bytes_to_read, out ptrBytesRead);
153 william 162 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 william 156 }
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 william 88 }
175    
176 william 164 public void WriteProcessMemory(UIntPtr MemoryAddress, byte[] bytesToWrite, out int bytesWritten)
177 william 88 {
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 william 164 public static extern Int32 ReadProcessMemory(IntPtr hProcess, UIntPtr lpBaseAddress, [In, Out] byte[] buffer, UInt32 size, out IntPtr lpNumberOfBytesRead);
232 william 88
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 william 164 public static extern Int32 WriteProcessMemory(IntPtr hProcess, UIntPtr lpBaseAddress, [In, Out] byte[] buffer, UInt32 size, out IntPtr lpNumberOfBytesWritten);
242 william 88
243    
244     }
245     }
246     #endregion
247     }