using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.Threading;
using System.Runtime.InteropServices;
using RomCheater.Logging;
using RomCheater.Core;
using System.IO;
namespace Sojaner.MemoryScanner
{
// code borrowed from: http://www.codeproject.com/KB/cs/sojaner_memory_scanner.aspx
#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 ProcessMemoryReader()
{
}
///
/// Process from which to read
///
public Process ReadProcess
{
get
{
return m_ReadProcess;
}
set
{
m_ReadProcess = value;
}
}
private Process m_ReadProcess = null;
private IntPtr m_hProcess = IntPtr.Zero;
public void OpenProcess()
{
// m_hProcess = ProcessMemoryReaderApi.OpenProcess(ProcessMemoryReaderApi.PROCESS_VM_READ, 1, (uint)m_ReadProcess.Id);
ProcessMemoryReaderApi.ProcessAccessType access;
access = ProcessMemoryReaderApi.ProcessAccessType.PROCESS_VM_READ
| ProcessMemoryReaderApi.ProcessAccessType.PROCESS_VM_WRITE
| ProcessMemoryReaderApi.ProcessAccessType.PROCESS_VM_OPERATION;
m_hProcess = ProcessMemoryReaderApi.OpenProcess((uint)access, 1, (uint)m_ReadProcess.Id);
}
public void CloseHandle()
{
try
{
int iRetValue;
iRetValue = ProcessMemoryReaderApi.CloseHandle(m_hProcess);
if (iRetValue == 0)
{
throw new Exception("CloseHandle failed");
}
}
catch (Exception ex)
{
//System.Windows.Forms.MessageBox.Show(ex.Message, "error", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Warning);
throw ex;
}
}
public bool DumpMemory(string filename, uint MemoryAddress, uint bytesToRead, out int bytesRead)
{
bytesRead = 0;
uint byte_alignment = 512; // 4mb alignment
uint address = MemoryAddress;
try
{
using (FileStream fs = new FileStream(filename, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite))
{
BinaryWriter bw = new BinaryWriter(fs);
//foreach (byte b in data) { bw.Write(b); }
for (uint i = 0; i <= bytesToRead; i += byte_alignment)
{
byte[] buffer = new byte[byte_alignment];
uint bytes_to_read = byte_alignment;
IntPtr ptrBytesRead;
ProcessMemoryReaderApi.ReadProcessMemory(m_hProcess, (IntPtr)address, buffer, bytes_to_read, out ptrBytesRead);
bytesRead = ptrBytesRead.ToInt32();
bw.Write(buffer);
bw.Flush();
address += byte_alignment;
}
bw.Close();
}
return true;
}
catch (OutOfMemoryException ex)
{
logger.Error.WriteLine("DumpMemory(): OutOfMemoryException");
logger.Error.WriteLine(ex.ToString());
}
catch (Exception ex)
{
logger.Error.WriteLine("DumpMemory(): Exception");
logger.Error.WriteLine(ex.ToString());
}
return false;
}
public byte[] ReadProcessMemory(uint MemoryAddress, uint bytesToRead, out int bytesRead)
{
bytesRead = 0;
uint address = MemoryAddress;
List aligned_array_list = new List();
try
{
uint byte_alignment = 512; // 4mb alignment
for (uint i = 0; i <= bytesToRead; i += byte_alignment)
{
byte[] buffer = new byte[byte_alignment];
uint bytes_to_read = byte_alignment;
IntPtr ptrBytesRead;
ProcessMemoryReaderApi.ReadProcessMemory(m_hProcess, (IntPtr)address, buffer, bytes_to_read, out ptrBytesRead);
bytesRead = ptrBytesRead.ToInt32();
aligned_array_list.Add(buffer);
address += byte_alignment;
}
//List big_array = new List();
//foreach (byte[] aligned_array in aligned_array_list) { foreach (byte b in aligned_array) { big_array.Add(b); } }
return new byte[] { };
}
catch (OutOfMemoryException ex)
{
logger.Error.WriteLine("ReadProcessMemory(): OutOfMemoryException");
logger.Error.WriteLine(ex.ToString());
}
catch (Exception ex)
{
logger.Error.WriteLine("ReadProcessMemory(): Exception");
logger.Error.WriteLine(ex.ToString());
}
return new byte[] { };
}
public void WriteProcessMemory(IntPtr MemoryAddress, byte[] bytesToWrite, out int bytesWritten)
{
IntPtr ptrBytesWritten;
ProcessMemoryReaderApi.WriteProcessMemory(m_hProcess, MemoryAddress, bytesToWrite, (uint)bytesToWrite.Length, out ptrBytesWritten);
bytesWritten = ptrBytesWritten.ToInt32();
}
///
/// ProcessMemoryReader is a class that enables direct reading a process memory
///
class ProcessMemoryReaderApi
{
// constants information can be found in
[Flags]
public enum ProcessAccessType
{
PROCESS_TERMINATE = (0x0001),
PROCESS_CREATE_THREAD = (0x0002),
PROCESS_SET_SESSIONID = (0x0004),
PROCESS_VM_OPERATION = (0x0008),
PROCESS_VM_READ = (0x0010),
PROCESS_VM_WRITE = (0x0020),
PROCESS_DUP_HANDLE = (0x0040),
PROCESS_CREATE_PROCESS = (0x0080),
PROCESS_SET_QUOTA = (0x0100),
PROCESS_SET_INFORMATION = (0x0200),
PROCESS_QUERY_INFORMATION = (0x0400)
}
// function declarations are found in the MSDN and in
// HANDLE OpenProcess(
// DWORD dwDesiredAccess, // access flag
// BOOL bInheritHandle, // handle inheritance option
// DWORD dwProcessId // process identifier
// );
[DllImport("kernel32.dll")]
public static extern IntPtr OpenProcess(UInt32 dwDesiredAccess, Int32 bInheritHandle, UInt32 dwProcessId);
// BOOL CloseHandle(
// HANDLE hObject // handle to object
// );
[DllImport("kernel32.dll")]
public static extern Int32 CloseHandle(IntPtr hObject);
// BOOL ReadProcessMemory(
// HANDLE hProcess, // handle to the process
// LPCVOID lpBaseAddress, // base of memory area
// LPVOID lpBuffer, // data buffer
// SIZE_T nSize, // number of bytes to read
// 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);
// BOOL WriteProcessMemory(
// HANDLE hProcess, // handle to process
// LPVOID lpBaseAddress, // base of memory area
// LPCVOID lpBuffer, // data buffer
// SIZE_T nSize, // count of bytes to write
// 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);
}
}
#endregion
}