Funzioni Read e Write Process Memory

In tutti i sistemi Windows (credo che da WindowsXP) vi sono funzioni che permettono di accedere, leggere e modificare la memoria dei processi in esecuzione. Queste funzioni sono: ReadProcessMemory e WriteProcessMemory. La prima funzione consente di leggere dei bytes da una zona di memoria di un determinato processo. La seconda funzione consente di scrivere dei bytes in una zona di memoria di un determinato processo. Queste due funzioni richiedono Kernel32.lib per essere dichiarate e utilizzate.
La sintassi delle due funzioni:

BOOL WINAPI ReadProcessMemory(
    __in HANDLE hProcess,
    __in LPCVOID lpBaseAddress,
    __out LPVOID lpBuffer,
    __in SIZE_T nSize,
    __out SIZE_T *lpNumberOfBytesRead
);

BOOL WINAPI WriteProcessMemory(
    __in HANDLE hProcess,
    __in LPVOID lpBaseAddress,
    __in LPCVOID lpBuffer,
    __in SIZE_T nSize,
    __out SIZE_T *lpNumberOfBytesWritten
);


La dichiarazione di queste due funzioni:

Public Declare Function WriteProcessMemory Lib "kernel32" (ByVal hProcess As Integer, ByVal lpBaseAddress As Integer, ByRef lpBuffer As Integer, ByVal nSize As Integer, ByRef lpNumberOfBytesWritten As Integer) As Integer
Public Declare Function ReadProcessMemory Lib "kernel32" Alias "ReadProcessMemory" (ByVal hProcess As Integer, ByVal lpBaseAddress As Integer, ByRef lpBuffer As Integer, ByVal nSize As Integer, ByRef lpNumberOfBytesWritten As Integer) As Integer

* Nota: ci possono essere variazioni di queste due dichiarazioni

Queste funzioni devono essere applicate ad un processo e per questo motivo e' necessario utilizzare altre funzioni per trovare il processo aperto. In VB.net potete trovare un processo usando la classe 'Process' ed ottenere il nome del processo stesso e il suo 'ID'.
Un piccolo esempio puo' aiutare:

Dim myProcesses As Process() = Process.GetProcessesByName("MyApplication")
Dim addr As Long = 0
If myProcesses.Length = 0 Then
    MsgBox("MyApplication isn't in execution.")
    Exit Sub
End If

Ora avete la vostra applicazione 'agganciata' e si puo' procedere ad aprire il processo. Per aprire il processo hai bisogno di un'altra funzione:

HANDLE WINAPI OpenProcess(
    __in DWORD dwDesiredAccess,
    __in BOOL bInheritHandle,
    __in DWORD dwProcessId
);


Dichiarazione di OpenProcess:

Public Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Integer, ByVal bInheritHandle As Integer, ByVal dwProcessId As Integer) As Integer


Ora siamo pronti per aprire il processo; di seguito un piccolo esempio:

processHandle = OpenProcess(PROCESS_ALL_ACCESS, 0, myProcesses(0).Id)
If processHandle = IntPtr.Zero Then
    MsgBox("Unable to open the process.")
    Exit Sub
End If

* Note: PROCESS_ALL_ACCESS è un Const con valore: &H1F0FFF
Ora il nostro processo e' aperto e pronto per essere letto e scritto.
Ecco un esempio che spiega entrambe le funzioni:

Dim RBuff As Long
Dim Address As Integer
Dim Value As Long
Dim Bytes As Integer
Address = &HAB0000
ReadProcessMemory(processHandle, Address, RBuff, 4, Nothing) ' Read 4 bytes and store in RBuff
Address = &HAD0101
Value = RBuff
WriteProcessMemory(processHandle, Address, Value, 4, Nothing) ' Write 4 bytes in another Address