首先祝大家七夕节快乐!
为什么说这个KeygenMe好玩呢?不是因为它的代码好玩,汇编代码在大部分眼里都比较枯燥。
说它好玩的原因,是因为完成它的全部过程很有意思。
话说今天闲得无聊,没情人的情人节就像一条汇编指令NOP,根本用不着je还是jne来判断,于是又来到了看雪上。总想在今天做点什么,顺手就打开了crackmes.de网站,本来是不打算破解的,但是找了一下,居然发现有一个已经发布快半个月了,还没有人提交作品,于是激情又来了。
附件 81686
http://www.crackmes.de/users/dark_pu...le_keygenme_1/
废话就不多说了,直接 上正题吧。
分析 完一遍,发现这个KeygenMe也没有想象中的那么难,用户名可以随便写,只要符合前面的跳转要求就行了,因为后面根本 就没用到它。Serial的算法也不是好麻烦 ,没有多余的Call,那到底是为什么没有人提交 呢?肯定 有问题,于是又到那个网站 上去看,发现这样一条信息。
This is a KeygenMe right ? so making some patches won't get you anywhere =) .
Your mission is to make a valid Keygen that will generate a random serial, coding the keygen may get a little harder.
作者说编写 keygen有点困难,我一想,有这个可能,因为计算过程中存在不定的数据,所以要能够编写一个真正的Keygen,麻烦还是有的。但是难道就这样放弃了,怎么能甘心啊,反正无聊,于是就继续 想。
我思考 了一下,想到只有用随机数才有可能解决这个不定向的数据问题,于是就写出了这样的代码
经过 调试后,得到 了正确的结果:
附件 81685
如:
ITS-=111-O)qZ-231<-4:13
ITS-7342-O9e^-42:2-2817
ITS-6622-O6]S-:251-8631
ITS-3391-O!xY-133;-1764
ITS-122;-O$[?-1674-1=22
ITS-3139-O!vW-7146-2772
ITS-4453-O5rg-1575-1<41
ITS-2:31-O"qS-5292-11<4
ITS-9214-O$eI-4671-5463
ITS-1168-O9[T-8532-8316
ITS-5524-O:|v-1845-6426
ITS-3292-O8^V-61:1-9423
ITS-4318-O-jW-6552-1>12
ITS-8242-O.dR-113=-13=1
ITS-2554-O5nc-3753-<222
ITS-5371-O3j]-2871-1791
ITS-1267-O?nm-1359-7272
ITS-9511-O#^A-4266-2655
ITS-4129-O'dK-31;3-51:2
ITS-2:22-O9ng-4329-<213
在这里面随便选了一个,注册成功了:D:
附件 81688
由于 本人英语太菜,因此就不发到那个网站 上去了,就发到看雪 上吧,算是七夕的一个纪念。:o:
总结:1、不要被表面吓倒,有压力才有动力
2、复习了获取“随机数”的方法,由于记忆力差,以前知道了又搞忘了。
3、调试过ARM程序才知道OD调试windows程序有多么爽。
为什么说这个KeygenMe好玩呢?不是因为它的代码好玩,汇编代码在大部分眼里都比较枯燥。
说它好玩的原因,是因为完成它的全部过程很有意思。
话说今天闲得无聊,没情人的情人节就像一条汇编指令NOP,根本用不着je还是jne来判断,于是又来到了看雪上。总想在今天做点什么,顺手就打开了crackmes.de网站,本来是不打算破解的,但是找了一下,居然发现有一个已经发布快半个月了,还没有人提交作品,于是激情又来了。
附件 81686
http://www.crackmes.de/users/dark_pu...le_keygenme_1/
废话就不多说了,直接 上正题吧。
代码:
00401000 >/$ 6A 00 push 0 ; /Style = MB_OK|MB_APPLMODAL
00401002 |. 68 00304000 push 00403000 ; |Title = "ItSecurity.ma KeygenMe (RESTRICTED PATCHING)"
00401007 |. 68 2D304000 push 0040302D ; |Text = "Itsecurity.ma KeygenME Coded by Souhail Hammou ..."
0040100C |. 6A 00 push 0 ; |hOwner = NULL
0040100E |. E8 19020000 call <jmp.&user32.MessageBoxA> ; \MessageBoxA
00401013 |. 68 60304000 push 00403060 ; ASCII "Please type your e-mail: "
00401018 |. E8 17020000 call 00401234
0040101D |. 68 C8000000 push 0C8
00401022 |. 68 60314000 push 00403160 ; ASCII "123456@"
00401027 |. E8 40020000 call 0040126C
0040102C |. 8D05 60314000 lea eax, dword ptr [403160]
00401032 |. 33D2 xor edx, edx
00401034 |. 33C9 xor ecx, ecx
00401036 |> 8A18 /mov bl, byte ptr [eax]
00401038 |. 80FB 40 |cmp bl, 40
0040103B |. 74 0C |je short 00401049 ; 比较是否为邮箱的特殊符号‘@’
0040103D |. 38D3 |cmp bl, dl
0040103F |. 0F84 A6010000 |je 004011EB ; 判断字符串是否结束
00401045 |. 41 |inc ecx
00401046 |. 40 |inc eax
00401047 |.^ EB ED \jmp short 00401036
00401049 |> 80F9 03 cmp cl, 3 ; 判断长度是否小于3,小于三则退出
0040104C |. 0F8E B9010000 jle 0040120B
00401052 |. 68 7A304000 push 0040307A ; ASCII "Please Enter a valid serial: "
00401057 |. E8 D8010000 call 00401234
0040105C |. 68 C8000000 push 0C8
00401061 |. 68 84414000 push 00404184 ; ASCII "ITS-9124-O790-8523-8523"
00401066 |. E8 01020000 call 0040126C ; 输入Serial
0040106B |. 68 84414000 push 00404184 ; /String = "ITS-9124-O790-8523-8523"
00401070 |. E8 C3020000 call <jmp.&kernel32.lstrlenA> ; \lstrlenA
00401075 |. 83F8 17 cmp eax, 17 ; 比较Serial的长度是否等于0x17,不等于则退出
00401078 |. 0F85 4D010000 jnz 004011CB
0040107E |. 8D05 84414000 lea eax, dword ptr [404184]
00401084 |. 33DB xor ebx, ebx
00401086 |. 8B18 mov ebx, dword ptr [eax]
00401088 |. 81FB 4954532D cmp ebx, 2D535449 ; 字符串前面4个为固定字串—"ITS-"
0040108E |. 0F85 37010000 jnz 004011CB
00401094 |. 83C0 08 add eax, 8
00401097 |. 8038 2D cmp byte ptr [eax], 2D ; 判断第8位是否为分隔符“-”
0040109A |. 0F85 2B010000 jnz 004011CB
004010A0 |. 33C9 xor ecx, ecx
004010A2 |. 33D2 xor edx, edx
004010A4 |. B1 03 mov cl, 3
004010A6 |. B2 05 mov dl, 5 ; 隔5个判断一次
004010A8 |> 03C2 /add eax, edx
004010AA |. FEC9 |dec cl
004010AC |. 8038 2D |cmp byte ptr [eax], 2D ; 判断当前指针所指向值是否为“-”
004010AF |.^ 74 F7 \je short 004010A8
004010B1 |. 80F9 00 cmp cl, 0 ; 如果出现次数不等于3-1=2次,说明不合规则,退出
004010B4 |. 0F85 11010000 jnz 004011CB
004010BA |. 8D05 84414000 lea eax, dword ptr [404184]
004010C0 |. 83C0 04 add eax, 4 ; 跳过前面4个字符
004010C3 |. 8B18 mov ebx, dword ptr [eax] ; 取第一个分隔符后面4字节数据,放入变量num1中
004010C5 |. 8D0D A8514000 lea ecx, dword ptr [4051A8]
004010CB |. 8919 mov dword ptr [ecx], ebx
004010CD |. 83C0 05 add eax, 5
004010D0 |. 8B18 mov ebx, dword ptr [eax] ; 取第二个分隔符后面4个字节的数据,放入变量num2中
004010D2 |. 8D0D CC614000 lea ecx, dword ptr [4061CC]
004010D8 |. 8919 mov dword ptr [ecx], ebx
004010DA |. 83C0 05 add eax, 5
004010DD |. 8B18 mov ebx, dword ptr [eax] ; 取第三个分隔符后面4字节数据,放入变量num3中
004010DF |. 8D0D F0714000 lea ecx, dword ptr [4071F0]
004010E5 |. 8919 mov dword ptr [ecx], ebx
004010E7 |. 83C0 05 add eax, 5
004010EA |. 8B18 mov ebx, dword ptr [eax] ; 取第四个分隔符后面4字节数据,放入变量num4中
004010EC |. 8D0D 14824000 lea ecx, dword ptr [408214]
004010F2 |. 8919 mov dword ptr [ecx], ebx
004010F4 |. 33C0 xor eax, eax ; 清零寄存器,为后面运算做准备
004010F6 |. 33DB xor ebx, ebx
004010F8 |. 33D2 xor edx, edx
004010FA |. 33C9 xor ecx, ecx
004010FC |. 8D05 A8514000 lea eax, dword ptr [4051A8] ; 取num1字符串
00401102 |. 8B00 mov eax, dword ptr [eax]
00401104 |. 2D 30303030 sub eax, 30303030 ; num1=num1-0x30303030,即以数字0为基础
00401109 |. 8D15 A8514000 lea edx, dword ptr [4051A8]
0040110F |. 8902 mov dword ptr [edx], eax
00401111 |. 8A1A mov bl, byte ptr [edx] ; 取num1中的低8位数值,记为变量a
00401113 |. 8A4A 01 mov cl, byte ptr [edx+1] ; 取num1中的9-16位的数值,记为变量b
00401116 |. 02D9 add bl, cl ; a=a+b
00401118 |. 8A4A 02 mov cl, byte ptr [edx+2] ; 取num1中的17-24位的数值,记为变量c
0040111B |. 02D9 add bl, cl ; a=a+c
0040111D |. 8A4A 03 mov cl, byte ptr [edx+3] ; 取num1中的25-32位的数值,记为变量d
00401120 |. 02D9 add bl, cl ; a=a+d
00401122 |. 80FB 10 cmp bl, 10 ; 判断各位相加后是否等于0x10
00401125 |. 0F85 A0000000 jnz 004011CB
0040112B |. 8D15 CC614000 lea edx, dword ptr [4061CC] ; 取num2字符串
00401131 |. 8A1A mov bl, byte ptr [edx] ; 取num2的第一个字符,记为a
00401133 |. 80FB 4F cmp bl, 4F ; 判断是否等于字母 “O”
00401136 |. 0F85 8F000000 jnz 004011CB
0040113C |. 8A4A 01 mov cl, byte ptr [edx+1] ; 取num2的第二个字符,记为b
0040113F |. 02D9 add bl, cl ; a=a+b
00401141 |. 8A4A 02 mov cl, byte ptr [edx+2] ; 取num2的第三个字符,记为c
00401144 |. 02D9 add bl, cl ; a=a+c
00401146 |. 8A4A 03 mov cl, byte ptr [edx+3] ; 取num2的第四个字符,记为d
00401149 |. 2AD9 sub bl, cl ; a=a-d
0040114B |. 80FB 8F cmp bl, 8F ; 判断a的值是否等于0x8F
0040114E |. 75 7B jnz short 004011CB
00401150 |. 8D05 F0714000 lea eax, dword ptr [4071F0] ; 取num3字符串
00401156 |. 8B00 mov eax, dword ptr [eax]
00401158 |. 2D 30303030 sub eax, 30303030 ; num3=num3-0x30303030
0040115D |. 8D15 F0714000 lea edx, dword ptr [4071F0]
00401163 |. 8902 mov dword ptr [edx], eax
00401165 |. 8A1A mov bl, byte ptr [edx] ; 取num3中的低8位数值,记为变量a
00401167 |. 8A4A 01 mov cl, byte ptr [edx+1] ; 取num3中的9-16位的数值,记为变量b
0040116A |. 02D9 add bl, cl ; a=a+b
0040116C |. 8A4A 02 mov cl, byte ptr [edx+2] ; 取num3中的17-24位的数值,记为变量c
0040116F |. 02D9 add bl, cl ; a=a+c
00401171 |. 8A4A 03 mov cl, byte ptr [edx+3] ; 取num3中的25-32位的数值,记为变量d
00401174 |. 80E9 02 sub cl, 2 ; d=d-2
00401177 |. 02D9 add bl, cl ; a=a+d
00401179 |. 80FB 10 cmp bl, 10 ; 判断所得的结果是否等于0x10
0040117C |. 75 4D jnz short 004011CB
0040117E |. 8D05 14824000 lea eax, dword ptr [408214] ; 取num4字符串
00401184 |. 8B00 mov eax, dword ptr [eax]
00401186 |. 2D 30303030 sub eax, 30303030 ; num4=num4-0x30303030
0040118B |. 8D15 14824000 lea edx, dword ptr [408214]
00401191 |. 8902 mov dword ptr [edx], eax
00401193 |. 8A1A mov bl, byte ptr [edx] ; 取num4中的低8位数值,记为变量a
00401195 |. 8A4A 01 mov cl, byte ptr [edx+1] ; 取num4中的9-16位的数值,记为变量b
00401198 |. 02D9 add bl, cl ; a=a+b
0040119A |. 8A4A 02 mov cl, byte ptr [edx+2] ; 取num4中的17-24位的数值,记为变量c
0040119D |. 02D9 add bl, cl ; a=a+c
0040119F |. 8A4A 03 mov cl, byte ptr [edx+3] ; 取num4中的25-32位的数值,记为变量d
004011A2 |. 02D9 add bl, cl ; a=a+d
004011A4 |. 80FB 12 cmp bl, 12 ; 判断运算结果是否等于0x12
004011A7 |. 75 22 jnz short 004011CB ; 等于则注册成功,否则注册失败
This is a KeygenMe right ? so making some patches won't get you anywhere =) .
Your mission is to make a valid Keygen that will generate a random serial, coding the keygen may get a little harder.
作者说编写 keygen有点困难,我一想,有这个可能,因为计算过程中存在不定的数据,所以要能够编写一个真正的Keygen,麻烦还是有的。但是难道就这样放弃了,怎么能甘心啊,反正无聊,于是就继续 想。
我思考 了一下,想到只有用随机数才有可能解决这个不定向的数据问题,于是就写出了这样的代码
代码:
#include <stdlib.h>
#include <iostream>
#include <conio.h>
#include <time.h>
int GetRand()
{
int b;
b=rand()%126;
if(b<=0x20)
b+=0x20;
return b;
}
void main()
{
int a,b,c,d,i;
char aa='O';
char xx[]="ITS-";//第一组数据
srand( (unsigned)time( NULL ) );
for(i=0;i<10;i++)
{
printf("%s",xx);
while(1)//第 二 组 数 据
{
a=GetRand();
b=GetRand();
c=GetRand();
d=GetRand();
if(((a-0x30)>0&&(b-0x30)>0&&(c-0x30)>0&&(d-0x30)>0))
{
if(((a-0x30)+(b-0x30)+(c-0x30)+(d-0x30))==0x10)
{
printf("%c%c%c%c-",a,b,c,d);
break;
}
}
}
while(1)//第三组数据
{
b=GetRand();
c=GetRand();
d=GetRand();
if(b>0&&c>90&&d>0)
{
if((aa+b+c-d)==0x8F)
{
printf("%c%c%c%c-",aa,b,c,d);
break;
}
}
}
while(1)//第 四 组 数 据
{
a=GetRand();
b=GetRand();
c=GetRand();
d=GetRand();
if(((a-0x30)>0&&(b-0x30)>0&&(c-0x30)>0&&(d-0x30)>0))
{
if(((a-0x30)+(b-0x30)+(c-0x30)+(d-0x30-2))==0x10)
{
printf("%c%c%c%c-",a,b,c,d);
break;
}
}
}
while(1)//第 五 组 数 据
{
a=GetRand();
b=GetRand();
c=GetRand();
d=GetRand();
if(((a-0x30)>0&&(b-0x30)>0&&(c-0x30)>0&&(d-0x30)>0))
{
if(((a-0x30)+(b-0x30)+(c-0x30)+(d-0x30))==0x12)
{
printf("%c%c%c%c\n",a,b,c,d);
break;
}
}
}
}
}
附件 81685
如:
ITS-=111-O)qZ-231<-4:13
ITS-7342-O9e^-42:2-2817
ITS-6622-O6]S-:251-8631
ITS-3391-O!xY-133;-1764
ITS-122;-O$[?-1674-1=22
ITS-3139-O!vW-7146-2772
ITS-4453-O5rg-1575-1<41
ITS-2:31-O"qS-5292-11<4
ITS-9214-O$eI-4671-5463
ITS-1168-O9[T-8532-8316
ITS-5524-O:|v-1845-6426
ITS-3292-O8^V-61:1-9423
ITS-4318-O-jW-6552-1>12
ITS-8242-O.dR-113=-13=1
ITS-2554-O5nc-3753-<222
ITS-5371-O3j]-2871-1791
ITS-1267-O?nm-1359-7272
ITS-9511-O#^A-4266-2655
ITS-4129-O'dK-31;3-51:2
ITS-2:22-O9ng-4329-<213
在这里面随便选了一个,注册成功了:D:
附件 81688
由于 本人英语太菜,因此就不发到那个网站 上去了,就发到看雪 上吧,算是七夕的一个纪念。:o:
总结:1、不要被表面吓倒,有压力才有动力
2、复习了获取“随机数”的方法,由于记忆力差,以前知道了又搞忘了。
3、调试过ARM程序才知道OD调试windows程序有多么爽。