/[RomCheater]/trunk/Win32/Sojaner.MemoryScanner/MemoryScanner.cs
ViewVC logotype

Diff of /trunk/Win32/Sojaner.MemoryScanner/MemoryScanner.cs

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 200 by william, Thu May 31 07:29:44 2012 UTC revision 245 by william, Sun Jun 3 14:50:09 2012 UTC
# Line 5  using System.Diagnostics; Line 5  using System.Diagnostics;
5  using System.Threading;  using System.Threading;
6  using System.Runtime.InteropServices;  using System.Runtime.InteropServices;
7  using RomCheater.Logging;  using RomCheater.Logging;
 using RomCheater.Core;  
8  using System.IO;  using System.IO;
9    using Sojaner.MemoryScanner.MemoryProviers;
10    
11  namespace Sojaner.MemoryScanner  namespace Sojaner.MemoryScanner
12  {  {
# Line 14  namespace Sojaner.MemoryScanner Line 14  namespace Sojaner.MemoryScanner
14      #region ProcessMemoryReader class      #region ProcessMemoryReader class
15      //Thanks goes to Arik Poznanski for P/Invokes and methods needed to read and write the Memory      //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      //For more information refer to "Minesweeper, Behind the scenes" article by Arik Poznanski at Codeproject.com
17      public class ProcessMemoryReader      internal class ProcessMemoryReader : IMemoryReader, IMemoryWriter, IFileWriter
18      {      {
19    
20          public ProcessMemoryReader()          public ProcessMemoryReader()
# Line 61  namespace Sojaner.MemoryScanner Line 61  namespace Sojaner.MemoryScanner
61                      throw new Exception("CloseHandle failed");                      throw new Exception("CloseHandle failed");
62                  }                  }
63              }              }
64              catch (Exception ex)              catch (SEHException ex)
65              {              {
                 //System.Windows.Forms.MessageBox.Show(ex.Message, "error", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Warning);  
66                  throw ex;                  throw ex;
67              }              }
68          }              catch (Exception ex)
   
         #region WriteProcessMemoryToFile  
         public bool WriteProcessMemoryToFile(string filename, uint MemoryAddress, uint bytesToRead, out int bytesRead)  
         {  
             RamDumper dumper = new RamDumper();  
             return dumper.DumpMemoryToFile(ReadProcess, filename, MemoryAddress, bytesToRead, out bytesRead);  
         }  
         #endregion  
   
         #region ReadProcessMemory  
         public byte[] ReadProcessMemory(uint MemoryAddress, uint bytesToRead, out int bytesRead)  
         {  
             RamDumper dumper = new RamDumper();  
             return dumper.DumpMemoryToByteArray(ReadProcess, MemoryAddress, bytesToRead, out bytesRead);  
         }  
         #endregion  
   
         #region WriteProcessMemory  
         public void WriteProcessMemory(UIntPtr MemoryAddress, byte byteToWrite, out int bytesWritten)  
         {  
             WriteProcessMemory(MemoryAddress, new byte[] { byteToWrite }, out bytesWritten);  
         }  
         public void WriteProcessMemory(UIntPtr MemoryAddress, byte[] bytesToWrite, out int bytesWritten)  
         {  
             IntPtr ptrBytesWritten;  
             ProcessMemoryReaderApi.WriteProcessMemory(m_hProcess, MemoryAddress, bytesToWrite, (uint)bytesToWrite.Length, out ptrBytesWritten);  
             bytesWritten = ptrBytesWritten.ToInt32();  
         }  
         #endregion  
   
         #region RamDumper  
         private interface IRamDumper  
         {  
            bool DumpMemoryToFile(Process ppid, string filename, uint MemoryAddress, uint bytesToRead, out int bytesRead);  
            byte[] DumpMemoryToByteArray(Process ppid, uint MemoryAddress, uint bytesToRead, out int bytesRead);  
         }  
         private class RamDumper : IRamDumper  
         {  
             public RamDumper() { }  
             private void InitMemoryDump(out uint byte_alignment)  
69              {              {
70                  byte_alignment = 102400; // get memory in 100mb chunks                  //System.Windows.Forms.MessageBox.Show(ex.Message, "error", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Warning);
71              }                  throw ex;
             #region IRamDumper members  
             #region DumpMemoryToFile  
             public bool DumpMemoryToFile(Process ppid, string filename, uint MemoryAddress, uint bytesToRead, out int bytesRead)  
             {  
                 //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));  
                 bytesRead = 0;  
                 uint byte_alignment = 0;  
                 // get common init parameters  
                 InitMemoryDump(out byte_alignment);  
                 uint address = MemoryAddress;  
                 uint _bytesToRead = bytesToRead;  
                 byte[] buffer = new byte[] { };  
                 try  
                 {  
                     FileInfo fi = new FileInfo(filename);  
                     if (fi.Exists)  
                         fi.Delete();  
                     using (FileStream fs = new FileStream(filename, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.ReadWrite))  
                     {  
                         BinaryWriter bw = new BinaryWriter(fs);  
                         //foreach (byte b in data) { bw.Write(b); }  
   
                         for (uint i = 0; i <= bytesToRead; )  
                         {  
                             if (_bytesToRead < byte_alignment)  
                             {  
                                 _bytesToRead = bytesToRead;  
                                 buffer = new byte[_bytesToRead];  
                             }  
                             else  
                             {  
                                 _bytesToRead = byte_alignment;  
                                 buffer = new byte[byte_alignment];  
                             }  
                             IntPtr ptrBytesRead;  
   
                             ProcessMemoryReader.ProcessMemoryReaderApi.ReadProcessMemory(m_hProcess, (UIntPtr)address, buffer, _bytesToRead, out ptrBytesRead);  
                             bytesRead = ptrBytesRead.ToInt32();  
                             bw.Write(buffer);  
                             bw.Flush();  
   
                             if (_bytesToRead < byte_alignment)  
                             {  
                                 i += _bytesToRead;  
                                 address += _bytesToRead;  
                             }  
                             else  
                             {  
                                 i += byte_alignment;  
                                 address += byte_alignment;  
                             }  
   
   
                         }  
                         bw.Close();  
                     }  
                     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", ppid.Id, ppid.ProcessName));  
                     return true;  
                 }  
                 catch (OutOfMemoryException ex)  
                 {  
                     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", ppid.Id, ppid.ProcessName));  
                     logger.Error.WriteLine("DumpMemory(): OutOfMemoryException");  
                     logger.Error.WriteLine(ex.ToString());  
                 }  
                 catch (Exception ex)  
                 {  
                     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", ppid.Id, ppid.ProcessName));  
                     logger.Error.WriteLine("DumpMemory(): Exception");  
                     logger.Error.WriteLine(ex.ToString());  
                 }  
                 return false;  
             }  
             #endregion  
             #region DumpMemoryToByteArray  
             public byte[] DumpMemoryToByteArray(Process ppid, uint MemoryAddress, uint bytesToRead, out int bytesRead)  
             {  
                 //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));  
                 bytesRead = 0;  
                 uint byte_alignment = 0;  
                 // get common init parameters  
                 InitMemoryDump(out byte_alignment);  
                 uint address = MemoryAddress;  
                 uint _bytesToRead = bytesToRead;  
                 byte[] buffer = new byte[] { };  
                 try  
                 {  
                     using (MemoryStream ms = new MemoryStream())  
                     {  
                         BinaryWriter bw = new BinaryWriter(ms);  
                         //foreach (byte b in data) { bw.Write(b); }  
   
                         for (uint i = 0; i <= bytesToRead; )  
                         {  
                             if (_bytesToRead < byte_alignment)  
                             {  
                                 _bytesToRead = bytesToRead;  
                                 buffer = new byte[_bytesToRead];  
                             }  
                             else  
                             {  
                                 _bytesToRead = byte_alignment;  
                                 buffer = new byte[byte_alignment];  
                             }  
                             IntPtr ptrBytesRead;  
   
                             ProcessMemoryReader.ProcessMemoryReaderApi.ReadProcessMemory(m_hProcess, (UIntPtr)address, buffer, _bytesToRead, out ptrBytesRead);  
                             bytesRead = ptrBytesRead.ToInt32();  
                             bw.Write(buffer);  
                             bw.Flush();  
   
                             if (_bytesToRead < byte_alignment)  
                             {  
                                 i += _bytesToRead;  
                                 address += _bytesToRead;  
                             }  
                             else  
                             {  
                                 i += byte_alignment;  
                                 address += byte_alignment;  
                             }  
   
   
                         }  
                         bw.Close();  
                         return ms.ToArray();  
                     }  
                     //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));  
                 }  
                 catch (OutOfMemoryException ex)  
                 {  
                     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", ppid.Id, ppid.ProcessName));  
                     logger.Error.WriteLine("DumpMemory(): OutOfMemoryException");  
                     logger.Error.WriteLine(ex.ToString());  
                 }  
                 catch (Exception ex)  
                 {  
                     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", ppid.Id, ppid.ProcessName));  
                     logger.Error.WriteLine("DumpMemory(): Exception");  
                     logger.Error.WriteLine(ex.ToString());  
                 }  
                 return new byte[]{};  
72              }              }
             #endregion  
             #endregion  
73          }          }
         #endregion  
