首页
社区
课程
招聘
[原创]一个Cracker代码分析及注册机编写,可以申请邀请码吗?
发表于: 2013-7-22 15:44 12350

[原创]一个Cracker代码分析及注册机编写,可以申请邀请码吗?

2013-7-22 15:44
12350

作者:obabydbg

这个crack早在几年前就被CCDebuger的一篇文章提到过,不过他只是讲解了一些爆破的方法。今天刚好有空,捡起来分析了一下。如果有什么分析不对的地方还请大家指出。第一次发贴,希望可以起来抛砖引玉的效果。还请个位高手多多指点。先谢谢了!!
工具:OD+editplus+UltraEdit

1.        程序运行界面


2.用OD载入程序

3.程序是用汇编语言编写的,无壳。查壳的过程就省略了。查看当前模块中的名称后,可以在bp GetDlgItemTextA下断

4.F9运行程序,输入用户名和注册码后断下

断下后,注意右下角。Call  GetDlgItemTextA到这一行,按回车键到反汇编窗口。到反汇编窗口后,往上翻,0040109C  /$  C705 82214000>mov dword ptr ds:[0x402182],0xFEDCBA98
在这一行下断,ctrl+F2重新运行程序。记住这个参数,程序中的算法要用到这个参数的。


5.重新运行程序,输入用户名注册码后在上面我们下断的地方断下

看到这里大家应该很熟悉了,读出用户名和注册码返回字节数。按F8单步运行程序,注册堆栈窗口,找到用户名和注册码在内存中的位置。

