首页
社区
课程
招聘
[原创]Sandboxie 注册算法分析
发表于: 2010-11-7 00:35 195535

[原创]Sandboxie 注册算法分析

uuk 活跃值
3
2010-11-7 00:35
195535

Sandboxie 注册算法分析
【文章作者】: uuk
【软件名称】: Sandboxie 3.49.06
【下载地址】: http://www.sandboxie.com/index.php
【加壳方式】: 无
【保护方式】: 序列号
【编写语言】: Microsoft Visual C++ 7.0
【使用工具】: PEID,IDA Pro with Hex-Rays plugin,Syser
【操作平台】: XP SP3,
【软件介绍】: Sandboxie 允许你在沙盘环境中运行浏览器或其他程序,因此运行所产生的变化可以随后删除。可用来消除上网、运行程序的痕迹,也可用来还原收藏夹、主页、注册表等。即 使在沙盘进程中下载的文件,也会随着沙盘的清空而删除。此软件在系统托盘中运行,如果想启动一个沙盘进程,请通过托盘图标(而不要用原方式)启动浏览器或 相应程序。
【作者声明】: 菜鸟学习算法,失误之处敬请诸位大侠赐教!

    Sandboxie自3.48版本开始采用新的激活方式——联网激活,但也为不能上网的电脑提供了离线激活方式。能离线激活说明注册的验证是在本地进行的,方便我们进行算法分析。官方离线激活网址:http://www.sandboxie.com/index.php?OfflineActivation。在之前我已经通过官方的离线激活网页得到一个离线激活码Key(RF0UD7XH6KREU2TX……E4YJ1PT8RW8PO)。
    通过跟踪激活过程,激活管理程序License.exe调用SbieDll.dll的SbieApi_ActivateLicense,SbieApi_ActivateLicense通过IRP_MJ_DEVICE_CONTROL与驱动SbieDrv.sys通信,最终验证过程在驱动SbieDrv.sys里。通过IoControlCode定位到函数sub_20744(重命名为ActivateLicense),查看ActivateLicense的交叉引用,发现在驱动加载过程中也被调用了,因此可以确认验证过程就是sub_20744。ActivateLicense反汇编代码如下:
.text:00020744    push    ebp
.text:00020745    mov     ebp, esp
.text:00020747    sub     esp, 28h
.text:0002074A    push    esi
.text:0002074B    push    24h     ; 36 = 24h
.text:0002074D    push    [ebp+pKey]      ; ActivationKey(UNICODE)
.text:00020750    xor     esi, esi
.text:00020752    push    pPagedPool_tzuk ; PagedPool("tzuk")
.text:00020758    mov     [ebp+var_18], esi
.text:0002075B    mov     [ebp+var_14], esi
.text:0002075E    call    sub_1C1C8     ; mpz_set_str (mpz_t rop, char *str, int base)
.text:0002075E                          ; return eax = rop
    仔细分析sub_1C1C8,会发现它是将字符串Key当作36进制数,转换成16进制的大数(有点像GMP库里的mpz_set_str(Key, ActivationKey, 36))。由于是大数操作,所以sub_1C1C8里有大量的内存操作,刚开始分析时就让我晕头转向,同时又是大数运算,比较复杂。我花了不少时间才搞明白它在做什么,也知道程序中是如何存储大数的。大数结构如下所示:
struct BigNum{unsigned int size;  unsigned int num[size];}
大数在内存中按从低到高的地址存储从低到高的数。知道了大数的结构,以及内存申请和释放操作,后面的分析就会轻松许多。
.text:00020763    cmp     eax, esi        ; 大数 Key = eax
.text:00020765    mov     [ebp+pKey], eax
.text:00020768    jnz     short loc_2077E
.text:0002077E ; ---------------------------------------------------------------------------
.text:0002077E
.text:0002077E loc_2077E:                 ; CODE XREF: ActivateLicense+24 j
.text:0002077E    push    ebx
.text:0002077F    push    edi
.text:00020780    push    offset MOD
.text:00020785    push    offset EXP
.text:0002078A    push    eax
.text:0002078B    push    pPagedPool_tzuk
.text:00020791    call    sub_1C09E    ; mpz_powm (mpz_t rop, mpz_t base, mpz_t exp, mpz_t mod)
.text:00020791               ; return eax = rop
    大致分析sub_1C09E,排除内存操作后,发现里面有一些除法运算,初步确定是在做大数除法,但是在自己用大数计算器验证时发现结果总是不对,于是以为在sub_1C09E里有其他小动作。花了好几个晚上,仔仔细细的研究了里面不确定的CALL,以及运算过程,最后确定sub_1C09E里面做的就是大数除法和求模运算。既然是除法,那为什么测试时结果不对呢?我又去分析了下测试过程,发现我写的一个字符串反转程序少做一次对换,导致中间的两个字符没被反转(大数在内存里是从小到大存储,而计算器中是从大到小,所以要反转)。这样浪费了几天时间,但也让我明白了大数除法的算法。确定了sub_1C09E里面的大数运算过程,写出数学表达示,化简后发现是类似mpz_powm(Reg, Key, EXP, MOD)的函数。在sub_1C09E之后,注册信息就以明码放在内存中,后面就是一些数据的校验了。想要写出注册机就得能反求Reg = Key^EXP mod MOD,我求不出来,于是到论坛上求助http://bbs.pediy.com/showthread.php?t=123926,lingyu大侠告知这是RSA2048加密算法,在这要感谢大侠们的指点! 
