-
-
[原创]探索Windows S3唤醒函数 (二)
-
发表于:
2020-4-14 23:44
3565
-
在前面一篇文章中,已经定位到了内核变量HalpWakeVector,我也说过这是开启OS S3大门的钥匙,那这篇文章就应该是登堂入室了。
hal模块对HalpWakeVector的引用不多,只有4处:
查找Hal模块对HalpLowStubPhysicalAddress的引用:
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(对应参数2)。跳转到HaliAcpiSleep,查看参数edx的来源,将看到如下代码段:
.text:00000001C003C963 mov edx, dword ptr cs:HalpLowStubPhysicalAddress
.text:00000001C003C969 call HalpSetupRealModeResume
.text:00000001C003C96E test al, al
.text:00000001C003C970 jnz loc_1C003CCA2
HaliAcpiSleep传入的值是另一个内核变量HalpLowStubPhysicalAddress。
.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(对应参数2)。跳转到HaliAcpiSleep,查看参数edx的来源,将看到如下代码段:
.text:00000001C003C963 mov edx, dword ptr cs:HalpLowStubPhysicalAddress
.text:00000001C003C969 call HalpSetupRealModeResume
.text:00000001C003C96E test al, al
.text:00000001C003C970 jnz loc_1C003CCA2
HaliAcpiSleep传入的值是另一个内核变量HalpLowStubPhysicalAddress。
.text:00000001C003C963 mov edx, dword ptr cs:HalpLowStubPhysicalAddress
.text:00000001C003C969 call HalpSetupRealModeResume
.text:00000001C003C96E test al, al
.text:00000001C003C970 jnz loc_1C003CCA2
2.Hal对HalpLowStubPhysicalAddress的引用:
查找Hal模块对HalpLowStubPhysicalAddress的引用:
在xrefs窗口会看到一些熟悉的字眼,比如SetupAcpiPhase0。记得Windows启动过程也分Phase0/Phase1两个阶段,所以,我猜想下面的Xrefs窗口中唯一的w xrefs项(注意这是Write引用)是在OS初始化阶段,对HalpLowStubPhysicalAddress进行初始化:
Down w HalpSetupAcpiPhase0+EC mov cs:HalpLowStubPhysicalAddress, rax
跳转到HalpSetupAcpiPhase0+0xEC处,发现果真如此,它调用HalpAllocPhysicalMemory分配物理页面并将返回值写入HalpLowStubPhysicalAddress:
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课