pusi Crackme 1.0 破解 (希望转载的时候保持完整)
【作者】 丁丁虾 ddxia/[CCG]
【E_mail】 ddxia@263.net (如果Crackme教学文章中有错,请来信:))
【Web】 http://go18.163.com/~ddxia
【目标】 pusi Crackme 1.0
【目标URL】 http://go18.163.com/~ddxia/crackme/pusicrackme1.0.zip
【工具】 W32dasm
很久都没有背诗啦!觉的有点对不起泱泱大国五千的文化,也没有这么可怕啦!只是
感到有些惭愧.......呵呵~~~~~~......人总是很矛盾的.......
【年代】:北宋
【作者】:晏几道
【作品】:醉落魄
满街斜月,垂鞭自唱阳关彻。
断尽柔肠思归切,
都为人人,不许多时别。
南桥昨夜风吹雪,
短长亭下征尘歇。
归时定有梅堪折。
欲把离愁,细捻花枝说
这个Crackme界面很简单,就是要求填写一个CODE,然后就检查它是否正确。所以破解
的工具,就是选择W32DASM就可以了。
1、分析代码
:00401099 6A0A
push 0000000A
:0040109B 6844304000 push 00403044
----》存放我们输入CODE的地址
:004010A0 68B80B0000 push 00000BB8
:004010A5 FF3554304000 push dword ptr
[00403054]
* Reference To: USER32.GetDlgItemTextA, Ord:0102h
|
:004010AB E8D2000000 Call 00401182
----》调用 GetDlgItemTextA
:004010B0 E814000000 call 004010C9
----》进行比较判断
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401097(C)
|
:004010B5 EB09
jmp 004010C0
:004010C9 56
push esi
:004010CA 57
push edi
:004010CB 51
push ecx
:004010CC 33F6
xor esi, esi
:004010CE 33FF
xor edi, edi
:004010D0 B908000000 mov ecx,
00000008 ----》只对前8个CODE进行操作
:004010D5 BE44304000 mov esi,
00403044 ----》存放fake code地址
:004010DA 803632
xor byte ptr [esi], 32
:004010DD 46
inc esi
:004010DE E2FA
loop 004010DA ----》循环8次 CODE XOR 32
:004010E0 BE44304000 mov esi,
00403044 ----》XOR后的结果地址
:004010E5 B904000000 mov ecx,
00000004 ----》循环4次
:004010EA 8A06
mov al, byte ptr [esi] --》取第1个CODE
:004010EC 8A5E01
mov bl, byte ptr [esi+01]-》取第2个CODE
:004010EF 32C3
xor al, bl ----》进行XOR
:004010F1 88874C304000 mov byte ptr
[edi+0040304C], al -》将结果存放到0040304C
:004010F7 83C602
add esi, 00000002 ----》跳到第3个CODE
:004010FA 47
inc edi ----》结果指针加1
:004010FB E2ED
loop 004010EA
:004010FD BE4C304000 mov esi,
0040304C ----》上面计算出4位结果
:00401102 8A06
mov al, byte ptr [esi] --》取出第1位
:00401104 8A5E01
mov bl, byte ptr [esi+01]-》取出第2位
:00401107 32C3
xor al, bl ----》第1位XOR第2位
:00401109 8A5E02
mov bl, byte ptr [esi+02]-》取出第3位
:0040110C 8A4E03
mov cl, byte ptr [esi+03]-》取出第4位
:0040110F 32D9
xor bl, cl ----》第3位XOR第4位
:00401111 32C3
xor al, bl ----》1^2结果XOR3^4结果
:00401113 B908000000 mov ecx,
00000008 ----》循环8次
:00401118 BE44304000 mov esi,
00403044 ----》经过XOR32的结果
:0040111D 3006
xor byte ptr [esi], al --》(经过XOR32的结果)XOR(1^2结果XOR3^4结果)
:0040111F 46
inc esi
:00401120 E2FB
loop 0040111D
:00401122 B908000000 mov ecx,
00000008
:00401127 BE44304000 mov esi,
00403044 ----》经过变化的结果地址
* Possible StringData Ref from Data Obj ->"qYyBELGood Work Cracker"
|
:0040112C BF08304000 mov edi,
00403008 ----》进行比较的字节地址
[403008] 71 18 59 1B 79 42 45 4C
:00401131 8A06
mov al, byte ptr [esi]
:00401133 3A07
cmp al, byte ptr [edi]
:00401135 751D
jne 00401154 ----》如果不相等就GAME OVER
:00401137 46
inc esi
:00401138 47
inc edi
:00401139 E2F6
loop 00401131
:0040113B 6A40
push 00000040 ----》成功的对话框
* Possible StringData Ref from Data Obj ->"Crackme 1.0"
|
:0040113D 6835304000 push 00403035
:00401142 6810304000 push 00403010
:00401147 FF3554304000 push dword ptr
[00403054]
* Reference To: USER32.MessageBoxA, Ord:01BBh
|
:0040114D E83C000000 Call 0040118E
:00401152 EB17
jmp 0040116B
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401135(C)
|
:00401154 6A30
push 00000030 -----》失败的对话框
* Possible StringData Ref from Data Obj ->"Crackme 1.0"
|
:00401156 6835304000 push 00403035
* Possible StringData Ref from Data Obj ->"Bad Serial, Sorry!"
|
:0040115B 6822304000 push 00403022
:00401160 FF3554304000 push dword ptr
[00403054]
* Reference To: USER32.MessageBoxA, Ord:01BBh
|
:00401166 E823000000 Call 0040118E
2、AcTion
Crack的第一大大招,乾坤大挪移,
:00401133 3A07
cmp al, byte ptr [edi]
:00401135 751D
jne 00401154 ----》如果不相等就GAME OVER
^^^^^^^^^^^^---》修改为nop nop (9090)
太简单了!!!收工 (众人倒.........口吐白沫.........:)
呵呵~~~~~~~~
想一想我们如何通过编程,计算出正确的结果。开始的时候,我也懵了,不知道
如何下手,虽然上面的分析头头是道,但编写KeyGen是第二次哦!!(若有什么不正确的地
方,请告诉我:)
左看右看,上想下思,终于找到一个突破口。呵呵~~~~~ 在哪里呢????
:00401113 B908000000 mov ecx,
00000008 ----》循环8次
:00401118 BE44304000 mov esi,
00403044 ----》经过XOR32的结果
:0040111D 3006
xor byte ptr [esi], al --》(经过XOR32的结果)XOR(1^2结果XOR3^4结果)
:0040111F 46
inc esi
:00401120 E2FB
loop 0040111D
xor byte ptr [esi], al----》就是这句啦!al 的值,如果按上面,用数学公式
逆推的化,我肯定要晕,想想当年数学能过就OK了 呵呵~~~~~ 想不到,如今确要用上。读书
的时候,什么都多学一点,今天看来并不坏 :)
COME ON!我们可以采用穷尽法,al (0x00--> 0xFF)也就是255次,不多不多:)
于是第一次就写出下面这个程序,目的就是让最后要比较的结果XOR al XOR 0x32,循环255
次,并把结果显示出来,筛一筛,看一看,合法的字符有没有 :)
#include <stdio.h>
unsigned char Table[8] = { 0x71,0x18,0x59,0x1B,0x79,0x42,0x45,0x4C};
unsigned char Code[8];
void main(void)
{
unsigned char i=0x00;
int n;
do
{
for(n=0;n<8;n++)
Code[n]=Table[n]^i^0x32 ;
printf("Code output: %s\n",Code);
i++;
} while(i < 0xFF);
}
呵呵~~~~ 看了几分钟结果,有点运气,找到了正确的CODE:Z3r0Ring ---》因为它
太眼熟了(外国的一位有名的CRACK大师) :)
收工!!(被众人群殴.........鼻青脸肿.....成了虾总......晕倒.......)
既然我们能计算出正确的CODE,何不按照程序的计算方法,编程成程序,再按分析
代码的情况,计算一番。于是就有了以下的程序 呵呵~~~~~
#include <stdio.h>
unsigned char Table[8] = { 0x71,0x18,0x59,0x1B,0x79,0x42,0x45,0x4C};
unsigned char Code[12];
unsigned char Temp[9];
void main(void)
{
unsigned char i=0x00;
unsigned char x;
int n;
Temp[8]=NULL;
do
{
for(n=0;n<8;n++) {
Code[n]=Table[n]^i^0x32 ;
//穷尽法计算出CODE
Temp[n]=Code[n];
//临时存放
}
//+++++++++++++++++++++++++++++++++++++++++++++++++
//:004010D0 mov ecx, 00000008
----》只对前8个CODE进行操作
//:004010D5 mov esi, 00403044
----》存放fake code地址
//:004010DA xor byte ptr [esi],
32
//:004010DD inc esi
//:004010DE loop 004010DA
----》循环8次 CODE XOR 32
//+++++++++++++++++++++++++++++++++++++++++++++++++
for(n=0;n<8;n++)
Code[n]=Code[n]^0x32;
//+++++++++++++++++++++++++++++++++++++++++++++++++
//:004010EA mov al, byte
ptr [esi] --》取第1个CODE
//:004010EC mov bl, byte
ptr [esi+01]-》取第2个CODE
//:004010EF xor al, bl
----》进行XOR
//:004010F1 mov byte
ptr [edi+0040304C], al -》将结果存放到0040304C
//:004010F7 add esi,
00000002 ----》跳到第3个CODE
//:004010FA inc edi
----》结果指针加1
//:004010FB loop 004010EA
//+++++++++++++++++++++++++++++++++++++++++++++++++
for(n=0;n<4;n++)
Code[8+n]=Code[n*2]^Code[n*2+1];
//+++++++++++++++++++++++++++++++++++++++++++++++++
//:004010FD mov
esi, 0040304C ----》上面计算出4位结果
//:00401102 mov
al, byte ptr [esi] --》取出第1位
//:00401104 mov
bl, byte ptr [esi+01]-》取出第2位
//:00401107 xor
al, bl ----》第1位XOR第2位
//:00401109 mov
bl, byte ptr [esi+02]-》取出第3位
//:0040110C mov
cl, byte ptr [esi+03]-》取出第4位
//:0040110F xor
bl, cl ----》第3位XOR第4位
//:00401111 xor
al, bl ----》1^2结果XOR3^4结果
//+++++++++++++++++++++++++++++++++++++++++++++++++
x=(Code[8]^Code[9])^(Code[10]^Code[11]);
Code[8]=NULL;
//+++++++++++++++++++++++++++++++++++++++++++++++++
//:00401113
mov ecx, 00000008 ----》循环8次
//:00401118
mov esi, 00403044 ----》经过XOR32的结果
//:0040111D
xor byte ptr [esi], al --》(经过XOR32的结果)XOR(1^2结果XOR3^4结果)
//:0040111F
inc esi
//:00401120
loop 0040111D
//:00401122
mov ecx, 00000008
//:00401127
mov esi, 00403044 ----》经过变化的结果地址
//
//* Possible StringData Ref from Data Obj ->"qYyBELGood Work Cracker"
//
|
//:0040112C
mov edi, 00403008 ----》进行比较的字节地址
//
[403008] 71 18 59 1B 79 42 45 4C
//
//:00401131
mov al, byte ptr [esi]
//:00401133
cmp al, byte ptr [edi]
//:00401135
jne 00401154 ----》如果不相等就GAME OVER
//:00401137
inc esi
//:00401138
inc edi
//:00401139
loop 00401131
//+++++++++++++++++++++++++++++++++++++++++++++++++
for(n=0;n<8;n++){
if (Table[n] != (Code[n]^x)) break;
if (n==7) printf("Code output:
%s\n",Temp);
}
i++;
} while(i < 0xFF);
}
3总结:穷尽法在写注册机中可是经常用的。关键是如何寻找到穷尽什么东东,然后
再反过来证明,直至得到最后的结果。
收工可以啦吧 !!! 呵呵~~~~~~ (啊没有时间啦!我要出去玩了:))
时间:2000.10.27
23:29
- 标 题:周末灌水篇 (11千字)
- 作 者:丁丁虾
- 时 间:2000-10-28 12:19:2
- 链 接:http://bbs.pediy.com