本帖最后由 zbnysjwsnd8 于 2017-8-16 22:32 编辑
我并不是大神 所以哪里有错误还请大佬们指出。
CM正脸照一张:
预备知识:
xor运算就是二进制运算:
1 xor 1 = 0
0 xor 0 = 0
1 xor 0 = 1
0 xor 1 = 1
可以得知:两者相等为0 不相等为1
如果有c = 100 xor 50
即c = 01100100B(100) xor 00110010B(50) = 01010110B(86)
运算过程如下:
开始调试:
OD载入 GetWindowTextA下断点 F9运行 输入假码 然后点击[Check]
在GetWindowTextA断下后回到程序领空
[Asm] 纯文本查看 复制代码 00401099 |. 6A 0A push 0xA ; /Count = A (10.)
0040109B |. 68 44304000 push Pusillus.00403044 ; |Buffer = Pusillus.00403044
004010A0 |. 68 B80B0000 push 0xBB8 ; |ControlID = BB8 (3000.)
004010A5 |. FF35 54304000 push dword ptr ds:[0x403054] ; |hWnd = 000B073A ('Pusillus Crackme 1.0',class='#32770')
004010AB |. E8 D2000000 call <jmp.&USER32.GetDlgItemTextA> ; \GetDlgItemTextA
004010B0 |. E8 14000000 call Pusillus.004010C9 ;算法部分
004010B5 |> EB 09 jmp short Pusillus.004010C0
F7跟进这个CALL(0x004010C9)
[Asm] 纯文本查看 复制代码 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,0x8 ; 循环八次
004010D5 |. BE 44304000 mov esi,Pusillus.00403044
004010DA |> 8036 32 /xor byte ptr ds:[esi],0x32 ; 注册码的每个字节和0x32异或
004010DD |. 46 |inc esi
004010DE |.^ E2 FA \loopd short Pusillus.004010DA
004010E0 |. BE 44304000 mov esi,Pusillus.00403044
004010E5 |. B9 04000000 mov ecx,0x4 ; 循环4次
004010EA |> 8A06 /mov al,byte ptr ds:[esi] ; 注册码[edi * 2]
004010EC |. 8A5E 01 |mov bl,byte ptr ds:[esi+0x1] ; 注册码[edi * 2 + 1]
004010EF |. 32C3 |xor al,bl ; 注册码[edi * 2] ^ 注册码[edi * 2 + 1]
004010F1 |. 8887 4C304000 |mov byte ptr ds:[edi+0x40304C],al ; 保存
004010F7 |. 83C6 02 |add esi,0x2
004010FA |. 47 |inc edi
004010FB |.^ E2 ED \loopd short Pusillus.004010EA
004010FD |. BE 4C304000 mov esi,Pusillus.0040304C
00401102 |. 8A06 mov al,byte ptr ds:[esi] ; 40304C处的第一个字节
00401104 |. 8A5E 01 mov bl,byte ptr ds:[esi+0x1] ; 40304C处的第二个字节
00401107 |. 32C3 xor al,bl ; 异或
00401109 |. 8A5E 02 mov bl,byte ptr ds:[esi+0x2] ; 40304C处的第三个字节
0040110C |. 8A4E 03 mov cl,byte ptr ds:[esi+0x3] ; 40304C处的第四个字节
0040110F |. 32D9 xor bl,cl ; 异或
00401111 |. 32C3 xor al,bl ; 再一次异或(40304C处的每个字节分别异或)
00401113 |. B9 08000000 mov ecx,0x8 ; 循环八次
00401118 |. BE 44304000 mov esi,Pusillus.00403044
0040111D |> 3006 /xor byte ptr ds:[esi],al ; 和al异或
0040111F |. 46 |inc esi
00401120 |.^ E2 FB \loopd short Pusillus.0040111D
00401122 |. B9 08000000 mov ecx,0x8 ; 循环八次
00401127 |. BE 44304000 mov esi,Pusillus.00403044
0040112C |. BF 08304000 mov edi,Pusillus.00403008 ; 0x71 0x18 0x59 0x1B 0x79 0x42 0x45 0x4C
00401131 |> 8A06 /mov al,byte ptr ds:[esi]
00401133 |. 3A07 |cmp al,byte ptr ds:[edi] ; 比较结果
00401135 |. 75 1D |jnz short Pusillus.00401154 ; 不相等则失败
00401137 |. 46 |inc esi
00401138 |. 47 |inc edi
00401139 |.^ E2 F6 \loopd short Pusillus.00401131
0040113B |. 6A 40 push 0x40 ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
0040113D |. 68 35304000 push Pusillus.00403035 ; |Title = "Crackme 1.0"
00401142 |. 68 10304000 push Pusillus.00403010 ; |Text = "Good Work Cracker"
00401147 |. FF35 54304000 push dword ptr ds:[0x403054] ; |hOwner = 000B073A ('Pusillus Crackme 1.0',class='#32770')
0040114D |. E8 3C000000 call <jmp.&USER32.MessageBoxA> ; \MessageBoxA
00401152 |. EB 17 jmp short Pusillus.0040116B
00401154 |> 6A 30 push 0x30 ; /Style = MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL
00401156 |. 68 35304000 push Pusillus.00403035 ; |Title = "Crackme 1.0"
0040115B |. 68 22304000 push Pusillus.00403022 ; |Text = "Bad Serial, Sorry!"
00401160 |. FF35 54304000 push dword ptr ds:[0x403054] ; |hOwner = 000B073A ('Pusillus Crackme 1.0',class='#32770')
00401166 |. E8 23000000 call <jmp.&USER32.MessageBoxA> ; \MessageBoxA
0040116B |> 5F pop edi ; 0019F184
0040116C |. 5E pop esi ; 0019F184
0040116D |. 59 pop ecx ; 0019F184
0040116E \. C3 retn
计算注册码:
如果写一个程序来计算的话 就是这样:
不过这个代码我看着不舒服 所以我又写了一种:
[C++] 纯文本查看 复制代码 #include <stdio.h>
int main(int argc, char* argv[])
{
unsigned char Key[] = {0x71,0x18,0x59,0x1B,0x79,0x42,0x45,0x4C,0x00,0x00};
unsigned char Data[sizeof(Key) + 1] = {0};
for(int i = 0;i < sizeof(Key) - 2;i++)
Key[i] ^= 0x32;
for(int i = 0;i < (sizeof(Key) - 2) / 2;i++)
Data[i] = Key[2 * i] ^ Key[2 * i + 1];
for(int i = 0;i < sizeof(Key) - 2;i++)
Key[i] ^= Data[0] ^ Data[1] ^ Data[2] ^ Data[3];
printf("%s",Key);
while(1);
return 0;
}
运行效果如图:
附一张成功图和CM源文件:
Pusillus.zip
(1.32 KB, 下载次数: 15)
|