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

C#实现64位进程代码注入时E9跳转地址计算错误问题求解

问题根源

  1. E9相对跳转的64位架构限制:x64下E9操作码对应的相对近跳转,偏移量仍为32位有符号整数,仅支持±2GB范围内的跳转。你给出的跳转源地址0x7FFBA13F52EE与目标地址0x7FF95BBD0000的差值已经超出2GB范围,强行计算偏移会触发整数溢出,最终得到错误的跳转地址。
  2. 原Jmp方法逻辑缺陷:使用无符号ulong计算偏移,没有处理有符号负数的场景,且强制截断为4字节的逻辑本身就不适用于超出范围的64位跳转场景。
  3. 补充:你原有代码调用Jmp方法时存在参数拼写错误,ConeInjectionAddress应为CodeInjectionAddress,请注意修正。

修复方案

方案1:使用x64绝对远跳转(推荐,无地址范围限制)

x64下可通过FF 25 00 00 00 00 + 8字节绝对地址的指令序列实现任意地址跳转,无需计算偏移,直接填入目标地址即可,指令总长度14字节。
对应C#实现代码:

public static byte[] Jmp64(ulong jumpTo, bool addNop = false)
{
    List<byte> result = new List<byte>();
    if (addNop)
    {
        result.Add(0x90); // 按需添加NOP
    }
    // 绝对跳转指令前缀
    result.AddRange(new byte[] { 0xFF, 0x25, 0x00, 0x00, 0x00, 0x00 });
    // 写入小端序的64位目标地址
    result.AddRange(BitConverter.GetBytes(jumpTo));
    return result.ToArray();
}

使用注意:需要确保跳转源地址处有至少14字节的可改写空间。如果原有空间不足,可将被覆盖的原始指令先复制到你的注入代码块末尾,注入逻辑执行完成后再跳回原地址后续位置即可。

方案2:保留E9相对跳转(仅适用于±2GB范围内的跳转)

如果确认跳转源和目标地址的偏移在2GB以内,可修正原偏移计算逻辑,适配有符号整数计算:

public static byte[] Jmp64Relative(ulong jumpTo, ulong jumpFrom, bool addNop = false)
{
    // 计算相对偏移,E9跳转长度为5字节,需减去5
    long offset = (long)jumpTo - (long)jumpFrom - 5;
    // 校验偏移是否在32位有符号整数范围内
    if (offset < int.MinValue || offset > int.MaxValue)
    {
        throw new InvalidOperationException("跳转偏移超出32位范围,无法使用E9相对跳转");
    }
    List<byte> result = new List<byte>();
    if (addNop)
    {
        result.Add(0x90);
    }
    result.Add(0xE9);
    // 写入小端序的32位偏移
    result.AddRange(BitConverter.GetBytes((int)offset));
    return result.ToArray();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 23:45:05