首页
社区
课程
招聘
[原创][原创]探索Windows S3唤醒函数 (一)
发表于: 2020-4-14 01:18 5668

[原创][原创]探索Windows S3唤醒函数 (一)

2020-4-14 01:18
5668
UefiCpuPkg\Universal\Acpi\S3Resume2Pei\S3Resume.c:
VOID
EFIAPI
S3ResumeBootOs (
  IN ACPI_S3_CONTEXT                *AcpiS3Context,
  IN PEI_S3_RESUME_STATE            *PeiS3ResumeState
  )
{
...
    DEBUG ((DEBUG_INFO, "Transfer to 32bit OS waking vector - %x\r\n", (UINTN)Facs->XFirmwareWakingVector));
      SwitchStack (
        (SWITCH_STACK_ENTRY_POINT) (UINTN) Facs->XFirmwareWakingVector,
        NULL,NULL,(VOID *)(UINTN)TempStackTop);
...
}
根据ACPI Spec,Facs->XFirmwareWakingVector是OS执行S3唤醒的函数:
UefiCpuPkg\Universal\Acpi\S3Resume2Pei\S3Resume.c:
VOID
EFIAPI
S3ResumeBootOs (
  IN ACPI_S3_CONTEXT                *AcpiS3Context,
  IN PEI_S3_RESUME_STATE            *PeiS3ResumeState
  )
{
...
    DEBUG ((DEBUG_INFO, "Transfer to 32bit OS waking vector - %x\r\n", (UINTN)Facs->XFirmwareWakingVector));
      SwitchStack (
        (SWITCH_STACK_ENTRY_POINT) (UINTN) Facs->XFirmwareWakingVector,
        NULL,NULL,(VOID *)(UINTN)TempStackTop);
...
}
根据ACPI Spec,Facs->XFirmwareWakingVector是OS执行S3唤醒的函数:
  X Firmware Waking
Vector
  8  24  64-bit physical address of OSPM’s Waking Vector. Before transitioning the system into a global sleeping state, OSPM fills in this field and the OSPM Flags field to describe the waking vector. OSPM populates this field with the physical memory address of an OS-specific wake function. During POST, the platform firmware checks if the value of this field is non-zero and if so transfers control to OSPM by jumping to this address after creating the appropriate execution environment













表格摘自ACPI 6.2 "5.2.10 Firmware ACPI Control Structure (FACS)",FACS表用于firmware和OS传输数据,表格中提到的OSPM是指OS的ACPI.sys模块。如表格所述,Facs->XFirmwareWakingVector的值由Windows 负责填写。在Comet lake platform上Facs->XFirmwareWakingVector的物理地址值为:0x2000,所以,我决定在windows上查找具体设置的代码(既然OS能设置,驱动模块也能设置,这是挂Hook的绝佳选择)。

查看ACPI table当然少不了rw工具,不过很可惜,不知出于什么原因,在xp\win7\win10上Facs->XFirmwareWakingVector都不约而同的不可见(目前,我猜想:如ACPI spec如说,该值只有在进入S3 Sleep时才会被设置):

表格摘自ACPI 6.2 "5.2.10 Firmware ACPI Control Structure (FACS)",FACS表用于firmware和OS传输数据,表格中提到的OSPM是指OS的ACPI.sys模块。如表格所述,Facs->XFirmwareWakingVector的值由Windows 负责填写。在Comet lake platform上Facs->XFirmwareWakingVector的物理地址值为:0x2000,所以,我决定在windows上查找具体设置的代码(既然OS能设置,驱动模块也能设置,这是挂Hook的绝佳选择)。

查看ACPI table当然少不了rw工具,不过很可惜,不知出于什么原因,在xp\win7\win10上Facs->XFirmwareWakingVector都不约而同的不可见(目前,我猜想:如ACPI spec如说,该值只有在进入S3 Sleep时才会被设置):

