• 标 题:又来敲CCG的大门了,Sorbet V1.1算法破解。电神魔鬼兄来看啊! (7千字)
  • 作 者:傲世男儿
  • 时 间:2000-10-1 2:16:54
  • 链 接:http://bbs.pediy.com

呵呵,我又来敲门了,真心希望SUN BIRD[CCG]及各位大客多多指教。
JMV Sorbet 1.1
就这个软件本身来说,编写的比较有创意,可以直接将图形文件的图标改为该文件的缩略图。另外,其配置/注册文件写成sorbet.cpl而放在控制面板的里面,很有些与众不同。
下载: URL ftp://ftp.bj.software.chinese.com/software/soft_photosee/JMV%20Sorbet%20Installer.exe
工具: TRW2k 1.22 W32DSM 8.93

随意输入密码:78787878787878-->load trw2k-->bpx hmemcpy-->F5-->确定-->拦住-->F12多次-->来到Sorbet领空。

F10来到这个Call:
:66002745 FF5028                  call [eax+28]
进入,很快就找到这里(下面比较注册码的前几位,非常简单):

:6601045F 8A08                    mov cl, byte ptr [eax]      //eax中存放着注册码的位置,取第一个字节'7'
:66010461 8A15C1A40166            mov dl, byte ptr [6601A4C1]

//66014C1中存放的内容为: "R7UK9AY34QHE"  ,这句取出'R'(Ox52),所以我们把al中的内容改为52
                                                                
:66010467 3ACA                    cmp cl, dl       
:66010469 751A                    jne 66010485        //继续
:6601046B 8A5001                  mov dl, byte ptr [eax+01]    //注册码的第二个字节'8'
:6601046E 8A0DC4A40166            mov cl, byte ptr [6601A4C4]  //应当为'K',所以我们把cl中的内容改为'K'(0x4B)
:66010474 3AD1                    cmp dl, cl
:66010476 750D                    jne 66010485            //继续
:66010478 50                      push eax
:66010479 E862000000              call 660104E0        //进这Call看看
......

:660104E0 8B542404                mov edx, dword ptr [esp+04]  //注册码地址给edx
.....
来到这里,这段多次在程序中出现,目的是为了过滤掉2D,20,5c,2f之类的无用符号:
:6601050E 8954241C                mov dword ptr [esp+1C], edx
:66010512 8A02                    mov al, byte ptr [edx]
:66010514 3C2D                    cmp al, 2D
:66010516 7410                    je 66010528
:66010518 3C20                    cmp al, 20
:6601051A 740C                    je 66010528
:6601051C 3C5C                    cmp al, 5C
:6601051E 7408                    je 66010528
:66010520 3C2F                    cmp al, 2F
:66010522 7404                    je 66010528
:66010524 3C5F                    cmp al, 5F
:66010526 7503                    jne 6601052B
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:66010516(C), :6601051A(C), :6601051E(C), :66010522(C)
|
:66010528 42                      inc edx
:66010529 EBE3                    jmp 6601050E        //如果等于那些无效字符,跳回去重新比较。
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:66010526(C)
|
:6601052B 8A02                    mov al, byte ptr [edx]        //取出第3个字符(非无效字符)
:6601052D 8A0DBDA40166            mov cl, byte ptr [6601A4BD]    
//66014BC后的内容是:56JWR7UK9AY34QHE
:66010533 42                      inc edx                        
:66010534 3AC1                    cmp al, cl                    //所以注册码中第3个字符为'6'
:66010536 8954241C                mov dword ptr [esp+1C], edx
:6601053A 753C                    jne 66010578

又经过一段判别无效字符的程序,来到这里:

:66010559 8A02                    mov al, byte ptr [edx]        //取出第4个字符(非无效字符)
:6601055B 42                      inc edx
:6601055C 33C9                    xor ecx, ecx                    //ecx == 0
:6601055E 8954241C                mov dword ptr [esp+1C], edx
:66010562 894C2410                mov dword ptr [esp+10], ecx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:66010572(C)
|
:66010566 3A81BCA40166            cmp al, byte ptr [ecx+6601A4BC] //所以注册码中第4个字符为'5'
:6601056C 7414                    je 66010582                      //跳到下面
......

