今天翻电脑偶尔发现一篇很早以前写的crackme破文,是PEDIY CrackMe 2007里面的,偷个懒就不修改了,虽然文章看起来很幼稚,但毕竟是自己动手的,保持原来的好,适合初学者,错误再所难免,请大家不要那东西砸我就好了
这是第二篇
不多说了,言归正转:
有壳,咱是初学,工具吧......
界面出来了。点Check,没反应!随便输入点什么东西再点,还是没反应!!
用OD加载后,查找一下字符串,结果没有找到 ,或者是查找当前模块的API函数,传说中的GetWindowText出现了,毫不犹豫下断点,运行程序,
输入用户名:pediy
注册玛:787878
F9......
停在:
//依据用户名的长度进行运算,不能为空
00401539 |. call <jmp.&USER32.GetDlgItemTextA> ; \GetDlgItemTextA
0040153E |. >mov ebx, eax ; eax=5
00401540 |. >or ebx, ebx
00401542 |. >jnz short 00401548 ; 用户名不能为空
00401544 |. >xor eax, eax
00401546 |. >jmp short 00401598
00401548 |> >mov edi, 2BC
0040154D |. >mov esi, 30
00401552 |. >mov eax, 48
00401557 |. >cdq
00401558 |. >idiv ebx
0040155A |. >sub esi, eax
0040155C |. >lea esi, dword ptr [esi+esi*4] ; 地址=000000AA
0040155F |. >sub edi, esi
00401561 |. >imul edi, edi, 6B
00401564 |. >sub edi, 0CF6C
0040156A |. >cmp edi, 2300
00401570 |. >jg short 0040157A
00401572 |. >cmp edi, 190
00401578 |. >jge short 0040157E
0040157A |> >xor eax, eax
0040157C |. >jmp short 00401598 ;失败推出
0040157E |> >lea eax, dword ptr [ebp-100]
00401584 |. >push eax
00401585 |. >push ebx
00401586 |. >push dword ptr [ebp+8]
00401589 |. >call 00401305 ;关键函数,用户名变形
0040158E |. >add esp, 0C
00401591 |. >or eax, eax ;关键比较,
00401593 |. >je short 00401598
00401595 |. >xor eax, eax
00401597 |. >inc eax
00401598 |> >pop edi
00401599 |. >pop esi
0040159A |. >pop ebx
0040159B |. >leave
0040159C \. >retn
... ... ;好像是数据初始化,省略 ,呵呵。。。
004013BC |. >mov eax, 11CF
004013C1 |. >movzx ecx, byte ptr [ebp-31F] ;好像必须是字母T,有没有其他的自己算吧 ,偷个懒
004013C8 |. >cdq
004013C9 |. >idiv ecx
004013CB |. >cmp edx, 17
004013CE |. >je short 004013D7
004013D0 |. >xor eax, eax
004013D2 |. >jmp 00401504
//对用户名进行逐位相加
004013D7 |> \>xor ebx, ebx
004013D9 |. >jmp short 004013E6
004013DB |> >/mov eax, dword ptr [ebp+10]
004013DE |. >|movsx eax, byte ptr [eax+ebx]
004013E2 |. >|add dword ptr [ebp-4], eax
004013E5 |. >|inc ebx
004013E6 |> > cmp ebx, dword ptr [ebp+C]
004013E9 |.^ >\jl short 004013DB
//用户名变形 后附的数据为用户名的第一个字母
004013EB |. >xor ebx, ebx
004013ED |. >jmp 00401475
004013F2 |> >/mov edx, dword ptr [ebp+10] ; 堆栈 ss:[0012FAD4]=0012FAE4, (ASCII "pediy")
004013F5 |. >|movsx edi, byte ptr [edx+ebx] ; 堆栈 ds:[0012FAE4]=70 ('p')
004013F9 |. >|mov esi, dword ptr [ebp-4] ; 堆栈 ss:[0012FAC0]=0000021B
004013FC |. >|mov ecx, ebx
004013FE |. >|shl ecx, 2 ; ecx=00000000
00401401 |. >|mov edx, ebx ; ebx=00000000
00401403 |. >|inc edx
00401404 |. >|sub ecx, edx ; edx=00000001
00401406 |. >|movzx ecx, byte ptr [ebp+ecx-11F] ; 堆栈 ss:[0012F9A4]=00
0040140E |. >|mov edx, edi ; edi=00000070
00401410 |. >|xor edx, ecx ; ecx=00000000 执行后edx=00000070
00401412 |. >|mov ecx, esi ; esi=0000021B
00401414 |. >|imul ecx, ebx
00401417 |. >|sub ecx, esi ; esi=0000021B ecx=00000000
00401419 |. >|mov esi, ecx ; ecx=FFFFFDE5
0040141B |. >|xor esi, FFFFFFFF
0040141E |. >|lea esi, dword ptr [edx+esi+14D] ; esi=0000021A 执行后esi=000003D7
00401425 |. >|mov ecx, dword ptr [ebp+C] ; 堆栈 ss:[0012FAD0]=00000005
00401428 |. >|mov edx, ebx ; ebx=00000000 edx=00000070
0040142A |. >|add edx, 3
0040142D |. >|imul ecx, edx ; edx=00000003
00401430 |. >|imul ecx, edi ; edi=00000070 ecx=0000000F 执行后ecx=00000690
00401433 |. >|mov eax, esi ; esi=000003D7
00401435 |. >|add eax, ecx ; 执行后eax=00000A67
00401437 |. >|mov ecx, 0A
0040143C |. >|xor edx, edx
0040143E |. >|div ecx ; ecx=0000000A
00401440 |. >|add edx, 30
00401443 |. >|mov byte ptr [ebp+ebx-104], dl ; dl=33 ('3') 堆栈 ss:[0012F9C0]=00
0040144A |. >|movzx edi, byte ptr [ebp+ebx-104] ; 堆栈 ss:[0012F9C0]=33 ('3')
00401452 |. >|xor edi, 0ADAC ; 执行后edi=0000AD9F
00401458 |. >|mov esi, ebx ; ebx=00000000
0040145A |. >|add esi, 2
0040145D |. >|mov eax, edi ; edi=0000AD9F
0040145F |. >|imul eax, esi ; esi=00000002 eax=0000AD9F 执行后eax=00015B3E
00401462 |. >|mov ecx, 0A
00401462 |. >|mov ecx, 0A
00401467 |. >|cdq
00401468 |. >|idiv ecx ; ecx=0000000A
0040146A |. >|add edx, 30 ; edx=00000004 eax=000022B9
0040146D |. >|mov byte ptr [ebp+ebx-104], dl ; dl=34 ('4') 堆栈 ss:[0012F7F0]=33 ('3') 变形后用户名
00401474 |. >|inc ebx ; ebx=00000000
00401475 |> > cmp ebx, dword ptr [ebp+C] ; 堆栈 ss:[0012F900]=00000005 ebx=00000001
00401478 |.^ >\jl 004013F2
//对变换后字符串进行格式化 得到的字串为 ASCII "T42202"
0040147E |. >lea eax, dword ptr [ebp-104]
00401484 |. >push eax
00401485 |. >push 54 ; T
00401487 |. >lea eax, dword ptr [ebp-424]
0040148D |. >push eax ; |Format
0040148E |. >lea eax, dword ptr [ebp-41F] ; |
00401494 |. >push eax ; |s
00401495 |. >call <jmp.&USER32.wsprintfA> ; \wsprintfA
0040149A |. >mov edi, dword ptr [ebp+C] ; 堆栈 ss:[0012F900]=00000005
0040149D |. >mov eax, edi ; edi=00000005
0040149F |. >imul eax, dword ptr [ebp-4] ; 堆栈 ss:[0012F8F0]=0000021B
004014A3 |. >mov ecx, 64
004014A8 |. >cdq
004014A9 |. >idiv ecx ; ecx=00000064 edx=00000000 执行后eax=0000001A edx=0000005F
004014AB |. >mov edi, edx ; edx=0000005F
004014AD |. >add edi, 30
004014B0 |. >push edi ; edi=0000008F 十进制为143
004014B1 |. >lea edi, dword ptr [ebp-41F] ; 堆栈地址=0012F4D5, (ASCII "T42202")
004014B7 |. >push edi
004014B8 |. >lea edi, dword ptr [ebp-42A] ; 堆栈地址=0012F4CA, (ASCII "%s-%d")
004014BE |. >push edi ; |Format
004014BF |. >lea edi, dword ptr [ebp-21F] ; |堆栈地址=0012F6D5
004014C5 |. >push edi ; |s
004014C6 |. >call <jmp.&USER32.wsprintfA> ; \wsprintfA
004014CB |. >add esp, 20 ; 格式化后得到 ASCII "T42202-143"
004014CE |. >lea ecx, dword ptr [ebp-21F] ; 堆栈地址=0012F6D5, (ASCII "T42202-143")
004014D4 |. >or eax, FFFFFFFF
004014D7 |> >/inc eax ; 判断变形后的字串的个数
004014D8 |. >|cmp byte ptr [ecx+eax], 0
004014DC |.^ >\jnz short 004014D7
004014DE |. >push eax ; eax=0000000A
004014DF |. >lea eax, dword ptr [ebp-31F] ; 堆栈地址=0012F5D5, (ASCII "787878")
004014E5 |. >push eax
004014E6 |. >lea eax, dword ptr [ebp-21F] ; 堆栈地址=0012F6D5, (ASCII "T42202-143")
004014EC |. >push eax
004014ED |. >call 004012C2 ;对注册码和用户名进行比较
004012C2 /$ >push ebp
004012C3 |. >mov ebp, esp
004012C5 |. >push ebx
004012C6 |. >push esi
004012C7 |. >push edi
004012C8 |. >mov ebx, dword ptr [ebp+10] ; 堆栈 ss:[0012F4B8]=0000000A
004012CB |. >xor esi, esi
004012CD |. >inc esi ; 执行后 esi=00000001
004012CE |. >jmp short 004012F9
//对变形后的用户名进行运算并与注册码进行比较
004012D0 |> >/mov edx, dword ptr [ebp+8] ; 堆栈 ss:[0012F4B0]=0012F6D5, (ASCII "T42202-143")
004012D3 |. >|movsx edi, byte ptr [edx+esi] ; 堆栈 ds:[0012F6D6]=34 ('4')
004012D7 |. >|mov eax, edi
004012D9 |. >|xor eax, 20 ; eax=00000034 执行后eax=00000014
004012DC |. >|mov ecx, 0A
004012E1 |. >|cdq
004012E2 |. >|idiv ecx ; 执行后 edx=00000000 eax=00000002
004012E4 |. >|mov edi, edx ; edx=00000000
004012E6 |. >|add edi, 30 ; 从4012D7到4012E6对用户名进行二次变形,与用户输入的注册码比较
; 从变形后的用户名的第2位开始:用户名 ^ 20 % a + 30
004012E9 |. >|mov edx, dword ptr [ebp+C] ; 堆栈 ss:[0012F4B4]=0012F5D5, (ASCII "787878")
004012EC |. >|movsx edx, byte ptr [edx+esi] ; 堆栈 ds:[0012F5D6]=38 ('8')
004012F0 |. >|cmp edi, edx
004012F2 |. >|je short 004012F8 ; 关键跳
004012F4 |. >|xor eax, eax
004012F6 |. >|jmp short 00401300
004012F8 |> >|inc esi
004012F9 |> > cmp esi, ebx ; ebx=0000000A esi=00000001
004012FB |.^ >\jl short 004012D0
004012FD |. >xor eax, eax
004012FF |. >inc eax
00401300 |> >pop edi
00401301 |. >pop esi
00401302 |. >pop ebx
00401303 |. >pop ebp
00401304 \. >retn
注册码生成方法:
1、判断用户名不为空 则2
2、判断用户输入的注册码的第一位是T ,则3 //可能还有其他字母,偷懒了,直接在程序中跟踪得到的
3、对用户名的每一位进行变形a
4、使用wsprintf函数对变形的数字串格式化,格式为:wsprintf(szBuff,"%c%s",q,a); //q='T'
5、得到用户名长度,经过计算的到一个值i
6、使用wsprintf函数对变形的数字串第二次格式化,格式为:wsprintf(szBuff,"%s-%d",a,i)
7、源程序中在对第二次格式化后的数据比较时进行第三次变换,而后得到正确的注册码
// 语言学的难,将就着看吧
// pp.cpp : Defines the entry point for the console application.
// vc++6
#include "stdafx.h"
#include <windows.h>
//#include <stdio.h>
//#include <string.h>
int main()
{
char m[256],a[256]="\0",q='T';//m 用户名 a 用户名第一次变形
char b[27]="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int l=0,p=0;
int i,r=0;
//do
//{
printf("请输入用户名:");
scanf("%s",m);
for(i=0;m[i]!='\0';i++) p+=(int)m[i]; //p 用户名进行累加
r=strlen(m);
for(i=0;i<r;i++)
{ //从第一个字母开始进行变形,
int j=0,k;
k=4*i-i-1;
j=i+1;
if(k<0) //如果k值<0
l=0;
else
l=(int)b[k];
l=(l^(int)m[i])+(p*(i-1)^4294967295)+333;//l=(l^(int)m[i])+(p*(i-1)^0xffffffff)+0x14d;
l+=5*(i+3)*(int)m[i];
l=l%10+48; //l=l%0xA+0x30;
l=l%100; //l=l%0x64;
l=(l^44460)*(i+2); //l=(l^0xADAC)*(i+2);
l=l%10+48; //l=l%0xA+0x30;
a[i]=(char)l;
}
LPTSTR szBuff=new TCHAR[1024];
wsprintf(szBuff,"%c%s",q,a); //对第一次变形的用户名格式化
i=strlen(m); //取得用户名长度
i=(i*p)%100+48; //取得用户名长度*用户名字母和%100+48
wsprintf(szBuff,"%s-%d",szBuff,i);//对第二次变形的用户名格式化
for(i=1;szBuff[i]!='\0';i++)
szBuff[i]=(szBuff[i]^32)%10+48;//对第二次变形的用户名再变换 szBuff[i]=(szBuff[i]^0x20)%0xA+0x30;
printf("注册码是: %s \n\n",szBuff);
}
//}while(r<20);
return 0;
}
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!