【发布时间】:2021-08-10 18:42:42
【问题描述】:
我想在我的程序中检测设备加密支持。此信息可在System Information 程序中找到。请查看下面的屏幕截图:
什么样的Win API 函数用于/可用于检测设备加密支持?什么System Information 程序用来检测它?我只是需要一些信息。
【问题讨论】:
我想在我的程序中检测设备加密支持。此信息可在System Information 程序中找到。请查看下面的屏幕截图:
什么样的Win API 函数用于/可用于检测设备加密支持?什么System Information 程序用来检测它?我只是需要一些信息。
【问题讨论】:
TL;DR:它使用来自fveapi.dll(Windows Bitlocker 驱动器加密 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"
在反汇编器中搜索contant会得到一个名为:
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
如果函数失败:
.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 中的函数。似乎它们都没有记录(据我快速搜索所见)。
我没有在 DeviceEncryptionDataPoints 调用者(基本上是 main() 函数)中找到任何东西,因为接下来的调用正在处理检查管理程序功能。
【讨论】: