Steam应用分发机制

Steam是Valve公司的一个软件发行平台,分发的每个产品都是一个Steam应用(Application)。Application可以是游戏、软件、可下载内容(DLC)、音视频等产品类型,每个Application有唯一的App ID。App每个版本有唯一的Build ID,正式版本的build会发布到默认分支(branch)。

将每个文件大小、SHA1哈希等信息记录在元数据清单文件中(Manifests),文件分组为不同Depot并分配唯一的Depot ID。Depot可以是语言包(localized)、add-on、DLC等类型的程序或资源集,根据地区语言、操作系统及架构、DLC等因素决定加载条件和顺序。

一个或多个Application、Depot组成了用于售卖的Packages单元,可以将多个Package捆绑为Bundles包打折售卖。Package的一个常见场景是用于区分面向不同地区发售的版本和定价。

App ID

App ID可以通过Steam官网的URL识别、通过客户端游戏属性获取,也可以通过steamdb.info等第三方网站查询。

1
2
3
# ID:3167020 
https://store.steampowered.com/app/3167020/Escape_From_Duckov/
https://steamdb.info/app/3167020/

DLC ID

DLC分为跟随主体的Depots和与主体关联但独立分组的Depots两类,可以通过Steam官网或客户端关联搜索,也可以在steamdb.info的Depots、Related Apps中查询。

1
2
3
4
# DLCs
https://steamdb.info/app/2807960/dlc/
# Related Apps
https://steamdb.info/app/2807960/linked/

Depot ID

主体或DLC可能存在多个Depot,用于区分不同操作系统、语言包的程序和资源文件组。每个Depot中会存在一个或多个文件清单(Manifests),App已安装的Depot和相应manifest信息记录在Steam\steamapps\appmanifest_{App ID}.acf,清单文件具有唯一的Manifest ID,使用{Depot ID}_{Manifest ID}.manifest的文件名格式。

1
2
3
4
5
6
7
# Steam Console (Steam.exe -console / Steam://nav/console)
app_info_print 3167020
# steamdb
https://steamdb.info/depot/3167021/manifests/

# appmanifest_3167020.acf
3167021_2300087279900170974.manifest

向Steam提供manifest清单及Depot相应的DecryptionKey即可获取Depot中的各个具体的程序和资源文件,DecryptionKey被记录在Steam\config\config.vdf #InstallConfigStore/Software/Valve/Steam/depots字段中。

解密方法

离线模式

为了让不需要联网的应用在断网时能正常运行,Steam支持以离线模式启动。所以获取整套Application-Depots-Manifests-DecryptionKey 最直观的方式就是使用共享账号/出租账号登录下载应用,下载后持续以离线模式运行。

优点是不需要理解任何分发机制细节,完全是Steam客户端的正常下载使用逻辑。但应用分散在多个账号时需要切号使用,且在下一次在线登录前无法更新。

Goldberg Steam Emulator

其它账号安装后的应用,离线模式也无法在未购买的账号中运行,是因为Steam客户端会检查账号最后一次在线登录时的记录,判断是否具备使用权限。如果能不再通过Steam官方客户端,而是直接启动应用则绕过了这一层权限判断。

一般应用为了和Steam联动游戏成就、创意工坊(Mod)、云存档等功能,会引入steam_api64.dll链接库文件。当其没有添加额外的检查/保护时,使用Goldberg Steam Emulator替换steam_api64.dll,便可劫持替换原有的Steam官方客户端,绕过Steam DRM逻辑,解决一部分应用的启动问题,

Goldberg Steam Emulator可以进一步配置局域网联机,此处不再展开。

SteamTools

使用Goldberg Steam Emulator会完全脱离Steam官方客户端,当遇到存在复杂校验逻辑的应用时无法绕过,且无法使用Steam成就、云存档。为了仅劫持Steam官方客户端中关于所有权校验的部分,需要安装SteamTools,根据GUI引导拖入包含App ID的字符串/链接/文件解锁特定应用。

1
2
3
4
5
6
# SteamTools注入文件
Steam\hid.dll
Steam\config\stplug-in
Steam\config\stUI
Steam\config\appdata.vdf
Steam\config\appdataX.vdf

离线模式下载后解锁还是依赖先登录共享账号,而将各个账号的整套Application-Depots-Manifests-DecryptionKey收集起来,便可实现比账号更细粒度的资源分发。进一步将下载并加入Steam数据库的动作lua脚本化,便是基于SteamTools实现的一键拖放清单入库。

Denuvo DRM

Denuvo DRM就是俗称的D加密,上文中的Goldberg Steam Emulator和SteamTools可以绕过Steam DRM检查,于是Denuvo等第三方DRM应需而生,提供用于保护Steam DRM的反破解能力。可在Denuvo Watch查看采用该保护方案的游戏。

Denuvo会在应用初次启动时收集硬件、驱动和操作系统的关键信息,经过暂不明确的算法处理后与Steam的账号及应用元数据组合生成一个xml,并将base64编码后的xml发送至服务器,服务器会根据上传信息生成与运行环境和账号应用配套的Token下发(通常限制每天仅可生成五次),下发后的Token存储在Steam\userdata\{Friend Code}\{App ID}\{Token ID}文件中。

应用再次启动时若检测Token文件未因运行环境或游戏版本更新而失效,则应用在运行过程中会利用Token和运行环境信息,解密出程序正常运行所需的指令地址。否则校验不通过或错误指令地址会导致程序退出或崩溃。该过程涉及对KUSER_SHARED_DATACPUIDPEB信息的采集和对ntdllSYSCALL的调用,以及对程序的CRC校验和虚拟机指令运算。参见Denuvo Analysis

离线模式

与Steam账号的离线模式逻辑相同,可以使用共享账号/出租账号初次联网生成Token后保持离线运行,完全遵循正常验证逻辑。同样存在多账号切换不便、无法更新的问题,其中多账号切换问题可利用Goldberg Steam Emulator的steamclient_loader或SteamTools授权功能,向受Denuvo保护的程序提供原账号ID解决,只是一种对离线功能的优化算不上真正意义的绕过。

动态绕过

Denuvo实现的保护最终是让程序在有限的运行环境中使用(比如限制了每天生成五次Token),如果能劫持向程序提供的运行环境信息,使其在多个不同运行环境中都误以为是同一个固定的运行环境,则可打破对次数的限制,当然这种动态劫持也可以补丁的方式固化。参见Reverse Engineering Denuvo in Hogwarts Legacy

静态绕过

动态绕过仍依赖于一个有效的原始Token,当完全移除或补丁绕过了程序中的各处Denuvo校验逻辑时便是真正意义上的破解。国内外均有比较知名的案例和ID(如3DM、Empress),非本文重点不再继续展开了。

Reference

  1. Steamworks Documentation > Store Presence > Applications

  2. Goldberg Steam Emulator

  3. ManifestHub

  4. Steamworks Documentation > Features > Steam DRM

  5. Denuvo Watch

  6. Denuvo Analysis

  7. Reverse Engineering Denuvo in Hogwarts Legacy

  8. Denuvo

  9. Empress (cracker)

  10. Steamless

  11. Origin Unwrapper

  12. 请勿轻信低价骗局!Steam假入库灰产陷阱手法剖析