c# - 写进程内存

标签 c# .net winapi nemerle

好的...我想让 win32api WriteProcessMemory 工作。

(只是为了在 .Net 平台上学习 winAPI!^___^)

我正在使用 Nemerle,但语法与 C# 类似,我可以肯定地阅读 C# 代码。

这是我的步骤:

1) 获取win api函数

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

2) 打开进程,获取调试权限^_^ 和...调用函数

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

3) 参数:

    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)调用:

    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 (测试用)

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

6) 使用 win Calc 将十六进制转换为十进制: (麻烦来了)

00b550d2 = B550D2 = 11882706 ...希望它是正确的 (我猜这是基地址) 嗯...什么是 NewValue ? 以及如何将字节数组作为整数输入:S

请帮帮我>_<

最佳答案

这是一个在 Nemerle 中使用 WriteProcessMemory 的例子:

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

关于c# - 写进程内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2205370/

相关文章:

c# - P/invoke System.ExecutionEngineException 将数组作为 ref/out 传递时

windows - 除了 "flags"参数外,ChildWindowFromPointEx 和 ChildWindowFromPoint 有何不同?

c++ - 删除定时器-队列定时器

c# - LinqToSql - 不允许在查询中显式构造实体类型 '{0}'

c# - 在 Angular 2 和 ASP.NET Core 中使用相对图像路径

.net - Fn 地址不可用

c++ - 64 位平台上的 WinAPI IcmpSendEcho

c# - 片段内的膨胀布局

javascript - 使用 GET 将复杂的 JS 对象从 Angular 传递到 C# WebApi

c# - Bitmap.SetPixel 未设置正确的颜色