Windows GDID 完整分析报告

Hacker News Top 论文

摘要

对微软全局设备标识符(GDID)的详细逆向工程揭示,它是一个通过微软账户分配的64位Passport唯一ID,打破了其源自硬件序列号的传言。该报告记录了从wlidsvc到Connected Devices Platform再到Delivery Optimization的完整技术栈。

暂无内容
查看原文
查看缓存全文

缓存时间: 2026/07/06 23:07

SmtimesIWndr/gdid-reversal 来源:https://github.com/SmtimesIWndr/gdid-reversal

完整逆向分析 Windows GDID

全局设备标识符完整逆向工程

主要来源‑8a2be2) 平台‑0078d6) 符号方法声明 微软的“全局设备标识符”(Global Device Identifier),即2026年7月Scattered Spider起诉书中提到的持久性Windows指纹,其实际生成、存储和传输方式。


TL;DR

下方所列内容正确,但缺少部分信息。无论是否登录Microsoft帐户,你都会拥有一个GDID。我发帖时并未意识到这一点,但后来进行了调查。CDP有一条匿名设备路径,当未连接MSA时会被使用。底层系统在事实上仍然正确,只是缺少了几点内容。

  • GDID是真实的遥测项。 它出现在美国联邦刑事起诉书(United States v. Peter Stokes,伊利诺伊州北区,2026年7月)中,格式为 Global Device Identifier g:6755467234350028。
  • 它是Microsoft帐户的“设备PUID”。 一个64位的Passport唯一标识符(Passport Unique ID),当Windows安装注册到Microsoft帐户时分配,在设备图中写作 g:。
  • 那些说法是错误的。 它不是“128位”,也不是“由序列号生成”。法院记录本身说明重新安装会产生新的GDID,这排除了它是由GPU等硬件序列号推导而来的可能。
  • 从下到上的堆栈: wlidsvc(Microsoft帐户服务)使用 login.live.com 配置设备,得到设备PUID -> 存储到注册表 -> 连接设备平台(cdp.dll / CDPSvc)读取该值并将其注册到**设备目录服务(Device Directory Service,DDS)**图中 -> 传递优化(Delivery Optimization)将其报告为文档中的 UCDOStatus.GlobalDeviceId。
  • 所有步骤均在一台运行Windows 11(26200)的实机上使用公共符号进行了复现。你可以通过一次注册表读取找到自己的GDID(§7)。

可信度标注。 每项声明都带有标签,供自行判断:[COURT] 原始来源事实,[OBSERVED] 在我的测试机上实机复现,[STATIC] 通过二进制文件和公共Windows PDB证明,[ASSESSED] 基于证据的有力推断。


目录

  1. 背景:法院实际说了什么
  2. 戳破那些爆火的谣言
  3. GDID出现在哪里:传递优化
  4. 谁拥有它:连接设备平台到DDS
  5. CDP如何获取:它消费,不计算
  6. 铸造者:MSA设备PUID(wlidsvc)
  7. 找到你自己的GDID
  8. 减少暴露风险
  9. 方法论(可复现)
  10. 局限与坦诚说明

1. 背景:法院实际说了什么

2026年7月1日,美国司法部公布了对Peter Stokes的刑事起诉书,他被指控是Scattered Spider(又名Octo Tempest / UNC3944 / 0ktapus)的成员。宣誓书描述了微软如何帮助FBI将活动归因到一台设备。

[COURT] 来自补充起诉书(¶25,第34页),原文:

“该ngrok账户是通过全局设备标识符 g:6755467234350028(以下简称“GDID”)设置的。据微软代表称,Windows生态系统中的全局设备标识符是一种持久的、设备级别的标识符,旨在唯一标识一台设备上的Windows操作系统安装……GDID是全局唯一的标识符,与设备上Windows的安装绑定。GDID在设备上的Windows操作系统更新过程中保持不变,但重新安装Windows……将产生一个新的唯一GDID。”

脚注还提到一个Microsoft用户可以拥有多个GDID。宣誓书随后将GDID的IP历史记录和浏览记录(例如 empirehotelnyc.com,一个Growtopia/Ubisoft登录URL)与嫌疑人登录的账户关联起来。

这里有两件事支撑了本报告的其余部分:

  1. 该值是 g: 加上一个十进制整数(g:6755467234350028)。转为十六进制是 0x0018000FC8CB93CC,因此是一个 64位 数字。
  2. 重新安装会产生新的GDID。 因此它不可能仅仅是固定硬件参数的函数。

