首页
社区
课程
招聘
[原创]Turbo Photo4.7的破解及不完全算法分析
发表于: 2005-12-18 14:23 9680

[原创]Turbo Photo4.7的破解及不完全算法分析

2005-12-18 14:23
9680
【原创】Turbo Photo的破解及不完全算法分析
Turbo Photo是一个以数码影像为背景,面向数码相机普通用户和准专业用户而设计的一套集图片管理,浏览,处理,输出为一身的软件系统。她包括两个部分:Turbo Photo 相册和Turbo Photo 编辑器。

【作者】WindayJiang
【破解声明】纯粹学习
【破解工具】WDSM,OLLDBG, eXeScopE,  PEID,
【破解难度】EASY
【软件保护】SN+TIME
【软件下载】http://www.stepok.com/chs/index.htm

运行软件,程序要关闭那一刻才会弹出注册框,错误注册会有提示

开工!先查壳吧,VC编的,没有加壳。

用OD加载,CTRL+N查看一下,找不到GETWINDOWTEXTA之类的常规函数,那么就试一下内存的吧, 调出注册窗口,输入12345-54321-888888-98765,按解锁,这时提示序列号错误,不要关闭它,回到OD,在DUMP里CTRL+B,查找HEX31 32 33 34 35, 如下:
004BB52C  31 32 33 34 35 00 35 34 33 32 31 00 38 38 38 38  12345.54321.8888
004BB53C  38 38 00 39 38 37 36 35 00 00 00 00 80 22 1D 40  88.98765......? @

