网页资讯视频图片知道文库贴吧地图采购
进入贴吧全吧搜索

 
 
 
日一二三四五六
       
       
       
       
       
       

签到排名:今日本吧第个签到,

本吧因你更精彩,明天继续来努力!

本吧签到人数:0

一键签到
成为超级会员,使用一键签到
一键签到
本月漏签0次!
0
成为超级会员,赠送8张补签卡
如何使用?
点击日历上漏签日期,即可进行补签。
连续签到:天  累计签到:天
0
超级会员单次开通12个月以上,赠送连续签到卡3张
使用连续签到卡
12月10日漏签0天
c语言吧 关注:801,498贴子:4,373,533
  • 看贴

  • 图片

  • 吧主推荐

  • 视频

  • 游戏

  • 1 2 3 4 下一页 尾页
  • 73回复贴,共4页
  • ,跳到 页  
<<返回c语言吧
>0< 加载中...

[源码分析] Windows Vista/7的TSforge激活技术

  • 只看楼主
  • 收藏

  • 回复
  • XeO2
  • 小吧主
    14
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
2025年2月,MASSGRAVE团队公开了一种全新的Windows激活技术——TSforge,其中的ZeroCID激活方法可以离线激活绝大多数基于NT6的Windows系统,包括Windows Vista、Windows 7、Windows 8、Windows 8.1以及同时代的多个Windows Server版本。ZeroCID无需联网,不会向系统中添加任何文件,不会修改任何可执行文件,也不会干预系统引导过程,堪称是目前各种破解技术中最洁净的Windows激活方法。
-
本文将以TSforge的开源代码为基础,深入拆解ZeroCID激活过程中的具体步骤。


  • XeO2
  • 小吧主
    14
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
本文的篇幅较长,且阅读TSforge的源代码需要一定的C#基础,在正式开始之前,不妨先浏览以下几个链接:
-
1. TSforge激活技术描述
https://massgrave.dev/tsforge
2. TSforge源代码
https://github.com/massgravel/TSforge
3. TSforge Blog
https://massgrave.dev/blog/tsforge
-
其中前两个是本文主要的参考资料来源,而第三个链接讲述了MASSGRAVE团队在TSforge诞生过程中的一些故事。


2025-12-10 01:40:21
广告
不感兴趣
开通SVIP免广告
  • XeO2
  • 小吧主
    14
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
1. ZeroCID与传统激活技术的对比
-
1.1 KMS激活
KMS激活本身是微软为了方便需要部署大量计算机的企业而产生的一种激活方式,然而由于用户可以自行搭建KMS服务器,因此KMS激活在个人计算机用户中成为了一种广为流传的盗版激活方式。因为网上存在一些公开的KMS服务器,所以用户可以使用Windows本身提供的工具进行KMS激活,因此楼主觉得KMS激活更像是对微软规则漏洞的利用,而不算一种真正意义上的激活破解。
-
KMS激活的主要缺点在于不是永久激活,因为KMS激活存在有效期,需要周期性地连接到KMS服务器从而保持激活状态,尽管公开KMS服务器的存在让KMS激活的效果基本相当于永久激活,但是跟正版序列号实现的“真永久激活”相比毕竟还是存在差距。


  • XeO2
  • 小吧主
    14
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
1.2 OEM激活
OEM激活本身是微软为品牌零售商设计的一种激活方式,OEM在计算机生产过程中直接把SLIC写入BIOS,操作系统在引导过程中会从BIOS中读取SLIC,在与系统中安装的OEM密钥和OEM证书核验通过后,系统便直接处于激活状态。
-
早期曾经有人尝试通过刷BIOS的方式向BIOS中写入SLIC从而伪造OEM激活状态,但是这种做法风险极高,后来的OEM激活工具普遍采用修改引导文件的方法,在系统启动过程中向内存特定位置注入SLIC,从而实现较为可靠的OEM激活。
-
OEM激活有很多缺点,首先这种方法需要修改引导文件,干预引导过程,其次这种方法诞生于BIOS+MBR流行的时代,对后来的UEFI+GPT支持不佳,比如著名的Win7 Activation在GPT磁盘上会要求用户首先为EFI分区分配盘符,然后才能正常激活,最后根据楼主自己的经历来看,OEM激活的稳定性实在是难以恭维,激活状态有时候会在毫无征兆的情况下突然失效,不得不重新激活,而且这种情况一旦发生,后续必然会出现得更加频繁,最终不得不重装系统。
-
OEM激活的代表工具是Win7 Activation,想必不少人都用过它吧。


  • XeO2
  • 小吧主
    14
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
1.3 ZeroCID
ZeroCID的全称是Zero Confirmation ID,这种激活方法实际上利用了Windows的电话激活过程,通过伪造数据让Windows认为系统已经通过电话激活流程。Windows本身以及许多与Windows关联的产品(比如Office)都支持电话激活,因此这种方法的适用范围极广。
-
与KMS激活和OEM激活相比,ZeroCID具有许多优点:
(1) 电话激活作为正版序列号激活的补充,可以实现离线永久激活;
(2) 除非重装系统或进行大更新,否则激活状态不会失效(Windows Vista和Windows 7已经停止支持很久了,不可能再有大更新);
(3) 不会向系统中添加任何文件;
(4) 不会修改系统中的任何可执行文件;
(5) 不会干预系统引导过程。
-
ZeroCID实际上只会修改系统中的两个(或一个)数据文件,其余操作都是调用系统本身提供的API,因此楼主认为这种激活方法是非常干净的。


  • XeO2
  • 小吧主
    14
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
尽管ZeroCID的优点非常多,但在楼主看来它仍然是不完美的,因为真正完美的激活方法应该是不需要调用系统API、也不需要修改任何系统文件的纯数学方法,目前已经被这种方法破解的系统是Windows XP,其代表工具是UMSKT。
-
这里顺带提一下Windows XP。
-
如今Windows XP已经可以算是一个历史悠久的系统了,这么多年,应用在XP身上的破解方法早已多得不可胜数,不过其中最完美的当数XP算号器,XP算号器实际上是根据对Windows序列号验证算法的逆向成果,直接用算法产生出有效的激活序列号;XP的电话激活系统在几年前也最终被完全破解,现在已经有公开的算法可以从XP的安装ID直接计算出应答ID,这种算法甚至可以在单片机上进行,用户完全可以如正版激活一般使用Windows本身提供的激活流程进行激活,在楼主看来这才是最完美的激活方法,希望Windows Vista/7也能迎来这么一天。


  • XeO2
  • 小吧主
    14
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
2 TSforge源代码的目录结构