2. 戳破那些爆火的谣言

社交媒体摘要声称GDID是*“安装时由序列号生成的128位标识符”。* 两个部分都是错误的:

声明(社交媒体)现实(原始来源)
“128位”起诉书中的值是 g:6755467234350028,这是一个十进制数,适合 64位(0x0018000FCB8CB93CC)。
“安装时由序列号生成”起诉书指出重新安装会产生新的GDID。如果是从固定序列号派生出来的值,重新安装后应该相同,不会改变。

在进一步逆向CDP后,我提供了一些错误信息。使用本地帐户并不能阻止GDID。如果未使用Microsoft帐户,CDP会采用匿名设备路径。阅读时请记住这一点。


3. GDID出现在哪里:传递优化

[STATIC] 微软公共Azure Monitor文档在 UCDOStatus(更新合规性 / 传递优化)表中定义了一个 GlobalDeviceId 列:

GlobalDeviceId (string):“Microsoft global device identifier. This is an identifier used by Microsoft internally.”

它紧挨着 LastCensusSeenTime、ISP、City、Country 等字段,因此设备ID与地理位置和IP对齐。这是微软在公开文档中命名该值的唯一地方。但传递优化只是报告它。重要的是它并不拥有这个值。向上游追踪,你会到达连接设备平台。


4. 谁拥有它:连接设备平台到DDS

[STATIC] C:\Windows\System32\cdp.dll(连接设备平台,服务 CDPSvc + CDPUserSvc)包含 GlobalDeviceId 符号以及一整套**设备目录服务(Device Directory Service)**注册子系统:

ddsregistrationclient.cpp ddsregistrationmanager.cpp ddsregistrationinfo.cpp DdsRegistrationClient RegisterUserDevicesObserver DdsRegistrationInfoProviderForCDP endpoints: dds.microsoft.com fd.dds.microsoft.com aad.cs.dds.microsoft.com cdpcs.access.microsoft.com device-id format string: "g:%s"

DDS = 设备目录服务,微软的跨设备身份图(Phone Link、云端剪贴板、“在电脑上继续”、Nearby Share的后端)。CDP是注册安装到该图中的Windows客户端,其键值为 g:。

4.1 实机捕获

[OBSERVED] 强制进行全新注册(在清除本地状态后重启 CDPSvc)并捕获CDP自身的ETW提供程序,得到了完整握手:

text DdsClient::RegisterUserDeviceAsync() RegistrationReason: Startup Account Type: MSA DDSClient: Registration response received. HTTP status code: 200 OnRegisterUserDeviceComplete GetDeviceIdAndTicketActivity -> deviceid: 0018XXXXXXXXXXXX

该 deviceid 写作 g:,结构与起诉书中的值匹配:

| | 值 | 十六进制(64位) | 类别前缀 | |—|—|—|—:|—| | 我的机器(已遮盖) | g:XXXXXXXXXXXXXXXX | 0x0018XXXXXXXXXXXX | 0018 | | 法院证据 | g:6755467234350028 | 0x0018000FC8CB93CC | 0018 |

两者都是64位值,位于相同的 0x0018 高位类别中(设备PUID命名空间,参见§6)。g: 前缀只是该整数的十进制表示。


5. CDP如何获取:它消费,不计算

[STATIC] 使用公共PDB(cdp.pdb),cdp.dll 中的设备ID路径仅仅是向身份栈发起请求并等待。CDP从不自行计算ID:

mermaid flowchart TD A["GetStableDeviceIdFromProvider0x0A3140"] --> B["provider.GetStableDeviceIdAsync(vtable +0x48)"] B --> C["OneCoreAccountProvider::GetStableDeviceIdAsync 0x0C8370"] C --> D["IWebAccountBackedAccountProvider(MSA / AAD identity COM)"] D --> E["OnGetStableDeviceIdCompleted(const char* deviceId) 0x06CEA0"] E -->|"assign() string, signal flag"| A

接收它的回调函数使其显而易见。该ID作为字符串出现,仅被存储:

asm ; OnGetStableDeviceIdCompleted mov rbp, r9 ; r9 = device-id STRING handed in by the identity provider lea rcx, [rsi+0xD8] ; CDP member field mov rdx, rbp call assign@basic_string ; store it, no computation, no serials call Set@CdpWaitableFlag ; unblock the waiter