在004BB52C下硬件断点,再次解锁就会来到这里:
00453430  |.  8BC8          MOV ECX,EAX
00453432  |.  33C0          XOR EAX,EAX
00453434  |.  83E1 03       AND ECX,3
00453437  |.  F3:A4         REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[>
.
CTRL+F9返回后来到这里:
00452EA3   .  B9 7CB14B00   MOV ECX,TPhoto.004BB17C
00452EA8   .  E8 53050000   CALL TPhoto.00453400       //注册码的比较CALL
00452EAD   .  85C0          TEST EAX,EAX         //判断EAX
00452EAF   .  75 1B         JNZ SHORT TPhoto.00452ECC   //跳就成功注册了,不跳就提示错误
00452EB1   .  50            PUSH EAX

于是修改452EAF为JMP SHORT TPhoto.00452ECC,但你很快就会发现这是不治本的,程序启动会再判断是否注册,于是点击452EAF右键,选FIND REFERENCES TO CALL DESTINATION,发现有2个地方调用,另一个就是4535CC,在此下断,重运行程序,断下:
004535CC  |.  E8 2FFEFFFF   CALL TPhoto.00453400
004535D1  \.  C3            RETN             //返回4533A5
……………..
004533A5  |.  F7D8          NEG EAX
004533A7  |.  5F            POP EDI         ;  TPhoto.004BBC58
004533A8  |.  5E            POP ESI
004533A9  |.  1BC0          SBB EAX,EAX
004533AB  |.  5D            POP EBP
004533AC  |.  F7D8          NEG EAX
004533AE  |.  5B            POP EBX
004533AF  |.  59            POP ECX           //上面是对EAX处理
004533B0  \.  C3            RETN            //返回453A37
………………..
00453A37  |.  8986 64030000 MOV DWORD PTR DS:[ESI+364],EAX                //将EAX写入内存标志位
00453A3D  |.  C786 68030000>MOV DWORD PTR DS:[ESI+368],1               
00453A47  |.  5E            POP ESI
00453A48  \.  C3            RETN                                                       

由上2处判断可知只要令标志返回1就OK了,下面我们看看注册码的比较CALL:
00453400  /$ >PUSH EBX                                          
00453401  |. >MOV EBX,ECX
00453403  |. >PUSH EBP               //"C:\WINNT\system32\tpflag.rg,注册信息文件
00453404  |. >MOV EBP,DWORD PTR SS:[ESP+C]
00453408  |. >LEA EDX,DWORD PTR DS:[EBX+3B0]          //第一段注册码地址放到EDX        /12345
0045340E  |. >PUSH ESI
0045340F  |. >CMP EDX,EBP
00453411  |. >PUSH EDI
00453412  |. >JE TPhoto.004534BE          //这里会跳
…….
004534BE  |>>MOV EDI,TPhoto.004B795C       ;  ASCII "DDGTM"  //字串DDGTM到EDI
004534C3  |.>MOV ESI,EDX                    //第一段注册码到ESI        12345
004534C5  |>>/MOV CL,BYTE PTR DS:[ESI]             //第1个注册码到CL                “1”
004534C7  |.>|MOV DL,BYTE PTR DS:[EDI]             //“D”
004534C9  |.>|MOV AL,CL                     //第1个注册码到AL
004534CB  |.>|CMP CL,DL                     //第1个注册是不是“D”
004534CD  |.>|JNZ SHORT TPhoto.004534ED             //不是跳走
004534CF  |.>|TEST AL,AL                     //AL是不是0
004534D1  |.>|JE SHORT TPhoto.004534E9                      //0就跳到4534E9
004534D3  |.>|MOV DL,BYTE PTR DS:[ESI+1]            //第2个注册码到CL                “2”
004534D6  |.>|MOV CL,BYTE PTR DS:[EDI+1]            //第二个“D”
004534D9  |.>|MOV AL,DL
004534DB  |.>|CMP DL,CL                                               
004534DD  |.>|JNZ SHORT TPhoto.004534ED            //不是跳走
004534DF  |.>|ADD ESI,2
004534E2  |.>|ADD EDI,2
004534E5  |.>|TEST AL,AL
004534E7  |.>\JNZ SHORT TPhoto.004534C5            //向上循环
004534E9  |>>XOR EAX,EAX                         //EAX清0
004534EB  |.>JMP SHORT TPhoto.004534F2            //跳到4534F2
004534ED  |>>SBB EAX,EAX                  //借位减
004534EF  |.>SBB EAX,-1
004534F2  |>>TEST EAX,EAX                               
004534F4  |.>JNZ SHORT TPhoto.004534FD             //如果不跳标志值就不能设为1
004534F6  |.>POP EDI
004534F7  |.>POP ESI
004534F8  |.>POP EBP
004534F9  |.>POP EBX
004534FA  |.>RETN 10
………………
004534FD  |> \8B>MOV EAX,DWORD PTR SS:[ESP+20]       //第4段注册码
00453501  |.  8B>MOV ECX,DWORD PTR SS:[ESP+1C]       //第3段注册码
00453505  |.  8B>MOV EDX,DWORD PTR SS:[ESP+18]             //第2段注册码
00453509  |.  50 PUSH EAX                   //第4段注册码入栈
0045350A  |.  51 PUSH ECX                   //第3段注册码入栈
0045350B  |.  52 PUSH EDX                  //第2段注册码入栈
0045350C  |.  55 PUSH EBP                  //第1段注册码入栈
0045350D  |.  8D>LEA ECX,DWORD PTR DS:[EBX+204]                     ; |
00453513  |.  E8>CALL TPhoto.0048E210            //看来这个最终的比较CALL了
00453518  |. >TEST EAX,EAX                 //标志是否为0
0045351A  |. >JNZ SHORT TPhoto.00453523           //0的话就是注册不成功了
……………………
00453523  |> >LEA EAX,DWORD PTR SS:[ESP+20]
00453527  |. >PUSH EAX
00453528  |. >CALL <JMP.&MFC42.#3811>
0045352D  |. >PUSH 0
0045352F  |. >MOV ECX,EAX
00453531  |. >CALL <JMP.&MFC42.#3337>
00453536  |. >MOV ECX,DWORD PTR DS:[EAX+14]
00453539  |. >ADD ECX,76C
0045353F  |. >CMP ECX,7D5                 //是否2005年?
00453545  |. >JLE SHORT TPhoto.0045358F
…………..
0045358F  |> >MOV EAX,1               //终于看到这个了,等得不就是这个嘛,呵呵
00453594  |. >POP EDI
00453595  |. >POP ESI
00453596  |. >MOV DWORD PTR DS:[EBX+368],EAX
0045359C  |. >POP EBP
0045359D  |. >POP EBX
0045359E  \. >RETN 10

篇幅有限,哪些JUMP该修改我就不说了,改完后当你再次运行程序会提示:注册号是非法的窗口,需要再次解锁,拿出EXESCOPE,找到该对话框274, 换算HEX是112, 再来WDASM看看:
* Possible Reference to Dialog: DialogID_0112
:00453B31 6812010000              push 00000112      //到OD设断这里
:00453B36 89742418                mov dword ptr [esp+18], esi
CTRL+K VIEW CALL TREE,看看是从什么地方调用的(这里要看2次,篇幅问题我只能省略了),来到这:
0042E79F   .  E8 3C4E0200   CALL TPhoto.004535E0
0042E7A4   .  3BC5          CMP EAX,EBP
0042E7A6   .  A1 E0B44B00   MOV EAX,DWORD PTR DS:[4BB4E0]/很面熟吧,在注册码比较那见过
0042E7AB   .  7F 4D         JG SHORT TPhoto.0042E7FA  //必须跳否则说非法
…………….
0042E7FA   > \3BC5          CMP EAX,EBP                               
0042E7FC   .  75 68         JNZ SHORT TPhoto.0042E866  //必须跳,否则是试用版
……………

修改一下,一个非常好用的软件就此告破!

总结一下:很长时间没写破文了,自己感觉也很累,比破的时间还要长:P, 破的时候没有用其他一些可能更有效更快捷的断点,而是用几个软件交叉配合,让刚学破解的NEWBIES熟练用用软件,写得不好还望大家多多原谅了。另外我没有时间再跟进注册算法,TPhoto.0048E210这个CALL估计就是算法的关键CALL,有兴趣的朋友可以再去看看。还有就是TurboPhotoAlbum.exe是相册,同样需要破解的,但跟上面思路一样,我就懒得写了:P

////////////////////////////////////////////////////////////////
If you want to crack well, learn ASM well !

WiNDaYJiANg       2005-12-18
////////////////////////////////////////////////////////////////


[课程]FART 脱壳王!加量不加价!FART作者讲授!

收藏
免费 7
支持
分享
最新回复 (11)
雪    币: 450
活跃值: (552)
能力值: ( LV9,RANK:690 )
在线值:
发帖
回帖
粉丝
2
支持
2005-12-18 14:59
0
雪    币: 44229
活跃值: (19965)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
3
文章不错。
排版格式不太美观,我们一般都是在记事本排好后粘贴上来。
2005-12-18 16:07
0
雪    币: 243
活跃值: (190)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
4
我是用WORD编辑的,习惯了用WORD,呵呵
写得急,等会我修改一下排版,谢谢你的意见!
2005-12-18 16:35
0
雪    币: 44229
活跃值: (19965)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
5
最初由 windayjian 发布
我是用WORD编辑的,习惯了用WORD,呵呵
写得急,等会我修改一下排版,谢谢你的意见!


算法过程是出来了,建议最后将算法再总结一下,能写出注册机就完美了。
另外,建议尽可能用国外软件来讨论。;)
2005-12-18 16:49
0
雪    币: 343
活跃值: (611)
能力值: ( LV9,RANK:810 )
在线值:
发帖
回帖
粉丝
6
弄过这个软件的老版本。是采用随机验证的。不过验证的地方比较集中,反破解的意义不大。新版的可能算法会有些变化吧。看样子你还需要继续看哦。
2005-12-18 17:19
0
雪    币: 243
活跃值: (190)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
7
最初由 ForEver 发布
弄过这个软件的老版本。是采用随机验证的。不过验证的地方比较集中,反破解的意义不大。新版的可能算法会有些变化吧。看样子你还需要继续看哦。


