本人刚学cracke,水平很菜.今下午琢磨了一下午才写了这篇破文~,这也是我第一次写的破文,不足之处还请各位大侠指教.
在逆推注册码和用户名的时候,我把计算关系列了出来,可搞了3小时还是不能算出来,试了很多次,计算器都点的手疼了.代码看了一遍又一遍还是不能成功,差点放弃.最后狠下心来,仔仔细细看了一遍,终
于发现了一个地方是我算错了.于是惊喜万分,马上逆推出来注册名和注册码.
那时的心情好激动!所以我劝大家要是认真坚持一下,就可以成功!
好了,切入正题:
字符串查找,看到注册成功信息后,下断.运行crackme,输入注册名:bzceff 注册码:aBbcdX 程序被断在这里:
0040137B |. 6A 40 push 40 ; /Count = 40 (64.)
0040137D |. 68 20334000 push 00403320 ; |Buffer = cztria~1.00403320
00401382 |. FF35 66324000 push dword ptr [403266] ; |hWnd = 00080262 (class='Edit',parent=0008025A)
00401388 |. E8 A3080000 call <jmp.&USER32.GetWindowTextA> ; \GetWindowTextA
0040138D |. 83F8 04 cmp eax, 4
00401390 |. 0F8E 9F000000 jle 00401435
00401396 |. 6A 40 push 40 ; /Count = 40 (64.)
00401398 |. 68 60334000 push 00403360 ; |Buffer = cztria~1.00403360
0040139D |. 68 B90B0000 push 0BB9 ; |ControlID = BB9 (3001.)
004013A2 |. FF75 08 push dword ptr [ebp+8] ; |hWnd
004013A5 |. E8 6E080000 call <jmp.&USER32.GetDlgItemTextA> ; \GetDlgItemTextA
004013AA |. 83F8 04 cmp eax, 4 ; 用户名注册码长度大于4位
004013AD |. 0F8E 82000000 jle 00401435
004013B3 |. A3 62324000 mov dword ptr [403262], eax
004013B8 |. FF35 66324000 push dword ptr [403266] ; /hWnd = 00080262 (class='Edit',parent=0008025A)
004013BE |. E8 AF080000 call <jmp.&USER32.SetFocus> ; \SetFocus
004013C3 |. BF 20334000 mov edi, 00403320 ; ASCII "bzceff"
004013C8 |. BE 20334000 mov esi, 00403320 ; ASCII "bzceff"
004013CD |> AC /lods byte ptr [esi]
004013CE |. 0C 00 |or al, 0
004013D0 |. 74 05 |je short 004013D7
004013D2 |. 0C 20 |or al, 20 ; 大写转换成小写
004013D4 |. AA |stos byte ptr es:[edi] ; 存入→地址403320
004013D5 |.^ EB F6 \jmp short 004013CD
004013D7 |> BF A0324000 mov edi, 004032A0
004013DC |. BE 60334000 mov esi, 00403360 ; 输入的假码存放esi
004013E1 |. 8D1D 20334000 lea ebx, dword ptr [403320] ; ebx指向403320,即用户名的地址
004013E7 |. 33C9 xor ecx, ecx ; ecx清零
004013E9 |> AC /lods byte ptr [esi] ; al依次存放假码的ASC码
004013EA |. 0C 00 |or al, 0 ; 取完了么?
004013EC |. 74 17 |je short 00401405
004013EE |. 8A13 |mov dl, byte ptr [ebx] ; 用户名字符依次存入dl
004013F0 |. 2AD0 |sub dl, al ; 用户名每一位asc码-对应假码字符的asc码存入dl
004013F2 |. 80CA 00 |or dl, 0
004013F5 |. 74 3E |je short 00401435 ; 判断输入的假码是否有空格字符
004013F7 |. 8AC2 |mov al, dl
004013F9 |. 24 0F |and al, 0F ; al的取值如果高于0F就取al-0f的值
004013FB |. 0C 00 |or al, 0
004013FD 74 36 je short 00401435
004013FF |. AA |stos byte ptr es:[edi] ; 把al中的值存入地址004032A0处
00401400 |. 02C8 |add cl, al ; 依次把计算出的al累加放入cl中
00401402 |. 43 |inc ebx ; 循环次数为假码的位数
00401403 |.^ EB E4 \jmp short 004013E9
00401405 |> 890D 6A324000 mov dword ptr [40326A], ecx ; cl中的结果存入地址40326A处
0040140B |. E8 27020000 call 00401637 ; 关键call
00401410 |. BE A0324000 mov esi, 004032A0
00401637 /$ BE A0324000 mov esi, 004032A0
0040163C |. 8B15 62324000 mov edx, dword ptr [403262] ; 假码的位数存入edx
00401642 |. 52 push edx
00401643 |. 33C0 xor eax, eax
00401645 |. 83EA 01 sub edx, 1 ; edx=edx-1 结果记为L
00401648 |. 03F2 add esi, edx
0040164A |. 8A06 mov al, byte ptr [esi] ; 4032A5的值存入al
0040164C |. F7E0 mul eax ; eax=al^2 记为x1
0040164E |. 5A pop edx
0040164F |. 83EA 01 sub edx, 1
00401652 |. F7E2 mul edx ; eax=x1*L 记为x2
00401654 |. B9 01000000 mov ecx, 1
00401659 |> 2BC1 /sub eax, ecx ; x2=x2-1-3-5-7-...
0040165B |. 83F8 00 |cmp eax, 0 ; x2<=0 退出循环
0040165E |. 7E 08 |jle short 00401668
00401660 |. 83C2 01 |add edx, 1 ; 循环次数存入edx 记为CS1
00401663 |. 83C1 02 |add ecx, 2
00401666 |.^ EB F1 \jmp short 00401659
00401668 |> 52 push edx
00401669 |. BE A0324000 mov esi, 004032A0
0040166E |. 8BFE mov edi, esi
00401670 |. 8B15 62324000 mov edx, dword ptr [403262]
00401676 |. 33C0 xor eax, eax
00401678 |. 83EA 01 sub edx, 1
0040167B |. 03F2 add esi, edx
0040167D |. 8A06 mov al, byte ptr [esi] ; 4032A5的值存入al
0040167F |. 83C0 01 add eax, 1
00401682 |. 5A pop edx ; edx=CS1 即上次循环次数出栈
00401683 |. 03C2 add eax, edx
00401685 |. D1E8 shr eax, 1 ; 右移1位后的结果记为x3
00401687 |. 8B15 62324000 mov edx, dword ptr [403262]
0040168D |. 03FA add edi, edx
0040168F |. AA stos byte ptr es:[edi] ; x3 存入4032A6处
00401690 |. F7E0 mul eax
00401692 |. 8B15 62324000 mov edx, dword ptr [403262]
00401698 |. 83EA 01 sub edx, 1
0040169B |. F7E2 mul edx ; x3*x3*L的值记为 x4
0040169D |. B9 01000000 mov ecx, 1
004016A2 |> 2BC1 /sub eax, ecx
004016A4 |. 83F8 00 |cmp eax, 0
004016A7 |. 7E 08 |jle short 004016B1
004016A9 |. 83C2 01 |add edx, 1 ; edx等于循环的次数记为 CS2
004016AC |. 83C1 02 |add ecx, 2
004016AF |.^ EB F1 \jmp short 004016A2
004016B1 |> 52 push edx
004016B2 |. BE A0324000 mov esi, 004032A0
004016B7 |. 8B15 62324000 mov edx, dword ptr [403262]
004016BD |. 33C0 xor eax, eax
004016BF |. 03F2 add esi, edx
004016C1 |. 8A06 mov al, byte ptr [esi] ; 4032A6处的值入al
004016C3 |. 83C0 01 add eax, 1 ; eax=x3+1
004016C6 |. 5A pop edx
004016C7 |. 03C2 add eax, edx
004016C9 |. D1E8 shr eax, 1 ; (x3+1+CS2)右移一位后结果记为 x5
004016CB |. A3 6E324000 mov dword ptr [40326E], eax ; x5存入地址40326E处
004016D0 \. C3 retn
跳转至这里:
00401410 |. BE A0324000 mov esi, 004032A0
00401415 |. 8B15 62324000 mov edx, dword ptr [403262]
0040141B |. C1EA 02 shr edx, 2 ; 假码位数右移2位 记为L0
0040141E |. 03F2 add esi, edx
00401420 |. 8A06 mov al, byte ptr [esi] ; [4032A0+L0]的值存入al
00401422 |. 33D2 xor edx, edx
00401424 |. 8B15 6E324000 mov edx, dword ptr [40326E] ; x5的值存入 edx
0040142A |. 2BD0 sub edx, eax ; edx=x5-eax 记为x6
0040142C |. A1 6A324000 mov eax, dword ptr [40326A] ; 40326A的值为原来累加在cl中的值
00401431 |. 3BC2 cmp eax, edx ; x6与40326A处数值进行比较
00401433 |. 74 31 je short 00401466 ; 相等就注册成功!
00401435 68 00200000 push 2000
0040143A |. 68 D1314000 push 004031D1 ; |Title = " Error"
0040143F |. 68 F9314000 push 004031F9 ; |Text = " Sorry Cracker, wrong."
00401444 |. FF75 08 push dword ptr [ebp+8] ; |hOwner
00401447 |. E8 02080000 call <jmp.&USER32.MessageBoxA> ; \MessageBoxA
0040144C |. 6A 40 push 40 ; /Length = 40 (64.)
0040144E |. 68 E0324000 push 004032E0 ; |Destination = cztria~1.004032E0
00401453 |. E8 56080000 call <jmp.&KERNEL32.RtlZeroMemory> ; \RtlZeroMemory
00401458 |. 6A 40 push 40 ; /Length = 40 (64.)
0040145A |. 68 A0334000 push 004033A0 ; |Destination = cztria~1.004033A0
0040145F |. E8 4A080000 call <jmp.&KERNEL32.RtlZeroMemory> ; \RtlZeroMemory
00401464 |. EB 2F jmp short 00401495
00401466 |> 68 00200000 push 2000 ; /Style = MB_OK|MB_TASKMODAL
0040146B |. 68 E5314000 push 004031E5 ; |Title = " <Registered>"
00401470 |. 68 10324000 push 00403210 ; |Text = " You did it!"
00401475 |. FF75 08 push dword ptr [ebp+8] ; |hOwner
00401478 |. E8 D1070000 call <jmp.&USER32.MessageBoxA> ; \MessageBoxA
0040147D |. 6A 40 push 40 ; /Length = 40 (64.)
用户名只能是字母不能为数字,或其他字符!
设用户名第一位字符的ASC码为A1,以此类推...最后一位字符记为AT;
设假码第一位字符ASC码为B1,以此类推... 最后一位字符记为BT;
An-Bn的值存放于004032A0处;
到这里为止,可以知道用户名多出的字符不参与计算!x6的值由(AT-BT),[4032A0+L0]经过一系列的转换得来的
x6=(A1-B1)+(A2-B2)+....(AT-BT)才能注册成功!
只要保证每次输入的AT,BT保持不变,x5的值是不会变化的;
设[4032A0+L0]处对应的用户名,假码字符分别为 AR,BR;
x5-(AR-BR)=(AR-BR)+(AT-BT)+W
这个W就是剩下(L-1)位对应的(AN-Bn)ASC码之和
到这一步很好算了,x5定值,W是可以随便假设的只要符合上面算法的条件,所以得到4032A0+L0]的假设值也就不难了!
第一次写破文,没有经验,很多地方看起来特别别扭.请大侠指出错误,造成你阅读上困扰,请原谅!
一组可用的字符:
注册名:bjcdef
注册码:aaacdx
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)