底线: GDID是在CDP之下,在Windows身份栈底部铸造而成,然后作为一个不透明的字符串交给CDP。这指向了Microsoft帐户服务。


6. 铸造者:MSA设备PUID(wlidsvc)

[STATIC] C:\Windows\System32\wlidsvc.dll,即 Microsoft帐户 / Passport(Windows Live ID)服务,是唯一包含字面 GlobalDeviceId 的身份二进制文件,并拥有完整的设备配置机制:

CDeviceIdentityBase::CreateNewDeviceIdentity / Provision / BindDeviceToHardware / GetDeviceCert DeviceAssociateRequest (Passport PPCRL SOAP -> login.live.com) ... DeviceIdStore::LogToRegistry BCryptGenRandom / CCryptRandom::GenRandom (device KEY, not the id)

该标识符是一个设备PUID(Passport Unique ID),一个64位的MSA标识符。其中的 BCryptGenRandom 生成的是设备身份验证密钥,BindDeviceToHardware 将其绑定到机器,而不是PUID。

6.1 由服务器分配

[STATIC] 客户端从服务器的SOAP响应中提取PUID,通过XPath进入响应体:

/S:Envelope/S:Body/ps:DeviceUpdatePropertiesResponse/HWPUIDFlipped

CAssociateDeviceRequest::ParseResponseBody 及相关 ParseResponse 方法将响应XML节点读入BSTR。因此流程是:客户端配置设备 -> login.live.com 分配并返回设备PUID -> 客户端存储该PUID。这正是为什么重新安装会产生新的GDID(新的配置,新的服务器分配PUID),以及为什么它不是一个硬件哈希。

6.2 以明文形式持久化存储

[OBSERVED] Microsoft帐户身份存储将值直接保留在注册表中,位于你自己的用户配置单元中:

HKCU\SOFTWARE\Microsoft\IdentityCRL\ExtendedProperties LID = 0018XXXXXXXXXXXX HKCU\SOFTWARE\Microsoft\IdentityCRL\Immersive\production\Token\{...} DeviceId = 0018XXXXXXXXXXXX

与CDP实时注册到DDS的值逐字节相同。你的用户帐户PUID是一个不同的数字,存储在其他地方,如 puid = 0003...(例如 00034002XXXXXXXX)。还有一个以PUID命名的HKLM缓存键(HKLM\SOFTWARE\Microsoft\IdentityCRL\NegativeCache\_),但那个是系统(SYSTEM)级别的,因此你需要从HKCU中读取该值。

前缀告诉你它是什么。 用户PUID是 0003 类别,设备PUID是 0018 类别。法院的GDID(0018000FCB8CB93CC)位于 0018 设备PUID空间内,与我的相同。

6.3 它验证图端点

[OBSERVED] MSA令牌缓存(HKLM\SOFTWARE\Microsoft\IdentityCRL\NegativeCache\...)包含设备令牌,其范围正好是CDP使用的端点:

scope=service::dds.microsoft.com::MBI_SSL_TOKEN_BROKER scope=service::activity.windows.com::MBI_SSL_SA_TOKEN_BROKER

因此,Microsoft帐户服务提供设备凭据,用于验证DDS注册和携带GDID的活动上传。

6.4 完整链路

mermaid flowchart TD subgraph MSA["MSA identity layer: wlidsvc.dll"] A1["Provision device with login.live.com(Passport PPCRL SOAP)"] --> A2["Server assigns Device PUID<ps:DevicePUID> / HWPUIDFlipped"] A2 --> A3["Store DeviceId / LID = PUIDHKLM\...\IdentityStore"] A3 --> A4["Issue device tokens fordds.microsoft.com and activity.windows.com"] end subgraph CDP["Device graph client: cdp.dll / CDPSvc"] B1["GetStableDeviceId -> receives PUID string"] --> B2["RegisterUserDeviceAsync -> DDSOBSERVED: HTTP 200"] end subgraph SRV["Server: Device Directory Service"] C1["Keys g:PUID to the MSA account,activity and IP history"] end subgraph REP["Reporting"] D1["Delivery Optimization ->UCDOStatus.GlobalDeviceId"] end A4 --> B1 B2 --> C1 C1 --> D1