其中红色的源代码文件是本文重点研究和解析的部分,蓝色是次重要的部分,白色是内容较少且可以快速理解的部分。
-
注意,上图并非TSforge源代码的全貌,这里只是截取了与ZeroCID有关的部分,其余一概忽略。
-
这张图很重要,后面阅读和分析源代码时,会在各个文件之间跳来跳去,因此这张图如同导航一般可以有效避免迷路。


  • XeO2
  • 小吧主
    14
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
3 ZeroCID的原理和整体流程
-
3.1 ZeroCID原理
Windows激活由一个被称为软件保护平台(Software Protection Platform, SPP)的子系统管理,SPP使用一个被称为物理存储(Physical Store)或可信存储(Trusted Store)的文件存储激活状态信息,当SPP重新启动时,它只会检查当前的安装ID(Installation ID, IID)、应答ID(Confirmation ID, CID)和硬件ID(Hardware ID, HWID)是否存在于可信存储内,因此只需向可信存储中写入自行构造的数据,即可骗过SPP,令其认为系统已经处于激活状态。



2025-12-10 01:34:21
广告
不感兴趣
开通SVIP免广告
  • XeO2
  • 小吧主
    14
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
3.2 ZeroCID激活流程
这里先用图示说明激活流程,为了便于理解,循序渐进,楼主会先给出简化版流程,在理解简化版流程后,完整版流程会展示其中的更多细节。
-
3.2.1 简化版流程

怎么样,是不是感觉比想象中的要简单很多呢?


  • XeO2
  • 小吧主
    14
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
3.2.2 完整版流程
好了,现在来挑战一下完整版流程吧。

不要被开头的一堆SLxxx函数调用吓到了,这些都是Windows软件认证服务提供的API,只需要使用固定的参数调用它们就可以了,没有任何难度,这里面真正麻烦的其实是解析可信存储中的数据结构,因为它有好几个版本。


  • XeO2
  • 小吧主
    14
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
4 ZeroCID源代码和等效的C语言实现
经过上一章的介绍,想必读者已经对ZeroCID的完整流程有了一个大致的了解,之所以要做这么多铺垫,是因为楼主不想让大家把我经历过的困难再经历一遍,而是能够快速地掌握整个流程中的关键点,从而提高代码阅读效率,否则这篇文章就没有什么意义了。
-
一个完善的程序总免不了拥有多个功能模块,各个模块之间互相调用也是在所难免的,因此阅读过程中在各个文件之间跳来跳去是常态,不过不用担心,楼主会在每一次文件跳转和函数调用时给出完整的调用链,确保大家不会迷路。
-
由于LibTSforge和LibTSforge/PhysicalStore目录下各有一个Common.cs文件,为避免混淆,楼主将前者称为"Common.cs",将后者称为"PhysicalStore/Common.cs"。


  • XeO2
  • 小吧主
    14
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
4.1 主程序
在TSforge的GitHub页面可以看到TSforge的使用方法:

要使用ZeroCID激活,只需添加/zcid参数即可,知道这一点,我们可以开始分析了。
-
调用链:Program.Main(Program.cs)
首先打开Program.cs,定位到Main函数:

先看看Logger.WriteLine是啥。
-
调用链:Program.Main(Program.cs) => Logger.WriteLine(Common.cs)
Logger类的定义在Common.cs里面:

原来就是在控制台上打印一些信息,既然这样,后面再遇到Logger.WriteLine的时候,我们将其直接忽略即可。
-
再看看Utils.Wow64EnableWow64FsRedirection。
-
调用链:Program.Main(Program.cs) => Utils.Wow64EnableWow64FsRedirection(Common.cs)
也是在Common.cs里面:

