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

64位内核驱动.cpp调用同项目汇编函数致系统冻结无蓝屏排查

问题原因

你遇到的系统无蓝屏直接冻结,核心是x64 Windows内核栈对齐规则违反+全局异常拦截工具的共同作用,具体问题点如下:

  • x64平台下所有函数调用执行前,栈指针RSP必须保持16字节对齐。执行call ATest指令时,CPU会自动将8字节的返回地址压入栈,进入ATest函数时RSP已经比16对齐的位置偏移了8字节。你代码中直接SUB RSP, 40h,40h(64字节)是16的整数倍,执行完这条指令后RSP仍然偏移8字节,不满足对齐要求。此时调用DbgPrint,只要函数内部使用了要求16字节对齐的SSE/AVX指令,就会立刻触发内核访问异常。
  • 你代码中调用了ByePgInitialize注册了全局异常处理,这个框架会拦截内核未处理异常并直接挂起系统,不会走默认的蓝屏(KeBugCheckEx)流程,所以你看不到BSOD,只会表现为系统完全锁死。
  • 汇编文件存在冗余风险代码:你定义了空的main过程,MASM默认会将END关键字前的首个非空过程识别为模块入口,容易和KMDF驱动默认的GsDriverEntry入口点冲突,引发不可预期的执行流错误。
  • 你注释掉的32位风格汇编调用逻辑完全不符合x64调用约定:x64下前4个参数通过RCX/RDX/R8/R9传递,不是栈传参,那部分代码如果启用会直接破坏栈结构。
修正步骤
  1. 修正汇编文件代码,删除冗余过程,保证栈对齐,正确预留x64调用要求的32字节影子空间:
EXTERN DbgPrint:PROC

.data
    dbgString byte "ATest() routine has been CALLED!\n", 0

.code

ATest PROC PUBLIC
    ; 进入函数时RSP偏移8字节(call压入返回地址导致)
    ; 压入非易失性寄存器RBP,RSP再减8,刚好对齐到16字节边界
    push rbp
    mov  rbp, rsp
    ; 预留32字节影子空间供被调用函数使用,长度为16的倍数,不破坏对齐
    sub  rsp, 20h
    mov  rcx, offset dbgString
    call DbgPrint
    ; 还原栈空间
    add  rsp, 20h
    pop  rbp
    ret
ATest ENDP

END
  1. 检查VS项目配置:
    • 右键MyASM.asm文件→属性,确认项类型设置为Microsoft Macro Assembler (ml64.exe),目标平台匹配x64。
    • 项目属性→链接器→高级→入口点,确认值为GsDriverEntry(KMDF驱动默认入口),避免被汇编模块错误设置入口。
  2. 调试阶段可以临时注释ByePgInitialize的调用,此时如果还有栈错误,系统会正常抛出蓝屏,方便通过WinDbg分析调用栈排查问题,不会直接锁死。
额外说明
  • 你之前写的SUB RSP,40h的栈预留值是错误的:如果不用push rbp的方式对齐,需要预留的栈空间是28h(40字节,含32字节影子空间+8字节对齐填充),硬编码偏移很容易算错对齐值,优先用push/pop非易失性寄存器的方式自然对齐,出错概率更低。
  • 内核模式下编写汇编必须严格遵守x64调用约定,非易失性寄存器(RBX/RBP/RSI/RDI/R12-R15)如果在函数中修改,必须在返回前还原,否则会引发调用者执行流混乱。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 13:30:44