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

Linux内核下如何通过C指针改写x86 movq指令的立即数操作数

实现方案

首先你需要明确x86-64指令的编码规则,以及内核态修改代码页的注意事项,具体实现步骤如下:

前置说明

从你提供的反汇编结果可以看出三条待修改指令的编码结构:

  1. 第一条mov $0x0,%rdx是短格式mov指令,总长度7字节:前3字节为0x48 0xc7 0xc2(REX前缀+操作码+ModR/M),后4字节存储32位有符号立即数,执行时会自动符号扩展到64位。注意你要修改的目标立即数0x19016bc83000超出了32位有符号数的范围,无法直接写入4字节空间,需要先将这条指令改为10字节长度的movabs格式,会覆盖原第二条指令的前3字节,需要你提前在汇编代码中预留足够空间,或者调整后续指令的偏移。
  2. 第二条movabs $0x7ffff7fc6000,%rsi总长度10字节:前2字节为0x48 0xbe,后8字节存储64位立即数,无需修改指令格式可直接改写立即数。
  3. 第三条movabs $0x19016bc83000,%rcx总长度10字节:前2字节为0x48 0xb9,后8字节存储64位立即数,无需修改指令格式可直接改写立即数。

实现代码

#include <linux/mm.h>
#include <asm/cacheflush.h>
#include <asm/io.h>
#include <linux/types.h>

void modify_sr_function(struct page *pageA)
{
    // 获取pageA映射后的内核虚拟地址,对应你说的0x1000地址
    uint8_t *code_base = (uint8_t *)kmap(pageA);
    if (!code_base)
        return;

    // 将代码页临时改为可写权限,避免写保护报错
    set_memory_rw((unsigned long)code_base, 1);

    // -------------------------- 修改第一条指令 --------------------------
    // 如果你汇编时已经将第一条写为movabs格式,可跳过opcode修改,直接写后面8字节立即数
    code_base[0] = 0x48;
    code_base[1] = 0xba; // movabs $imm64, %rdx的opcode
    *(uint64_t *)(code_base + 2) = 0x19016bc83000ULL;

    // -------------------------- 修改第二条指令 --------------------------
    // 第二条指令起始偏移为0x7,跳过前2字节opcode直接写8字节立即数
    *(uint64_t *)(code_base + 0x7 + 2) = 0x19016bc74000ULL;

    // -------------------------- 修改第三条指令 --------------------------
    // 第三条指令起始偏移为0x11,跳过前2字节opcode直接写8字节立即数
    *(uint64_t *)(code_base + 0x11 + 2) = 0x0ULL;

    // 恢复代码页只读权限
    set_memory_ro((unsigned long)code_base, 1);

    // 刷新指令缓存,确保CPU执行修改后的新指令
    flush_icache_range((unsigned long)code_base, (unsigned long)code_base + 0x40);

    kunmap(pageA);
}

额外注意事项

  • 如果你不需要修改第一条指令的格式,请确保目标立即数在-2^31 ~ 2^31-1范围内,可直接修改*(uint32_t *)(code_base + 3)为对应的32位值。
  • 修改代码的过程中必须保证没有其他CPU在并发执行这段代码,否则会触发未知异常甚至内核崩溃。
  • 如果你使用的架构支持PXN(执行权限禁止),需要确保目标页同时拥有可执行权限。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 14:30:03