探索Windows S3唤醒函数 (二)

本文深入探讨了HalpWakeVector与HalpLowStubPhysicalAddress在OSS3上下文切换中的关键作用。HalpWakeVector作为开启OSS3的钥匙,在HalpSetupRealModeResume函数中被用于存储HalpLowStubPhysicalAddress的值。HalpLowStubPhysicalAddress则在OS初始化阶段由HalpSetupAcpiPhase0函数通过HalpAllocPhysicalMemory分配物理页面并初始化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前面一篇文章中,已经定位到了变量HalpWakeVector,我也说过这是开启OS S3大门的钥匙,那这篇文章就应该是登堂入室了。

1.从HalpWakeVector过度到HalpLowStubPhysicalAddress:

hal模块对HalpWakeVector的引用不多,只有4处:

但是现阶段只用到HalpSetupRealModeResume函数。

.text:00000001C003D320 HalpSetupRealModeResume proc near       ; CODE XREF: HaliAcpiSleep+139↑p
.text:00000001C003D320                                         ; DATA XREF: .pdata:00000001C0054240↓o
.text:00000001C003D320
.text:00000001C003D320 arg_0           = qword ptr  8
.text:00000001C003D320
.text:00000001C003D320                 mov     [rsp+arg_0], rcx
.text:00000001C003D325                 sub     rsp, 28h
.text:00000001C003D329                 mov     rax, cs:HalpWakeVector
.text:00000001C003D330                 test    rax, rax
.text:00000001C003D333                 jnz     short loc_1C003D336
.text:00000001C003D335                 int     3               ; Trap to Debugger
.text:00000001C003D336
.text:00000001C003D336 loc_1C003D336:                          ; CODE XREF: HalpSetupRealModeResume+13↑j
.text:00000001C003D336                 mov     [rax], edx      ; store HalpLowStubPhysicalAddress to HalpWakeVector

HalpSetupRealModeResume入口处先获得HalpWakeVector的地址,如果地址非空,则向其中写入HaliAcpiSleep调用HalpSetupRealModeResume时传入的参数edx。跳转到HaliAcpiSleep,将看到如下代码段:

.text:00000001C003C963                 mov     edx, dword ptr cs:HalpLowStubPhysicalAddress
.text:00000001C003C969                 call    HalpSetupRealModeResume
.text:00000001C003C96E                 test    al, al
.text:00000001C003C970                 jnz     loc_1C003CCA2

HaliAcpiSleep传入的值是HalpLowStubPhysicalAddress。

2.Hal对HalpLowStubPhysicalAddress的引用:

查找Hal模块对HalpLowStubPhysicalAddress的引用:

在xrefs窗口会看到一些熟悉的字眼,比如SetupAcpiPhase0。记得Windows启动过程也分Phase0/Phase1两个阶段,所以,我猜想下面的w xrefs(注意是Write引用)是在OS初始化阶段,对HalpLowStubPhysicalAddress进行初始化:

Down	w	HalpSetupAcpiPhase0+EC	mov     cs:HalpLowStubPhysicalAddress, rax

跳转到HalpSetupAcpiPhase0+0xEC处果真如此,它调用HalpAllocPhysicalMemory分配物理页面并将返回值写入HalpLowStubPhysicalAddress:

INIT:00000001C0071E1B                 mov     edx, 100000h
INIT:00000001C0071E20                 mov     rcx, rbx
INIT:00000001C0071E23                 call    HalpAllocPhysicalMemory
INIT:00000001C0071E28                 mov     cs:HalpLowStubPhysicalAddress, rax
INIT:00000001C0071E2F                 test    rax, rax
INIT:00000001C0071E32                 jz      short loc_1C0071E53

由此可见,双机调试时需要在HalpSetupAcpiPhase0函数上下断点,观察HalpLowStubPhysicalAddress的值是否和UEFI S3Resume时访问的Facs->XFirmwareWakingVector相同。下一篇就动手验证一下。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值