这个crackme忘了在哪里下载的了,没有加壳,算法也很简单,不过要想弄出注册码还得动下脑筋(主要是要熟悉xor运算)。O(∩_∩)O~
列出关键代码:
004010C9 /$ 56 push esi
004010CA |. 57 push edi
004010CB |. 51 push ecx
004010CC |. 33F6 xor esi, esi
004010CE |. 33FF xor edi, edi
004010D0 |. B9 08000000 mov ecx, 8
004010D5 |. BE 44304000 mov esi, 00403044 ; 输入的8个字节 记为a[i] i=0...7
004010DA |> 8036 32 /xor byte ptr [esi], 32 ; b[i] <-- a[i] xor 0x32 i=0...7
004010DD |. 46 |inc esi
004010DE |.^ E2 FA \loopd short 004010DA
004010E0 |. BE 44304000 mov esi, 00403044
004010E5 |. B9 04000000 mov ecx, 4
004010EA |> 8A06 /mov al, byte ptr [esi]
004010EC |. 8A5E 01 |mov bl, byte ptr [esi+1]
004010EF |. 32C3 |xor al, bl
004010F1 |. 8887 4C304000 |mov byte ptr [edi+40304C], al
004010F7 |. 83C6 02 |add esi, 2
004010FA |. 47 |inc edi
004010FB |.^ E2 ED \loopd short 004010EA
004010FD |. BE 4C304000 mov esi, 0040304C
00401102 |. 8A06 mov al, byte ptr [esi]
00401104 |. 8A5E 01 mov bl, byte ptr [esi+1]
00401107 |. 32C3 xor al, bl
00401109 |. 8A5E 02 mov bl, byte ptr [esi+2]
0040110C |. 8A4E 03 mov cl, byte ptr [esi+3]
0040110F |. 32D9 xor bl, cl
00401111 |. 32C3 xor al, bl ; al <-- b[0] xor b[1] xor... b[7]
00401113 |. B9 08000000 mov ecx, 8
00401118 |. BE 44304000 mov esi, 00403044
0040111D |> 3006 /xor byte ptr [esi], al ; c[i] <-- b[i] xor al i=0...7
0040111F |. 46 |inc esi
00401120 |.^ E2 FB \loopd short 0040111D
00401122 |. B9 08000000 mov ecx, 8
00401127 |. BE 44304000 mov esi, 00403044
0040112C |. BF 08304000 mov edi, 00403008
00401131 |> 8A06 /mov al, byte ptr [esi]
00401133 |. 3A07 |cmp al, byte ptr [edi] ; 逐字节比较
00401135 |. 75 1D |jnz short 00401154
00401137 |. 46 |inc esi
00401138 |. 47 |inc edi
00401139 |.^ E2 F6 \loopd short 00401131
0040113B |. 6A 40 push 40 ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
0040113D |. 68 35304000 push 00403035 ; |Title = "Crackme 1.0"
00401142 |. 68 10304000 push 00403010 ; |Text = "Good Work Cracker"
00401147 |. FF35 54304000 push dword ptr [403054] ; |hOwner = 000B0382 ('Pusillus Crackme 1.0',class='#32770')
0040114D |. E8 3C000000 call <jmp.&USER32.MessageBoxA> ; \MessageBoxA
00401152 |. EB 17 jmp short 0040116B
00401154 |> 6A 30 push 30 ; /Style = MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL
00401156 |. 68 35304000 push 00403035 ; |Title = "Crackme 1.0"
0040115B |. 68 22304000 push 00403022 ; |Text = "Bad Serial, Sorry!"
00401160 |. FF35 54304000 push dword ptr [403054] ; |hOwner = 000B0382 ('Pusillus Crackme 1.0',class='#32770')
00401166 |. E8 23000000 call <jmp.&USER32.MessageBoxA> ; \MessageBoxA
0040116B |> 5F pop edi
0040116C |. 5E pop esi
0040116D |. 59 pop ecx
0040116E \. C3 retn
算法分析:
输入为8字节字符,记为a[0...7],
b[i] <-- a[i] xor 0x32, i=0...7, al <-- b[0] xor b[1] xor ... b[7],
c[i] <-- b[i] xor al, i=0...7,
然后c[0...7]与 “71 18 59 1B 79 42 45 4C”逐字节比较,全部相等则注册成功。
想找到注册码,必须要知道al。al该如何计算呢
熟悉xor运算就可以知道了 O(∩_∩)O~
c[0] xor c[1] xor ... c[7]
=(b[0] xor al) xor (b[1] xor al) xor ... (b[7] xor al)
=(b[0] xor b[1] xor ... b[7]) xor (al xor al xor ... al) (8个al异或=0)
=(b[0] xor b[1] xor ... b[7]) xor 0
=b[0] xor b[1] xor ... b[7]
=al
所以 al = c[0] xor c[1] xor ... c[7]
好了,虽然算法简单,不过本人比较懒,不想手算,写了个程序算出注册码,代码如下:
#include <stdio.h>
#include <windows.h>
int main()
{
unsigned char ch[8]=
{0x71,0x18,0x59,0x1b,0x79,0x42,0x45,0x4c};
unsigned char t = 0;
int i;
for (i=0; i<8; i++)
t ^= ch[i];
for (i=0; i<8; i++)
{
ch[i] ^= t;
ch[i] ^= 0x32;
printf("%c",ch[i]);
} //运行结果为Z3r0Ring
printf("\n");
system("PAUSE");
return 0;
}
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课