How can I write on another process memory?
Asked Answered
S

4

11

I have an address that I would like to modify. I have the process. I have the new value. So now what?

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

// Address
var addr = 0x00A66E11;

// Value
var val = 0x63;

How can I write 0x63 (99) to this address on another process memory?

Shigella answered 7/1, 2011 at 6:24 Comment(1)
Don't user var addr... it defaults to int. Use IntPtr instead.Impediment
S
15

@Harvey, from your answer I dug up and found a lot:

Open, Close and Write signatures:

[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);

Flags:

[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
}

Make my life easier method:

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);
}

Writing into another process memory:

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

    WriteMem(p, 0x00A66DB9, 99);
}
Shigella answered 7/1, 2011 at 6:56 Comment(4)
Uh... may I suggest that you never, ever again use int to represent a memory address? Thank you. :)Impediment
I am too lazy to type IntPtr, but I will keep that in mind :PShigella
You forgot to CloseHandle() in WriteMem()Makeyevka
You may also like to check the return value of WriteProcessMemory() as TomTom pointed out it indeed requires privilege to do that. If you don't have enough privilege, you may need to call AdjustTokenPrivilege.Makeyevka
J
6

Despite P/Invoke native functions such as WriteProcessMemory works perfectly, libraries dedicated to memory editing exist and enables you to accomplish this task in an easier way.

Using the library MemorySharp, this can be summarized as:

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

The previous code assumes the address where the value is written is not rebased.

Juliettejulina answered 5/9, 2016 at 21:45 Comment(0)
M
5

Check out WriteProcessMemory at pinvoke.net

Here is another similar post on StackOverflow but they are talking about C++. You can do the same using pinvoke.

Makeyevka answered 7/1, 2011 at 6:31 Comment(2)
ote the real documentation on that and the HIGH rights rtequirements you need. Even an admin account is not enough. msdn.microsoft.com/en-us/library/ms681674(v=vs.85).aspx is a starting point.Freer
Thanks, from this reference I found a lot :)Shigella
I
1

You can use WriteProcessMemory, but be aware that you need to turn on debug privileges, and that it won't work with lots of secured processes in Vista and later.

And that you'll probably shoot yourself in the foot and crash things a few times. I suggest you don't have any important programs running when you do this.

Good luck, you'll need it. :)

Impediment answered 7/1, 2011 at 6:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.