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

如何在Windows系统中编写自修改代码?解决调试异常问题

运行时修改自身代码:Windows vs DOS的差异及解决方案

核心原因

你猜的没错,问题根源就是Windows的内存保护机制:DOS是实模式系统,没有内存分页和权限隔离,代码段与数据段可直接读写执行;但Windows采用保护模式,可执行文件的代码节(通常是.text)默认被标记为PAGE_EXECUTE_READ(可执行、只读),直接向代码页写入会触发EXCEPTION_ACCESS_VIOLATION异常,这就是OllyDbg报错的原因。

可行解决方案

1. 修改目标内存页的属性(最直接方法)

使用Windows API VirtualProtect 修改代码所在内存页的权限,临时赋予可写权限,修改完成后可按需恢复原权限。

汇编示例(x86):

; 假设要修改的代码起始地址为target_code,大小为4字节
push ebp
mov ebp, esp
sub esp, 4          ; 预留保存旧属性的栈空间

push 0              ; lpflOldProtect:旧属性指针
push PAGE_EXECUTE_READWRITE ; flNewProtect:新属性(可执行、可读、可写)
push 4              ; dwSize:修改的内存大小
push target_code    ; lpAddress:目标代码地址
call VirtualProtect ; 调用API修改权限

; 执行代码修改操作,例如替换为NOP指令
mov byte ptr [target_code], 0x90

; 恢复原属性(可选操作)
push dword ptr [ebp-4] ; 传入之前保存的旧属性
push 0
push 4
push target_code
call VirtualProtect

mov esp, ebp
pop ebp

2. 文件映射技术的应用

文件映射更适合持久化修改可执行文件或跨进程共享代码修改,而非运行时动态修改当前进程的内存代码:

  • 通过CreateFile打开自身可执行文件
  • 用CreateFileMapping创建映射对象
  • 用MapViewOfFile获取映射到内存的地址
  • 修改映射区域后,调用UnmapViewOfFile同步到磁盘
    这种方式修改的是磁盘上的文件,而非当前运行进程的内存代码;若要修改运行时内存,VirtualProtect的效率和直接性更高。

3. 其他替代思路

  • 将代码放在数据段:把需要修改的代码放在数据节(默认PAGE_READWRITE),再用VirtualProtect给该段添加PAGE_EXECUTE权限,即可实现读写执行。
  • 动态分配可执行内存:用VirtualAlloc分配一块PAGE_EXECUTE_READWRITE属性的内存,将需要修改的代码拷贝到该区域,修改后直接执行这块内存中的代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 11:42:16