【文章标题】: PEDIY CRACKME#1
【文章作者】: gchao
【作者邮箱】: bysdy915@tom.com
【软件名称】: Bigman's Crackme6
【软件大小】: 7k
【下载地址】: 自己搜索下载
【加壳方式】: Aspack
【编写语言】: vc++
【使用工具】: od,peid,Aspackdie1.41
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
【详细过程】
打开软件输入NAME和SERIAL发现没有任何提示。
用PEID查看发现加了壳,用ASPACKDIE脱掉,得到CRACKME6_U
因为没有提示对话框,于是在获得输入时下断点。
用OD载入,运行CRACKME,输入NAME和SERIAL,在COMMAND中输入BPX GetDlgItemTextA,点击CHECK,被断在00401539处。
00401539 |. E8 FA010000 call ; /GetDlgItemTextA ;压F8跳过CALL,
0040153E |. 89C3 mov ebx, eax
00401540 |. 09DB or ebx, ebx
00401542 |. 75 04 jnz short 00401548;判断NAME是否为空,不为空则往下跳,否者EAX清零返回
00401544 |. 31C0 xor eax, eax
00401546 |. EB 50 jmp short 00401598
00401548 |> BF BC020000 mov edi, 2BC
0040154D |. BE 30000000 mov esi, 30
00401552 |. B8 48000000 mov eax, 48
00401557 |. 99 cdq
00401558 |. F7FB idiv ebx
0040155A |. 29C6 sub esi, eax
0040155C |. 8D34B6 lea esi, dword ptr [esi+esi*4]
0040155F |. 29F7 sub edi, esi
00401561 |. 6BFF 6B imul edi, edi, 6B
00401564 |. 81EF 6CCF0000 sub edi, 0CF6C
0040156A |. 81FF 00230000 cmp edi, 2300
00401570 |. 7F 08 jg short 0040157A
00401572 |. 81FF 90010000 cmp edi, 190
00401578 |. 7D 04 jge short 0040157E
0040157A |> 31C0 xor eax, eax
0040157C |. EB 1A jmp short 00401598;以上判断name的位数是否在3——9位之间,否则跳向出错
0040157E |> /8D85 00FFFFFF lea eax, dword ptr [ebp-100]
00401584 |. 50 push eax
00401585 |. 53 push ebx
00401586 |. FF75 08 push dword ptr [ebp+8]
00401589 |. E8 77FDFFFF call 00401305;关键CALL F7跟入因为在后面就是判断和RETN了
跟进后经过一些读写操作后就到这
00401397 >|. C745 FC 00000>mov dword ptr [ebp-4], 0 ; 获得注册码
0040139E |. 68 00010000 push 100 ; /Count = 100 (256.)
004013A3 |. 8D85 E1FCFFFF lea eax, dword ptr [ebp-31F] ; |
004013A9 |. 50 push eax ; |Buffer
004013AA |. 6A 66 push 66 ; |ControlID = 66 (102.)
004013AC |. FF75 08 push dword ptr [ebp+8] ; |hWnd
004013AF |. E8 84030000 call ; /GetDlgItemTextA
GetDlgItemTextA这次获得的是SERIAL
004013B4 |. 09C0 or eax, eax
004013B6 |. /0F84 48010000 je 00401504;判断SERIAL是否为0
004013BC |. |B8 CF110000 mov eax, 11CF
004013C1 |. |0FB68D E1FCFF>movzx ecx, byte ptr [ebp-31F]
004013C8 |. |99 cdq
004013C9 |. |F7F9 idiv ecx
004013CB |. |83FA 17 cmp edx, 17
004013CE |. |74 07 je short 004013D7
004013D0 |. |31C0 xor eax, eax
004013D2 |. |E9 2D010000 jmp 00401504
004013D7 |> |31DB xor ebx, ebx
004013D9 |. |EB 0B jmp short 004013E6
这里判断SERIAL的第一位,通过求0X11cf%BUF[0],判断结果是否是0x17,如果不是则出错,满足结果的有6,8,H,Q,T,l(我怎么
知道的?写个C的循环不就算出来的么~~)
于是重新开始NAME仍然是gchao,但SERIAL的第一位必须是以上几个数,这里我选了H
重复上面过程,结果跳过了出错的004013D2 |. /E9 2D010000 jmp 00401504
跳向了这:
004013DB |> /8B45 10 /mov eax, dword ptr [ebp+10]
004013DE |. |0FBE0418 |movsx eax, byte ptr [eax+ebx]
004013E2 |. |0145 FC |add dword ptr [ebp-4], eax
004013E5 |. |43 |inc ebx
004013E6 |> |3B5D 0C cmp ebx, dword ptr [ebp+C]
004013E9 |.^/7C F0 /jl short 004013DB
这段是把NAME的各个位的ASCII相加
跳出上面的循环后再运行一行,就开始了算出注册号的过程
004013F2 |> /8B55 10 /mov edx, dword ptr [ebp+10]
004013F5 |. |0FBE3C1A |movsx edi, byte ptr [edx+ebx]
004013F9 |. |8B75 FC |mov esi, dword ptr [ebp-4];刚刚上面算出来的总ASCII值
004013FC |. |89D9 |mov ecx, ebx
004013FE |. |C1E1 02 |shl ecx, 2
00401401 |. |89DA |mov edx, ebx
00401403 |. |42 |inc edx
00401404 |. |29D1 |sub ecx, edx
00401406 |. |0FB68C0D E1FE>|movzx ecx, byte ptr [ebp+ecx-11F]
0040140E |. |89FA |mov edx, edi
00401410 |. |31CA |xor edx, ecx
00401412 |. |89F1 |mov ecx, esi
00401414 |. |0FAFCB |imul ecx, ebx
00401417 |. |29F1 |sub ecx, esi
00401419 |. |89CE |mov esi, ecx
0040141B |. |83F6 FF |xor esi, FFFFFFFF
0040141E |. |8DB432 4D0100>|lea esi, dword ptr [edx+esi+14D]
00401425 |. |8B4D 0C |mov ecx, dword ptr [ebp+C]
00401428 |. |89DA |mov edx, ebx
0040142A |. |83C2 03 |add edx, 3
0040142D |. |0FAFCA |imul ecx, edx
00401430 |. |0FAFCF |imul ecx, edi
00401433 |. |89F0 |mov eax, esi
00401435 |. |01C8 |add eax, ecx
00401437 |. |B9 0A000000 |mov ecx, 0A
0040143C |. |31D2 |xor edx, edx
0040143E |. |F7F1 |div ecx
00401440 |. |83C2 30 |add edx, 30
00401443 |. |88941D FCFEFF>|mov byte ptr [ebp+ebx-104], dl
0040144A |. |0FB6BC1D FCFE>|movzx edi, byte ptr [ebp+ebx-104]
00401452 |. |81F7 ACAD0000 |xor edi, 0ADAC
00401458 |. |89DE |mov esi, ebx
0040145A |. |83C6 02 |add esi, 2
0040145D |. |89F8 |mov eax, edi
0040145F |. |0FAFC6 |imul eax, esi
00401462 |. |B9 0A000000 |mov ecx, 0A
00401467 |. |99 |cdq
00401468 |. |F7F9 |idiv ecx
0040146A |. |83C2 30 |add edx, 30
0040146D |. |88941D FCFEFF>|mov byte ptr [ebp+ebx-104], dl
00401474 |. |43 |inc ebx
00401475 |> |3B5D 0C cmp ebx, dword ptr [ebp+C]
00401478 |.^/0F8C 74FFFFFF /jl 004013F2
通过反复的跟踪,他的过程相当于是:
k = ~(i*total-total) + (i+3)*n*bufn[i] + (bufn[i]^table[4*i-(i+1)+1]) + 0x14d;
j = (((k%0xa +0x30)^0xADAC) * (i+2)) % 0xa + 0x30;
(bufn[i]为第i位注册名的ASCII值,table[]是程序算SERIAL的查询表,这里就是从A-Z,
我怎么知道?在这一句00401406 |. 0FB68C0D E1FE>|movzx ecx, byte ptr [ebp+ecx-11F]
突然来了一个ss:[0012f7d7]=43(‘C’)(我是第2次循环才发现的,第一次是0,没注意,嘿嘿)于是内存中
跟入就看到啦~~~
)
好了,跳出循环后
0040147E |. 8D85 FCFEFFFF lea eax, dword ptr [ebp-104]
00401484 |. 50 push eax ;获得6位注册码入栈
00401485 |. 6A 54 push 54
00401487 |. 8D85 DCFBFFFF lea eax, dword ptr [ebp-424]
0040148D |. 50 push eax ; |Format
0040148E |. 8D85 E1FBFFFF lea eax, dword ptr [ebp-41F] ; |
00401494 |. 50 push eax ; |s
00401495 |. E8 CE020000 call ; /wsprintfA
这里在获得6位注册码前加T
0040149A |. 8B7D 0C mov edi, dword ptr [ebp+C]
0040149D |. 89F8 mov eax, edi
0040149F |. 0FAF45 FC imul eax, dword ptr [ebp-4]
004014A3 |. B9 64000000 mov ecx, 64
004014A8 |. 99 cdq
004014A9 |. F7F9 idiv ecx
004014AB |. 89D7 mov edi, edx
004014AD |. 83C7 30 add edi, 30
这段相当于是
把n (NAME的总位数)* total(前面说过了) % 0x64 +0x30;做为后面的几位
004014B0 |. 57 push edi
004014B1 |. 8DBD E1FBFFFF lea edi, dword ptr [ebp-41F]
004014B7 |. 57 push edi
004014B8 |. 8DBD D6FBFFFF lea edi, dword ptr [ebp-42A]
004014BE |. 57 push edi ; |Format
004014BF |. 8DBD E1FDFFFF lea edi, dword ptr [ebp-21F] ; |
004014C5 |. 57 push edi ; |s
004014C6 |. E8 9D020000 call ; /wsprintfA
这里是在前面的7位注册码T00004(我这是这个)后加上‘-’和把上面算出来的n * total % 0x64 +0x30转化10进制当作SERIAL
,我这算出来的是0x76,转换成10进制就是118
到目前为止得到了T00004-118,很像是SERIAL了吧,但很不幸,还不是啦~~~不信你输入看看嘿嘿
继续
004014D4 |. 83C8 FF or eax, FFFFFFFF
004014D7 |> 40 /inc eax
004014D8 |. 803C01 00 |cmp byte ptr [ecx+eax], 0
004014DC |.^ 75 F9 /jnz short 004014D7
这段是计算下目前的注册码是多少位的
然后又有一个CALL,当然是跟入啦
004012C8 |. 8B5D 10 mov ebx, dword ptr [ebp+10]
004012CB |. 31F6 xor esi, esi
004012CD |. 46 inc esi
004012CE |. EB 29 jmp short 004012F9
004012D0 |> 8B55 08 /mov edx, dword ptr [ebp+8]
004012D3 |. 0FBE3C32 |movsx edi, byte ptr [edx+esi]
004012D7 |. 89F8 |mov eax, edi
004012D9 |. 83F0 20 |xor eax, 20
004012DC |. B9 0A000000 |mov ecx, 0A
004012E1 |. 99 |cdq
004012E2 |. F7F9 |idiv ecx
004012E4 |. 89D7 |mov edi, edx
004012E6 |. 83C7 30 |add edi, 30
004012E9 |. 8B55 0C |mov edx, dword ptr [ebp+C]
004012EC |. 0FBE1432 |movsx edx, byte ptr [edx+esi]
004012F0 |. 39D7 |cmp edi, edx
004012F2 74 04 je short 004012F8
;这里每算一位就要和你输入的注册码相比较,我是改成JMP的,方便调试,免得每次都要重来
004012F4 |. 31C0 |xor eax, eax
004012F6 |. EB 08 |jmp short 00401300
004012F8 |> 46 |inc esi
004012F9 |> 39DE cmp esi, ebx
004012FB |.^ 7C D3 /jl short 004012D0
这里吧刚刚算出来的位数做为循环次数,对刚刚的注册码进行2次加工~~
算法是:
bufms[i]^0x20) %0xa +0x30
bufms[i]为当前暂时注册码的第i位~~
于是到目前为止,大功造成,追出注册码了
我的是T66660774
下面是整个的算法,我用的是C:
#include<stdio.h>
#include<string.h>
char table[28] = {0x00,'A','B','C','D','E','F','G','H','I','J','K','L',
'M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','/0'};
void print()
{
printf("/t/tThe keygen of TheBigMan's CrackMe #6/n");
printf("/t/t/t/t/tcracked by gchao/n");
}
int getlen(int n)
{
int i = 1;
while((n/=10) != 0){
i++;
}
return i;
}
void itoc(int temp,int j,char * buf)
{
while(j > 0){
buf[--j]=temp%10+0x30;
temp /= 10;
}
}
int main()
{
long int i,j,n,total,k,temp;
char bufn[20]={0},bufs[40]={'T'},bufms[40]={'T'},ch;
total = 0;
print();
printf("type in your name,/nthe name must more than 3 lettles:/n");
scanf("%s",bufn);
n = strlen(bufn);
for(i = 0;i < n;i++)
total += bufn[i]; //算出注册名的ASCII的总和
for(i = 0;i < n;i++){
k = ~(i*total-total) + (i+3)*n*bufn[i] + (bufn[i]^table[4*i-(i+1)+1]) + 0x14d;
j = (((k%0xa +0x30)^0xADAC) * (i+2)) % 0xa + 0x30;
bufms[i+1] = j;
}
bufms[++i] = '-';
temp = n * total % 0x64 +0x30;
j=getlen(temp); //j中存放-之后的数字
itoc(temp,j,&bufms[++i]); //将整型数据转化成字符串并写入到后续序列号
for(i = 1; i <= (n+j+1); i++)
bufs[i]=(((long int)bufms[i])^0x20) %0xa +0x30;
printf("Serial is: %s/n",bufs);
return 0;
}
【经验总结】
1.因为没有提示对话框,于是在获得输入时下断点。
用OD载入,运行CRACKME,输入NAME和SERIAL,在COMMAND中输入BPX GetDlgItemTextA
2008年05月18日 上午 10:01:39
【文章作者】: gchao
【作者邮箱】: bysdy915@tom.com
【软件名称】: Bigman's Crackme6
【软件大小】: 7k
【下载地址】: 自己搜索下载
【加壳方式】: Aspack
【编写语言】: vc++
【使用工具】: od,peid,Aspackdie1.41
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
【详细过程】
打开软件输入NAME和SERIAL发现没有任何提示。
用PEID查看发现加了壳,用ASPACKDIE脱掉,得到CRACKME6_U
因为没有提示对话框,于是在获得输入时下断点。
用OD载入,运行CRACKME,输入NAME和SERIAL,在COMMAND中输入BPX GetDlgItemTextA,点击CHECK,被断在00401539处。
00401539 |. E8 FA010000 call ; /GetDlgItemTextA ;压F8跳过CALL,
0040153E |. 89C3 mov ebx, eax
00401540 |. 09DB or ebx, ebx
00401542 |. 75 04 jnz short 00401548;判断NAME是否为空,不为空则往下跳,否者EAX清零返回
00401544 |. 31C0 xor eax, eax
00401546 |. EB 50 jmp short 00401598
00401548 |> BF BC020000 mov edi, 2BC
0040154D |. BE 30000000 mov esi, 30
00401552 |. B8 48000000 mov eax, 48
00401557 |. 99 cdq
00401558 |. F7FB idiv ebx
0040155A |. 29C6 sub esi, eax
0040155C |. 8D34B6 lea esi, dword ptr [esi+esi*4]
0040155F |. 29F7 sub edi, esi
00401561 |. 6BFF 6B imul edi, edi, 6B
00401564 |. 81EF 6CCF0000 sub edi, 0CF6C
0040156A |. 81FF 00230000 cmp edi, 2300
00401570 |. 7F 08 jg short 0040157A
00401572 |. 81FF 90010000 cmp edi, 190
00401578 |. 7D 04 jge short 0040157E
0040157A |> 31C0 xor eax, eax
0040157C |. EB 1A jmp short 00401598;以上判断name的位数是否在3——9位之间,否则跳向出错
0040157E |> /8D85 00FFFFFF lea eax, dword ptr [ebp-100]
00401584 |. 50 push eax
00401585 |. 53 push ebx
00401586 |. FF75 08 push dword ptr [ebp+8]
00401589 |. E8 77FDFFFF call 00401305;关键CALL F7跟入因为在后面就是判断和RETN了
跟进后经过一些读写操作后就到这
00401397 >|. C745 FC 00000>mov dword ptr [ebp-4], 0 ; 获得注册码
0040139E |. 68 00010000 push 100 ; /Count = 100 (256.)
004013A3 |. 8D85 E1FCFFFF lea eax, dword ptr [ebp-31F] ; |
004013A9 |. 50 push eax ; |Buffer
004013AA |. 6A 66 push 66 ; |ControlID = 66 (102.)
004013AC |. FF75 08 push dword ptr [ebp+8] ; |hWnd
004013AF |. E8 84030000 call ; /GetDlgItemTextA
GetDlgItemTextA这次获得的是SERIAL
004013B4 |. 09C0 or eax, eax
004013B6 |. /0F84 48010000 je 00401504;判断SERIAL是否为0
004013BC |. |B8 CF110000 mov eax, 11CF
004013C1 |. |0FB68D E1FCFF>movzx ecx, byte ptr [ebp-31F]
004013C8 |. |99 cdq
004013C9 |. |F7F9 idiv ecx
004013CB |. |83FA 17 cmp edx, 17
004013CE |. |74 07 je short 004013D7
004013D0 |. |31C0 xor eax, eax
004013D2 |. |E9 2D010000 jmp 00401504
004013D7 |> |31DB xor ebx, ebx
004013D9 |. |EB 0B jmp short 004013E6
这里判断SERIAL的第一位,通过求0X11cf%BUF[0],判断结果是否是0x17,如果不是则出错,满足结果的有6,8,H,Q,T,l(我怎么
知道的?写个C的循环不就算出来的么~~)
于是重新开始NAME仍然是gchao,但SERIAL的第一位必须是以上几个数,这里我选了H
重复上面过程,结果跳过了出错的004013D2 |. /E9 2D010000 jmp 00401504
跳向了这:
004013DB |> /8B45 10 /mov eax, dword ptr [ebp+10]
004013DE |. |0FBE0418 |movsx eax, byte ptr [eax+ebx]
004013E2 |. |0145 FC |add dword ptr [ebp-4], eax
004013E5 |. |43 |inc ebx
004013E6 |> |3B5D 0C cmp ebx, dword ptr [ebp+C]
004013E9 |.^/7C F0 /jl short 004013DB
这段是把NAME的各个位的ASCII相加
跳出上面的循环后再运行一行,就开始了算出注册号的过程
004013F2 |> /8B55 10 /mov edx, dword ptr [ebp+10]
004013F5 |. |0FBE3C1A |movsx edi, byte ptr [edx+ebx]
004013F9 |. |8B75 FC |mov esi, dword ptr [ebp-4];刚刚上面算出来的总ASCII值
004013FC |. |89D9 |mov ecx, ebx
004013FE |. |C1E1 02 |shl ecx, 2
00401401 |. |89DA |mov edx, ebx
00401403 |. |42 |inc edx
00401404 |. |29D1 |sub ecx, edx
00401406 |. |0FB68C0D E1FE>|movzx ecx, byte ptr [ebp+ecx-11F]
0040140E |. |89FA |mov edx, edi
00401410 |. |31CA |xor edx, ecx
00401412 |. |89F1 |mov ecx, esi
00401414 |. |0FAFCB |imul ecx, ebx
00401417 |. |29F1 |sub ecx, esi
00401419 |. |89CE |mov esi, ecx
0040141B |. |83F6 FF |xor esi, FFFFFFFF
0040141E |. |8DB432 4D0100>|lea esi, dword ptr [edx+esi+14D]
00401425 |. |8B4D 0C |mov ecx, dword ptr [ebp+C]
00401428 |. |89DA |mov edx, ebx
0040142A |. |83C2 03 |add edx, 3
0040142D |. |0FAFCA |imul ecx, edx
00401430 |. |0FAFCF |imul ecx, edi
00401433 |. |89F0 |mov eax, esi
00401435 |. |01C8 |add eax, ecx
00401437 |. |B9 0A000000 |mov ecx, 0A
0040143C |. |31D2 |xor edx, edx
0040143E |. |F7F1 |div ecx
00401440 |. |83C2 30 |add edx, 30
00401443 |. |88941D FCFEFF>|mov byte ptr [ebp+ebx-104], dl
0040144A |. |0FB6BC1D FCFE>|movzx edi, byte ptr [ebp+ebx-104]
00401452 |. |81F7 ACAD0000 |xor edi, 0ADAC
00401458 |. |89DE |mov esi, ebx
0040145A |. |83C6 02 |add esi, 2
0040145D |. |89F8 |mov eax, edi
0040145F |. |0FAFC6 |imul eax, esi
00401462 |. |B9 0A000000 |mov ecx, 0A
00401467 |. |99 |cdq
00401468 |. |F7F9 |idiv ecx
0040146A |. |83C2 30 |add edx, 30
0040146D |. |88941D FCFEFF>|mov byte ptr [ebp+ebx-104], dl
00401474 |. |43 |inc ebx
00401475 |> |3B5D 0C cmp ebx, dword ptr [ebp+C]
00401478 |.^/0F8C 74FFFFFF /jl 004013F2
通过反复的跟踪,他的过程相当于是:
k = ~(i*total-total) + (i+3)*n*bufn[i] + (bufn[i]^table[4*i-(i+1)+1]) + 0x14d;
j = (((k%0xa +0x30)^0xADAC) * (i+2)) % 0xa + 0x30;
(bufn[i]为第i位注册名的ASCII值,table[]是程序算SERIAL的查询表,这里就是从A-Z,
我怎么知道?在这一句00401406 |. 0FB68C0D E1FE>|movzx ecx, byte ptr [ebp+ecx-11F]
突然来了一个ss:[0012f7d7]=43(‘C’)(我是第2次循环才发现的,第一次是0,没注意,嘿嘿)于是内存中
跟入就看到啦~~~
)
好了,跳出循环后
0040147E |. 8D85 FCFEFFFF lea eax, dword ptr [ebp-104]
00401484 |. 50 push eax ;获得6位注册码入栈
00401485 |. 6A 54 push 54
00401487 |. 8D85 DCFBFFFF lea eax, dword ptr [ebp-424]
0040148D |. 50 push eax ; |Format
0040148E |. 8D85 E1FBFFFF lea eax, dword ptr [ebp-41F] ; |
00401494 |. 50 push eax ; |s
00401495 |. E8 CE020000 call ; /wsprintfA
这里在获得6位注册码前加T
0040149A |. 8B7D 0C mov edi, dword ptr [ebp+C]
0040149D |. 89F8 mov eax, edi
0040149F |. 0FAF45 FC imul eax, dword ptr [ebp-4]
004014A3 |. B9 64000000 mov ecx, 64
004014A8 |. 99 cdq
004014A9 |. F7F9 idiv ecx
004014AB |. 89D7 mov edi, edx
004014AD |. 83C7 30 add edi, 30
这段相当于是
把n (NAME的总位数)* total(前面说过了) % 0x64 +0x30;做为后面的几位
004014B0 |. 57 push edi
004014B1 |. 8DBD E1FBFFFF lea edi, dword ptr [ebp-41F]
004014B7 |. 57 push edi
004014B8 |. 8DBD D6FBFFFF lea edi, dword ptr [ebp-42A]
004014BE |. 57 push edi ; |Format
004014BF |. 8DBD E1FDFFFF lea edi, dword ptr [ebp-21F] ; |
004014C5 |. 57 push edi ; |s
004014C6 |. E8 9D020000 call ; /wsprintfA
这里是在前面的7位注册码T00004(我这是这个)后加上‘-’和把上面算出来的n * total % 0x64 +0x30转化10进制当作SERIAL
,我这算出来的是0x76,转换成10进制就是118
到目前为止得到了T00004-118,很像是SERIAL了吧,但很不幸,还不是啦~~~不信你输入看看嘿嘿
继续
004014D4 |. 83C8 FF or eax, FFFFFFFF
004014D7 |> 40 /inc eax
004014D8 |. 803C01 00 |cmp byte ptr [ecx+eax], 0
004014DC |.^ 75 F9 /jnz short 004014D7
这段是计算下目前的注册码是多少位的
然后又有一个CALL,当然是跟入啦
004012C8 |. 8B5D 10 mov ebx, dword ptr [ebp+10]
004012CB |. 31F6 xor esi, esi
004012CD |. 46 inc esi
004012CE |. EB 29 jmp short 004012F9
004012D0 |> 8B55 08 /mov edx, dword ptr [ebp+8]
004012D3 |. 0FBE3C32 |movsx edi, byte ptr [edx+esi]
004012D7 |. 89F8 |mov eax, edi
004012D9 |. 83F0 20 |xor eax, 20
004012DC |. B9 0A000000 |mov ecx, 0A
004012E1 |. 99 |cdq
004012E2 |. F7F9 |idiv ecx
004012E4 |. 89D7 |mov edi, edx
004012E6 |. 83C7 30 |add edi, 30
004012E9 |. 8B55 0C |mov edx, dword ptr [ebp+C]
004012EC |. 0FBE1432 |movsx edx, byte ptr [edx+esi]
004012F0 |. 39D7 |cmp edi, edx
004012F2 74 04 je short 004012F8
;这里每算一位就要和你输入的注册码相比较,我是改成JMP的,方便调试,免得每次都要重来
004012F4 |. 31C0 |xor eax, eax
004012F6 |. EB 08 |jmp short 00401300
004012F8 |> 46 |inc esi
004012F9 |> 39DE cmp esi, ebx
004012FB |.^ 7C D3 /jl short 004012D0
这里吧刚刚算出来的位数做为循环次数,对刚刚的注册码进行2次加工~~
算法是:
bufms[i]^0x20) %0xa +0x30
bufms[i]为当前暂时注册码的第i位~~
于是到目前为止,大功造成,追出注册码了
我的是T66660774
下面是整个的算法,我用的是C:
#include<stdio.h>
#include<string.h>
char table[28] = {0x00,'A','B','C','D','E','F','G','H','I','J','K','L',
'M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','/0'};
void print()
{
printf("/t/tThe keygen of TheBigMan's CrackMe #6/n");
printf("/t/t/t/t/tcracked by gchao/n");
}
int getlen(int n)
{
int i = 1;
while((n/=10) != 0){
i++;
}
return i;
}
void itoc(int temp,int j,char * buf)
{
while(j > 0){
buf[--j]=temp%10+0x30;
temp /= 10;
}
}
int main()
{
long int i,j,n,total,k,temp;
char bufn[20]={0},bufs[40]={'T'},bufms[40]={'T'},ch;
total = 0;
print();
printf("type in your name,/nthe name must more than 3 lettles:/n");
scanf("%s",bufn);
n = strlen(bufn);
for(i = 0;i < n;i++)
total += bufn[i]; //算出注册名的ASCII的总和
for(i = 0;i < n;i++){
k = ~(i*total-total) + (i+3)*n*bufn[i] + (bufn[i]^table[4*i-(i+1)+1]) + 0x14d;
j = (((k%0xa +0x30)^0xADAC) * (i+2)) % 0xa + 0x30;
bufms[i+1] = j;
}
bufms[++i] = '-';
temp = n * total % 0x64 +0x30;
j=getlen(temp); //j中存放-之后的数字
itoc(temp,j,&bufms[++i]); //将整型数据转化成字符串并写入到后续序列号
for(i = 1; i <= (n+j+1); i++)
bufs[i]=(((long int)bufms[i])^0x20) %0xa +0x30;
printf("Serial is: %s/n",bufs);
return 0;
}
【经验总结】
1.因为没有提示对话框,于是在获得输入时下断点。
用OD载入,运行CRACKME,输入NAME和SERIAL,在COMMAND中输入BPX GetDlgItemTextA
2008年05月18日 上午 10:01:39