Parent Directory
|
Revision Log
|
Patch
--- trunk/Win32/Sojaner.MemoryScanner/MemoryScanner.cs 2012/05/28 04:14:03 156 +++ trunk/Win32/Sojaner.MemoryScanner/MemoryScanner.cs 2012/06/02 18:31:40 229 @@ -5,6 +5,8 @@ using System.Threading; using System.Runtime.InteropServices; using RomCheater.Logging; +using RomCheater.Core; +using System.IO; namespace Sojaner.MemoryScanner { @@ -12,7 +14,7 @@ #region ProcessMemoryReader class //Thanks goes to Arik Poznanski for P/Invokes and methods needed to read and write the Memory //For more information refer to "Minesweeper, Behind the scenes" article by Arik Poznanski at Codeproject.com - public class ProcessMemoryReader + public class ProcessMemoryReader : IPatchMemory, IReadMemory { public ProcessMemoryReader() @@ -36,7 +38,7 @@ private Process m_ReadProcess = null; - private IntPtr m_hProcess = IntPtr.Zero; + private static IntPtr m_hProcess = IntPtr.Zero; public void OpenProcess() { @@ -66,46 +68,586 @@ } } - public byte[] ReadProcessMemory(IntPtr MemoryAddress, uint bytesToRead, out int bytesRead) + #region WriteProcessMemoryToFile + public bool WriteProcessMemoryToFile(string filename, uint MemoryAddress, uint bytesToRead, out int bytesRead) { - try - { - byte[] buffer = new byte[bytesToRead - 1]; + RamDumper dumper = new RamDumper(); + return dumper.DumpMemoryToFile(ReadProcess, filename, MemoryAddress, bytesToRead, out bytesRead); + } + #endregion + + #region ReadProcessMemory + public void ReadProcessMemory(uint MemoryAddress, uint bytesToRead, out int bytesRead, out byte[] data) + { + RamDumper dumper = new RamDumper(); + dumper.DumpMemoryToByteArray(ReadProcess, MemoryAddress, bytesToRead, out bytesRead, out data); + } + //public void ReadProcessMemory(uint MemoryAddress, uint bytesToRead, out int bytesRead,out sbyte[] data) + //{ + // RamDumper dumper = new RamDumper(); + // dumper.DumpMemoryToByteArray(ReadProcess, MemoryAddress, bytesToRead, out bytesRead, out data); + //} + #endregion - IntPtr ptrBytesRead; - ProcessMemoryReaderApi.ReadProcessMemory(m_hProcess, MemoryAddress, buffer, bytesToRead, out ptrBytesRead); + #region ReadProcessMemory + public bool ReadFirstNonZeroByte(uint MemoryAddress, uint bytesToRead, out uint address) + { + RamDumper dumper = new RamDumper(); + return dumper.ReadFirstNonZeroByte(ReadProcess, MemoryAddress, bytesToRead, out address); + } + #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 - bytesRead = ptrBytesRead.ToInt32(); - return buffer; + #region IPatchMemory members + public bool PatchMemory(uint address, byte value) + { + int bytesWritten; + byte[] bitData = BitConverter.GetBytes(value); + WriteProcessMemory((UIntPtr)address, bitData, out bytesWritten); + CloseHandle(); + byte check = 0; + ReadMemory(address, out check); + if (check == value) return true; + return false; + } + public bool PatchMemory(uint address, sbyte value) + { + int bytesWritten; + byte[] bitData = BitConverter.GetBytes(value); + WriteProcessMemory((UIntPtr)address, bitData, out bytesWritten); + CloseHandle(); + sbyte check = 0; + ReadMemory(address, out check); + if (check == value) return true; + return false; + } + public bool PatchMemory(uint address, ushort value) + { + int bytesWritten; + byte[] bitData = BitConverter.GetBytes(value); + WriteProcessMemory((UIntPtr)address, bitData, out bytesWritten); + CloseHandle(); + ushort check = 0; + ReadMemory(address, out check); + if (check == value) return true; + return false; + } + public bool PatchMemory(uint address, short value) + { + int bytesWritten; + byte[] bitData = BitConverter.GetBytes(value); + WriteProcessMemory((UIntPtr)address, bitData, out bytesWritten); + CloseHandle(); + short check = 0; + ReadMemory(address, out check); + if (check == value) return true; + return false; + } + public bool PatchMemory(uint address, uint value) + { + int bytesWritten; + byte[] bitData = BitConverter.GetBytes(value); + WriteProcessMemory((UIntPtr)address, bitData, out bytesWritten); + CloseHandle(); + uint check = 0; + ReadMemory(address, out check); + if (check == value) return true; + return false; + } + public bool PatchMemory(uint address, int value) + { + int bytesWritten; + byte[] bitData = BitConverter.GetBytes(value); + WriteProcessMemory((UIntPtr)address, bitData, out bytesWritten); + CloseHandle(); + int check = 0; + ReadMemory(address, out check); + if (check == value) return true; + return false; + } + public bool PatchMemory(uint address, ulong value) + { + int bytesWritten; + byte[] bitData = BitConverter.GetBytes(value); + WriteProcessMemory((UIntPtr)address, bitData, out bytesWritten); + CloseHandle(); + ulong check = 0; + ReadMemory(address, out check); + if (check == value) return true; + return false; + } + public bool PatchMemory(uint address, long value) + { + int bytesWritten; + byte[] bitData = BitConverter.GetBytes(value); + WriteProcessMemory((UIntPtr)address, bitData, out bytesWritten); + CloseHandle(); + long check = 0; + ReadMemory(address, out check); + if (check == value) return true; + return false; + } + #endregion + #region IReadMemory members + public bool ReadMemory(uint address, out byte value) + { + try + { + value = 0; + int bytesReadSize; + byte[] bitData; + ReadProcessMemory(address, sizeof(byte), out bytesReadSize, out bitData); + value = bitData[0]; + return true; } - catch (OutOfMemoryException ex) + catch { - logger.Error.WriteLine("ReadProcessMemory(): OutOfMemoryException"); - logger.Error.WriteLine(ex.ToString()); + value = 0x00; + return false; } - catch (Exception ex) + } + public bool ReadMemory(uint address, out sbyte value) + { + try + { + value = 0; + int bytesReadSize; + byte[] bitData; + ReadProcessMemory(address, sizeof(byte), out bytesReadSize, out bitData); + value = Convert.ToSByte(bitData[0]); + return true; + } + catch { - logger.Error.WriteLine("ReadProcessMemory(): Exception"); - logger.Error.WriteLine(ex.ToString()); + value = 0x00; + return false; } - bytesRead = 0; - return new byte[] { }; } - - public void WriteProcessMemory(IntPtr MemoryAddress, byte[] bytesToWrite, out int bytesWritten) + public bool ReadMemory(uint address, out ushort value) { - IntPtr ptrBytesWritten; - ProcessMemoryReaderApi.WriteProcessMemory(m_hProcess, MemoryAddress, bytesToWrite, (uint)bytesToWrite.Length, out ptrBytesWritten); - - bytesWritten = ptrBytesWritten.ToInt32(); + try + { + value = 0; + int bytesReadSize; + byte[] bitData; + ReadProcessMemory(address, sizeof(byte), out bytesReadSize, out bitData); + value = BitConverter.ToUInt16(bitData, 0); + return true; + } + catch + { + value = 0x00; + return false; + } + } + public bool ReadMemory(uint address, out short value) + { + try + { + value = 0; + int bytesReadSize; + byte[] bitData; + ReadProcessMemory(address, sizeof(byte), out bytesReadSize, out bitData); + value = BitConverter.ToInt16(bitData, 0); + return true; + } + catch + { + value = 0x00; + return false; + } } + public bool ReadMemory(uint address, out uint value) + { + try + { + value = 0; + int bytesReadSize; + byte[] bitData; + ReadProcessMemory(address, sizeof(byte), out bytesReadSize, out bitData); + value = BitConverter.ToUInt32(bitData, 0); + return true; + } + catch + { + value = 0x00; + return false; + } + } + public bool ReadMemory(uint address, out int value) + { + try + { + value = 0; + int bytesReadSize; + byte[] bitData; + ReadProcessMemory(address, sizeof(byte), out bytesReadSize, out bitData); + value = BitConverter.ToInt32(bitData, 0); + return true; + } + catch + { + value = 0x00; + return false; + } + } + public bool ReadMemory(uint address, out ulong value) + { + try + { + value = 0; + int bytesReadSize; + byte[] bitData; + ReadProcessMemory(address, sizeof(byte), out bytesReadSize, out bitData); + value = BitConverter.ToUInt64(bitData, 0); + return true; + } + catch + { + value = 0x00; + return false; + } + } + public bool ReadMemory(uint address, out long value) + { + try + { + value = 0; + int bytesReadSize; + byte[] bitData; + ReadProcessMemory(address, sizeof(byte), out bytesReadSize, out bitData); + value = BitConverter.ToInt64(bitData, 0); + return true; + } + catch + { + value = 0x00; + return false; + } + } + #endregion + #region RamDumper + private interface IRamDumper + { + bool DumpMemoryToFile(Process ppid, string filename, uint MemoryAddress, uint bytesToRead, out int bytesRead); + void DumpMemoryToByteArray(Process ppid, uint MemoryAddress, uint bytesToRead, out int bytesRead, out byte[] data); + } + private class RamDumper : IRamDumper + { + public RamDumper() { } + private void InitMemoryDump(out uint byte_alignment) + { + byte_alignment = 102400; // get memory in 100mb chunks + } + #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 void DumpMemoryToByteArray(Process ppid, uint MemoryAddress, uint bytesToRead, out int bytesRead, out byte[] data) + { + data = new byte[] { }; + //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 = 1; + // 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(); + data = 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()); + } + } + #endregion + #region DumpMemoryToByteArray (sbyte) + //public void DumpMemoryToByteArray(Process ppid, uint MemoryAddress, uint bytesToRead, out int bytesRead, out sbyte[] data) + //{ + // data = new sbyte[] { }; + // //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 = 1; + // // get common init parameters + // //InitMemoryDump(out byte_alignment); + // uint address = MemoryAddress; + // uint _bytesToRead = bytesToRead; + // sbyte[] buffer = new sbyte[] { }; + // 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 sbyte[_bytesToRead]; + // } + // else + // { + // _bytesToRead = byte_alignment; + // buffer = new sbyte[byte_alignment]; + // } + // IntPtr ptrBytesRead; + + // ProcessMemoryReader.ProcessMemoryReaderApi.ReadProcessMemory(m_hProcess, (UIntPtr)address, (byte[])(Array)buffer, _bytesToRead, out ptrBytesRead); + // bytesRead = ptrBytesRead.ToInt32(); + // bw.Write((byte[])(Array)buffer); + // bw.Flush(); + + // if (_bytesToRead < byte_alignment) + // { + // i += _bytesToRead; + // address += _bytesToRead; + // } + // else + // { + // i += byte_alignment; + // address += byte_alignment; + // } + + + // } + // bw.Close(); + // data = (sbyte[])(Array)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()); + // } + //} + #endregion + #endregion + #region ReadFirstNonZeroByte + public bool ReadFirstNonZeroByte(Process ppid, uint MemoryAddress, uint bytesToRead, out uint address) + { + //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)); + address = 0; + uint byte_alignment = 1; + // get common init parameters + //InitMemoryDump(out byte_alignment); + uint mem_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)mem_address, buffer, _bytesToRead, out ptrBytesRead); + //bw.Write(buffer); + //bw.Flush(); + if (_bytesToRead < byte_alignment) + { + i += _bytesToRead; + mem_address += _bytesToRead; + } + else + { + i += byte_alignment; + mem_address += byte_alignment; + } + for (uint j = 0; j < buffer.Length; j++) + { + if (buffer[j] != 0) + { + address = mem_address; + break; + } + } + if (address != 0) + break; + } + // bw.Close(); + //} + //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)); + return true; + } + 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 false; + } + #endregion + } + #endregion /// <summary> /// ProcessMemoryReader is a class that enables direct reading a process memory /// </summary> - class ProcessMemoryReaderApi + public class ProcessMemoryReaderApi { // constants information can be found in <winnt.h> [Flags] @@ -148,7 +690,7 @@ // SIZE_T * lpNumberOfBytesRead // number of bytes read // ); [DllImport("kernel32.dll")] - public static extern Int32 ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [In, Out] byte[] buffer, UInt32 size, out IntPtr lpNumberOfBytesRead); + public static extern Int32 ReadProcessMemory(IntPtr hProcess, UIntPtr lpBaseAddress, [In, Out] byte[] buffer, UInt32 size, out IntPtr lpNumberOfBytesRead); // BOOL WriteProcessMemory( // HANDLE hProcess, // handle to process @@ -158,7 +700,7 @@ // SIZE_T * lpNumberOfBytesWritten // count of bytes written // ); [DllImport("kernel32.dll")] - public static extern Int32 WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [In, Out] byte[] buffer, UInt32 size, out IntPtr lpNumberOfBytesWritten); + public static extern Int32 WriteProcessMemory(IntPtr hProcess, UIntPtr lpBaseAddress, [In, Out] byte[] buffer, UInt32 size, out IntPtr lpNumberOfBytesWritten); }
ViewVC Help | |
Powered by ViewVC 1.1.22 |