Search code examples
c#.netwinapinemerle

WriteProcessMemory


Ok... I want to make win32api WriteProcessMemory works.

(Just for learning winAPI on .Net platforms ! ^___^)

I'm using Nemerle but the syntax is similar C# and I can read C# code sure.

So here is my steps :

1) get win api function

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

2) Open process, Get debug privileges ^_^ and ... call function

    def WriteToMem(ProcessHandle : IntPtr, BaseAddress : int, NewVal : array[byte]) : bool
    {
        mutable BytesWritten : int = 0;
        WriteProcessMemory(ProcessHandle, BaseAddress, NewVal, NewVal.Length, out BytesWritten)
    }

3) parameters :

    PatchOptions.noerror = 
    if (this.textBox1.Text=="" && !this.checkBox1.Checked)
    {
        MessageBox.Show("Wind header caption could not be empty");
        false
    }
    else
    if (this.textBox4.Text=="" && this.checkBox1.Checked)
    {
        MessageBox.Show("Process Id could not be empty");
        false
    }
    else
    if (this.textBox2.Text=="")
    {
        MessageBox.Show("BaseAddress could not be empty");
        false
    }
    else
    if (this.textBox3.Text=="")
    {
        MessageBox.Show("NewValue could not be empty");
        false
    }
    else
    {
        try
        {
            if(checkBox1.Checked)
            {
                PatchOptions.WinHeader=this.textBox4.Text.ToString();
                PatchOptions.window=false;
            }
            else
            {
                PatchOptions.WinHeader=this.textBox1.Text.ToString();
                PatchOptions.window=true;
            }
            PatchOptions.BaseAddress=Int32.Parse( this.textBox2.Text.ToString() );
            PatchOptions.NewValue=BitConverter.GetBytes(Int32.Parse(this.textBox3.Text.ToString()));
            this.Close();
            true
        }
        catch
        {
            e is Exception => MessageBox.Show("You entered incorrect values.");
            false
        } 
    }

4) call :

    def isinjected() : string
    {
    if (Options.PatchOptions.noerror)
    {
        try
        {
            Memory.Patch(Options.PatchOptions.WinHeader,Options.PatchOptions.BaseAddress,Options.PatchOptions.NewValue,Options.PatchOptions.window);
        }
        catch
        {
            | e is Exception => MessageBox.Show("Memory Patching error");
            ""
        }
    }
    else
    {
        MessageBox.Show("Patch options Error");
        ""
    }
    }

    def injection = isinjected();
    unless (injection=="")
        this.label1.Text =injection; 

5) Notepad ShowStatus offset :D (for test)

00b550d2 - 89 35 2c c0 b5 00 - mov [00b5c02c],esi
00b5509d - 89 3d 2c c0 b5 00 - mov [00b5c02c],edi

6) Convert Hex to Dec using win Calc : (here is trouble)

00b550d2 = B550D2 = 11882706 ... hope it's correct (that's base address I guess) hm... what is NewValue ? And how can I enter byte array as integer :S

help me please >_<


Solution

  • Here is an example of WriteProcessMemory use in Nemerle:

    using System.Runtime.InteropServices;
    using System;
    using WinApi;
    
    [ Flags ]
    enum AllocationType
    {
        | Commit = 0x1000
    }
    
    [ Flags ]
    enum ProcessAccess : int
    {
        | VMOperation = 0x8
        | VMRead      = 0x10
        | VMWrite     = 0x20
    }
    
    [ Flags ]
    enum MemoryProtection
    {
        | ReadWrite = 0x04
    }
    
    module WinApi
    {
        [ DllImport("kernel32.dll") ]
        public extern OpenProcess
            ( dwDesiredAccess : ProcessAccess
            , bInheritHandle  : bool
            , dwProcessId     : int
            ) : IntPtr;
    
        [ DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true) ]
        public extern VirtualAllocEx
            ( hProcess         : IntPtr
            , lpAddress        : IntPtr
            , dwSize           : uint
            , flAllocationType : AllocationType
            , flProtect        : MemoryProtection
            ) : IntPtr;
    
        [ DllImport("kernel32.dll", SetLastError = true) ]
        public extern WriteProcessMemory
            ( hProcess               : IntPtr
            , lpBaseAddress          : IntPtr
            , lpBuffer               : array[byte]
            , nSize                  : uint
            , lpNumberOfBytesWritten : out int
            ) : bool;
    }
    
    def data = System.Text.Encoding.Unicode.GetBytes("Hello World!\0");
    
    def process = OpenProcess
        ( dwDesiredAccess
            = ProcessAccess.VMOperation
            | ProcessAccess.VMRead
            | ProcessAccess.VMWrite
        , bInheritHandle  = false
        , dwProcessId     = 0x00005394 // Notepad instance
        );
    Console.WriteLine($"process: $process");
    
    def memory = VirtualAllocEx
        ( hProcess         = process
        , lpAddress        = IntPtr.Zero
        , dwSize           = data.Length :> uint
        , flAllocationType = AllocationType.Commit
        , flProtect        = MemoryProtection.ReadWrite
        );
    Console.WriteLine($"memory: $memory");
    
    mutable bytesWritten;
    _ = WriteProcessMemory
        ( hProcess               = process
        , lpBaseAddress          = memory
        , lpBuffer               = data
        , nSize                  = data.Length :> uint
        , lpNumberOfBytesWritten = out bytesWritten
        );
    Console.WriteLine($"bytesWritten: $bytesWritten");