起诉书中所指出的关于“GDID”的一切——每次安装持久存在、更新后保持不变、重新安装后更新、与Microsoft帐户绑定、可跨IP和浏览记录追踪——全部源于它是服务器分配的MSA设备PUID,由CDP注册到设备图中。


7. 找到你自己的GDID

[OBSERVED] 在已登录Microsoft帐户的机器上,只需一次从你自己的用户配置单元中读取注册表,无需管理员权限:

powershell (Get-ItemProperty 'HKCU:\SOFTWARE\Microsoft\IdentityCRL\ExtendedProperties').LID

这将给出你的设备PUID,为16位十六进制数字(例如 0018XXXXXXXXXXXX)。要查看服务器端显示的 g: 形式:

powershell $hex = (Get-ItemProperty 'HKCU:\SOFTWARE\Microsoft\IdentityCRL\ExtendedProperties').LID "g:$([Convert]::ToUInt64($hex,16))"

如果 ExtendedProperties\LID 在你的机器上为空,相同的值位于 HKCU\SOFTWARE\Microsoft\IdentityCRL\Immersive\production\Token\{...}\DeviceId 下。

不要发布你自己的值。 你的设备PUID、你的MSA CID(0003...)以及你的用户SID都可以去匿名化。在任何公开发布中请遮盖它们。唯一安全引用的值是法院的那个,因为它已经是公开的。


8. 减少暴露风险

GDID的存在是因为你的设备已注册到Microsoft帐户设备图中,并且连接设备平台保持同步。要减少它:

  • 关闭连接设备平台(CDPSvc、CDPUserSvc)并关闭活动历史记录(设置 → 隐私 → 活动历史记录)以停止图同步和活动上传。
  • 删除 %LOCALAPPDATA%\ConnectedDevicesPlatform 仅会清除本地CDP状态。PUID会从身份存储中立即回来,因此单独这样做是不够的。
  • 重新安装会给你一个新的GDID(起诉书如此说明),但一旦再次注册,它就会与一个新的GDID绑定。

9. 方法论(可复现)

所有内容均来自一台标准Windows 11(build 26200)机器。

  • 实机捕获: 使用 logman 在强制全新 CDPSvc 注册时捕获CDP的TraceLogging ETW提供程序(Microsoft.Windows.CDP.*),并使用 tracerpt 解码。
  • 注册表和令牌缓存: IdentityStore 和 IdentityCRL 位于 HKLM\SOFTWARE\Microsoft 下。ETW和静态分析是实际有效的方法。代理只会浪费你的时间。

附录:CDP ETW提供程序GUID(点击展开) 通过EventSource名称哈希(命名空间加上UTF-16BE大写的提供程序名称的SHA1)计算。对照已知的 System.Runtime 值 49592c0f-5a05-516d-aa4b-a64e02026c89 进行验证:

Microsoft.Windows.CDP.Core {7762de0c-b0a6-571a-68d3-c018bf009496} Microsoft.Windows.CDP.Core.Error {a1ea5efc-402e-5285-3898-22a5acce1b76} Microsoft.Windows.CDP.CDS {dfa6e32a-095f-5f57-d025-0887d33507a1} Microsoft.Windows.CDP.Aggr {bc1826c8-369c-5b0b-4cd1-3c6ae5bfe2e7} Microsoft.Windows.CDP.AFS {5fe36556-c4cd-509a-8c3e-2a547ea568ae} Microsoft.Windows.CDP.OnecoreAccountProvider {4ee5bf9a-3e8f-540b-8bfb-12457a2854b6} Microsoft.Windows.CDP {9f4cc6dc-1bab-5772-0c71-a89954718d66}

附录:关键二进制文件和符号(点击展开)

二进制文件角色显著符号
wlidsvc.dllMicrosoft帐户 / Passport服务,铸造设备PUIDCDeviceIdentityBase::CreateNewDeviceIdentity,CAssociateDeviceRequest::ParseResponseBody,DeviceIdStore::LogToRegistry
cdp.dll连接设备平台,注册PUID到DDSDdsRegistrationClient,GetStableDeviceIdFromProvider(0x0A3140),OnGetStableDeviceIdCompleted(0x06CEA0)
dosvc.dll / DO将ID报告为 UCDOStatus.GlobalDeviceId无

注册表:HKLM\SOFTWARE\Microsoft

相似文章