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

在现代系统中编写运行自修改代码(SMC)遇权限异常求助

解决Windows下汇编SMC中栈不可执行导致的异常问题

问题根源

Windows默认启用**数据执行保护(DEP)**机制,栈内存区域默认仅被赋予可读可写权限,不允许执行代码。直接将控制权转移到栈上的指令时,会触发EXCEPTION_ACCESS_VIOLATION异常。

解决方法

通过VirtualProtect函数修改目标栈页的内存权限,将其设置为PAGE_EXECUTE_READWRITE(可读、可写、可执行),即可让栈上的代码正常执行。

修正后的示例代码

.386
.model flat, stdcall
option casemap:none

include smc.Inc ; 包含Win32API定义,以及MsgCaption、MsgBoxText等常量

.code
magic:
    mov eax, esp
    sub esp, 28h ; 预留栈空间存放待执行的代码
    
    ; 修改当前栈页的权限为可执行
    push eax                ; 保存旧权限的输出参数地址
    push PAGE_EXECUTE_READWRITE ; 目标权限
    push 4096               ; 内存页大小(x86平台默认4KB)
    push eax                ; 要修改权限的栈起始地址
    call VirtualProtect
    add esp, 10h            ; 清理VirtualProtect的参数栈
    
    ; 向栈中写入待执行的代码序列
    mov dword ptr[eax], 1778421864h ; push MB_OK; nop; push
    mov dword ptr[eax+4], offset MsgCaption
    mov dword ptr[eax+8], 2425393256h ; nop nop nop push
    mov dword ptr[eax+12], offset MsgBoxText
    mov dword ptr[eax+16], 1778421992h ; push NULL; nop; call
    mov dword ptr[eax+20], MessageBox
    mov dword ptr[eax+24], 3281031312h ; ret nop nop nop
    
    ; 安全跳转到栈上执行代码
    call dword ptr[eax]
    ret

start:
    call magic
    invoke ExitProcess, NULL
end start

关键说明

  • 调用VirtualProtect时,需传入栈起始地址、内存页大小、目标权限,以及一个接收旧权限的临时地址(这里直接用栈上的空间)。
  • 修正了原代码中[espx]的笔误,替换为正确的寄存器寻址[eax]。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 14:50:59