可以很清楚的在内存区看到输入的注册码和用户名了,0x402182就是上面提到的那个数据,往下看,一会就会用到了。
004010D2  |.  0BC0          or eax,eax     ;输入的用户名不能为空
004010D4  |.  74 49         je short cycle.0040111F
004010D6  |.  B9 10000000   mov ecx,0x10
004010DB  |.  2BC8          sub ecx,eax
004010DD  |.  BE 60214000   mov esi,cycle.00402160                   ;  ASCII "obaby"
004010E2  |.  8BFE          mov edi,esi                              ;  cycle.00401029
004010E4  |.  03F8          add edi,eax
004010E6  |.  FC            cld
004010E7  |.  F3:A4         rep movs byte ptr es:[edi],byte ptr ds:[>
这几句其实就是把我们输入的用户名填充成一个16字节的用户名,如:我输入的是obaby,填充成16字节的用户名后为obabyobabyobabyo,就是用我们输入的用户名来填充空的字节,要求用户名为16位,这个跟后面算法有关系的,一会就可以看到了。

004010E9  |.  33C9          xor ecx,ecx
004010EB  |.  BE 71214000   mov esi,cycle.00402171                   ;  ASCII "0000000000000000"
004010F0  |>  41            /inc ecx
004010F1  |.  AC            |lods byte ptr ds:[esi]
004010F2  |.  0AC0          |or al,al
004010F4  |.  74 0A         |je short cycle.00401100
004010F6  |.  3C 7E         |cmp al,0x7E
004010F8  |.  7F 06         |jg short cycle.00401100
004010FA  |.  3C 30         |cmp al,0x30
004010FC  |.  72 02         |jb short cycle.00401100
004010FE  |.^ EB F0         \jmp short cycle.004010F0
00401100  |>  83F9 11       cmp ecx,0x11       ;必须要为16个字节
00401103  |.  75 1A         jnz short cycle.0040111F
接下来这几个是来检测注册码了,输入的字符秘须大于0x30小于0x7E,并且注册码要为16个字节,要不然直接跳到retn了。
6.接下来就是算法了,这个算法其实不难,但是挺麻烦的,如果不细心看的话,一会就转晕了。
00401105  |.  E8 E7000000   call cycle.004011F1    ;第一个call运算
0040110A  |.  B9 01FF0000   mov ecx,0xFF01
0040110F  |.  51            push ecx
00401110  |.  E8 7B000000   call cycle.00401190     ;第二个call运算
00401115  |.  83F9 01       cmp ecx,0x1           ;经过上面的运行到这里ecx必须要等于1,如果不等于1就跳向注册失败了。
00401118  |.  74 06         je short cycle.00401120
0040111A  |>  E8 47000000   call cycle.00401166
0040111F  |>  C3            retn


这里只是一半,后面还有一半。这个算法其实就是把16位的用户名和16位的注册码分成二部分,每部分分别为8位,这二个call运行只用到了前8位,也就是说用户名的前8位和注册码的前8位经过上面运行后ecx必须要为1才行。

我们分别看这二个call.

004011F1  /$  A1 60214000   mov eax,dword ptr ds:[0x402160] ;用户名的前四位
004011F6  |.  8B1D 64214000 mov ebx,dword ptr ds:[0x402164] ;4-7位
004011FC  |.  3305 71214000 xor eax,dword ptr ds:[0x402171]  ;注册码的前四位
00401202  |.  331D 75214000 xor ebx,dword ptr ds:[0x402175]  ;4-7位
00401208  |.  25 0F1F3F7F   and eax,0x7F3F1F0F
0040120D  |.  81E3 00010307 and ebx,0x7030100

这是第一个call传进来的数据,下面的运算都是围绕前8位的数据来打操作的。
接下来我们看看第二个call

004011DE  |.  FF05 82214000 |inc dword ptr ds:[0x402182]
注意这句,这里指向的数据就是0xFEDCBA98,开始我们说到的,这个数据是会变的,运算中会自加。这就是前8位运算的二个call了。不是很难,但是看着挺烦人的。
这二个call运算完了以后,ecx一定要等于1哦。
7.ecx==1后跳到下面运算,不是只用到了前8位嘛,现在开始运算后8位了。

00401120  |> \A1 68214000   mov eax,dword ptr ds:[0x402168]
00401125  |.  8B1D 6C214000 mov ebx,dword ptr ds:[0x40216C]
0040112B  |.  33C3          xor eax,ebx
0040112D  |.  3305 82214000 xor eax,dword ptr ds:[0x402182] ;前面提到的那个数据,前面会自加,在这里会进行异或运算
00401133  |.  0D 40404040   or eax,0x40404040
00401138  |.  25 77777777   and eax,0x77777777
0040113D  |.  3305 79214000 xor eax,dword ptr ds:[0x402179]
00401143  |.  3305 7D214000 xor eax,dword ptr ds:[0x40217D]
00401149  |.^ 75 CF         jnz short cycle.0040111A
0040114B  |.  E8 2B000000   call cycle.0040117B
00401150  \.  C3            retn
如果ecx=1就跳到这了,看内存这里用到的就是用户名和注册码的后8位了。运算结束后ZF必须要为1,要不然就跳到注册错误了。


可以看到,ZF=1跳向正确,否则跳向错误。
下面是编写的注册机:
.386
.model flat,stdcall
option casemap:none
include windows.inc
include kernel32.inc
include user32.inc
include masm32.inc
includelib kernel32.lib
includelib user32.lib
includelib masm32.lib

crackcallA proto
crackcallB proto
crackcallC proto
crackcallD proto
.data
value     dword 0fedcba98h
printname db 'input name: ',0
printpawd db 'input password: ',0
szFmt        db 'Done!!!',0
username  db 17 dup (0)
password db 17 dup (0)

.code
start:
        invoke StdOut,addr printname
        invoke StdIn,addr username,lengthof username
        invoke StdOut,addr printpawd
        invoke StdIn,addr password,lengthof password

        xor ecx,ecx
        lea esi,username
        lea edi,username
usernameloop:
        mov al,byte ptr [esi]
        or al,al
        jz usernamelab
        inc ecx
        inc esi
        jmp usernameloop
usernamelab:
        mov eax,10h
        mov edx,ecx
        sub eax,ecx
        xchg eax,ecx
        mov esi,edi
        add edi,edx
        cld
        rep movs byte ptr es:[edi],byte ptr [esi]

        xor ecx,ecx
        lea esi,password
passwordloop:
        inc ecx
        mov al,byte ptr [esi]
        or al,al
        je passwordcount
        inc esi
        jmp passwordloop
passwordcount:
        cmp ecx,011h
        jnz over

        call crackcallA
        mov ecx,0ff01h
        push ecx
        call crackcallB

        cmp ecx,1
        je tab1
        call crackcallC

tab1:
        mov eax,dword ptr [username+8]
        mov ebx,dword ptr [username+12]
        xor eax,ebx
        xor eax,dword ptr [value]
        or  eax,040404040h
        and eax,077777777h
        xor eax,dword ptr [password+8]
        xor eax,dword ptr [password+12]
        jz done
        call crackcallD
       
done:
        invoke StdOut,addr szFmt
over:
        invoke ExitProcess,0

crackcallA proc
        mov eax,dword ptr [username]
        mov ebx,dword ptr [username+4]
        xor eax,dword ptr [password]
        xor ebx,dword ptr [password+4]
        and eax,07f3f1f0fh
        and ebx,07030100h
        xor ecx,ecx
begin:
        mov     esi, eax
        mov     edi, ebx
        shl     esi, cl
        shl     edi, cl
        and     esi, 080808080h
        and     edi, 080808080h
        mov     edx, esi
        shr     dh, 7
        shl     dx, 7
        shr     edx, 8
        shr     dh, 7
        shl     dx, 7
        shr     edx, 8
        shr     dh, 7
        shr     dx, 1
        mov     esi, edx
        mov     edx, edi
        shr     dh, 7
        shl     dx, 7
        shr     edx, 8
        shr     dh, 7
        shl     dx, 7
        shr     edx, 8
        shr     dh, 7
        shr     dx, 5
        mov     edi, edx
        xor     edi, esi
        mov     edx, edi
        and     edx, 0FFh                                      
        push    ecx
        push    edx
        mov     edx, 8
        xchg    eax, ecx                                    
        cmp     eax, 3
        jg      lab1
        mul     dl
        pop     edx
        add     eax, 8
        xchg    eax, ecx
        rol     eax, cl                                      
        xor     eax, edx
        ror     eax, cl                                    
        jmp     lab2
lab1:
        sub     eax, 3
        mul     dl
        pop     edx
        xchg    eax, ecx
        rol     ebx, cl
        xor     ebx, edx
        ror     ebx, cl
lab2:
        pop     ecx
        inc     ecx                                         
        cmp     ecx, 8
        jnz     begin
        ret
crackcallA endp

crackcallB proc
        pop     edi
        pop     ecx
        push    edi
        cmp     ecx, 080h
        jle     done1
        push    ecx
        mov     esi, ecx
        and     ecx, 0FFh
        mov     edi, eax
        cmp     ecx, 8
        jle     lab1
        mov     edi, ebx
        shr     ecx, 4
lab1:
        rol     edi, 8
        shr     ecx, 1
        jnz     lab1
        shr     esi, 8
        and     edi, esi
        and     edi, 0FFh
        pop     ecx
lab3:
        mov     esi, 080h
lab4:
        test    esi, edi
        je      lab2
        xor     edi, esi
        push    edi
        and     ecx, 0FF00h
        xchg    esi, ecx
        xor     ch, cl
        xor     esi, ecx
        xchg    ecx, esi
        push    ecx
        inc     dword ptr [value]
        call    crackcallB
        pop     edi
        jmp     lab3
lab2:
        shr     esi, 1
        jnz     lab4
done1:
        ret
crackcallB endp

crackcallC proc
        xor ecx,ecx
tap0:
        lea edi,password
        mov al,byte ptr [edi]
        inc al
        mov byte ptr [edi],al
        call crackcallA
        mov ecx,0ff01h
        push ecx
        call crackcallB
        ;add esp,4

        cmp ecx,1
        je retncall
        lea edi,password
        mov al,byte ptr [edi]
        ;inc al
        ;mov byte ptr [edi],al
        ;mov al,byte ptr [edi]
        cmp al,07eh
        jle tap0
        lea edi,password
        mov byte ptr [edi],'0'

        lea edi,password
        mov al, byte ptr [edi+1]
        inc al
        mov byte ptr [edi+1],al
        mov al,byte ptr [edi+1]
        cmp al,07eh
        jle tap0
        lea edi,password
        mov byte ptr [edi+1],'0'

        lea edi,password
        mov al, byte ptr [edi+2]
        inc al
        mov byte ptr [edi+2],al
        mov al,byte ptr [edi+2]
        cmp al,07eh
        jle tap0
        lea edi,password
        mov byte ptr [edi+2],'0'

        lea edi,password
        mov al,byte ptr  [edi+3]
        inc al
        mov byte ptr [edi+3],al
        mov al,byte ptr [edi+3]
        cmp al,07eh
        jle tap0
        lea edi,password
        mov byte ptr [edi+3],'0'

        lea edi,password
        mov al,byte ptr  [edi+4]
        inc al
        mov byte ptr [edi+4],al
        mov al,byte ptr [edi+4]
        cmp al,07eh
        jle tap0
        lea edi,password
        mov byte ptr [edi+4],'0'

        lea edi,password
        mov al,byte ptr [edi+5]
        inc al
        mov byte ptr [edi+5],al
        mov al,byte ptr [edi+5]
        cmp al,07eh
        jle tap0
        lea edi,password
        mov byte ptr [edi+5],'0'

        lea edi,password
        mov al,byte ptr [edi+6]
        inc al
        mov byte ptr [edi+6],al
        mov al,byte ptr [edi+6]
        cmp al,07eh
        jle tap0
        lea edi,password
        mov byte ptr [edi+6],'0'

        lea edi,password
        mov al,byte ptr [edi+7]
        inc al
        mov byte ptr [edi+7],al
        mov al,byte ptr [edi+7]
        cmp al,07eh
        jle tap0

retncall:
        ret
crackcallC endp

crackcallD proc
tap0:
        lea edi,password
        mov al,byte ptr [edi+8]
        inc al
        mov byte ptr [edi+8],al

        mov eax,dword ptr [username+8]
        mov ebx,dword ptr [username+12]
        xor eax,ebx
        xor eax,dword ptr [value]
        or  eax,040404040h
        and eax,077777777h
        xor eax,dword ptr [password+8]
        xor eax,dword ptr [password+12]
        jz retncall
        lea edi,password
        mov al,byte ptr [edi+8]
        cmp al,07eh
        jle tap0
        mov byte ptr [edi+8],'0'

        lea edi,password
        mov al,byte ptr [edi+9]
        inc al
        mov byte ptr [edi+9],al
        cmp al,07eh
        jle tap0
        mov byte ptr [edi+9],'0'

        lea edi,password
        mov al,byte ptr [edi+0ah]
        inc al
        mov byte ptr [edi+0ah],al
        cmp al,07eh
        jle tap0
        mov byte ptr [edi+0ah],'0'

        lea edi,password
        mov al,byte ptr [edi+0bh]
        inc al
        mov byte ptr [edi+0bh],al
        cmp al,07eh
        jle tap0
        mov byte ptr [edi+0bh],'0'

        lea edi,password
        mov al,byte ptr [edi+0ch]
        inc al
        mov byte ptr [edi+0ch],al
        cmp al,07eh
        jle tap0
        mov byte ptr [edi+0ch],'0'

        lea edi,password
        mov al,byte ptr [edi+0dh]
        inc al
        mov byte ptr [edi+0dh],al
        cmp al,07eh
        jle tap0
        mov byte ptr [edi+0dh],'0'

        lea edi,password
        mov al,byte ptr [edi+0eh]
        inc al
        mov byte ptr [edi+0eh],al
        cmp al,07eh
        jle tap0
        mov byte ptr [edi+0eh],'0'

        lea edi,password
        mov al,byte ptr [edi+0fh]
        inc al
        mov byte ptr [edi+0fh],al
        cmp al,07eh
        jle tap0

retncall:
        ret
crackcallD endp

end start
注册机中有些算法是自已抄的原程序的,所以会看到很多眼熟的地方哦。
这是二组计算出来后正确的用户名和注册码:
obaby
19400000CQrC0000
obaby
;7422222VSpA3222

我在word上面排版好了的,怎么上来就这样了,大家将就看看吧。图片不知道怎么没有了,我把图片打包上传附件了


[峰会]看雪.第八届安全开发者峰会10月23日上海龙之梦大酒店举办!

上传的附件:
收藏
免费 5
支持
分享
最新回复 (15)
雪    币: 9033
活跃值: (2969)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
2
由于是第一次发贴,图片不怎么如何上传,就不附图了,直接上代码。希望这次可以看得比较清楚

【软件名称】cycle.EXE
【应用平台】Win9x/NT/2000/XP
【软件大小】8K
【破解声明】破解只是感兴趣,无其它目的。失误之处敬请诸位大侠赐教!
【破解工具】PEiD,OD, UE

========================================================================================
【分析过程】
1.        查壳后,无壳。程序是用汇编写的
2.        用OD载入程序,停在这里
00401000 >/$  6A 00         push 0x0                                 ; /pModule = NULL
00401002  |.  E8 A4020000   call <jmp.&KERNEL32.GetModuleHandleA>    ; \GetModuleHandleA
00401007  |.  A3 94214000   mov dword ptr ds:[0x402194],eax
0040100C  |.  6A 00         push 0x0                                 ; /lParam = NULL
0040100E  |.  68 29104000   push cycle.00401029                      ; |DlgProc = cycle.00401029
00401013  |.  6A 00         push 0x0                                 ; |hOwner = NULL
00401015  |.  6A 68         push 0x68                                ; |pTemplate = 0x68
00401017  |.  FF35 94214000 push dword ptr ds:[0x402194]             ; |hInst = NULL
0040101D  |.  E8 8F020000   call <jmp.&USER32.DialogBoxParamA>       ; \DialogBoxParamA
00401022  |.  6A 00         push 0x0                                 ; /ExitCode = 0x0
00401024  \.  E8 7C020000   call <jmp.&KERNEL32.ExitProcess>         ; \ExitProcess
3.        右键 查找->当前模块名称,找到GetDlgItemTextA函数,从文本中读取字符串,就在这个函数下断,bp GetDlgItemTextA
4.        F9先让程序跑起来,程序跑起来以后在Name和Serial分别输入obaby和1111111111111111,程序要求注册码为16位,稍后会分析到的。这里先输入16个1。
单击check,程序断下了。注意右下角:
0012FAE8   004010BA  /CALL 到 GetDlgItemTextA 来自 cycle.004010B5
在这句单击右键,选择反汇编窗口跑随,这样就来到程序领空了。
0040109C  /$  C705 82214000>mov dword ptr ds:[0x402182],0xFEDCBA98
004010A6  |.  6A 11         push 0x11                                ; /Count = 11 (17.)
004010A8  |.  68 71214000   push cycle.00402171                      ; |Buffer = cycle.00402171
004010AD  |.  68 E9030000   push 0x3E9                               ; |ControlID = 3E9 (1001.)
004010B2  |.  FF75 08       push [arg.1]                             ; |hWnd = 001F06A8 ('CycleCrackme',class='#32770')
004010B5  |.  E8 0F020000   call <jmp.&USER32.GetDlgItemTextA>       ; \GetDlgItemTextA
004010BA  |.  0BC0          or eax,eax
004010BC  |.  74 61         je short cycle.0040111F
004010BE  |.  6A 11         push 0x11                                ; /Count = 11 (17.)
004010C0  |.  68 60214000   push cycle.00402160                      ; |Buffer = cycle.00402160
004010C5  |.  68 E8030000   push 0x3E8                               ; |ControlID = 3E8 (1000.)
004010CA  |.  FF75 08       push [arg.1]                             ; |hWnd = 001F06A8 ('CycleCrackme',class='#32770')
004010CD  |.  E8 F7010000   call <jmp.&USER32.GetDlgItemTextA>       ; \GetDlgItemTextA
004010D2  |.  0BC0          or eax,eax
004010D4  |.  74 49         je short cycle.0040111F
004010D6  |.  B9 10000000   mov ecx,0x10
004010DB  |.  2BC8          sub ecx,eax
004010DD  |.  BE 60214000   mov esi,cycle.00402160
004010E2  |.  8BFE          mov edi,esi                              ;  cycle.00401029
向上翻,在0040109C  /$  C705 82214000>mov dword ptr ds:[0x402182],0xFEDCBA98
这句下断,重新开始。F9运行程序,输入Name和Serial,程序断下了。上面这二个函数大家应该很熟悉,就是我们第一次下断的地方。从文本中读取数据。
5.        F8一路往下走,一直到这里。
004010D2  |.  0BC0          or eax,eax
004010D4  |.  74 49         je short cycle.0040111F
004010D6  |.  B9 10000000   mov ecx,0x10
004010DB  |.  2BC8          sub ecx,eax
004010DD  |.  BE 60214000   mov esi,cycle.00402160
004010E2  |.  8BFE          mov edi,esi                              ;  cycle.00401029
004010E4  |.  03F8          add edi,eax
004010E6  |.  FC            cld
004010E7  |.  F3:A4         rep movs byte ptr es:[edi],byte ptr ds:[>
这里会先判断用户名是否为空,程序在这里会把用户名也变成16个字节的数据。例如我输入的用户名是obaby,经过上面的运算后用户名会变成obabyobabyobabyo,会用输入的用户名来填充其它为0的字节,一直到把16个字节填充完成。

6.        F8往下走,到这里
004010E9  |.  33C9          xor ecx,ecx     //首先把ecx清空
004010EB  |.  BE 71214000   mov esi,cycle.00402171   //这里指向注册码
004010F0  |>  41            /inc ecx   //这里先加了,如果输入的注册码为16个字节,那么ecx会等于17(0x11)
004010F1  |.  AC            |lods byte ptr ds:[esi]
004010F2  |.  0AC0          |or al,al
004010F4  |.  74 0A         |je short cycle.00401100
004010F6  |.  3C 7E         |cmp al,0x7E
004010F8  |.  7F 06         |jg short cycle.00401100
004010FA  |.  3C 30         |cmp al,0x30
004010FC  |.  72 02         |jb short cycle.00401100
004010FE  |.^ EB F0         \jmp short cycle.004010F0
00401100  |>  83F9 11       cmp ecx,0x11
00401103  |.  75 1A         jnz short cycle.0040111F     //这里不能跳,跳就死
这里实际上就是对输入的注册码进行计数,注册码必须为16个字节。输入的字节不能大于0x7E(~),也不能小于0x30(‘0’)。

7.        对用户名和注册码处理结束后,就是作者写的算法了。算法实际上分为二部分,我们一步步看。
00401105  |.  E8 E7000000   call cycle.004011F1    //第一个call,F7进入
0040110A  |.  B9 01FF0000   mov ecx,0xFF01
0040110F  |.  51            push ecx
00401110  |.  E8 7B000000   call cycle.00401190  //第二个call,F7进入
00401115  |.  83F9 01       cmp ecx,0x1      
00401118  |.  74 06         je short cycle.00401120 //必须跳,不跳就死
上面二个call运算完成后,ecx必须要为1。要不然就注册错误了。

004011F1  /$  A1 60214000   mov eax,dword ptr ds:[0x402160]
004011F6  |.  8B1D 64214000 mov ebx,dword ptr ds:[0x402164] //用户名前8个字节
004011FC  |.  3305 71214000 xor eax,dword ptr ds:[0x402171]
00401202  |.  331D 75214000 xor ebx,dword ptr ds:[0x402175] //注册码的前8个字节异或
00401208  |.  25 0F1F3F7F   and eax,0x7F3F1F0F
0040120D  |.  81E3 00010307 and ebx,0x7030100
00401213  |.  33C9          xor ecx,ecx
00401215  |>  8BF0          /mov esi,eax
00401217  |.  8BFB          |mov edi,ebx
00401219  |.  D3E6          |shl esi,cl
0040121B  |.  D3E7          |shl edi,cl
0040121D  |.  81E6 80808080 |and esi,0x80808080
00401223  |.  81E7 80808080 |and edi,0x80808080
00401229  |.  8BD6          |mov edx,esi                             ;  cycle.00401029
0040122B  |.  C0EE 07       |shr dh,0x7
0040122E  |.  66:C1E2 07    |shl dx,0x7
00401232  |.  C1EA 08       |shr edx,0x8
00401235  |.  C0EE 07       |shr dh,0x7
00401238  |.  66:C1E2 07    |shl dx,0x7
0040123C  |.  C1EA 08       |shr edx,0x8
0040123F  |.  C0EE 07       |shr dh,0x7
00401242  |.  66:D1EA       |shr dx,1
00401245  |.  8BF2          |mov esi,edx
00401247  |.  8BD7          |mov edx,edi
00401249  |.  C0EE 07       |shr dh,0x7
0040124C  |.  66:C1E2 07    |shl dx,0x7
00401250  |.  C1EA 08       |shr edx,0x8
00401253  |.  C0EE 07       |shr dh,0x7
00401256  |.  66:C1E2 07    |shl dx,0x7
0040125A  |.  C1EA 08       |shr edx,0x8
0040125D  |.  C0EE 07       |shr dh,0x7
00401260  |.  66:C1EA 05    |shr dx,0x5
00401264  |.  8BFA          |mov edi,edx
00401266  |.  33FE          |xor edi,esi                             ;  cycle.00401029
00401268  |.  8BD7          |mov edx,edi
0040126A  |.  81E2 FF000000 |and edx,0xFF
00401270  |.  51            |push ecx
00401271  |.  52            |push edx
00401272  |.  BA 08000000   |mov edx,0x8
00401277  |.  91            |xchg eax,ecx
00401278  |.  83F8 03       |cmp eax,0x3
0040127B  |.  7F 0F         |jg short cycle.0040128C
0040127D  |.  F6E2          |mul dl
0040127F  |.  5A            |pop edx                                 ;  cycle.004010BA
00401280  |.  83C0 08       |add eax,0x8
00401283  |.  91            |xchg eax,ecx
00401284  |.  D3C0          |rol eax,cl
00401286  |.  33C2          |xor eax,edx
00401288  |.  D3C8          |ror eax,cl
0040128A  |.  EB 0D         |jmp short cycle.00401299
0040128C  |>  83E8 03       |sub eax,0x3
0040128F  |.  F6E2          |mul dl
00401291  |.  5A            |pop edx                                 ;  cycle.004010BA
00401292  |.  91            |xchg eax,ecx
00401293  |.  D3C3          |rol ebx,cl
00401295  |.  33DA          |xor ebx,edx
00401297  |.  D3CB          |ror ebx,cl
00401299  |>  59            |pop ecx                                 ;  cycle.004010BA
0040129A  |.  41            |inc ecx
0040129B  |.  83F9 08       |cmp ecx,0x8
0040129E  |.^ 0F85 71FFFFFF \jnz cycle.00401215
004012A4  \.  C3            retn

第二个call
00401190  /$  5F            pop edi                                  ;  cycle.004010BA
00401191  |.  59            pop ecx                                  ;  cycle.004010BA
00401192  |.  57            push edi
00401193  |.  81F9 80000000 cmp ecx,0x80
00401199  |.  7E 55         jle short cycle.004011F0
0040119B  |.  51            push ecx
0040119C  |.  8BF1          mov esi,ecx
0040119E  |.  81E1 FF000000 and ecx,0xFF
004011A4  |.  8BF8          mov edi,eax
004011A6  |.  83F9 08       cmp ecx,0x8
004011A9  |.  7E 05         jle short cycle.004011B0
004011AB  |.  8BFB          mov edi,ebx
004011AD  |.  C1E9 04       shr ecx,0x4
004011B0  |>  C1C7 08       /rol edi,0x8
004011B3  |.  D1E9          |shr ecx,1
004011B5  |.^ 75 F9         \jnz short cycle.004011B0
004011B7  |.  C1EE 08       shr esi,0x8
004011BA  |.  23FE          and edi,esi                              ;  cycle.00401029
004011BC  |.  81E7 FF000000 and edi,0xFF
004011C2  |.  59            pop ecx                                  ;  cycle.004010BA
004011C3  |>  BE 80000000   mov esi,0x80
004011C8  |>  85FE          /test esi,edi
004011CA  |.  74 20         |je short cycle.004011EC
004011CC  |.  33FE          |xor edi,esi                             ;  cycle.00401029
004011CE  |.  57            |push edi
004011CF  |.  81E1 00FF0000 |and ecx,0xFF00
004011D5  |.  87CE          |xchg esi,ecx
004011D7  |.  32E9          |xor ch,cl
004011D9  |.  33F1          |xor esi,ecx
004011DB  |.  87F1          |xchg ecx,esi                            ;  cycle.00401029
004011DD  |.  51            |push ecx
004011DE  |.  FF05 82214000 |inc dword ptr ds:[0x402182]  //这里很重要
004011E4  |.  E8 A7FFFFFF   |call cycle.00401190
004011E9  |.  5F            |pop edi                                 ;  cycle.004010BA
004011EA  |.^ EB D7         |jmp short cycle.004011C3
004011EC  |>  D1EE          |shr esi,1
004011EE  |.^ 75 D8         \jnz short cycle.004011C8
004011F0  \>  C3            retn
这里用到的数据实际上是第一个call里面对用户名和注册码进行运算后的数据。
inc dword ptr ds:[0x402182]这里自加的数据,实际上是
0040109C  /$  C705 82214000>mov dword ptr ds:[0x402182],0xFEDCBA98
第二次下断的第一句。这个数据开始作者就定义了,只是会根据实际输入的用户名和注册码运算后,再次改变这个数据。
上面这二个call对输入的用户名和注册码进行运算后,ecx必须要为1。要不然就跳向结束了。当ecx=1后,跳到后半部分的算法运算了,到这里程序还只用到了前8位数据,后8后数据还没有用到。
00401120  |> \A1 68214000   mov eax,dword ptr ds:[0x402168]
00401125  |.  8B1D 6C214000 mov ebx,dword ptr ds:[0x40216C] //用户名的后8位数据
0040112B  |.  33C3          xor eax,ebx
0040112D  |.  3305 82214000 xor eax,dword ptr ds:[0x402182] //就是刚刚提到的那个比较重要的数据
00401133  |.  0D 40404040   or eax,0x40404040
00401138  |.  25 77777777   and eax,0x77777777
0040113D  |.  3305 79214000 xor eax,dword ptr ds:[0x402179]
00401143  |.  3305 7D214000 xor eax,dword ptr ds:[0x40217D]//对注册码的后8位进行异或
00401149  |.^ 75 CF         jnz short cycle.0040111A //ZF必须要为1,不死就死了
0040114B  |.  E8 2B000000   call cycle.0040117B
程序的算法一共分为二处,第一处运算完成为ecx=1,第二处运算完成后ZF=1。知道这个条件后,就可以自已动手写一个注册机了。下面是用masm32写的一个注册机。
.386
.model flat,stdcall
option casemap:none
include windows.inc
include kernel32.inc
include user32.inc
include masm32.inc
includelib kernel32.lib
includelib user32.lib
includelib masm32.lib

crackcallA proto
crackcallB proto
crackcallC proto
crackcallD proto
.data
value     dword 0fedcba98h
printname db 'input name: ',0
printpawd db 'input password: ',0
szFmt        db 'done!!!!',0
username  db 17 dup (0)
password db 17 dup (0)

.code
start:
        invoke StdOut,addr printname
        invoke StdIn,addr username,lengthof username
        invoke StdOut,addr printpawd
        invoke StdIn,addr password,lengthof password

        xor ecx,ecx
        lea esi,username
        lea edi,username
usernameloop:
        mov al,byte ptr [esi]
        or al,al
        jz usernamelab
        inc ecx
        inc esi
        jmp usernameloop
usernamelab:
        mov eax,10h
        mov edx,ecx
        sub eax,ecx
        xchg eax,ecx
        mov esi,edi
        add edi,edx
        cld
        rep movs byte ptr es:[edi],byte ptr [esi]

        xor ecx,ecx
        lea esi,password
passwordloop:
        inc ecx
        mov al,byte ptr [esi]
        or al,al
        je passwordcount
        inc esi
        jmp passwordloop
passwordcount:
        cmp ecx,011h
        jnz over

        call crackcallA
        mov ecx,0ff01h
        push ecx
        call crackcallB

        cmp ecx,1
        je tab1
        call crackcallC

tab1:
        mov eax,dword ptr [username+8]
        mov ebx,dword ptr [username+12]
        xor eax,ebx
        xor eax,dword ptr [value]
        or  eax,040404040h
        and eax,077777777h
        xor eax,dword ptr [password+8]
        xor eax,dword ptr [password+12]
        jz done
        call crackcallD
       
done:
        invoke StdOut,addr szFmt
over:
        invoke ExitProcess,0

crackcallA proc
        mov eax,dword ptr [username]
        mov ebx,dword ptr [username+4]
        xor eax,dword ptr [password]
        xor ebx,dword ptr [password+4]
        and eax,07f3f1f0fh
        and ebx,07030100h
        xor ecx,ecx
begin:
        mov     esi, eax
        mov     edi, ebx
        shl     esi, cl
        shl     edi, cl
        and     esi, 080808080h
        and     edi, 080808080h
        mov     edx, esi
        shr     dh, 7
        shl     dx, 7
        shr     edx, 8
        shr     dh, 7
        shl     dx, 7
        shr     edx, 8
        shr     dh, 7
        shr     dx, 1
        mov     esi, edx
        mov     edx, edi
        shr     dh, 7
        shl     dx, 7
        shr     edx, 8
        shr     dh, 7
        shl     dx, 7
        shr     edx, 8
        shr     dh, 7
        shr     dx, 5
        mov     edi, edx
        xor     edi, esi
        mov     edx, edi
        and     edx, 0FFh                                      
        push    ecx
        push    edx
        mov     edx, 8
        xchg    eax, ecx                                    
        cmp     eax, 3
        jg      lab1
        mul     dl
        pop     edx
        add     eax, 8
        xchg    eax, ecx
        rol     eax, cl                                      
        xor     eax, edx
        ror     eax, cl                                    
        jmp     lab2
lab1:
        sub     eax, 3
        mul     dl
        pop     edx
        xchg    eax, ecx
        rol     ebx, cl
        xor     ebx, edx
        ror     ebx, cl
lab2:
        pop     ecx
        inc     ecx                                         
        cmp     ecx, 8
        jnz     begin
        ret
crackcallA endp

crackcallB proc
        pop     edi
        pop     ecx
        push    edi
        cmp     ecx, 080h
        jle     done1
        push    ecx
        mov     esi, ecx
        and     ecx, 0FFh
        mov     edi, eax
        cmp     ecx, 8
        jle     lab1
        mov     edi, ebx
        shr     ecx, 4
lab1:
        rol     edi, 8
        shr     ecx, 1
        jnz     lab1
        shr     esi, 8
        and     edi, esi
        and     edi, 0FFh
        pop     ecx
lab3:
        mov     esi, 080h
lab4:
        test    esi, edi
        je      lab2
        xor     edi, esi
        push    edi
        and     ecx, 0FF00h
        xchg    esi, ecx
        xor     ch, cl
        xor     esi, ecx
        xchg    ecx, esi
        push    ecx
        inc     dword ptr [value]
        call    crackcallB
        pop     edi
        jmp     lab3
lab2:
        shr     esi, 1
        jnz     lab4
done1:
        ret
crackcallB endp

crackcallC proc
        xor ecx,ecx
tap0:
        lea edi,password
        mov al,byte ptr [edi]
        inc al
        mov byte ptr [edi],al
        call crackcallA
        mov ecx,0ff01h
        push ecx
        call crackcallB
        ;add esp,4

        cmp ecx,1
        je retncall
        lea edi,password
        mov al,byte ptr [edi]
        ;inc al
        ;mov byte ptr [edi],al
        ;mov al,byte ptr [edi]
        cmp al,07eh
        jle tap0
        lea edi,password
        mov byte ptr [edi],'0'

        lea edi,password
        mov al, byte ptr [edi+1]
        inc al
        mov byte ptr [edi+1],al
        mov al,byte ptr [edi+1]
        cmp al,07eh
        jle tap0
        lea edi,password
        mov byte ptr [edi+1],'0'

        lea edi,password
        mov al, byte ptr [edi+2]
        inc al
        mov byte ptr [edi+2],al
        mov al,byte ptr [edi+2]
        cmp al,07eh
        jle tap0
        lea edi,password
        mov byte ptr [edi+2],'0'

        lea edi,password
        mov al,byte ptr  [edi+3]
        inc al
        mov byte ptr [edi+3],al
        mov al,byte ptr [edi+3]
        cmp al,07eh
        jle tap0
        lea edi,password
        mov byte ptr [edi+3],'0'

        lea edi,password
        mov al,byte ptr  [edi+4]
        inc al
        mov byte ptr [edi+4],al
        mov al,byte ptr [edi+4]
        cmp al,07eh
        jle tap0
        lea edi,password
        mov byte ptr [edi+4],'0'

        lea edi,password
        mov al,byte ptr [edi+5]
        inc al
        mov byte ptr [edi+5],al
        mov al,byte ptr [edi+5]
        cmp al,07eh
        jle tap0
        lea edi,password
        mov byte ptr [edi+5],'0'

        lea edi,password
        mov al,byte ptr [edi+6]
        inc al
        mov byte ptr [edi+6],al
        mov al,byte ptr [edi+6]
        cmp al,07eh
        jle tap0
        lea edi,password
        mov byte ptr [edi+6],'0'

        lea edi,password
        mov al,byte ptr [edi+7]
        inc al
        mov byte ptr [edi+7],al
        mov al,byte ptr [edi+7]
        cmp al,07eh
        jle tap0

retncall:
        ret
crackcallC endp

crackcallD proc
tap0:
        lea edi,password
        mov al,byte ptr [edi+8]
        inc al
        mov byte ptr [edi+8],al

        mov eax,dword ptr [username+8]
        mov ebx,dword ptr [username+12]
        xor eax,ebx
        xor eax,dword ptr [value]
        or  eax,040404040h
        and eax,077777777h
        xor eax,dword ptr [password+8]
        xor eax,dword ptr [password+12]
        jz retncall
        lea edi,password
        mov al,byte ptr [edi+8]
        cmp al,07eh
        jle tap0
        mov byte ptr [edi+8],'0'

        lea edi,password
        mov al,byte ptr [edi+9]
        inc al
        mov byte ptr [edi+9],al
        cmp al,07eh
        jle tap0
        mov byte ptr [edi+9],'0'

        lea edi,password
        mov al,byte ptr [edi+0ah]
        inc al
        mov byte ptr [edi+0ah],al
        cmp al,07eh
        jle tap0
        mov byte ptr [edi+0ah],'0'

        lea edi,password
        mov al,byte ptr [edi+0bh]
        inc al
        mov byte ptr [edi+0bh],al
        cmp al,07eh
        jle tap0
        mov byte ptr [edi+0bh],'0'

        lea edi,password
        mov al,byte ptr [edi+0ch]
        inc al
        mov byte ptr [edi+0ch],al
        cmp al,07eh
        jle tap0
        mov byte ptr [edi+0ch],'0'

        lea edi,password
        mov al,byte ptr [edi+0dh]
        inc al
        mov byte ptr [edi+0dh],al
        cmp al,07eh
        jle tap0
        mov byte ptr [edi+0dh],'0'

        lea edi,password
        mov al,byte ptr [edi+0eh]
        inc al
        mov byte ptr [edi+0eh],al
        cmp al,07eh
        jle tap0
        mov byte ptr [edi+0eh],'0'

        lea edi,password
        mov al,byte ptr [edi+0fh]
        inc al
        mov byte ptr [edi+0fh],al
        cmp al,07eh
        jle tap0

retncall:
        ret
crackcallD endp

end start
       
测试成功,附上二种计算正确的注册码:
1. obaby
19400000CQrC0000
2.obaby
;7422222VSpA3222
【分析总结】
其实编写注册机,注册机里面的算法可以照抄程序本身的,只是加了一些测试环节。我们只需要满足二个条件就可以了。Ecx=1和zf=1。如果满足这二个条件,那么注册码就是正解的。每个用户名可以生成多个注册码。所以用户名和注册码并不是唯一的。
2013-7-23 15:08
0
雪    币: 44153
活跃值: (20195)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
3
图片见:http://bbs.pediy.com/showpost.php?postid=292659

邀请码己发你短信了。
2013-7-23 20:35
0
雪    币: 119
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
楼主,关键是CM啊。麻烦传个附件,或加个传送门啊
2013-7-24 20:14
0
雪    币: 95880
活跃值: (200544)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
5
+1
2013-7-25 09:48
0
雪    币: 341
活跃值: (138)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
6
我记得我曾经看过一个视频《练习从OD中提取代码写注册机》 就是直接拿出算法部分代码写成个小程序做注册机。
2013-7-25 10:51
0
雪    币: 101
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
直接扣出来用内联汇编?
2013-7-25 14:02
0
雪    币: 12
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
写的很详细啊
2013-7-25 15:10
0
雪    币: 341
活跃值: (138)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
9
en 百度下就看到了
2013-7-25 15:22
0
雪    币: 101
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
偷懒只能搬起石头砸自己的脚
2013-7-25 15:50
0
雪    币: 9033
活跃值: (2969)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
11
有些代码是扣出来的,后续研究后再更新
2013-7-25 17:00
0
雪    币: 396
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
写的还是很详细的,学习啦
2013-7-26 09:07
0
雪    币: 611
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
太长了,看得两眼发昏。。。不过还是忍着看了个大概
2013-7-26 11:31
0
雪    币: 680
活跃值: (68)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
14
好长好长
2013-7-26 15:59
0
雪    币: 81
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
谢谢 收藏
2013-7-26 22:52
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
看完眼睛都看累了.还得慢慢消化.
2013-7-31 23:02
0
游客
登录 | 注册 方可回帖
返回
//