Code:
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace Reader
{
/// <summary>
/// ProcessMemoryReader is a class that enables direct reading a process memory
/// </summary>
class ProcessMemoryReaderApi
{
// constants information can be found in <winnt.h>
public const uint PROCESS_TERMINATE = 0x0001;
public const uint PROCESS_CREATE_THREAD = 0x0002;
public const uint PROCESS_SET_SESSIONID = 0x0004;
public const uint PROCESS_VM_OPERATION = 0x0008;
public const uint PROCESS_VM_READ = 0x0010;
public const uint PROCESS_VM_WRITE = 0x0020;
public const uint PROCESS_DUP_HANDLE = 0x0040;
public const uint PROCESS_CREATE_PROCESS = 0x0080;
public const uint PROCESS_SET_QUOTA = 0x0100;
public const uint PROCESS_SET_INFORMATION = 0x0200;
public const uint PROCESS_QUERY_INFORMATION = 0x0400;
public const uint TH32CS_SNAPHEAPLIST = 0x00000001;
public const uint TH32CS_SNAPPROCESS = 0x00000002;
public const uint TH32CS_SNAPTHREAD = 0x00000004;
public const uint TH32CS_SNAPMODULE = 0x00000008;
public const uint TH32CS_SNAPMODULE32 = 0x00000010;
public const uint TH32CS_SNAPALL = (TH32CS_SNAPHEAPLIST | TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD | TH32CS_SNAPMODULE);
public const uint TH32CS_INHERIT = 0x80000000;
public const int SE_PRIVILEGE_ENABLED = 0x00000002;
public const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;
public const int TOKEN_QUERY = 0x00000008;
// function declarations are found in the MSDN and in <winbase.h>
// 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);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern int GetSecurityInfo(int HANDLE, int SE_OBJECT_TYPE, int SECURITY_INFORMATION, int psidOwner, int psidGroup, out IntPtr pDACL, IntPtr pSACL, out IntPtr pSecurityDescriptor);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern int SetSecurityInfo(int HANDLE, int SE_OBJECT_TYPE, int SECURITY_INFORMATION, int psidOwner, int psidGroup, IntPtr pDACL, IntPtr pSACL);
}
public class ProcessMemoryReader
{
public ProcessMemoryReader()
{
}
/// <summary>
/// Process from which to read
/// </summary>
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_CREATE_PROCESS | ProcessMemoryReaderApi.PROCESS_QUERY_INFORMATION | ProcessMemoryReaderApi.PROCESS_VM_OPERATION | ProcessMemoryReaderApi.PROCESS_VM_WRITE | ProcessMemoryReaderApi.PROCESS_VM_READ | ProcessMemoryReaderApi.PROCESS_TERMINATE, 1, (uint)m_ReadProcess.Id);
if (m_hProcess == IntPtr.Zero)
{
IntPtr pDACL, pSecDesc;
ProcessMemoryReaderApi.GetSecurityInfo((int)Process.GetCurrentProcess().Handle, /*SE_KERNEL_OBJECT*/ 6, /*DACL_SECURITY_INFORMATION*/ 4, 0, 0, out pDACL, IntPtr.Zero, out pSecDesc);
m_hProcess = ProcessMemoryReaderApi.OpenProcess(0x40000, 0, (uint)ReadProcess.Id);
ProcessMemoryReaderApi.SetSecurityInfo((int)m_hProcess, /*SE_KERNEL_OBJECT*/ 6, /*DACL_SECURITY_INFORMATION*/ 4 | /*UNPROTECTED_DACL_SECURITY_INFORMATION*/ 0x20000000, 0, 0, pDACL, IntPtr.Zero);
ProcessMemoryReaderApi.CloseHandle(m_hProcess);
m_hProcess = ProcessMemoryReaderApi.OpenProcess(ProcessMemoryReaderApi.PROCESS_CREATE_PROCESS | ProcessMemoryReaderApi.PROCESS_QUERY_INFORMATION | ProcessMemoryReaderApi.PROCESS_VM_OPERATION | ProcessMemoryReaderApi.PROCESS_VM_WRITE | ProcessMemoryReaderApi.PROCESS_VM_READ | ProcessMemoryReaderApi.PROCESS_TERMINATE, 0, (uint)m_ReadProcess.Id);
if (m_hProcess == IntPtr.Zero)
{
MessageBox.Show("no handle found", "scan stopped");
return;
}
}
}
public void CloseHandle()
{
int iRetValue;
iRetValue = ProcessMemoryReaderApi.CloseHandle(m_hProcess);
if (iRetValue == 0)
{
throw new Exception("CloseHandle failed");
}
}
public byte[] ReadProcessMemory(IntPtr MemoryAddress, uint bytesToRead, out int bytesReaded)
{
byte[] buffer = new byte[bytesToRead];
IntPtr ptrBytesReaded;
ProcessMemoryReaderApi.ReadProcessMemory(m_hProcess, MemoryAddress, buffer, bytesToRead, out ptrBytesReaded);
bytesReaded = ptrBytesReaded.ToInt32();
return buffer;
}
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();
}
}
}
only starts ONE "reading session", i've found in the past that opening -> reading -> closing, ... repeat.... can get you kicked... or well... had that several times...