获取设备加密支持信息
Get device encryption support information
我想在我的程序中检测设备加密支持。此信息在 System Information
程序中可用。请查看下面的屏幕截图:
检测设备加密支持的 Win API
函数有哪些 used/available? System Information
程序使用什么来检测它?我只是需要一些信息。
TL;DR:它使用了 fveapi.dll
中未记录的函数(Windows Bitlocker Drive Encryption API)。它似乎只依赖于 TPM 功能。
请注意,我只花了大约 15 分钟,但我怀疑我错过了一些重要的东西,尽管这可能是可能的。
一点逆向工程
在搜索栏中输入 system information
,看到它生成了 msinfo32.exe
。将二进制文件放入反汇编程序中。它使用 MUI 文件,所以我必须在 MUI 文件中搜索字符串,而不是可执行文件。
搜索 Device Encryption Support
导致字符串 ID 951 (0x3b7)
STRINGTABLE
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
{
951, "Device Encryption Support|%s"
在反汇编程序中搜索内容会导致一个名为的函数:
DeviceEncryptionDataPoints(struct CWMIHelper *, struct CPtrList *)
前面提到的字符串加载几乎就在开头:
.text:00000001400141E9 mov edx, 3B7h
.text:00000001400141EE lea rcx, [rsp+2C8h+var_280]
.text:00000001400141F3
.text:00000001400141F3 loc_1400141F3:
.text:00000001400141F3 ; try {
.text:00000001400141F3 call cs:__imp_?LoadStringW@CString@@QEAAHI@Z ; CString::LoadStringW(uint)
所以我们绝对是在正确的功能。
它加载 fveapi.dll
模块:
.text:0000000140014269 xor edx, edx ; hFile
.text:000000014001426B mov r8d, 800h ; dwFlags
.text:0000000140014271 lea rcx, LibFileName ; "fveapi.dll"
.text:0000000140014278 call cs:__imp_LoadLibraryExW
获取 FveQueryDeviceEncryptionSupport
上的指针:
.text:00000001400142AB lea rdx, aFvequerydevice ; "FveQueryDeviceEncryptionSupport"
.text:00000001400142B2 mov rcx, rdi ; hModule
.text:00000001400142B5 call cs:__imp_GetProcAddress
并立即调用该函数(这是一个受保护的 CFG 调用,但它在这里):
.text:00000001400142CA mov [rsp+2C8h+var_254], rbx
.text:00000001400142CF mov [rsp+2C8h+var_260], 14h
.text:00000001400142D7 mov [rsp+2C8h+var_25C], 1
.text:00000001400142DF mov [rsp+2C8h+var_258], 1
.text:00000001400142E7 lea rcx, [rsp+2C8h+var_260]
.text:00000001400142EC call cs:__guard_dispatch_icall_fptr
Return值
如果函数失败:
.text:00000001400142EC call cs:__guard_dispatch_icall_fptr
.text:00000001400142F2 mov esi, eax
.text:00000001400142F4 test eax, eax
.text:00000001400142F6 js loc_1400143F0 ; check failure
我们降落在这里:
.text:00000001400143F7 mov edx, 2FFh
.text:00000001400143FC lea rcx, [rsp+2C8h+var_288]
.text:0000000140014401 call cs:__imp_?LoadStringW@CString@@QEAAHI@Z ; CString::LoadStringW(uint)
字符串 0x2FF (767) 是:
767, "Elevation Required to View"
如果调用成功,代码将检查其中一个参数,该参数肯定是 out
参数:
.text:00000001400142EC call cs:__guard_dispatch_icall_fptr
.text:00000001400142F2 mov esi, eax
.text:00000001400142F4 test eax, eax
.text:00000001400142F6 js loc_1400143F0
.text:00000001400142FC cmp dword ptr [rsp+2C8h+var_254], ebx ; rbx = 0
.text:0000000140014300 jnz short loc_14001431D
.text:0000000140014302 mov edx, 3B8h
.text:0000000140014307 lea rcx, [rsp+2C8h+var_288]
.text:000000014001430C call cs:__imp_?LoadStringW@CString@@QEAAHI@Z ; CString::LoadStringW(uint)
如果为 0,则使用字符串 0x3b8 (952):
952, "Meets prerequisites"
否则调用各种故障函数。
失败
万一失败,调用UpdateDeviceEncryptionStateFailureString
函数:
.text:0000000140014325 lea r9, [rsp+2C8h+var_294] ; int *
.text:000000014001432A lea r8, [rsp+2C8h+var_290] ; int *
.text:000000014001432F mov edx, 3C1h ; unsigned int
.text:0000000140014334 lea rcx, [rsp+2C8h+var_288] ; struct CString *
.text:0000000140014339 call ?UpdateDeviceEncryptionStateFailureString@@YAXPEAVCString@@IPEAH1@Z ; UpdateDeviceEncryptionStateFailureString(CString *,uint,int *,int *)
它的主要目标是从资源文件中获取一些字符串。
最突出的是 0x3b9:
.text:0000000140013A37 mov edx, 3B9h
.text:0000000140013A3C mov rcx, rbx
.text:0000000140013A3F call cs:__imp_?LoadStringW@CString@@QEAAHI@Z ; CString::LoadStringW(uint)
953, "Reasons for failed automatic device encryption"
我的情况就是这样,因为我没有 TPM。
其他功能
从 DeviceEncryptionDataPoints
调用的所有其他函数(至少为了获得所需的结果)都来自 fveapi.dll
。
一个函数里有很多东西叫做PerformIndividualHardwareTests(HINSTANCE hModule, struct CString *, int *, int *)
:
.text:0000000140013AEF lea rdx, aNgscbcheckisao ; "NgscbCheckIsAOACDevice"
.text:0000000140013AF6 mov [rbp+var_1F], 0
.text:0000000140013AFA mov rdi, r9
.text:0000000140013AFD mov [rbp+var_20], 0
.text:0000000140013B01 mov rsi, r8
.text:0000000140013B04 mov [rbp+var_1E], 0
.text:0000000140013B08 mov rbx, rcx
.text:0000000140013B0B call cs:__imp_GetProcAddress
.text:0000000140013B12 nop dword ptr [rax+rax+00h]
.text:0000000140013B17 mov r12, rax
.text:0000000140013B1A test rax, rax
.text:0000000140013B1D jz loc_140013CB9
.text:0000000140013B23 lea rdx, aNgscbcheckishs ; "NgscbCheckIsHSTIVerified"
.text:0000000140013B2A mov rcx, rbx ; hModule
.text:0000000140013B2D call cs:__imp_GetProcAddress
.text:0000000140013B34 nop dword ptr [rax+rax+00h]
.text:0000000140013B39 mov r15, rax
.text:0000000140013B3C test rax, rax
.text:0000000140013B3F jz loc_140013CB9
.text:0000000140013B45 lea rdx, aNgscbcheckhsti ; "NgscbCheckHSTIPrerequisitesVerified"
.text:0000000140013B4C mov rcx, rbx ; hModule
.text:0000000140013B4F call cs:__imp_GetProcAddress
.text:0000000140013B56 nop dword ptr [rax+rax+00h]
.text:0000000140013B5B mov r13, rax
.text:0000000140013B5E test rax, rax
.text:0000000140013B61 jz loc_140013CB9
.text:0000000140013B67 lea rdx, aNgscbcheckdmas ; "NgscbCheckDmaSecurity"
.text:0000000140013B6E mov rcx, rbx ; hModule
.text:0000000140013B71 call cs:__imp_GetProcAddress
还检查了一个注册表项 SYSTEM\CurrentControlSet\Control\BitLocker\AutoDE\HSTI
:
.text:0000000140013C10 lea r8, ?NGSCB_AUTODE_HSTI_REQUIRED@@3QBGB ; "HSTIVerificationRequired"
.text:0000000140013C17 mov [rsp+60h+pcbData], rax ; pcbData
.text:0000000140013C1C lea rdx, ?NGSCB_AUTODE_HSTI_PREREQS@@3QBGB ; "SYSTEM\CurrentControlSet\Control\Bit"...
.text:0000000140013C23 lea rax, [rbp+var_1C]
.text:0000000140013C27 mov r9d, 10h ; dwFlags
.text:0000000140013C2D mov [rsp+60h+pvData], rax ; pvData
.text:0000000140013C32 mov rcx, 0FFFFFFFF80000002h ; hkey
.text:0000000140013C39 and [rsp+60h+var_40], 0
.text:0000000140013C3F call cs:__imp_RegGetValueW
和一些其他功能(NgscbCheckPreventDeviceEncryption
、NgscbGetWinReConfiguration
、FveCheckTpmCapability
、...),再次,全部来自 fveapi.dll
模块。
所以基本上检查都是基于这个 DLL 中的函数。似乎其中 none 个已记录在案(据我快速搜索所见)。
我在 DeviceEncryptionDataPoints
调用方(基本上是 main() 函数)中没有找到任何东西,因为下一个调用是处理检查管理程序功能。
我想在我的程序中检测设备加密支持。此信息在 System Information
程序中可用。请查看下面的屏幕截图:
检测设备加密支持的 Win API
函数有哪些 used/available? System Information
程序使用什么来检测它?我只是需要一些信息。
TL;DR:它使用了 fveapi.dll
中未记录的函数(Windows Bitlocker Drive Encryption API)。它似乎只依赖于 TPM 功能。
请注意,我只花了大约 15 分钟,但我怀疑我错过了一些重要的东西,尽管这可能是可能的。
一点逆向工程
在搜索栏中输入 system information
,看到它生成了 msinfo32.exe
。将二进制文件放入反汇编程序中。它使用 MUI 文件,所以我必须在 MUI 文件中搜索字符串,而不是可执行文件。
搜索 Device Encryption Support
导致字符串 ID 951 (0x3b7)
STRINGTABLE
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
{
951, "Device Encryption Support|%s"
在反汇编程序中搜索内容会导致一个名为的函数:
DeviceEncryptionDataPoints(struct CWMIHelper *, struct CPtrList *)
前面提到的字符串加载几乎就在开头:
.text:00000001400141E9 mov edx, 3B7h
.text:00000001400141EE lea rcx, [rsp+2C8h+var_280]
.text:00000001400141F3
.text:00000001400141F3 loc_1400141F3:
.text:00000001400141F3 ; try {
.text:00000001400141F3 call cs:__imp_?LoadStringW@CString@@QEAAHI@Z ; CString::LoadStringW(uint)
所以我们绝对是在正确的功能。
它加载 fveapi.dll
模块:
.text:0000000140014269 xor edx, edx ; hFile
.text:000000014001426B mov r8d, 800h ; dwFlags
.text:0000000140014271 lea rcx, LibFileName ; "fveapi.dll"
.text:0000000140014278 call cs:__imp_LoadLibraryExW
获取 FveQueryDeviceEncryptionSupport
上的指针:
.text:00000001400142AB lea rdx, aFvequerydevice ; "FveQueryDeviceEncryptionSupport"
.text:00000001400142B2 mov rcx, rdi ; hModule
.text:00000001400142B5 call cs:__imp_GetProcAddress
并立即调用该函数(这是一个受保护的 CFG 调用,但它在这里):
.text:00000001400142CA mov [rsp+2C8h+var_254], rbx
.text:00000001400142CF mov [rsp+2C8h+var_260], 14h
.text:00000001400142D7 mov [rsp+2C8h+var_25C], 1
.text:00000001400142DF mov [rsp+2C8h+var_258], 1
.text:00000001400142E7 lea rcx, [rsp+2C8h+var_260]
.text:00000001400142EC call cs:__guard_dispatch_icall_fptr
Return值
如果函数失败:
.text:00000001400142EC call cs:__guard_dispatch_icall_fptr
.text:00000001400142F2 mov esi, eax
.text:00000001400142F4 test eax, eax
.text:00000001400142F6 js loc_1400143F0 ; check failure
我们降落在这里:
.text:00000001400143F7 mov edx, 2FFh
.text:00000001400143FC lea rcx, [rsp+2C8h+var_288]
.text:0000000140014401 call cs:__imp_?LoadStringW@CString@@QEAAHI@Z ; CString::LoadStringW(uint)
字符串 0x2FF (767) 是:
767, "Elevation Required to View"
如果调用成功,代码将检查其中一个参数,该参数肯定是 out
参数:
.text:00000001400142EC call cs:__guard_dispatch_icall_fptr
.text:00000001400142F2 mov esi, eax
.text:00000001400142F4 test eax, eax
.text:00000001400142F6 js loc_1400143F0
.text:00000001400142FC cmp dword ptr [rsp+2C8h+var_254], ebx ; rbx = 0
.text:0000000140014300 jnz short loc_14001431D
.text:0000000140014302 mov edx, 3B8h
.text:0000000140014307 lea rcx, [rsp+2C8h+var_288]
.text:000000014001430C call cs:__imp_?LoadStringW@CString@@QEAAHI@Z ; CString::LoadStringW(uint)
如果为 0,则使用字符串 0x3b8 (952):
952, "Meets prerequisites"
否则调用各种故障函数。
失败
万一失败,调用UpdateDeviceEncryptionStateFailureString
函数:
.text:0000000140014325 lea r9, [rsp+2C8h+var_294] ; int *
.text:000000014001432A lea r8, [rsp+2C8h+var_290] ; int *
.text:000000014001432F mov edx, 3C1h ; unsigned int
.text:0000000140014334 lea rcx, [rsp+2C8h+var_288] ; struct CString *
.text:0000000140014339 call ?UpdateDeviceEncryptionStateFailureString@@YAXPEAVCString@@IPEAH1@Z ; UpdateDeviceEncryptionStateFailureString(CString *,uint,int *,int *)
它的主要目标是从资源文件中获取一些字符串。
最突出的是 0x3b9:
.text:0000000140013A37 mov edx, 3B9h
.text:0000000140013A3C mov rcx, rbx
.text:0000000140013A3F call cs:__imp_?LoadStringW@CString@@QEAAHI@Z ; CString::LoadStringW(uint)
953, "Reasons for failed automatic device encryption"
我的情况就是这样,因为我没有 TPM。
其他功能
从 DeviceEncryptionDataPoints
调用的所有其他函数(至少为了获得所需的结果)都来自 fveapi.dll
。
一个函数里有很多东西叫做PerformIndividualHardwareTests(HINSTANCE hModule, struct CString *, int *, int *)
:
.text:0000000140013AEF lea rdx, aNgscbcheckisao ; "NgscbCheckIsAOACDevice"
.text:0000000140013AF6 mov [rbp+var_1F], 0
.text:0000000140013AFA mov rdi, r9
.text:0000000140013AFD mov [rbp+var_20], 0
.text:0000000140013B01 mov rsi, r8
.text:0000000140013B04 mov [rbp+var_1E], 0
.text:0000000140013B08 mov rbx, rcx
.text:0000000140013B0B call cs:__imp_GetProcAddress
.text:0000000140013B12 nop dword ptr [rax+rax+00h]
.text:0000000140013B17 mov r12, rax
.text:0000000140013B1A test rax, rax
.text:0000000140013B1D jz loc_140013CB9
.text:0000000140013B23 lea rdx, aNgscbcheckishs ; "NgscbCheckIsHSTIVerified"
.text:0000000140013B2A mov rcx, rbx ; hModule
.text:0000000140013B2D call cs:__imp_GetProcAddress
.text:0000000140013B34 nop dword ptr [rax+rax+00h]
.text:0000000140013B39 mov r15, rax
.text:0000000140013B3C test rax, rax
.text:0000000140013B3F jz loc_140013CB9
.text:0000000140013B45 lea rdx, aNgscbcheckhsti ; "NgscbCheckHSTIPrerequisitesVerified"
.text:0000000140013B4C mov rcx, rbx ; hModule
.text:0000000140013B4F call cs:__imp_GetProcAddress
.text:0000000140013B56 nop dword ptr [rax+rax+00h]
.text:0000000140013B5B mov r13, rax
.text:0000000140013B5E test rax, rax
.text:0000000140013B61 jz loc_140013CB9
.text:0000000140013B67 lea rdx, aNgscbcheckdmas ; "NgscbCheckDmaSecurity"
.text:0000000140013B6E mov rcx, rbx ; hModule
.text:0000000140013B71 call cs:__imp_GetProcAddress
还检查了一个注册表项 SYSTEM\CurrentControlSet\Control\BitLocker\AutoDE\HSTI
:
.text:0000000140013C10 lea r8, ?NGSCB_AUTODE_HSTI_REQUIRED@@3QBGB ; "HSTIVerificationRequired"
.text:0000000140013C17 mov [rsp+60h+pcbData], rax ; pcbData
.text:0000000140013C1C lea rdx, ?NGSCB_AUTODE_HSTI_PREREQS@@3QBGB ; "SYSTEM\CurrentControlSet\Control\Bit"...
.text:0000000140013C23 lea rax, [rbp+var_1C]
.text:0000000140013C27 mov r9d, 10h ; dwFlags
.text:0000000140013C2D mov [rsp+60h+pvData], rax ; pvData
.text:0000000140013C32 mov rcx, 0FFFFFFFF80000002h ; hkey
.text:0000000140013C39 and [rsp+60h+var_40], 0
.text:0000000140013C3F call cs:__imp_RegGetValueW
和一些其他功能(NgscbCheckPreventDeviceEncryption
、NgscbGetWinReConfiguration
、FveCheckTpmCapability
、...),再次,全部来自 fveapi.dll
模块。
所以基本上检查都是基于这个 DLL 中的函数。似乎其中 none 个已记录在案(据我快速搜索所见)。
我在 DeviceEncryptionDataPoints
调用方(基本上是 main() 函数)中没有找到任何东西,因为下一个调用是处理检查管理程序功能。