是的,采用随机验证,我后来再看了一下,还是没能看懂,呵呵
2005-12-18 17:47
0
雪    币: 343
活跃值: (611)
能力值: ( LV9,RANK:810 )
在线值:
发帖
回帖
粉丝
8
序列号格式:XXXXX-XXXXXX-XXXXX-XXXXX

我们假设输入的四组序列号分别用s1[6],s2[6],s3[7],s4[6]来表示。
其中s1[0]代表第一组序列号的第一个字符。其余类推。

loc46B2EE:        mov        dword ptr [ebx],     offset loc_46A9A0 ;这些地址其实就是验证注册码
                mov        dword ptr [ebx+4],   offset loc_46A910 ;的CALL,软件作者根据计算机
                mov        dword ptr [ebx+8],   offset sub_46A890 ;用户名选择一部分来验证。如
                mov        dword ptr [ebx+0Ch], offset loc_46A980 ;果只跟踪用到的CALL来做注册
                mov        dword ptr [ebx+10h], offset loc_46A810 ;机是不能通用的。这大概也是
                mov        dword ptr [ebx+14h], offset sub_46AC80 ;软件作者对破解的防范。
                mov        dword ptr [ebx+18h], offset sub_46AD40 ;
                mov        dword ptr [ebx+1Ch], offset sub_46AE00 ;下面我们一一分析这些CALL。
                mov        dword ptr [ebx+20h], offset loc_46AEB0 ;
                mov        dword ptr [ebx+24h], offset sub_46AF40 ;
                mov        dword ptr [ebx+28h], offset loc_46AB80 ;
                mov        dword ptr [ebx+2Ch], offset loc_46AB20 ;
                mov        dword ptr [ebx+30h], offset loc_46AAC0 ;
                mov        dword ptr [ebx+34h], offset loc_46ABE0 ;
                mov        dword ptr [ebx+38h], offset loc_46AA60 ;
                mov        dword ptr [ebx+3Ch], offset loc_46AC40 ;