虽然在RW中未见Facs->XFirmwareWakingVector的值,但也不能阻挡我搜索的步伐。查找ReactOS 3.15源码后,我选择用windbg搜索WakeVector相关的符号:
drivers\bus\acpi\acpica\hardware\hwsleep.c
ACPI_STATUS
AcpiSetFirmwareWakingVector64 (
    UINT64                  PhysicalAddress)
{
    ACPI_FUNCTION_TRACE (AcpiSetFirmwareWakingVector64);
 
 
    /* Determine if the 64-bit vector actually exists */
 
    if ((AcpiGbl_FACS->Length <= 32) || (AcpiGbl_FACS->Version < 1))
    {
        return_ACPI_STATUS (AE_NOT_EXIST);
    }
 
    /* Clear 32-bit vector, set the 64-bit X_ vector */
 
    AcpiGbl_FACS->FirmwareWakingVector = 0;
    AcpiGbl_FACS->XFirmwareWakingVector = PhysicalAddress;
    return_ACPI_STATUS (AE_OK);
}
(跟各位得瑟一把,由于工作缘故,我有部分Checked Build OS,所以我逆向的工作量会减轻不少),并最终在hal模块中找到对应的(变量)符号,然而该变量的值依然是空:
drivers\bus\acpi\acpica\hardware\hwsleep.c
ACPI_STATUS
AcpiSetFirmwareWakingVector64 (
    UINT64                  PhysicalAddress)
{
    ACPI_FUNCTION_TRACE (AcpiSetFirmwareWakingVector64);
 
 
    /* Determine if the 64-bit vector actually exists */
 
    if ((AcpiGbl_FACS->Length <= 32) || (AcpiGbl_FACS->Version < 1))
    {
        return_ACPI_STATUS (AE_NOT_EXIST);
    }
 
    /* Clear 32-bit vector, set the 64-bit X_ vector */
 
    AcpiGbl_FACS->FirmwareWakingVector = 0;
    AcpiGbl_FACS->XFirmwareWakingVector = PhysicalAddress;
    return_ACPI_STATUS (AE_OK);
}
(跟各位得瑟一把,由于工作缘故,我有部分Checked Build OS,所以我逆向的工作量会减轻不少),并最终在hal模块中找到对应的(变量)符号,然而该变量的值依然是空:
kd> x *!*WakeVector*
82a21c98          hal!HalpWakeVector = <no type information>
 
kd> dd hal!HalpWakeVector
82a21c98  00000000 00000000 00000000 00000000
很遗憾,Windows内核原理\Windows情景分析等经典书都不曾关注S3\S4的实现,而本文OS相关代码是在虚拟机上做的测试,虚拟机进入S3后系统被挂起,windbg也失去作用,因此,我对hal模块进行简单的逆向分析。
kd> x *!*WakeVector*
82a21c98          hal!HalpWakeVector = <no type information>
 
kd> dd hal!HalpWakeVector
82a21c98  00000000 00000000 00000000 00000000
很遗憾,Windows内核原理\Windows情景分析等经典书都不曾关注S3\S4的实现,而本文OS相关代码是在虚拟机上做的测试,虚拟机进入S3后系统被挂起,windbg也失去作用,因此,我对hal模块进行简单的逆向分析。

1.确定hal模块:

kd> lm m hal
Browse full module list
start    end        module name
82a04000 82a3d000   hal        (pdb symbols)          e:\symbols\win7x86sp1chk\halmacpi.pdb\0B89B9AEB8FB4822A25882B9A877C1031\halmacpi.pdb
kd> lmvm hal
Browse full module list
start    end        module name
82a04000 82a3d000   hal        (pdb symbols)          e:\symbols\win7x86sp1chk\halmacpi.pdb\0B89B9AEB8FB4822A25882B9A877C1031\halmacpi.pdb
    Loaded symbol image file: halmacpi.dll
    Image path: halmacpi.dll
    Image name: halmacpi.dll
虚拟机上使用的hal模块对应c:\windows\system32\halmacpi.dll,用IDA加载该dll(附注,根据调试发现,下文将提到的hal函数在win7\win8.1\win10差别不大,因此对于这部分内容在各OS之间还是具有参考价值)。本文借助win10x64 TH2 Checked build的halmacpi.dll为参考,分析了win10 RS5 free build的halmacpi.dll流程(附注,微软提供的win10x64 TH2 Checked build无法正常安装使用,如果看官手头有该OS,需要用dism命令,从镜像中提取halmacpi.dll。此处要感谢我的同事lyly,告诉我dism提取镜像中模块的方法)

2.搜索对hal!HalpWakeVector的引用:

呵呵,很可惜,还真没找到。不过运气好,在"Strings window"中看到一串重要的字符串以及函数HalpAcpiGetFacsMapping对它的引用:
kd> lm m hal
Browse full module list
start    end        module name
82a04000 82a3d000   hal        (pdb symbols)          e:\symbols\win7x86sp1chk\halmacpi.pdb\0B89B9AEB8FB4822A25882B9A877C1031\halmacpi.pdb
kd> lmvm hal
Browse full module list
start    end        module name
82a04000 82a3d000   hal        (pdb symbols)          e:\symbols\win7x86sp1chk\halmacpi.pdb\0B89B9AEB8FB4822A25882B9A877C1031\halmacpi.pdb
    Loaded symbol image file: halmacpi.dll
    Image path: halmacpi.dll
    Image name: halmacpi.dll
