└文章标题┐:无标题CrackMe分析
└破文作者┐:-=>大菜一号<=-
└破解对象┐:附件中..
└下载地址┐:附件中..
└对象大小┐:不知
└加壳方式┐:没有
└保护方式┐:普通算法
└编写语言┐:Delphi
└使用工具┐:OD
└破解平台┐:D版xp
└破解声明┐:Crack真好玩!
----------------------------------------------------------------------------------
└破解过程┐:
这个CrackMe算法一点都不难,,其实偶也不知道啦~~大概它用了Delphi什么什么函数``没跟进call里头`不过看得出的结果就知道怎么算了``哦呵呵呵,,
还有``这个CrackME还挺罗嗦滴!!字符串超长``汗`
OD找到"you got it!"字符串``
输入"jiangwu55",,"121212"
断在....
00430C58 /. 55 push ebp
00430C59 |. 8BEC mov ebp, esp
00430C5B |. B9 05000000 mov ecx, 5
00430C60 |> 6A 00 /push 0
00430C62 |. 6A 00 |push 0
00430C64 |. 49 |dec ecx
00430C65 |.^ 75 F9 \jnz short 00430C60
00430C67 |. 51 push ecx
00430C68 |. 53 push ebx
00430C69 |. 56 push esi
00430C6A |. 8BF0 mov esi, eax
00430C6C |. 33C0 xor eax, eax
00430C6E |. 55 push ebp
00430C6F |. 68 DF0E4300 push 00430EDF
00430C74 |. 64:FF30 push dword ptr fs:[eax]
00430C77 |. 64:8920 mov dword ptr fs:[eax], esp
00430C7A |. 8D45 EC lea eax, dword ptr [ebp-14]
00430C7D |. E8 3A2AFDFF call 004036BC
00430C82 |. 8D45 F8 lea eax, dword ptr [ebp-8]
00430C85 |. E8 322AFDFF call 004036BC
00430C8A |. 8D45 F4 lea eax, dword ptr [ebp-C]
00430C8D |. E8 2A2AFDFF call 004036BC
00430C92 |. 8D45 F0 lea eax, dword ptr [ebp-10]
00430C95 |. E8 222AFDFF call 004036BC
00430C9A |. 8D45 FC lea eax, dword ptr [ebp-4]
00430C9D |. E8 1A2AFDFF call 004036BC
00430CA2 |. 33DB xor ebx, ebx
00430CA4 |. 8D55 FC lea edx, dword ptr [ebp-4]
00430CA7 |. 8B86 DC010000 mov eax, dword ptr [esi+1DC]
00430CAD |. E8 669FFEFF call 0041AC18
00430CB2 |. 8D55 F8 lea edx, dword ptr [ebp-8]
00430CB5 |. 8B86 E0010000 mov eax, dword ptr [esi+1E0]
00430CBB |. E8 589FFEFF call 0041AC18 ;取name
00430CC0 |. 8B45 FC mov eax, dword ptr [ebp-4]
00430CC3 |. E8 702CFDFF call 00403938 ;取name长度
00430CC8 |. 83F8 06 cmp eax, 6 ;和6比较
00430CCB |. 7D 0F jge short 00430CDC ;小于出错
00430CCD |. B8 F40E4300 mov eax, 00430EF4 ; name must be at least 6 characters long
00430CD2 |. E8 65DEFFFF call 0042EB3C
00430CD7 |. E9 E8010000 jmp 00430EC4
00430CDC |> 837D F8 00 cmp dword ptr [ebp-8], 0 ;code为空出错
00430CE0 |. 75 34 jnz short 00430D16
00430CE2 |. B8 240F4300 mov eax, 00430F24 ; enter a serial #
00430CE7 |. E8 50DEFFFF call 0042EB3C
00430CEC |. E9 D3010000 jmp 00430EC4
00430CF1 |> 8B45 FC /mov eax, dword ptr [ebp-4]
00430CF4 |. E8 3F2CFDFF |call 00403938
00430CF9 |. 2BC3 |sub eax, ebx
00430CFB |. 8B55 FC |mov edx, dword ptr [ebp-4]
00430CFE |. 8A5402 FF |mov dl, byte ptr [edx+eax-1]
00430D02 |. 8D45 E4 |lea eax, dword ptr [ebp-1C]
00430D05 |. E8 562BFDFF |call 00403860
00430D0A |. 8B55 E4 |mov edx, dword ptr [ebp-1C]
00430D0D |. 8D45 F4 |lea eax, dword ptr [ebp-C]
00430D10 |. E8 2B2CFDFF |call 00403940
00430D15 |. 43 |inc ebx
00430D16 |> 8B45 FC mov eax, dword ptr [ebp-4] ;name传到eax
00430D19 |. E8 1A2CFDFF |call 00403938 ;取长度
00430D1E |. 3BD8 |cmp ebx, eax ;计数器比较
00430D20 |.^ 7C CF \jl short 00430CF1 ;没完跳上去
不用跟那个循环在干啥了`循环过后,,可以看到"55uwgnaij",呵``顺序变反了
00430D22 |. BB 01000000 mov ebx, 1
00430D27 |. EB 36 jmp short 00430D5F
00430D29 |> FF75 EC /push dword ptr [ebp-14]
00430D2C |. 8D45 E4 |lea eax, dword ptr [ebp-1C]
00430D2F |. 8B55 FC |mov edx, dword ptr [ebp-4]
00430D32 |. 8A541A FF |mov dl, byte ptr [edx+ebx-1]
00430D36 |. E8 252BFDFF |call 00403860
00430D3B |. FF75 E4 |push dword ptr [ebp-1C]
00430D3E |. 8D55 E0 |lea edx, dword ptr [ebp-20]
00430D41 |. 8B45 F4 |mov eax, dword ptr [ebp-C]
00430D44 |. 0FB64418 FF |movzx eax, byte ptr [eax+ebx-1]
00430D49 |. E8 2A5AFDFF |call 00406778
00430D4E |. FF75 E0 |push dword ptr [ebp-20]
00430D51 |. 8D45 EC |lea eax, dword ptr [ebp-14]
00430D54 |. BA 03000000 |mov edx, 3
00430D59 |. E8 9A2CFDFF |call 004039F8
00430D5E |. 43 |inc ebx
00430D5F |> 8B45 FC mov eax, dword ptr [ebp-4]
00430D62 |. E8 D12BFDFF |call 00403938
00430D67 |. 3BD8 |cmp ebx, eax ;计数器从一开始,比较长度 ,也就是循环name长度-1次了
00430D69 |.^ 7C BE \jl short 00430D29 ;
也不用知道循环在做啥,,因为最后得到新字符串"j53i53a117n119g103w110u975105"
上面循环name长度-1次,则为"jiangwu5",少了一个'5',而那些数就是变反顺序后的asc了,穿插一下就变成新的字符串了`
00430D6B |. BB 01000000 mov ebx, 1
00430D70 |. 8D45 F4 lea eax, dword ptr [ebp-C]
00430D73 |. E8 4429FDFF call 004036BC
00430D78 |. EB 4D jmp short 00430DC7
00430D7A |> 8D45 DC /lea eax, dword ptr [ebp-24]
00430D7D |. 8B55 EC |mov edx, dword ptr [ebp-14]
00430D80 |. 8A141A |mov dl, byte ptr [edx+ebx] ;计数器从一开始,所以是取上面循环得到的新字符串的第二位
00430D83 |. 8850 01 |mov byte ptr [eax+1], dl
00430D86 |. C600 01 |mov byte ptr [eax], 1
00430D89 |. 8D55 DC |lea edx, dword ptr [ebp-24]
00430D8C |. 8D45 D8 |lea eax, dword ptr [ebp-28]
00430D8F |. E8 581AFDFF |call 004027EC
00430D94 |. 8D45 D4 |lea eax, dword ptr [ebp-2C]
00430D97 |. 8B55 EC |mov edx, dword ptr [ebp-14]
00430D9A |. 8A141A |mov dl, byte ptr [edx+ebx]
00430D9D |. 8850 01 |mov byte ptr [eax+1], dl
00430DA0 |. C600 01 |mov byte ptr [eax], 1
00430DA3 |. 8D55 D4 |lea edx, dword ptr [ebp-2C]
00430DA6 |. 8D45 D8 |lea eax, dword ptr [ebp-28]
00430DA9 |. B1 02 |mov cl, 2
00430DAB |. E8 0C1AFDFF |call 004027BC
00430DB0 |. 8D55 D8 |lea edx, dword ptr [ebp-28]
00430DB3 |. 8D45 F0 |lea eax, dword ptr [ebp-10]
00430DB6 |. E8 212BFDFF |call 004038DC
00430DBB |. 8D45 F4 |lea eax, dword ptr [ebp-C]
00430DBE |. 8B55 F0 |mov edx, dword ptr [ebp-10]
00430DC1 |. E8 7A2BFDFF |call 00403940
00430DC6 |. 43 |inc ebx
00430DC7 |> 8B45 EC mov eax, dword ptr [ebp-14]
00430DCA |. E8 692BFDFF |call 00403938
00430DCF |. 48 |dec eax
00430DD0 |. 3BD8 |cmp ebx, eax ;计数器比较
00430DD2 |.^ 7C A6 \jl short 00430D7A ;没完就跳上去
呵``还是不用知道它在干啥,因为最后得到"
5533ii5533aa111177nn111199gg110033ww111100uu9977551100
和这串""j53i53a117n119g103w110u975105""比较一下``看不出的就是"八嘎"(笨蛋)
去掉第一位和最后一位之后全部的字符都变两儿了``呵
00430DD4 |. BB 01000000 mov ebx, 1
00430DD9 |. 8D45 EC lea eax, dword ptr [ebp-14]
00430DDC |. E8 DB28FDFF call 004036BC
00430DE1 |. EB 1C jmp short 00430DFF
00430DE3 |> 8D55 E4 /lea edx, dword ptr [ebp-1C]
00430DE6 |. 8B45 F4 |mov eax, dword ptr [ebp-C]
00430DE9 |. 0FB64418 FF |movzx eax, byte ptr [eax+ebx-1]
00430DEE |. E8 8559FDFF |call 00406778
00430DF3 |. 8B55 E4 |mov edx, dword ptr [ebp-1C]
00430DF6 |. 8D45 EC |lea eax, dword ptr [ebp-14]
00430DF9 |. E8 422BFDFF |call 00403940
00430DFE |. 43 |inc ebx
00430DFF |> 8B45 F4 mov eax, dword ptr [ebp-C]
00430E02 |. E8 312BFDFF |call 00403938
00430E07 |. 3BD8 |cmp ebx, eax ;计数器比较
00430E09 |.^ 7C D8 \jl short 00430DE3
``唉``这个CrakcMe就是这么罗嗦,,也不用知道循环在发什么疯了`
循环后得到:
"5353515110510553535151979749494949555511011049494949575710310349494848515111911949494949484811711757575555535349494848"
NND~够罗嗦~~~~
再和"5533ii5533aa111177nn111199gg110033ww111100uu9977551100"这串比较``
看得出来吧~~
把每个字符的十进制ASC都格式化成字符串连到一块了
00430E0B |. BB 03000000 mov ebx, 3 ;3传到ebx
00430E10 |. 8D45 F4 lea eax, dword ptr [ebp-C]
00430E13 |. E8 A428FDFF call 004036BC
00430E18 |. 83FB 30 cmp ebx, 30 ;ebx和0x30比较
00430E1B |. 7D 22 jge short 00430E3F
00430E1D |> 8D45 E4 /lea eax, dword ptr [ebp-1C]
00430E20 |. 8B55 EC |mov edx, dword ptr [ebp-14]
00430E23 |. 8A541A FF |mov dl, byte ptr [edx+ebx-1] ;edx里是那个又长又臭的字符串`,ebx现在是3,减一后就是2,从0开始数,新字符串的第2位取出来
00430E27 |. E8 342AFDFF |call 00403860
00430E2C |. 8B55 E4 |mov edx, dword ptr [ebp-1C]
00430E2F |. 8D45 F4 |lea eax, dword ptr [ebp-C]
00430E32 |. E8 092BFDFF |call 00403940
00430E37 |. 83C3 03 |add ebx, 3 ;ebx+3
00430E3A |. 83FB 30 |cmp ebx, 30 ;和0x30比较
00430E3D |.^ 7C DE \jl short 00430E1D ;小于等于就跳上去
循环后可以得到"511153574945114",
那串字符很长吧``哦呵呵``0x30的十进制为48,每次循环从3的倍数开始字符串中相应的字符,一直到ebx加到大于48,就跳出循环,循环了15次``
00430E3F |> BB 01000000 mov ebx, 1
00430E44 |. EB 5B jmp short 00430EA1
00430E46 |> 8B45 FC /mov eax, dword ptr [ebp-4]
00430E49 |. E8 EA2AFDFF |call 00403938
00430E4E |. 03C3 |add eax, ebx ; 原注册名的长度加上计数器,计数器从一开始
00430E50 |. 8B55 EC |mov edx, dword ptr [ebp-14]
00430E53 |. 8A5402 FD |mov dl, byte ptr [edx+eax-3] ; 根据结果减三后相对应的位置对字符串字符(是那串又长又臭的,别搞错了)
00430E57 |. 8D45 E4 |lea eax, dword ptr [ebp-1C]
00430E5A |. E8 012AFDFF |call 00403860
00430E5F |. 8B45 E4 |mov eax, dword ptr [ebp-1C]
00430E62 |. E8 4159FDFF |call 004067A8
00430E67 |. 50 |push eax
00430E68 |. 8D45 E4 |lea eax, dword ptr [ebp-1C]
00430E6B |. 8B55 F4 |mov edx, dword ptr [ebp-C]
00430E6E |. 8A541A FF |mov dl, byte ptr [edx+ebx-1] ; 从最后字符串中取字符(循环15次得出来的字符串)
00430E72 |. E8 E929FDFF |call 00403860
00430E77 |. 8B45 E4 |mov eax, dword ptr [ebp-1C]
00430E7A |. E8 2959FDFF |call 004067A8
00430E7F |. 5A |pop edx
00430E80 |. 2BC2 |sub eax, edx
00430E82 |. 99 |cdq
00430E83 |. 33C2 |xor eax, edx
00430E85 |. 2BC2 |sub eax, edx
00430E87 |. 8D55 E8 |lea edx, dword ptr [ebp-18]
00430E8A |. E8 E958FDFF |call 00406778
00430E8F |. 8D45 F4 |lea eax, dword ptr [ebp-C]
00430E92 |. E8 712CFDFF |call 00403B08
00430E97 |. 8B55 E8 |mov edx, dword ptr [ebp-18]
00430E9A |. 8A12 |mov dl, byte ptr [edx]
00430E9C |. 885418 FF |mov byte ptr [eax+ebx-1], dl
00430EA0 |. 43 |inc ebx
00430EA1 |> 8B45 F4 mov eax, dword ptr [ebp-C]
00430EA4 |. E8 8F2AFDFF |call 00403938
00430EA9 |. 3BD8 |cmp ebx, eax ; 计数器和最字符串长度比较,
00430EAB |.^ 7E 99 \jle short 00430E46 ; 没算完就跳上去
这个循环比较难说清楚`就拿我输入的注册名来举个例子:
第一次循环
"jiangwu55"->长度9
长度+1=10
10-3=7
从0开始算,从很长的那个字符串里取出第7位,就是'1'
再从"511153574945114"里取出第一位
sprintf(a,"%i",abs(asc('1')-asc('5')))
a就是"4"
最后的格式化也可以:
itoa(abs(atoi('1')-atoi('5')))
是一样的`
00430EAD |. 8B45 F4 mov eax, dword ptr [ebp-C] ;这里ebp-c是真码
00430EB0 |. 8B55 F8 mov edx, dword ptr [ebp-8] ;假码
00430EB3 |. E8 902BFDFF call 00403A48 ;这里比较
00430EB8 |. 75 0A jnz short 00430EC4
00430EBA |. B8 400F4300 mov eax, 00430F40 ; you got it!!! :)
00430EBF |. E8 78DCFFFF call 0042EB3C
00430EC4 |> 33C0 xor eax, eax
00430EC6 |. 5A pop edx
00430EC7 |. 59 pop ecx
00430EC8 |. 59 pop ecx
00430EC9 |. 64:8910 mov dword ptr fs:[eax], edx
00430ECC |. 68 E60E4300 push 00430EE6
00430ED1 |> 8D45 E0 lea eax, dword ptr [ebp-20]
00430ED4 |. BA 08000000 mov edx, 8
00430ED9 |. E8 0228FDFF call 004036E0
00430EDE \. C3 retn
呼````
下面是C注册机:
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <iostream.h>
int main()
{
char name[200],code[200],tempbuf[200],temp[50];
int i,len,k1=6,k2=0,namelen=0;
cout<<"Your Name:";
cin>>name;
len=lstrlen(name);
namelen=len;
for(i=0;i<len;i++)
tempbuf[i]=name[len-i-1];
memset(code,0,sizeof(code)); //code所有元素归零
for(i=0;i<len-1;i++)
{
sprintf(temp,"%c%d",name[i],tempbuf[i]);
lstrcat(code,temp);
}
len=lstrlen(code);
memset(name,0,sizeof(name));
memset(temp,0,sizeof(temp));
for(i=1;i<=len-2;i++)
{
sprintf(temp,"%c%c",code[i],code[i]);
lstrcat(name,temp);
}
len=lstrlen(name);
memset(code,0,sizeof(code));
memset(temp,0,sizeof(temp));
for(i=0;i<len;i++)
{
sprintf(temp,"%d",name[i]);
lstrcat(code,temp);
}
memset(name,0,sizeof(name));
memset(temp,0,sizeof(temp));
for(i=0;i<15;i++)
{
name[i]=code[k1-4];
k1+=3;
}
memset(temp,0,sizeof(temp));
memset(tempbuf,0,sizeof(tempbuf));
len=lstrlen(name);
k1=0;
for(i=0;i<len;i++)
{
k1=code[namelen+i+1-3];
k2=name[i];
if(k1>k2)//---------------------------------------
sprintf(temp,"%i",k1-k2); //
else //直接判断两种情况,不用abs
sprintf(temp,"%i",k2-k1);//---------------
lstrcat(tempbuf,temp);
}
cout<<"Your Serial:"<<tempbuf<<endl;
}
就这样``完了``
----------------------------------------------------------------------------------
└经验总结┐:
呵``原来Crack也不很难,至少这个是这样@@ ^.^``
----------------------------------------------------------------------------------
└版权声明┐ 本文原创于看雪软件安全论坛, 转载请注明作者并保持文章的完整, 谢谢!
2007年4月17日 12:56:47
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课