;///////////////////////////////////////////////////////////////

第一个CALL: s1[4] = 4Dh ('M')

;-------------------------------------------------
loc_46A9A0:                                ; DATA XREF: sub_46B200+EEo
                mov        eax, [esp+4]      ;第一组序列号
                push        ebx
                push        esi
                push        edi
                mov        bl, [eax+4]       ;指向第五个字符

loc_46AA45:                                ; CODE XREF: .text:0046AA2Aj
                mov        edx, dword_490278 ;这个全局变量里是 1 ,追一下可以看到
                xor        ecx, ecx
                movsx        eax, bl
                add        edx, 4Ch
                pop        edi
                cmp        eax, edx          ;不等于 4Dh 失败
                pop        esi
                setz        cl
                mov        eax, ecx
                pop        ebx
                retn
;///////////////////////////////////////////////////////////////

第二个CALL: s1[2]>=43h && s1[2]<=4Ch

;---------------------------------------------------------------
loc_46A910:                                ; DATA XREF: sub_46B200+F4o

loc_46A961:                                ; CODE XREF: .text:0046A94Aj
                mov        edx, [esp+4]    ;第一组序列号
                mov        al, [edx+2]     ;指向第三个字符
                cmp        al, 43h         ;小于43h失败
                jl        short loc_46A976
                cmp        al, 4Ch         ;大于4Ch失败
                jg        short loc_46A976

unknown_libname_47:
                mov        eax, 1
                retn
; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?

loc_46A976:                                ; CODE XREF: .text:0046A93Bj
                                        ; .text:0046A93Fj .text:0046A955j
                                        ; .text:0046A959j .text:0046A96Aj
                                        ; .text:0046A96Ej
                xor        eax, eax
                retn
;///////////////////////////////////////////////////////////////

第三个CALL: s1[1]>=42h && s1[1]<=44

;---------------------------------------------------------------
sub_46A890        proc near                ; DATA XREF: sub_46B200+FBo

loc_46A8CB:                                ; CODE XREF: sub_46A890+21j
                push        ecx
                lea        ecx, [esp+0Ch+var_8]
                mov        eax, esp
                mov        dword ptr [eax], 5
                call        sub_46B4B0
                test        eax, eax
                jz        short loc_46A8F2
                mov        ecx, [esp+8+arg_0]     ;第一组序列号
                xor        eax, eax
                cmp        byte ptr [ecx+1], 41h  ;第二个字符等于41h则失败
                setnl        al
                add        esp, 8
                retn
; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?

loc_46A8F2:                                ; CODE XREF: sub_46A890+4Fj
                mov        edx, [esp+8+arg_0]
                mov        al, [edx+1]
                cmp        al, 41h               ;小于41h则失败
                jl        short loc_46A90A
                cmp        al, 45h               ;大于等于45h则失败
                jge        short loc_46A90A
                mov        eax, 1
                add        esp, 8
                retn
; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?

loc_46A90A:                                ; CODE XREF: sub_46A890+2Cj
                                        ; sub_46A890+30j sub_46A890+6Bj
                                        ; sub_46A890+6Fj
                xor        eax, eax
                add        esp, 8
                retn
sub_46A890        endp
;///////////////////////////////////////////////////////////////

第四个CALL:s1[3]>=42 && s1[3]<=79

;---------------------------------------------------------------
loc_46A980:                                ; DATA XREF: sub_46B200+102o
                mov        eax, [esp+4]    ;第一组序列号
                mov        al, [eax+3]     ;第四个字符
                cmp        al, 41h         ;小于41h失败
                jl        short loc_46A995
                cmp        al, 7Ah         ;大于等于7ah失败
                jge        short loc_46A995

unknown_libname_48:
                mov        eax, 1
                retn
; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?

loc_46A995:                                ; CODE XREF: .text:0046A989j
                                        ; .text:0046A98Dj
                xor        eax, eax
                retn
;///////////////////////////////////////////////////////////////

第五个CALL:s1[0] = 44h ('D')

;---------------------------------------------------------------
loc_46A810:                                ; DATA XREF: sub_46B200+109o
               

loc_46A866:                                ; CODE XREF: .text:0046A843j
                                        ; DATA XREF: .text:0046A880o
                mov        eax, [esp+4]        ;第一组序列号
                mov        al, [eax]       ;第一个字符
                cmp        al, 44h         ;小于44h失败
                jl        short loc_46A874
                cmp        al, 45h         ;大于等于45h失败

loc_46A872:                                ; CODE XREF: .text:0046A856j
                                        ; .text:0046A864j
                jl        short unknown_libname_43 ; default

loc_46A874:                                ; CODE XREF: .text:0046A852j
                                        ; .text:0046A860j .text:0046A86Ej
                xor        eax, eax
                retn
; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?

unknown_libname_43:                        ; CODE XREF: .text:0046A841j
                                        ; .text:0046A843j .text:0046A872j
                                        ; DATA XREF: .text:0046A880o
                mov        eax, 1                ; default
                retn                               
;///////////////////////////////////////////////////////////////

第六个CALL: s4[0] = (s1[4]%7 + s1[2]%5 + s1[1]*2 + s1[0]) % 1Ah + 41h

;---------------------------------------------------------------
sub_46AC80        proc near                ; DATA XREF: sub_46B200+110o

                sub        esp, 8
                lea        eax, [esp+8+var_4]
                push        eax
                call        ?GetTickCount@CTime@@SG?AV1@XZ ; CTime::GetTickCount(void)
                mov        ecx, [eax]
                push        0
                mov        [esp+0Ch+var_8], ecx
                lea        ecx, [esp+0Ch+var_8]
                call        ?GetLocalTm@CTime@@QBEPAUtm@@PAU2@@Z ; CTime::GetLocalTm(tm *)
                mov        eax, [eax+4]
                cmp        eax, 2Dh
                jle        short loc_46ACF9
                mov        ecx, [esp+8+arg_0]   
                push        esi
                mov        esi, 7
                push        edi
                movsx        eax, byte ptr [ecx+4] ;第一组序列号第五个字符
                cdq
                idiv        esi                  
                movsx        eax, byte ptr [ecx+2] ;第一组序列号第三个字符
                mov        edi, 5               
                mov        esi, edx              
                cdq
                idiv        edi
                pop        edi
                add        esi, edx              
                movsx        edx, byte ptr [ecx+1] ;第一组序列号第二个字符
                movsx        ecx, byte ptr [ecx]   ;第一组序列号第一个字符
                lea        eax, [esi+edx*2]      
                pop        esi
                add        eax, ecx             ;eax = s1[4]%7 + s1[2]%5 + s1[1]*2 + s1[0]
                mov        ecx, 1Ah            
                cdq
                idiv        ecx
                mov        eax, [esp+8+arg_C]   
                movsx        ecx, byte ptr [eax]  ;s4[0]
                xor        eax, eax
                add        dl, 41h              ;eax % 1ah +41
                and        edx, 0FFh
                cmp        ecx, edx
                setz        al
                add        esp, 8
                retn