虚拟机上使用的hal模块对应c:\windows\system32\halmacpi.dll,用IDA加载该dll(附注,根据调试发现,下文将提到的hal函数在win7\win8.1\win10差别不大,因此对于这部分内容在各OS之间还是具有参考价值)。本文借助win10x64 TH2 Checked build的halmacpi.dll为参考,分析了win10 RS5 free build的halmacpi.dll流程(附注,微软提供的win10x64 TH2 Checked build无法正常安装使用,如果看官手头有该OS,需要用dism命令,从镜像中提取halmacpi.dll。此处要感谢我的同事lyly,告诉我dism提取镜像中模块的方法)

2.搜索对hal!HalpWakeVector的引用:

呵呵,很可惜,还真没找到。不过运气好,在"Strings window"中看到一串重要的字符串以及函数HalpAcpiGetFacsMapping对它的引用:
虚拟机上使用的hal模块对应c:\windows\system32\halmacpi.dll,用IDA加载该dll(附注,根据调试发现,下文将提到的hal函数在win7\win8.1\win10差别不大,因此对于这部分内容在各OS之间还是具有参考价值)。本文借助win10x64 TH2 Checked build的halmacpi.dll为参考,分析了win10 RS5 free build的halmacpi.dll流程(附注,微软提供的win10x64 TH2 Checked build无法正常安装使用,如果看官手头有该OS,需要用dism命令,从镜像中提取halmacpi.dll。此处要感谢我的同事lyly,告诉我dism提取镜像中模块的方法)

2.搜索对hal!HalpWakeVector的引用:

呵呵,很可惜,还真没找到。不过运气好,在"Strings window"中看到一串重要的字符串以及函数HalpAcpiGetFacsMapping对它的引用:

01C003D8C0 aHalpacpigetfac db '**** HalpAcpiGetFacsMapping: No FADT found.',0Ah,0
.text:00000001C003D8C0                                         ; DATA XREF: HalpAcpiGetFacsMapping+54↑o

01C003D8C0 aHalpacpigetfac db '**** HalpAcpiGetFacsMapping: No FADT found.',0Ah,0
.text:00000001C003D8C0                                         ; DATA XREF: HalpAcpiGetFacsMapping+54↑o

2.1.在HalpAcpiGetFacsMapping内部,有两段代码片:

01C0001E39                 mov     edx, 'PCAF'
.text:00000001C0001E3E                 call    HalpAcpiGetTableWork
.text:00000001C0001E43                 test    rax, rax
.text:00000001C0001E46                 jnz     short loc_1C0001E83 ; Physical memory address of the FACS
这段代码是根据表的签名来查找Acpi table,Long字符数组'PCAF'其实就是FACP表的签名。HalpAcpiGetTableWork将返回FACP表的物理地址。然后再从FACP->FIRMWARE_CTRL和签名"SCAF"获得Facs地址:
01C0001E39                 mov     edx, 'PCAF'
.text:00000001C0001E3E                 call    HalpAcpiGetTableWork
.text:00000001C0001E43                 test    rax, rax
.text:00000001C0001E46                 jnz     short loc_1C0001E83 ; Physical memory address of the FACS
这段代码是根据表的签名来查找Acpi table,Long字符数组'PCAF'其实就是FACP表的签名。HalpAcpiGetTableWork将返回FACP表的物理地址。然后再从FACP->FIRMWARE_CTRL和签名"SCAF"获得Facs地址:
01C0001E83 loc_1C0001E83:                          ; CODE XREF: HalpAcpiGetFacsMapping+52↑j
.text:00000001C0001E83                 mov     edx, [rax+FACP_20.FIRMWARE_CTRL] ; Facp->FIRMWARE_CTRL
.text:00000001C0001E86                 mov     r9d, 'SCAF'     ; Physical memory address of the FACS
...
.text:00000001C0001EB2                 call    HalpAcpiCheckAndMapTable
.text:00000001C0001EB7                 mov     cs:HalpAcpiFacsMapping, rax ; cs:HalpAcpiFacsMapping: hold facs phyical address
...
.text:00000001C0001ED3                 mov     rax, cs:HalpAcpiFacsMapping ;返回Facs表di'zhi
  FIRMWARE_CTRL  4  36  Physical memory address of the FACS, where OSPM and Firmware exchange control information. See Section 5.2.6, “Root System Description Table,” for a description of the FACS. If the X_FIRMWARE_CTRL field contains a non zero value which can be used by the OSPM, then this field must be ignored by the OSPM. If the HARDWARE_REDUCED_ACPI flag is set, and both this field and the X_FIRMWARE_CTRL field are zero, there is no FACS available. 