从这里开始注册码的计算变得复杂起来了,我也是分析了一下算法才得到注册码的:
:66010582 83F911                  cmp ecx, 00000011                
:66010585 894C2410                mov dword ptr [esp+10], ecx
:66010589 7DED                    jge 66010578                  //不跳
:6601058B 83F905                  cmp ecx, 00000005
:6601058E 77E8                    ja 66010578                     //不跳
:66010590 83F902                  cmp ecx, 00000002           

* Possible Reference to String Resource ID=00002: "will end in a few minutes"
                                  |
:66010593 BF02000000              mov edi, 00000002            //注意:这里edi==2了,这在后面是个标志
:66010598 7602                    jbe 6601059C                  //跳
:6601059A 8BF9                    mov edi, ecx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:66010598(C)
|
:6601059C 897C2414                mov dword ptr [esp+14], edi  //注意:[esp+14]==2,这在后面也会用到
....
又经过一段判别无效字符的程序,来到这里

:660105BD 8A0A                    mov cl, byte ptr [edx]      //取出第六个字符
:660105BF 42                      inc edx                                
:660105C0 8954241C                mov dword ptr [esp+1C], edx
:660105C4 33C0                    xor eax, eax                    //eax -> 0

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:660105D2(C)
|
:660105C6 3A88BCA40166            cmp cl, byte ptr [eax+6601A4BC] //-------------->
:660105CC 7410                    je 660105DE                      //这个小循环的作用是在“56JWR7UK9AY34QHE”这个字符串中
:660105CE 40                      inc eax                          //中查找和你输入的第5个字符相等的字符在这个字符串中的位置,
:660105CF 83F811                  cmp eax, 00000011                  //结果记录在eax中。相当于Delphi/BCB中的StrPos()
:660105D2 7CF2                    jl 660105C6                    //<---------------

如果找到,就跳来这里:
:660105DE 83F811                  cmp eax, 00000011
:660105E1 7D95                    jge 66010578
:660105E3 83F810                  cmp eax, 00000010
:660105E6 7790                    ja 66010578

:660105DE 83F811                  cmp eax, 00000011      //------〉
:660105E1 7D95                    jge 66010578          //如果同最后一个字符相同或是没找到,注册失败
:660105E3 83F810                  cmp eax, 00000010
:660105E6 7790                    ja 66010578            //<-----

又经过一段判别无效字符的程序,再找出第6,7个字符在“56JWR7UK9AY34QHE”这个串中的位置。分别记录在ebp,ebx之中,
当然,如果ebp<11||ebx<11,注册失败,同上面一样,下面也是如此。
。。。。
:66010688 33F6                    xor esi, esi          //esi-->0
:6601068A 85FF                    test edi, edi          //然后这里检查edi的值了,记得吗,是2
:6601068C 765C                    jbe 660106EA
。。。。
又经过一段判别无效字符的程序,再找出第8个字符在“56JWR7UK9AY34QHE”这个串中的位置。记录在eax中,如果eax<11,执行下面一段程序。
.....
:660106DF 8B442414                mov eax, dword ptr [esp+14]  //记得吗,上面也说过,[esp+14] = 2,
:660106E3 46                      inc esi                      //这句话在一个循环体内,加两次后esi==eax==2
:660106E4 3BF0                    cmp esi, eax                
:660106E6 7306                    jnb 660106EE                    //不跳。但从下一行开始循环,知道在此行跳出为止
:660106E8 EBA4                    jmp 6601068E                    //跳,如此循环,直到自上面一行跳出。
。。。
又经过一段判别无效字符的程序,再找出第10个字符在“56JWR7UK9AY34QHE”这个串中的位置,记录在eax中,如果eax<11,执行下面一段程序。
:6601072C B910000000              mov ecx, 00000010  //-->
:66010731 2BCB                    sub ecx, ebx        //检查EBX+EAX是否等于16,不等则注册失败。
:66010733 3BC1                    cmp eax, ecx        //其中EBX为第7个字符在“56JWR7UK9AY34QHE”这个串中的位置
:66010735 0F853DFEFFFF            jne 66010578        //<---

到此为止,虽然注册码的检查还没有完,但其所有的检查方式都已经出现,罗嗦了这么多,也不想再说了,如果有哪位朋友还有什么问题或者什么不同的意见,欢迎交流。
公布一下找到的注册号:
                    Sorbet V1.1
                sn:    RK65KKKKKKKK
                        
                        国庆快乐!                
                                                    傲世男儿
                                                          2000/09/30