下面是数据校验过程:
.text:00020796    mov     ebx, eax        ; ebx = Reg = eax
.text:00020798    mov     eax, [ebx]
.text:0002079A    cmp     eax, 4          ; Reg 长度size大于4
.text:0002079D    push    12h
.text:0002079F    pop     esi
.text:000207A0    jbe     loc_20A39
.text:000207A6    mov     cl, [ebx+4]
.text:000207A9    and     cl, 0Fh
.text:000207AC    cmp     cl, 1           ; Reg 最低位为1
.text:000207AF    push    13h
.text:000207B1    pop     esi
.text:000207B2    jnz     loc_20A39
.text:000207B8    push    14h
.text:000207BA    pop     esi
.text:000207BB    lea     eax, ds:0FFFFFFF4h[eax*4] ; size*4-0Ch
.text:000207C2    push    eax
.text:000207C3    lea     edi, [ebx+10h]
.text:000207C6    push    edi
.text:000207C7    call    sub_1B4B8      ; CheckSum 数据校验
    sub_1B4B8是对注册信息Reg进行校验,返回两个校验值,里面有两个CALL(sub_1B392、sub_1B418),看Hex-Rays plugin生成的C代码,很容易就能自己写出个checksum生成函数,代码在附件里有。也不知道是有现成的函数,还是作者杜撰的。
.text:000207CC    cmp     eax, [ebx+8]  ; 比较校验值1与[ebx+8]
.text:000207CF    jnz     loc_20A39
.text:000207D5    cmp     edx, [ebx+0Ch] ; 比较校验值2与[ebx+0Ch]
.text:000207D8    jnz     loc_20A39
.text:000207DE    cmp     dword ptr [edi], 80000001h ; [ebx+10h]
.text:000207E4    push    21h
.text:000207E6    pop     esi
.text:000207E7    jnz     loc_20A39
.text:000207ED    cmp     dword ptr [ebx+14h], 1 ; [ebx+14h] == 1
.text:000207F1    push    22h
.text:000207F3    pop     esi
.text:000207F4    jnz     loc_20A39
    再后面还有到期时间与当前系统时间的比较,软件版本的比较,系统码的比较,在IDA里很容易就能看得懂,这里就不详细说明了。注册信息的结构如下所示:
 
    关于注册机:RSA2048是很难反求的,只能通过替换公钥的方法进行破解(看雪论坛精华里看到的)。由于是替换驱动SbieDrv.sys里的公钥,替换后还得修正文件的CheckSum,不然驱动不能加载。附件里是我写的一个简单的Patch和Keygen。
    同时有个疑问:SbieDrv.sys打过补丁后,其数字签名就变成无效了,既然RSA可以通过替换公钥进行攻击,那文件的数字签名可不可以伪造?

Keygen.rar


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 7
支持
分享
最新回复 (158)
雪    币: 15
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
虽然我还没有能力全部理解,但是还是坚持仔仔细细的看了一遍。
真精彩
2010-11-7 01:19
0
雪    币: 550
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
感谢分享
2010-11-7 01:27
0
雪    币: 150
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
终于有破解了
2010-11-7 08:53
0
雪    币: 150
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
想问问楼主,能不能看出这个软件是在哪保存到期时间的?
2010-11-7 08:55
0
雪    币: 379
活跃值: (233)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
6
不是很明白你说的是什么意思,它的激活码是保存在注册表里的,不管是联网激活还是离线激活都一样,联网激活是自动的,离线激活是手动的。
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{98E6BD24-2D93-41A5-BC6D-CB7C1507318B}
2010-11-7 10:05
0
雪    币: 150
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
再后面还有到期时间与当前系统时间的比较,软件版本的比较,系统码的比较,在IDA里很容易就能看得懂,这里就详细说明了。注册信息的结构如下所示