01C0001E83 loc_1C0001E83:                          ; CODE XREF: HalpAcpiGetFacsMapping+52↑j
.text:00000001C0001E83                 mov     edx, [rax+FACP_20.FIRMWARE_CTRL] ; Facp->FIRMWARE_CTRL
.text:00000001C0001E86                 mov     r9d, 'SCAF'     ; Physical memory address of the FACS
...
.text:00000001C0001EB2                 call    HalpAcpiCheckAndMapTable
.text:00000001C0001EB7                 mov     cs:HalpAcpiFacsMapping, rax ; cs:HalpAcpiFacsMapping: hold facs phyical address
...
.text:00000001C0001ED3                 mov     rax, cs:HalpAcpiFacsMapping ;返回Facs表di'zhi
最后于 2020-4-14 23:50 被hyjxiaobia编辑 ,原因: 修改部分内容
收藏
免费 3
支持
分享
最新回复 (14)
雪    币: 24477
活跃值: (62774)
能力值: (RANK:135 )
在线值:
发帖
回帖
粉丝
2
感谢分享!
2020-4-14 09:16
0
雪    币: 248
活跃值: (3789)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
谢谢分享,另外,用代理也下载到符号表了
最后于 2020-4-15 14:40 被luskyc编辑 ,原因:
2020-4-14 18:30
0
雪    币: 802
活跃值: (4433)
能力值: ( LV12,RANK:260 )
在线值:
发帖
回帖
粉丝
4
yy虫子yy 谢谢分享,另求win 7 x64符号表
我仔细看了一下你的sys文件,应该是Free build的吧?这个符号表可以通过windbg从MS调试服务器下载到。
最后于 2020-4-14 23:54 被hyjxiaobia编辑 ,原因: 追加内容
2020-4-14 23:28
0
雪    币: 802
活跃值: (4433)
能力值: ( LV12,RANK:260 )
在线值:
发帖
回帖
粉丝
5
我仔细看了一下你的sys文件,应该是Free build的吧?这个符号表可以通过windbg从MS调试服务器下载到。
2020-4-14 23:52
0
雪    币: 83
活跃值: (1082)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
6
yy虫子yy 谢谢分享,另求win 7 x64符号表
跳出五行外 不在轮回中?
2020-4-15 07:05
0
雪    币: 248
活跃值: (3789)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
hyjxiaobia 我仔细看了一下你的sys文件,应该是Free build的吧?这个符号表可以通过windbg从MS调试服务器下载到。
已经可以下载了,要开代理才行
但之前是不需要开代理的
最后于 2020-4-15 14:41 被luskyc编辑 ,原因:
2020-4-15 09:05
0
雪    币: 802
活跃值: (4433)
能力值: ( LV12,RANK:260 )
在线值:
发帖
回帖
粉丝
8
这个我也知道,你开个代理软件试试,据说可以
2020-4-15 09:20
0
雪    币: 248
活跃值: (3789)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
killpy 跳出五行外 不在轮回中?
哈哈,是啊,跳出五行之外才好跑路啊
2020-4-15 09:21
0
雪    币: 248
活跃值: (3789)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
hyjxiaobia 这个我也知道,你开个代理软件试试,据说可以
代理已经可以下载了,可能是对IP有限制吧
不是论坛上流传的说法,什么服务器关了
2020-4-15 14:46
0
雪    币: 688
活跃值: (189)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
符号服务器被墙了,并非是微软对用户限制,也不是关服务器了
2020-4-17 06:03
0
雪    币: 802
活跃值: (4433)
能力值: ( LV12,RANK:260 )
在线值:
发帖
回帖
粉丝
12
Ms说是迁移到云上,鬼知道怎样
2020-4-17 22:35
0
雪    币: 3727
活跃值: (3847)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
13
我有7的checked build...
2020-4-18 01:07
0
雪    币: 802
活跃值: (4433)
能力值: ( LV12,RANK:260 )
在线值:
发帖
回帖
粉丝
14
我倒也有
2020-4-18 14:13
0
雪    币: 12
活跃值: (220)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
大神
2021-3-21 11:09
0
游客
登录 | 注册 方可回帖
返回
//