通过c#编辑内存地址

本文关键字:地址 内存 编辑 通过 | 更新日期: 2023-09-27 18:11:39

我想编辑一个活动的应用程序(编辑内存地址),

在地址00498D45上,我想编辑它的值

当前值:

MOV BYTE PTR SS:[EBP-423],7

更新值:

 MOV BYTE PTR SS:[EBP-423],8

到目前为止我得到的是这个(在网上搜索了一下,这是我得到的):

提前感谢!

using System.Runtime.InteropServices;
    [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
}
[DllImport("kernel32.dll")]
private static extern IntPtr OpenProcess(ProcessAccessFlags dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, int dwProcessId);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, uint nSize, out int lpNumberOfBytesWritten);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [Out] byte[] lpBuffer, int dwSize, out int lpNumberOfBytesRead);
[DllImport("kernel32.dll")]
public static extern Int32 CloseHandle(IntPtr hProcess);
Process process = Process.GetProcessesByName("My Apps Name").FirstOrDefault();
public static bool WriteMemory(Process process, int address, long value, out int bytesWritten)
{
    IntPtr hProc = OpenProcess(ProcessAccessFlags.All, false, process.Id);
    byte[] val = BitConverter.GetBytes(value);
    bool worked = WriteProcessMemory(hProc, new IntPtr(address), val, (UInt32) val.LongLength, out bytesWritten);
    CloseHandle(hProc);
    return worked;
}

通过c#编辑内存地址

从你的另一个问题:

WriteMemory(Process process,00498D45 , MOV BYTE PTR SS:[EBP-423],8)
这个问题太多了,我不知道从哪里开始。首先,这根本不是正确的c#语法。
  1. 你正在调用一个函数,但是你有一个Process,就像它是一个签名。
  2. 00498D45在任何基数下都不是一个有效的常数。如果你指的是十六进制,(你可能会这样做,因为你正在处理地址)然后像所有其他类c语言一样,应该表示为0x00498D45
  3. 这是ASCII的x86汇编代码(但它不是字符串,你只是一团糟)。您不能将ASCII汇编码放入另一个进程的地址空间!

也许你应该多研究一下编译和汇编在构建程序时是如何工作的,以及你的CPU在执行程序时实际在做什么。另外,我建议您通读一下您显然从某处获取的示例代码,并尝试理解它。你最好了解发生了什么,而不是让每个人帮助你修复你拼凑的东西。</rant>

无论如何,在你组装你的代码之后,它看起来像这样(重新组装):
C68559FEFFFF08    mov byte [ebp-0x1a7],0x8

这意味着你的指令实际上是字节串C6 85 59 FE FF FF 08。这就是你需要写入目标应用程序的内容。

这是你要做的事情的基础:

byte[] new_instr = new byte[] {0xC6, 0x85, 0x59, 0xFE, 0xFF, 0xFF, 0x08};
IntPtr target_addr = (IntPtr)0x00498D45;
int bytesWritten;
WriteProcessMemory(hProcess, target_addr, new_instr, (UInt32)new_instr.Length, out bytesWritten);

您复制并粘贴的WriteMemory内存函数在这里不起作用。问题是,它只写一个4字节的long。你需要写7个字节。因此,您要么必须修改该函数以使用byte[]参数,要么自己动手。


我钦佩你的雄心壮志,但你真的应该从低一点开始。编写一些c#代码,让自己熟悉用类C语言编程。然后写一些C来熟悉当你做得不完美时崩溃的情况。然后尝试一下汇编——也许在C代码中编写一些小的内联片段。最后,您将准备好破解其他正在运行的进程的指令。

你可以使用像MemorySharp这样的注入库(我是作者)。所有这些函数都封装在一个方便的API中,并集成了一个汇编程序(FASM语法)。因此,这段代码执行您想要的:

using (var m = new MemorySharp(ApplicationFinder.FromProcessName("My App").First()))
{
    m.Assembly.Inject("MOV BYTE [EBP-423],8", new IntPtr(0x00498D45));
}