sub_46AC80        endp
;///////////////////////////////////////////////////////////////

第七个CALL: s4[1] = (s2[3]%3 + s2[4]*5 + s2[0]*2 + s2[1] + s2[2]) % 1Ah + 41h

;---------------------------------------------------------------
sub_46AD40        proc near                ; DATA XREF: sub_46B200+117o
                sub        esp, 8
                lea        eax, [esp+8+var_4]
                push        eax
                call        ?GetTickCount@CTime@@SG?AV1@XZ ; CTime::GetTickCount(void)
                mov        ecx, [eax]
                push        0
                mov        [esp+0Ch+var_8], ecx
                lea        ecx, [esp+0Ch+var_8]
                call        ?GetLocalTm@CTime@@QBEPAUtm@@PAU2@@Z ; CTime::GetLocalTm(tm *)
                mov        eax, [eax+18h]
                inc        eax
                cmp        eax, 5
                jle        short loc_46ADB8
                mov        ecx, [esp+8+arg_4]   ;第二组序列号
                push        esi
                mov        esi, 3
                movsx        eax, byte ptr [ecx+3] ;s2[3]
                cdq
                idiv        esi
                movsx        eax, byte ptr [ecx+4] ;s2[4]
                pop        esi
                lea        eax, [eax+eax*4]
                add        edx, eax
                movsx        eax, byte ptr [ecx]   ;s2[0]
                lea        eax, [edx+eax*2]
                movsx        edx, byte ptr [ecx+2] ;s2[2]
                movsx        ecx, byte ptr [ecx+1] ;s2[1]
                add        eax, edx
                add        eax, ecx
                mov        ecx, 1Ah
                cdq
                idiv        ecx
                mov        eax, [esp+8+arg_C]    ;第四组序列号
                movsx        ecx, byte ptr [eax+1] ;s4[1]
                xor        eax, eax
                add        dl, 41h
                and        edx, 0FFh
                cmp        ecx, edx
                setz        al
                add        esp, 8
                retn
sub_46AD40        endp
;///////////////////////////////////////////////////////////////

第八个CALL: s4[2] = (s3[3]*23 + s3[5] + s3[0])% 1Ah + 41h

;---------------------------------------------------------------
sub_46AE00        proc near                ; DATA XREF: sub_46B200+11Eo
                sub        esp, 8
                lea        eax, [esp+8+var_4]
                push        eax
                call        ?GetTickCount@CTime@@SG?AV1@XZ ; CTime::GetTickCount(void)
                mov        ecx, [eax]
                push        0
                mov        [esp+0Ch+var_8], ecx
                lea        ecx, [esp+0Ch+var_8]
                call        ?GetLocalTm@CTime@@QBEPAUtm@@PAU2@@Z ; CTime::GetLocalTm(tm *)
                mov        eax, [eax]
                and        eax, 80000007h
                jns        short loc_46AE2C
                dec        eax
                or        eax, 0FFFFFFF8h
                inc        eax