这个到期时间,肯定会保存在机器上的某个位置吧,不知道能不能找到在哪保存的,如果能找到的话,或许可以做些处理,那就不用总去激活它了。
2010-11-7 10:16
0
雪    币: 150
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8

三、注册信息收集
1、版本号:“C:\Program Files\Sandboxie\License.exe print version”,如3.50
2、系统码:“C:\Program Files\Sandboxie\License.exe print syscode”,如5BA2F01DBAB60EA8
3、到期时间:年月日,形如20110214

哦,在第三步的时候,可以用filemon和regmon监视下看看,呵呵,谢谢了,有空试试,看能不能找到
2010-11-7 10:21
0
雪    币: 379
活跃值: (233)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
9
注册信息的结构里我标出来了,在第三行,是31121120,逆着看就是2011-12-31
2010-11-7 10:22
0
雪    币: 150
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
不太明白什么意思
我的意思是,沙盘每次启动时都会读取这个到期时间,我想知道它是从哪读取到这个值的
2010-11-7 10:38
0
雪    币: 379
活跃值: (233)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
11
激活码(Key)保存在注册表中,每次沙盘启动时做 Reg = Key^EXP mod MOD, 得到注册信息 Reg。如果所有校验都通过,则执行
.text:00020A15 loc_20A15:                              ; CODE XREF: ActivateLicense+2BCj
.text:00020A15                 mov     eax, dword ptr [ebp+Time]
.text:00020A18                 mov     dword_28A80, eax
.text:00020A1D                 mov     eax, dword ptr [ebp+Time+4]
.text:00020A20                 mov     dword_28A84, eax
.text:00020A25                 mov     eax, [ebp+var_18]
.text:00020A28                 mov     dword_28A88, eax
.text:00020A2D                 mov     eax, [ebp+var_14]
.text:00020A30                 mov     dword_28A8C, eax
.text:00020A35                 xor     esi, esi
.text:00020A37                 jmp     short loc_20A51

将到期时间保存在变量 dword_28A80(ExpiredDate_Low),dword_28A84(ExpiredDate_High)里。之后查询是否激活,剩余时间等全用的是 ExpiredDate,注册信息 Reg 在 ActivateLicense 执行之后就被释放了。
2010-11-7 10:50
0
雪    币: 150
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
也就是说到期时间也是通过key计算出来的?而不是专门保存一个值在注册表里,哦,那看来没办法了
2010-11-7 10:55
0
雪    币: 379
活跃值: (233)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
13
是的,但可以爆破,直接给 ExpiredDate 赋值,只是这样每次有新版本都得重新爆破。
2010-11-7 10:59
0
雪    币: 236
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
很不错,最近刚好想试试自己注册下沙盘的,多谢啦
2010-11-7 11:21
0
雪    币: 709
活跃值: (2420)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
15
楼主分析的很详细. 它的驱动没有数字签名呀.
2010-11-7 14:23
0
雪    币: 370
活跃值: (15)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
16
及时雨啊,一直还在3.46
刚要问为什么没有记录下驱动跟踪细节,原来楼主用了Syser+IDA,似乎用的人不多,大部分都windbg
2010-11-7 15:02
0
雪    币: 379
活跃值: (233)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
17
它的驱动有数字签名,所以打过补丁后显示签名无效
2010-11-7 15:12
0
雪    币: 379
活跃值: (233)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
18
也是第一次跟踪驱动,试了下 Syser ,能用,所以就先用着了,如果不能用估计下一个就会试 Windbg
2010-11-7 15:14
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
终于等到了  谢谢楼主
2010-11-7 15:24
0
雪    币: 709
活跃值: (2420)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
20
楼主好样的,一直用3.46,这次终于可以用3.49了...
2010-11-7 19:19
0
雪    币: 379
活跃值: (233)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
21
谢谢! 3.50都出来了,破解也可以用在 3.50 上
2010-11-7 20:48
0
雪    币: 709
活跃值: (2420)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
22
2010-11-7 21:05
0
雪    币: 185
活跃值: (477)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
还在用老版本 不过还是收藏了 哈哈
2010-11-8 09:16
0
雪    币: 150
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
win7 64位 激活失败
2010-11-8 13:48
0
雪    币: 150
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
提示
This is not a valid Activation Key.  [C0000080]
2010-11-8 14:07
0
游客
登录 | 注册 方可回帖
返回
//