74          /// <summary>          /// <summary>
75          /// ProcessMemoryReader is a class that enables direct reading a process memory          /// ProcessMemoryReader is a class that enables direct reading a process memory
76          /// </summary>          /// </summary>
77          public class ProcessMemoryReaderApi          private class ProcessMemoryReaderApi
78          {          {
79              // constants information can be found in <winnt.h>              // constants information can be found in <winnt.h>
80              [Flags]              [Flags]
# Line 303  namespace Sojaner.MemoryScanner Line 117  namespace Sojaner.MemoryScanner
117              //                  SIZE_T * lpNumberOfBytesRead  // number of bytes read              //                  SIZE_T * lpNumberOfBytesRead  // number of bytes read
118              //                  );              //                  );
119              [DllImport("kernel32.dll")]              [DllImport("kernel32.dll")]
120              public static extern Int32 ReadProcessMemory(IntPtr hProcess, UIntPtr lpBaseAddress, [In, Out] byte[] buffer, UInt32 size, out IntPtr lpNumberOfBytesRead);              public static extern Int32 ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [In, Out] byte[] buffer, UInt32 size, out IntPtr lpNumberOfBytesRead);
121    
122              //          BOOL WriteProcessMemory(              //          BOOL WriteProcessMemory(
123              //                  HANDLE hProcess,                // handle to process              //                  HANDLE hProcess,                // handle to process
# Line 313  namespace Sojaner.MemoryScanner Line 127  namespace Sojaner.MemoryScanner
127              //                  SIZE_T * lpNumberOfBytesWritten // count of bytes written              //                  SIZE_T * lpNumberOfBytesWritten // count of bytes written
128              //                  );              //                  );
129              [DllImport("kernel32.dll")]              [DllImport("kernel32.dll")]
130              public static extern Int32 WriteProcessMemory(IntPtr hProcess, UIntPtr lpBaseAddress, [In, Out] byte[] buffer, UInt32 size, out IntPtr lpNumberOfBytesWritten);              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      #endregion
307  }  }

Legend:
Removed from v.200  
changed lines
  Added in v.245

  ViewVC Help
Powered by ViewVC 1.1.22