就是一个Win32 API,这个API的意义在于,当32位程序运行在64位Windows上时,Windows会自动把对64位文件夹的操作重定向到32位文件夹,比如把System32重定向到SysWOW64,把Program Files重定向到Program Files (x86),该API可以禁用这种重定向。
我们为64位Windows编译64位程序,为32位Windows编译32位程序,因此不需要该API。


  • XeO2
  • 小吧主
    14
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
Main函数的剩余部分是一个try...catch,由于C语言的异常处理较为繁琐,因此我们不作任何异常处理,只看try块。
-
调用链:Program.Main(Program.cs)
try块的内容如图所示,剩余未展示的部分是连续的else if判断。

args是一个string数组,代表命令行参数,显然这里至少有一个参数"/zcid",因此args.Length不等于0.
-
接下来的ParseArguments显然是一个解析命令行参数的函数。
-
调用链:Program.Main(Program.cs) => Program.ParseArguments(Program.cs)

ParseArguments首先创建了一个Options对象,来看看Options的定义。
-
调用链:Program.Main(Program.cs) => Program.ParseArguments(Program.cs) => Program.Options(Program.cs)

没有构造函数,那就是按定义进行默认构造了。
-
调用链:Program.Main(Program.cs) => Program.ParseArguments(Program.cs)

接下来就是遍历args中的参数了,string的Trim方法用于去除前后的空白符,ToLowerInvariant方法用于把字母转化为小写,switch用于判断参数内容。
-
我们直接定位到case "/zcid":

只是设置了一个布尔变量。
-
ParseArguments的最后自然是返回一开始创建的Options对象,无需多言。


  • XeO2
  • 小吧主
    14
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
调用链:Program.Main(Program.cs)
现在我们知道options里面只有ZCID是true,其他成员都是默认值,因此options.ShowHelp这一条件自然也不成立。

紧接着Main函数定义了两个变量并使用了??运算符,这里需要解释一下。
-
首先观察Options中Production和Version的定义:

类型名后面有一个问号,这是C#的可空(Nullable)类型,这种类型的变量除了类型本身的值外还可以具有空值(null),??运算符的规则是,如果左操作数非空,则表达式的值就是左操作数的值,否则是右操作数的值。
-
这里的options.Version和options.Production显然都是空值,因此这两条语句实际上相当于:
PSVersion version = Utils.DetectVersion();
bool production = SPPUtils.DetectCurrentKey();
在进入这两个函数之前,楼主先剧透一下这两个变量的含义。
version变量表示Windows版本,也就是Vista、7、8、8.1、10等,这从PSVersion的定义就可以看得出来:

WinBlue是Windows 8.1的别名,WinModern自然就是Windows 10了。
production变量表示Windows是正式版(true)还是测试版(false),这个变量的唯一作用是在后续的解密过程中选择RSA密钥。由于测试版Windows难以通过常规途径获得,因此正常情况下我们能接触到的Windows都是正式版。
-
好了,先来看看Utils.DetectVersion函数。
-
调用链:Program.Main(Program.cs) => Utils.DetectVersion(Common.cs)
Utils.DetectVersion的逻辑非常简单,就是根据Windows不断增长的Build确定操作系统版本。

Windows SDK提供了<VersionHelpers.h>用于确定Windows版本,这个头文件提供了一系列内联函数,在旧版Windows上也可以正常使用。

因此我们可以用C语言编写如下代码:


2025-12-10 01:28:21
广告
不感兴趣
开通SVIP免广告
  • XeO2
  • 小吧主
    14
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
好,再看看SPPUtils.DetectCurrentKey函数。
-
调用链:Program.Main(Program.cs) => SPPUtils.DetectCurrentKey(SPPUtils.cs)
SPPUtils.DetectCurrentKey首先调用了SLApi.RefreshLicenseStatus。

-
调用链:Program.Main(Program.cs) => SPPUtils.DetectCurrentKey(SPPUtils.cs) => SLApi.RefreshLicenseStatus(SLAPI.cs)
SLApi.RefreshLicenseStatus又调用了SLConsumeWindowsRight。

SLConsumeWindowsRight就是slc.dll中的一个API:

然而,如果我们在C语言中调用这个API,会发现<slpublic.h>中并没有该函数的声明,微软的文档中也不见这个函数的身影,这是一个未公开的函数。
-
幸好我们可以通过x86修饰名一窥该函数的参数情况:

再经过对slc.dll的反汇编和对其他SLAPI的观察和总结,最终得到SLConsumeWindowsRight的函数原型如下:

参数的作用仍然是未知的,不过没关系,我们直接用0作为参数即可。


登录百度账号

扫二维码下载贴吧客户端

下载贴吧APP
看高清直播、视频!
  • 贴吧页面意见反馈
  • 违规贴吧举报反馈通道
  • 贴吧违规信息处理公示
  • 1 2 3 4 下一页 尾页
  • 73回复贴,共4页
  • ,跳到 页  
<<返回c语言吧
分享到:
©2025 Baidu贴吧协议|隐私政策|吧主制度|意见反馈|网络谣言警示