loc_46AE2C:                                ; CODE XREF: sub_46AE00+25j
                cmp        eax, 5
                jle        short loc_46AE70
                mov        edx, [esp+8+arg_8]       ;第三组序列号
                movsx        ecx, byte ptr [edx+3]    ;s[3]
                lea        eax, [ecx+ecx*2]
                shl        eax, 3
                sub        eax, ecx
                movsx        ecx, byte ptr [edx+5]    ;s[5]
                movsx        edx, byte ptr [edx]      ;s[0]
                add        eax, ecx
                mov        ecx, 1Ah
                add        eax, edx
                cdq
                idiv        ecx
                mov        eax, [esp+8+arg_C]    ;第四组序列号
                movsx        ecx, byte ptr [eax+2] ;s4[2]
                xor        eax, eax
                add        dl, 41h
                and        edx, 0FFh
                cmp        ecx, edx
                setz        al
                add        esp, 8
                retn
sub_46AE00        endp
;///////////////////////////////////////////////////////////////

第九个CALL: s4[3] = (s3[1]*7 + s3[2] + s2[2] + s1[3]) % 1Ah + 41h
        
;---------------------------------------------------------------
loc_46AEB0:                                ; DATA XREF: sub_46B200+125o
                call        sub_46A690
                cmp        eax, 5
                jle        short loc_46AF06
                mov        edx, [esp+0Ch]        ;第三组序列号
                movsx        ecx, byte ptr [edx+1] ;s3[1]
                movsx        edx, byte ptr [edx+2] ;s3[2]
                lea        eax, ds:0[ecx*8]
                sub        eax, ecx
                mov        ecx, [esp+4]          ;第一组序列号
                movsx        ecx, byte ptr [ecx+3] ;s1[3]
                add        eax, ecx
                mov        ecx, [esp+8]          ;第二组序列号
                movsx        ecx, byte ptr [ecx+2] ;s2[2]
                add        eax, ecx
                mov        ecx, 1Ah
                add        eax, edx
                cdq
                idiv        ecx
                mov        eax, [esp+10h]        ;第四组序列号
                movsx        ecx, byte ptr [eax+3] ;s4[3]
                xor        eax, eax
                add        dl, 41h
                and        edx, 0FFh
                cmp        ecx, edx
                setz        al
                retn
;///////////////////////////////////////////////////////////////

第十个CALL: 返回 1 ,即成功标志
        
;---------------------------------------------------------------
       
;///////////////////////////////////////////////////////////////

第十一个CALL: s3[3]>=49h && s3[3]<=52h
        
;---------------------------------------------------------------
loc_46AB80:                                ; DATA XREF: sub_46B200+133o
                call        sub_46A690
                cmp        eax, 8
                jle        short loc_46AB9F
                mov        eax, [esp+0Ch]        ;第三组序列号
                mov        al, [eax+3]           ;s3[3]
                cmp        al, 49h
                jl        short unknown_libname_63
                cmp        al, 52h
                jg        short unknown_libname_63

unknown_libname_60:
                mov        eax, 1
                retn       
;///////////////////////////////////////////////////////////////

第十二个CALL: s3[2]>=42h && s3[2]<=4Bh
        
;---------------------------------------------------------------               
loc_46AB20:                                ; DATA XREF: sub_46B200+13Ao
                call        sub_46A690
                cmp        eax, 8
                jle        short loc_46AB3F
                mov        eax, [esp+0Ch]          ;第三组序列号
                mov        al, [eax+2]             ;s3[2]
                cmp        al, 42h
                jl        short unknown_libname_59
                cmp        al, 4Bh
                jg        short unknown_libname_59

unknown_libname_56:
                mov        eax, 1
                retn
;///////////////////////////////////////////////////////////////

第十三个CALL: s3[1]>=48h && s3[1]<=51h
        
;---------------------------------------------------------------       
loc_46AAC0:                                ; DATA XREF: sub_46B200+141o
                call        sub_46A690
                cmp        eax, 8
                jle        short loc_46AADF
                mov        eax, [esp+0Ch]
                mov        al, [eax+1]
                cmp        al, 48h
                jl        short unknown_libname_55
                cmp        al, 51h
                jg        short unknown_libname_55

unknown_libname_52:
                mov        eax, 1
                retn       
;///////////////////////////////////////////////////////////////

第十四个CALL: s3[4]>=4bh && s3[4]<=54
        
