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

x64汇编中LEA/MOV获取WndProc指针异常问题求助

问题原因与解决方案

核心原因

这是ML64汇编器对函数符号的解析逻辑导致的:你代码中引用的WndProc1被汇编器解析成了函数存根(Thunk)的地址,而非实际函数入口地址。存根本质是一个跳转指令,指向真正的函数代码,但直接把存根地址作为窗口过程指针传给Windows时,会因调用约定或跳转逻辑不匹配导致异常。

从反汇编结果能明显看出差异:

  • call WndProc1指令实际跳转到了函数入口07FF6AB9411F5h(汇编器对call指令自动解析为过程入口)
  • lea rbx,[WndProc1]却指向了存根地址07FF6AB941014h(汇编器把符号当成了数据指针解析)

你添加testptr dq 0后用lea rbx,[testptr+8]能得到正确地址,本质是手动绕过了汇编器对WndProc1符号的错误解析,直接计算到了实际函数代码的偏移位置。

解决方案

以下几种方法都能解决这个问题:

1. 显式指定FLAT段访问函数地址

修改指针获取代码为:

mov rbx, FLAT:WndProc1
mov wc.lpfnWndProc, rbx

FLAT:前缀强制汇编器从平坦段中获取函数的实际入口地址,而非存根指针。

2. 显式声明函数为PUBLIC

在WndProc1函数定义前添加PUBLIC WndProc1,确保汇编器将其标记为全局过程符号,正确解析入口地址:

PUBLIC WndProc1
WndProc1 proc
    ; 函数代码
WndProc1 endp

3. 提前声明函数为PROC类型

在使用WndProc1前添加外部过程声明,明确告诉汇编器这是一个过程符号:

EXTRN WndProc1:PROC

补充说明

x64汇编中,ML64对函数符号的默认处理会区分调用指令(如call)和普通内存访问(如mov/lea):call指令会自动解析到过程入口,而mov/lea如果没有明确的符号类型声明,可能会解析到存根或导入表指针,这是导致你问题的根本原因。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 15:15:23