WriteProcessMemory (kernel32)
Last changed: 109.202.69.200

.
Summary

C# Signature:

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

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

Warning
Do not use int or uint as out parameter, you will get a nice buffer overflow in x64. Using uint for nSize seems ok, because it is passed in register.

VB.Net Signature:

<DllImport("kernel32.dll", SetLastError:=True)> _
Public Shared Function WriteProcessMemory(ByVal hProcess As IntPtr, ByVal lpBaseAddress As IntPtr, ByVal lpBuffer As Byte(), ByVal nSize As System.UInt32, <Out()> ByRef lpNumberOfBytesWritten As IntPtr) As Boolean
End Function

Boo Signature:

[DllImport("kernel32.dll", SetLastError : true)]
protected static def WriteProcessMemory(hProcess as IntPtr, lpBaseAddress as IntPtr, lpBuffer as (byte), nSize as int, ref lpNumberOfBytesWritten as int) as bool:
     pass

User-Defined Types:

None.

Notes:

None.

Tips & Tricks:

Use the Signature with the IntPtr as lpBuffer for passing Structures, which got copied to the unmanaged Heap with Marshal.AllocHGlobal and Marshal.StructureToPtr.

Sample Code:

public int WriteByteArray( IntPtr BaseAddress, byte [] NewVal )
{
    // Return Value
    int ReturnVal;

    // Write Memory Byte Array
    ReturnVal = WriteProcessMemory( this.hProcess, BaseAddress, NewVal, NewVal.Length, out this.BytesWritten );

    return this.BytesWritten;
}

// Sample with IntPtr as lpBuffer for passing structs
public class SomeClass
{
    // Some Win32 Struct in CSharp
    [StructLayout(LayoutKind.Sequential)]
    private struct LVITEM
    {
        public UInt32 mask;
        public Int32 iItem;
        public Int32 iSubItem;
        public UInt32 state;
        public UInt32 stateMask;
        public IntPtr pszText;
        public Int32 cchTextMax;
        public Int32 iImage;
        public IntPtr lParam;
        public Int32 iIndent;
        public Int32 iGroupId;
        public UInt32 cColumns;
        public UIntPtr puColumns;
        public IntPtr piColFmt;
        public Int32 iGroup;
    }

    public void WriteStructureToProcessMemory(IntPtr processHandle, IntPtr BaseAddress)
    {
        UInt32 sizeOfLVITEM = (UInt32)Marshal.SizeOf(typeof(LVITEM));
       IntPtr ptrToLvItem = Marshal.AllocHGlobal((int)sizeOfLVITEM);
        Marshal.StructureToPtr(lvItem, ptrToLvItem, true);

        WriteProcessMemory(processHandle, BaseAddress, ptrToLvItem, sizeOfLVITEM, UIntPtr.Zero);
    }

}

'VB.Net
Public Shared Function Poke(ByVal proc As Process, ByVal target As Integer, ByVal data As Byte()) As Boolean
    Return WriteProcessMemory(proc.Handle, New IntPtr(target), data, data.Length, 0)
End Function

Alternative Managed API:

The ManagedWindowsApi project (http://mwinapi.sourceforge.net) provides a ProcessMemoryChunk class to allocate and access memory of a different process.

Documentation