└文章标题┐:haoshuaioo's 第一个CrackMe随便分析分析
└破文作者┐:-=>大菜一号<=-
└破解对象┐:附件中
└下载地址┐:附件中
└对象大小┐:未知
└加壳方式┐:没有
└保护方式┐:普通算法
└编写语言┐:BC
└使用工具┐:od
└破解平台┐:d-xp
└破解声明┐:``````````无语``
------------------------------------------------------------------
└破解过程┐:
嘿嘿`那个什么兄的第一个CrackMe,过了N天了`居然没看到人发破文!(难道是在等我。。)哦呵呵呵``开玩笑呼!!!很简单!!
算法是这样的:
输入的注册名,第四位乘以第五位(结果记a),第三位减去注册名长度(结果记len),a再减去len(结果记b),第四位减去注册名长度(结果记c),b+c(结果记d),d或上注册名第一位,再减去注册名长度,以"%04X"格式化为字符串,再取出前四位(记作e),e左移0x1c位(记作f),f加上e,其和就是注册码!
呵呵``不难!!就因为没人发破文,我也来玩玩!!好像CrackMe赛要来了哦!本人还找不到大牛组队~~汗啊~~看来这次玩玩别人的cm算了!— — !
下面分析一下代码!对了,这个CM是BC写的,函数断一点用也没有~~呵呵~~~用OD万能断~~找到这样一个关键处:
00401AC8 /$ 55 push ebp <-断这里
00401AC9 |. 8BEC mov ebp, esp
00401ACB |. 81C4 78FFFFFF add esp, -88
00401AD1 |. B9 05000000 mov ecx, 5
00401AD6 |. 53 push ebx
00401AD7 |. 56 push esi
00401AD8 |. 57 push edi
00401AD9 |. 56 push esi
00401ADA |. 8D7D C0 lea edi, dword ptr [ebp-40]
00401ADD |. BE 8C914700 mov esi, 0047918C
00401AE2 |. F3:A5 rep movs dword ptr es:[edi], dword p>
00401AE4 |. 5E pop esi
00401AE5 |. 8D7D A0 lea edi, dword ptr [ebp-60]
00401AE8 |. 56 push esi
00401AE9 |. BE A0914700 mov esi, 004791A0
00401AEE |. B9 08000000 mov ecx, 8
00401AF3 |. F3:A5 rep movs dword ptr es:[edi], dword p>
00401AF5 |. 5E pop esi
00401AF6 |. 8D7D 80 lea edi, dword ptr [ebp-80]
00401AF9 |. 56 push esi
00401AFA |. BE C0914700 mov esi, 004791C0
00401AFF |. B9 08000000 mov ecx, 8
00401B04 |. F3:A5 rep movs dword ptr es:[edi], dword p>
00401B06 |. 33C0 xor eax, eax
00401B08 |. 5E pop esi
00401B09 |. 33D2 xor edx, edx
00401B0B |. 8945 F0 mov dword ptr [ebp-10], eax
00401B0E |. 8955 EC mov dword ptr [ebp-14], edx
00401B11 |. 33C9 xor ecx, ecx
00401B13 |. 894D E8 mov dword ptr [ebp-18], ecx
00401B16 |. 33F6 xor esi, esi
00401B18 |. 8D5D C0 lea ebx, dword ptr [ebp-40]
00401B1B |. 8B45 08 mov eax, dword ptr [ebp+8]
00401B1E |> 8A10 /mov dl, byte ptr [eax] ; 取注册名字符
00401B20 |. 84D2 |test dl, dl
00401B22 |. 74 0A |je short 00401B2E ; 是否已算完
00401B24 |. 8813 |mov byte ptr [ebx], dl
00401B26 |. 46 |inc esi ; 计数器加一
00401B27 |. 43 |inc ebx ; ebx+1,指向下一个内存格
00401B28 |. 40 |inc eax ; eas加一,指向下一个注册名字符
00401B29 |. 83FE 20 |cmp esi, 20 ; 计数器和0x20比较
00401B2C |.^ 7C F0 \jl short 00401B1E ; 小于就跳上去
00401B2E |> 0FBE7D C1 movsx edi, byte ptr [ebp-3F] ; 注册名第二位到edi
00401B32 |. 0FBE45 C2 movsx eax, byte ptr [ebp-3E] ; 注册名第三位到eax
00401B36 |. 8945 FC mov dword ptr [ebp-4], eax
00401B39 |. 0FBE55 C3 movsx edx, byte ptr [ebp-3D] ; 注册名第四位到edx
00401B3D |. 8955 F8 mov dword ptr [ebp-8], edx
00401B40 |. 0FBE4D C4 movsx ecx, byte ptr [ebp-3C] ; 注册名第五位到ecx
00401B44 |. 894D F4 mov dword ptr [ebp-C], ecx
00401B47 |. 8D45 C0 lea eax, dword ptr [ebp-40]
00401B4A |. 50 push eax
00401B4B |. E8 5C8F0500 call 0045AAAC ; 取长度
00401B50 |. 8BF0 mov esi, eax
00401B52 |. 8B45 F0 mov eax, dword ptr [ebp-10]
00401B55 |. 59 pop ecx
00401B56 |. 8D5C05 C0 lea ebx, dword ptr [ebp+eax-40]
00401B5A |> 8B05 E0914700 /mov eax, dword ptr [4791E0]
00401B60 |. 8945 DC |mov dword ptr [ebp-24], eax
00401B63 |. 8B05 E4914700 |mov eax, dword ptr [4791E4]
00401B69 |. 8945 E0 |mov dword ptr [ebp-20], eax
00401B6C |. 66:8B05 E8914>|mov ax, word ptr [4791E8]
00401B73 |. 66:8945 E4 |mov word ptr [ebp-1C], ax
00401B77 |. 8B4D F8 |mov ecx, dword ptr [ebp-8] ; 注册名第四位到ecx
00401B7A |. 8B45 FC |mov eax, dword ptr [ebp-4] ; 注册名第三位到eax
00401B7D |. 0FAF4D F4 |imul ecx, dword ptr [ebp-C] ; 注册名第四位乘以第五位
00401B81 |. 2BC6 |sub eax, esi ; 注册名第三位减去注册名长度
00401B83 |. 8B55 F8 |mov edx, dword ptr [ebp-8] ; 注册名第四位传到edx
00401B86 |. 2BC8 |sub ecx, eax ; 上面乘积减去上面的减差
00401B88 |. 2BD6 |sub edx, esi ; 注册名第四位减去注册名长度
00401B8A |. 03D1 |add edx, ecx ; 第二个减差加第三个减差
00401B8C |. 8BC2 |mov eax, edx ; 结果传到eax
00401B8E |. 0FBE13 |movsx edx, byte ptr [ebx] ; 循环计数器位对应的注册名到edx
00401B91 |. 0BC2 |or eax, edx ; 与上面结果做或运算
00401B93 |. 2BC6 |sub eax, esi ; 或运算结果减去注册名长度
00401B95 |. 50 |push eax ; /<%04X>
00401B96 |. 8D45 DC |lea eax, dword ptr [ebp-24] ; |
00401B99 |. 68 EE914700 |push 004791EE ; |%04x
00401B9E |. 50 |push eax ; |s
00401B9F |. E8 EA680700 |call <jmp.&USER32.wsprintfA> ; \wsprintfA
00401BA4 |. 83C4 0C |add esp, 0C ; 格式化十六进制字符串
00401BA7 |. 8D4D 80 |lea ecx, dword ptr [ebp-80]
00401BAA |. 51 |push ecx
00401BAB |. E8 FC8E0500 |call 0045AAAC
00401BB0 |. 59 |pop ecx
00401BB1 |. 83F8 20 |cmp eax, 20
00401BB4 |. 73 2D |jnb short 00401BE3
00401BB6 |. 8D45 DC |lea eax, dword ptr [ebp-24]
00401BB9 |. 50 |push eax ; /Arg2
00401BBA |. 8D55 80 |lea edx, dword ptr [ebp-80] ; |
00401BBD |. 52 |push edx ; |Arg1
00401BBE |. E8 AD8E0500 |call 0045AA70 ; \CrackMe`.0045AA70
00401BC3 |. 83C4 08 |add esp, 8
00401BC6 |. 4F |dec edi
00401BC7 |. FF45 F0 |inc dword ptr [ebp-10]
00401BCA |. 43 |inc ebx
00401BCB |. 3B75 F0 |cmp esi, dword ptr [ebp-10]
00401BCE |. 75 0A |jnz short 00401BDA
00401BD0 |. 837D F0 00 |cmp dword ptr [ebp-10], 0
00401BD4 |. 0F94C1 |sete cl
00401BD7 |. 83E1 01 |and ecx, 1
00401BDA |> 85FF |test edi, edi
00401BDC |. 7E 05 |jle short 00401BE3
00401BDE |.^ E9 77FFFFFF \jmp 00401B5A
00401BE3 |> 8D55 84 lea edx, dword ptr [ebp-7C] <-结果指针到edx
00401BE6 |. 8D45 80 lea eax, dword ptr [ebp-80]
00401BE9 |. 8B0A mov ecx, dword ptr [edx] <-取出dword双字
00401BEB |. C1E1 1C shl ecx, 1C <-左移0x1c位
00401BEE |. 0308 add ecx, dword ptr [eax] <-加上左dword双字
00401BF0 |. 33D2 xor edx, edx <-ecx是正确的注册码
00401BF2 |. 898D 78FFFFFF mov dword ptr [ebp-88], ecx
00401BF8 8995 7CFFFFFF mov dword ptr [ebp-84], edx
00401BFE |. DFAD 78FFFFFF fild qword ptr [ebp-88] <-居然装入浮点``汗````
00401C04 |. DD5D D4 fstp qword ptr [ebp-2C]
00401C07 |. 6A 20 push 20 ; /Arg3 = 00000020
00401C09 |. 6A 00 push 0 ; |Arg2 = 00000000
00401C0B |. 50 push eax ; |Arg1
00401C0C |. E8 BB8D0500 call 0045A9CC ; \CrackMe`.0045A9CC
00401C11 |. 83C4 0C add esp, 0C
00401C14 |. FF75 D8 push dword ptr [ebp-28] ; /Arg4
00401C17 |. FF75 D4 push dword ptr [ebp-2C] ; |Arg3
00401C1A |. 68 F3914700 push 004791F3 ; |%.0f
00401C1F |. 8D4D 80 lea ecx, dword ptr [ebp-80] ; |
00401C22 |. 51 push ecx ; |Arg1
00401C23 |. E8 BCA80500 call 0045C4E4 ; \CrackMe`.0045C4E4 <-注册码格式化
00401C28 |. 83C4 10 add esp, 10
00401C2B |. 8B45 0C mov eax, dword ptr [ebp+C]
00401C2E |. 50 push eax ; /<%s>
00401C2F |. 68 F8914700 push 004791F8 ; |%s
00401C34 |. 8D55 A0 lea edx, dword ptr [ebp-60] ; |
00401C37 |. 52 push edx ; |s
00401C38 |. E8 51680700 call <jmp.&USER32.wsprintfA> ; \wsprintfA <-假码格式化,其实就是复制嘛!
00401C3D |. 83C4 0C add esp, 0C
00401C40 |. 33C0 xor eax, eax
00401C42 |. 8D5D 80 lea ebx, dword ptr [ebp-80]
00401C45 |> 803B 00 /cmp byte ptr [ebx], 0-------------------
00401C48 |. 74 0A |je short 00401C54
00401C4A |. FF45 EC |inc dword ptr [ebp-14]
00401C4D |. 40 |inc eax 统计真码长度(或者说检查每位是否为空)
00401C4E |. 43 |inc ebx
00401C4F |. 83F8 20 |cmp eax, 20
00401C52 |.^ 7C F1 \jl short 00401C45----------------------
00401C54 |> 33C0 xor eax, eax
00401C56 |. 8D5D A0 lea ebx, dword ptr [ebp-60]
00401C59 |> 803B 00 /cmp byte ptr [ebx], 0------------------
00401C5C |. 74 0A |je short 00401C68
00401C5E |. FF45 E8 |inc dword ptr [ebp-18]
00401C61 |. 40 |inc eax 统计假码长度(或者说检查每位是否为空)
00401C62 |. 43 |inc ebx
00401C63 |. 83F8 20 |cmp eax, 20
00401C66 |.^ 7C F1 \jl short 00401C59--------------------
00401C68 |> 8B45 EC mov eax, dword ptr [ebp-14]
00401C6B |. 3B45 E8 cmp eax, dword ptr [ebp-18] <-两者长度比较
00401C6E |. 74 04 je short 00401C74 <-不等就出错
00401C70 |. 33C0 xor eax, eax
00401C72 |. EB 21 jmp short 00401C95
00401C74 |> 33D2 xor edx, edx
00401C76 |. 8D45 A0 lea eax, dword ptr [ebp-60]
00401C79 |. 8D5D 80 lea ebx, dword ptr [ebp-80]
00401C7C |. 3B55 EC cmp edx, dword ptr [ebp-14]
00401C7F |. 7D 12 jge short 00401C93
00401C81 |> 8A0B /mov cl, byte ptr [ebx]
00401C83 |. 3A08 |cmp cl, byte ptr [eax] <-这个循环依次比较两者是否相等
00401C85 |. 74 04 |je short 00401C8B
00401C87 |. 33C0 |xor eax, eax
00401C89 |. EB 0A |jmp short 00401C95
00401C8B |> 42 |inc edx
00401C8C |. 40 |inc eax
00401C8D |. 43 |inc ebx
00401C8E |. 3B55 EC |cmp edx, dword ptr [ebp-14]
00401C91 |.^ 7C EE \jl short 00401C81
00401C93 |> B0 01 mov al, 1 <-eax是个标志,1就注册成功,0则相反
00401C95 |> 5F pop edi
00401C96 |. 5E pop esi
00401C97 |. 5B pop ebx
00401C98 |. 8BE5 mov esp, ebp
00401C9A |. 5D pop ebp
00401C9B \. C3 retn
呼呼,,下面注册机:(部分mfc代码)
char name[100],code[100];
DWORD* p;
unsigned long num=0,m=0;
int i,k=0,l=0;
GetDlgItemText(IDC_EDIT1,name,-1);
k=name[3]*name[4];
l=name[2]-strlen(name);
l=k-l;
k=name[3]-strlen(name);
l+=k;
l |=name[0];
l-=strlen(name);
sprintf(code,"%04X",l);
p=(DWORD*)code;
num=*p;
m=num;
num<<=0x1c;
num+=m;
sprintf(code,"%i",num);
SetDlgItemText(IDC_EDIT2,code);
注册机少许缺陷``呵呵```不管了!!
我没用循环哦,因为最后取的是dword,前四位,照这种算法来看,不用算到注册名后面去了,算第一次就行了!省事!!
对了``注册名长度要大于3
就这样```收工~!!!
----------------------------------------------------------------------------------
└经验总结┐:
原来crack也不难``哦呵呵``
至少这个是这样`
----------------------------------------------------------------------------------
└版权声明┐ 本文原创于看雪软件安全论坛, 转载请注明作者并保持文章的完整, 谢谢!
2007年5月31日 11:14:37
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!