You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# 使用Memory.dll实现AOB Injection(代码洞穴)时Opcode未修改问题

问题根因及修复方案

1. 目标地址拼写错误

你的代码注释标注的目标注入地址是UserAssembly+36652EE2,但实际传入CreateCodeCave方法的地址是UserAssembly+36652EE,少了最后一位字符2,导致程序写入到了错误的内存地址,目标地址自然不会有变化。

2. 覆写字节长度不符合跳转指令要求

CreateCodeCave方法的第三个参数为需要覆盖的原地址处的字节长度:

  • x86架构下近跳转jmp指令固定占5字节
  • x64架构下远跳转jmp指令占14字节
    你仅传入了2,长度小于跳转指令的最小占用空间,Memory.dll会判定操作非法,不会执行原地址的patch逻辑。

3. 目标内存页无写入权限

UserAssembly模块对应的内存页默认权限为RX(可读可执行),没有可写权限,需要先调用ChangeProtection方法将目标地址的内存权限修改为RWX(可读可写可执行),才能正常写入跳转指令。

4. 进程操作句柄无效

需要先校验OpenProcess的返回结果,确认进程名匹配且程序获得了足够的操作权限,若获取的进程句柄无效,后续所有内存操作都会静默失败。


修复后参考代码

// 打开目标进程,注意进程名不要加.exe后缀
bool openSuccess = m.OpenProcess("Process");
if (!openSuccess)
{
    Console.WriteLine("打开进程失败,请检查进程名和权限");
    return;
}

// 目标注入地址,注意不要拼写错误
string injectAddress = "UserAssembly+36652EE2";
// 自定义写入代码洞穴的Opcode
byte[] freezebytesX = { 0xF3, 0x0F };

// 先修改目标地址内存权限为RWX
m.ChangeProtection(injectAddress, 5, MemoryProtection.ExecuteReadWrite, out _);

// x86架构下传入覆写长度为5,足够写入jmp指令
UIntPtr codecavebase = m.CreateCodeCave(injectAddress, freezebytesX, 5);

// 64位进程不要用int接收地址,会溢出截断
UIntPtr codecaveAllocAddress = UIntPtr.Add(codecavebase, freezebytesX.Length);
long jumpBackOffset = (long)codecaveAllocAddress - 6;
        
Console.WriteLine("Read Allocated Memory: 0x" + jumpBackOffset.ToString("X") + "\r\n" + codecaveAllocAddress);

// 操作完成后改回原内存权限
m.ChangeProtection(injectAddress, 5, MemoryProtection.ExecuteRead, out _);

内容的提问来源于stack exchange,提问作者Discord Programs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 17:45:04