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
相关产品推荐
相关产品推荐