;---------------------------------------------------------------       
loc_46ABE0:                                ; DATA XREF: sub_46B200+148o
                call        sub_46A690
                cmp        eax, 5
                jle        short loc_46ABFF
                mov        eax, [esp+0Ch]           ;第三组序列号
                mov        al, [eax+4]              ;s3[4]
                cmp        al, 4Bh
                jl        short unknown_libname_67
                cmp        al, 54h
                jg        short unknown_libname_67

unknown_libname_64:
                mov        eax, 1
                retn
;///////////////////////////////////////////////////////////////

第十五个CALL: s3[0] = 47h ('G')
        
;---------------------------------------------------------------         

loc_46AA60:                                ; DATA XREF: sub_46B200+14Fo
                call        sub_46A690
                cmp        eax, 8
                jle        short loc_46AA77
                mov        ecx, [esp+0Ch]           ;第三组序列号
                xor        eax, eax
                cmp        byte ptr [ecx],        47h      ;s[0] == 47h
                setz        al
                retn
;///////////////////////////////////////////////////////////////

第十六个CALL: s3[5]>=4Ah && s3[5]<=53h
        
;---------------------------------------------------------------         
loc_46AC40:                                ; DATA XREF: sub_46B200+156o
                call        sub_46A690
                cmp        eax, 8
                jle        short loc_46AC5F
                mov        eax, [esp+0Ch]           ;第三组序列号
                mov        al, [eax+5]              ;s3[5]
                cmp        al, 4Ah
                jl        short loc_46AC74
                cmp        al, 53h
                jg        short loc_46AC74

unknown_libname_68:
                mov        eax, 1
                retn               
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////

总结一下:
   把所有的条件合并起来,就是生成注册码的方法了。为了省空间和容易阅读,我省去
了一部分代码,而取判断的最小集。软件作者在验证注册码时采用随机验证的方法。因此
不正确的注册码可能当时并不提示。而在过一段时间才提示的。
   这个软件的注册方法很值得借鉴,只是验证部分的CALL过于集中,容易给人发现。如
果把验证的CALL分散开,必然会大大增加破解的难度。

   软件在注册后的启动画面上仍然是'Trial version',这可能是软件的Bug.软件靠一个
全局标志判断是否出现‘Trial version’或‘Registered to’。但却没有初始化这个
全局标志。

   下面的这些算法放在一起就可以做注册机了:
   
        s1[0] = 44h ('D')
        s1[1]>=42h && s1[1]<=44
        s1[2]>=43h && s1[2]<=4Ch
        s1[3]>=42 && s1[3]<=79
        s1[4] = 4Dh ('M')
        
        s4[0] = (s1[4]%7 + s1[2]%5 + s1[1]*2 + s1[0]) % 1Ah + 41h
        s4[1] = (s2[3]%3 + s2[4]*5 + s2[0]*2 + s2[1] + s2[2]) % 1Ah + 41h
        s4[2] = (s3[3]*23 + s3[5] + s3[0])% 1Ah + 41h
        s4[3] = (s3[1]*7 + s3[2] + s2[2] + s1[3]) % 1Ah + 41h
        
        s3[0] = 47h ('G')
        s3[1]>=48h && s3[1]<=51h
        s3[2]>=42h && s3[2]<=4Bh
        s3[3]>=49h && s3[3]<=52h
        s3[4]>=4bh && s3[4]<=54
        s3[5]>=4Ah && s3[5]<=53h
2005-12-18 18:37
0
雪    币: 243
活跃值: (190)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
9
强,学习了!
2005-12-18 18:43
0
雪    币: 214
活跃值: (15)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
10
学习并支持
2005-12-19 20:35
0
雪    币: 370
活跃值: (15)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
11
学习了
感觉真是 "抛砖引玉",不断深入
建议加精

2005-12-19 21:39
0
雪    币: 427
活跃值: (412)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
找不到难度大的是吧,我给你一个0DAY从未有过破解的实例。
http://www.mediatwins.com/data/aedtools_pro.exe
2005-12-19 22:27
0
游客
登录 | 注册 方可回帖
返回
//