2011-01-07 10 views
5

Tengo una dirección que me gustaría modificar. Tengo el proceso. Tengo el nuevo valor. ¿Y ahora que?¿Cómo puedo escribir en otra memoria de proceso?

// My Process 
var p = Process.GetProcessesByName("ePSXe").FirstOrDefault(); 

// Address 
var addr = 0x00A66E11; 

// Value 
var val = 0x63; 

¿Cómo puedo escribir 0x63 (99) a esta dirección de memoria en otro proceso?

+0

No usar 'var addr' ... por defecto es' int'. Use 'IntPtr' en su lugar. – Mehrdad

Respuesta

10

@Harvey, de su respuesta que desenterrado y se encontró una gran cantidad:

abrir, cerrar y escritura firmas:

[DllImport("kernel32.dll")] 
static extern IntPtr OpenProcess(ProcessAccessFlags dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, int dwProcessId); 

[DllImport("kernel32.dll", SetLastError = true)] 
static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, uint nSize, out int lpNumberOfBytesWritten); 

[DllImport("kernel32.dll")] 
public static extern Int32 CloseHandle(IntPtr hProcess); 

Banderas:

[Flags] 
public enum ProcessAccessFlags : uint 
{ 
    All = 0x001F0FFF, 
    Terminate = 0x00000001, 
    CreateThread = 0x00000002, 
    VMOperation = 0x00000008, 
    VMRead = 0x00000010, 
    VMWrite = 0x00000020, 
    DupHandle = 0x00000040, 
    SetInformation = 0x00000200, 
    QueryInformation = 0x00000400, 
    Synchronize = 0x00100000 
} 

hacer mi vida método más fácil:

public static void WriteMem(Process p, int address, long v) 
{ 
    var hProc = OpenProcess(ProcessAccessFlags.All, false, (int)p.Id); 
    var val = new byte[] { (byte)v }; 

    int wtf = 0; 
    WriteProcessMemory(hProc, new IntPtr(address), val, (UInt32)val.LongLength, out wtf); 

    CloseHandle(hProc); 
} 

Escribir en otra memoria de proceso:

static void Main(string[] args) 
{ 
    var p = Process.GetProcessesByName("ePSXe").FirstOrDefault(); 

    WriteMem(p, 0x00A66DB9, 99); 
} 
+5

Uh ... ¿puedo sugerir que nunca, ** alguna vez ** vuelva a utilizar 'int' para representar una dirección de memoria? Gracias. :) – Mehrdad

+0

Soy demasiado flojo para escribir 'IntPtr', pero lo tendré en cuenta: P – BrunoLM

+1

Olvidaste CloseHandle() en WriteMem() –

4

Salida WriteProcessMemory en pinvoke.net

Aquí hay otro semejante post en StackOverflow pero están hablando de C++. Puedes hacer lo mismo usando pinvoke.

+0

ota la documentación real sobre eso y los requisitos de derechos ALTOS que necesita. Incluso una cuenta de administrador no es suficiente. http://msdn.microsoft.com/en-us/library/ms681674(v=vs.85).aspx es un punto de partida. – TomTom

+0

Gracias, de esta referencia encontré mucho :) – BrunoLM

0

Puede usar WriteProcessMemory, pero tenga en cuenta que debe activar los privilegios de depuración y que no funcionará con muchos procesos seguros en Vista y posterior.

Y es probable que se pegue un tiro en el pie y choque cosas varias veces. Sugiero que no tenga ningún programa importante ejecutándose cuando haga esto.

Buena suerte, la necesitarás. :)

2

A pesar de las funciones nativas P/Invoke como WriteProcessMemory funciona perfectamente, existen bibliotecas dedicadas a la edición de la memoria y le permite realizar esta tarea de una manera más fácil.

El uso de la biblioteca MemorySharp, esto se puede resumir como:

using(var sharp = new MemorySharp(Process.GetProcessesByName("ePSXe").FirstOrDefault())) 
{ 
    sharp[0x00A66E11, false].Write(0x63); 
} 

El código anterior asume la dirección donde se escribe el valor no está rebasada.

Cuestiones relacionadas