猜数记---BCWIPE注册半破解
作者:Fpc
目标:取得注册码
软件名称:BCWipe v2.34.2
主页:www.jetico.com
简介:外壳扩展程序,用于完全抹除磁盘上的敏感信息,使它人无法恢复(当然自己也不能,所以要小心呀。)
前几天贴过暴破注册的方法,但遇到有注册码输入而没追出,感觉实在是不舒服。今天又追了一次,没有完全成功,但已经可以注册了。‘猜数记’就来源于此,注册码是一点点试出来的,有点搞笑。
原因就在于,作者不是那么笨。BW先判断输入的注册码(Irc)格式是否正确,接下来将Irc中各字符变为32进制数,作变换与两个给定的字串比较,若不等则注册失败。
它的格式是“WP-####-####-####-####”,“#”可以是数字或字母。
首先给出一个有效的注册码“WP-1234-&*^%-81VH-7F21”,最后的8位是关键,中间的“&*^%”可以用别的符号和数字‘0’以及字母‘I’、‘O’的任意组合来代替。
在本破解中,先看注册码计算的核心部分:
《1》
这个CALL对Irc作变换处理,如果出口是Eax=1,则表示需进一步处理;若出口是Eax=0,则表示不需要可以直接验证Irc是否正确(这个很重要)。
* Referenced by a CALL at Address:
|:10012C95
|
:10012CC0 8B442408
mov eax, dword ptr [esp+08]
:10012CC4 53
push ebx
:10012CC5 8B5C2408
mov ebx, dword ptr [esp+08]
:10012CC9 56
push esi
:10012CCA 57
push edi
:10012CCB 33F6
xor esi, esi
:10012CCD 8D7810
lea edi, dword ptr [eax+10]
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10012CF5(C)
|
:10012CD0 8A4FFF
mov cl, byte ptr [edi-01] <- 从Irc最后一位开始取一个字符
:10012CD3 4F
dec edi
:10012CD4 51
push ecx <-
将这个字符压栈
:10012CD5 E8A6000000 call
10012D80 《2》 将它换成32进制数,返回值在Eax中
:10012CDA 83C404
add esp, 00000004
:10012CDD 83F8FF
cmp eax, FFFFFFFF <- Eax=-1表示Irc中含有不在码表中的字符
:10012CE0 741E
je 10012D00 <-
向下跳,准备返回。这个跳转在本破解中起到关键作用!!
:10012CE2 6A05
push 00000005
:10012CE4 50
push eax
:10012CE5 56
push esi
:10012CE6 53
push ebx
:10012CE7 E824000000 call
10012D10
:10012CEC 83C605
add esi, 00000005
:10012CEF 83C410
add esp, 00000010
:10012CF2 83FE50
cmp esi, 00000050
:10012CF5 7CD9
jl 10012CD0 <-
不到16次则继续
:10012CF7 5F
pop edi
:10012CF8 5E
pop esi
:10012CF9 B801000000 mov eax,
00000001 <- 表示Irc中的字符均可转换为32进制数
:10012CFE 5B
pop ebx
:10012CFF C3
ret
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10012CE0(C)
|
:10012D00 5F
pop edi <-
遇到“不正常”字符时跳到这里
:10012D01 5E
pop esi
:10012D02 33C0
xor eax, eax
:10012D04 5B
pop ebx
:10012D05 C3
ret
《2》 这个CALL将调用前的最后一次压栈字符换算为32进制数,返回值在Eax中,注意32进制数从0开始;
若所查的字符不在其中则 Eax=-1。
例如:1->0,3->2,9->8,W->A,K->17,M->1F,&->-1,0->-1。
* Referenced by a CALL at Address:
|:10012CD5
|
:10012D80 8A0D5CC30210 mov cl, byte
ptr [1002C35C]
这个地址是32进制数的码表(很重要):
“12345678 9QWERTYU PASDFGHK LZXCVBNM”
<- 注意其中没有0、I、O
:10012D86 33C0
xor eax, eax
:10012D88 84C9
test cl, cl
:10012D8A 7413
je 10012D9F
:10012D8C 8A542404
mov dl, byte ptr [esp+04]
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10012D9D(C)
|
:10012D90 3ACA
cmp cl, dl
:10012D92 740E
je 10012DA2
:10012D94 8A885DC30210 mov cl, byte
ptr [eax+1002C35D]
:10012D9A 40
inc eax
:10012D9B 84C9
test cl, cl
:10012D9D 75F1
jne 10012D90
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10012D8A(C)
|
:10012D9F 83C8FF
or eax, FFFFFFFF <- 如果字符不在其中则Eax=-1
<-
想不到这个也是有用的
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10012D92(C)
|
:10012DA2 C3
ret
:10012DA3 90
nop
《3》这个CALL编写的实在是精彩,其作用是将得到的32进制数作移位变换,存放于目标地址。
* Referenced by a CALL at Address:
|:10012CE7
|
:10012D10 8B442408
mov eax, dword ptr [esp+08]
:10012D14 53
push ebx
:10012D15 56
push esi
:10012D16 57
push edi
:10012D17 8BF8
mov edi, eax
:10012D19 81E707000080 and edi, 80000007
<- Edi值每次都在变,在下面用作移位的位数(很高明)
:10012D1F 7905
jns 10012D26
<- Edi=0、5、2、7、4、1、8.....
:10012D21 4F
dec edi <-
:10012D22 83CFF8
or edi, FFFFFFF8 <- 这三个好象不会被执行到
:10012D25 47
inc edi <-
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10012D1F(C)
|
:10012D26 8B74241C
mov esi, dword ptr [esp+1C]
:10012D2A 8B5C2410
mov ebx, dword ptr [esp+10] <- 取得目标地址,内容一开始时为空
:10012D2E 99
cdq
:10012D2F B908000000 mov ecx,
00000008
:10012D34 83E207
and edx, 00000007
:10012D37 2BCE
sub ecx, esi
:10012D39 BEFF000000 mov esi,
000000FF
:10012D3E 03C2
add eax, edx
:10012D40 33D2
xor edx, edx
:10012D42 D3FE
sar esi, cl
:10012D44 C1F803
sar eax, 03 <-
调整Eax的位置
Eax的改变方式是随着这个CALL的调用Eax=0、0、1、1、2、3、3、4、4、.......
:10012D47 03C3
add eax, ebx <-
Eax指向目标地址
:10012D49 8BCF
mov ecx, edi
:10012D4B 8A7001
mov dh, byte ptr [eax+01]
:10012D4E 8BDE
mov ebx, esi
:10012D50 8A10
mov dl, byte ptr [eax]
:10012D52 D3E3
shl ebx, cl
:10012D54 8B4C2418
mov ecx, dword ptr [esp+18] <- 取得一个32进制数
:10012D58 23F1
and esi, ecx <-
相当于Esi=Ecx
:10012D5A 8BCF
mov ecx, edi
:10012D5C D3E6
shl esi, cl <-
Esi*2的N次方
:10012D5E F7D3
not ebx
:10012D60 23D3
and edx, ebx
:10012D62 5F
pop edi
:10012D63 0BD6
or edx, esi <-
结果送Edx,注意它用Or的方式保留低位字节的值
:10012D65 5E
pop esi
:10012D66 8BCA
mov ecx, edx
:10012D68 5B
pop ebx
:10012D69 8808
mov byte ptr [eax], cl
:10012D6B C1F908
sar ecx, 08
:10012D6E 884801
mov byte ptr [eax+01], cl
:10012D71 C3
ret
小结:综合《1》和《2》《3》,程序按从后到前的顺序取得Irc,换成32进制数,移位得到注册码1(Rc1)。
举例如下(可能有错误,只是表明计算过程是这样的):
假设Irc:WP-1234-2345-4567-6789,则(以下为16进制)
9->8,8*1=8;
8->7,7*20=E0。 Rc1[0]=E0 OR 8=E8;
7->6,6*4=18;
6->5,5*80=280。 Rc1[1]=80 OR 18=98;Rc1[2]=2;
7->6,6*10=60。 Rc1[2]=60 OR 2=62;(注意这个位只计算一次)
6->5,5*2=A;
5->4,4*40=100。 Rc1[3]=00 OR A=A;Rc1[4]=1;
.........................
生成的Rc1:E8 98 62 0A 01
这个Rc1要与下面的字串作比较,因为我看不出算法,无法反推,只能用计算器来算(这个过程很麻烦)
====================================================================
* Referenced by a CALL at Addresses:
|:1000728A , :1000771C , :10007BD4
|
:10007620 83EC0C
sub esp, 0000000C
:10007623 8B0D00420310 mov ecx, dword
ptr [10034200]
:10007629 8B542410
mov edx, dword ptr [esp+10]
:1000762D 33C0
xor eax, eax
:1000762F 53
push ebx
:10007630 89442404
mov dword ptr [esp+04], eax
:10007634 56
push esi
:10007635 8944240C
mov dword ptr [esp+0C], eax
:10007639 51
push ecx
:1000763A 6689442414 mov word
ptr [esp+14], ax
:1000763F 68CC410310 push
100341CC
:10007644 8D442410
lea eax, dword ptr [esp+10]
:10007648 52
push edx
:10007649 50
push eax
:1000764A E8119D0000 call
10011360 <= 详细在下面
* Possible StringData Ref from Data Obj ->"$LS98"
<= 看是否为此
|
:1000764F 8B35F8410310 mov esi, dword
ptr [100341F8]
:10007655 83C410
add esp, 00000010
:10007658 8D442408
lea eax, dword ptr [esp+08] <= 由IRC求得的码
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1000767E(C)
|
:1000765C 8A10
mov dl, byte ptr [eax]
:1000765E 8A1E
mov bl, byte ptr [esi]
:10007660 8ACA
mov cl, dl
:10007662 3AD3
cmp dl, bl
:10007664 751E
jne 10007684
:10007666 84C9
test cl, cl
:10007668 7416
je 10007680
:1000766A 8A5001
mov dl, byte ptr [eax+01]
:1000766D 8A5E01
mov bl, byte ptr [esi+01]
:10007670 8ACA
mov cl, dl
:10007672 3AD3
cmp dl, bl
:10007674 750E
jne 10007684
:10007676 83C002
add eax, 00000002
:10007679 83C602
add esi, 00000002
:1000767C 84C9
test cl, cl
:1000767E 75DC
jne 1000765C
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10007668(C)
|
:10007680 33C0
xor eax, eax
:10007682 EB05
jmp 10007689
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:10007664(C), :10007674(C)
|
:10007684 1BC0
sbb eax, eax
:10007686 83D8FF
sbb eax, FFFFFFFF
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10007682(U)
|
:10007689 85C0
test eax, eax
<- 此处改为CMP EAX,EAX就可暴破
:1000768B 7443
je 100076D0
* Possible StringData Ref from Data Obj ->"$BCWP"
|
:1000768D 8B35FC410310 mov esi, dword
ptr [100341FC] <- 另一次机会
:10007693 8D442408
lea eax, dword ptr [esp+08]
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:100076B9(C)
|
:10007697 8A10
mov dl, byte ptr [eax]
:10007699 8A1E
mov bl, byte ptr [esi]
:1000769B 8ACA
mov cl, dl
:1000769D 3AD3
cmp dl, bl
:1000769F 751E
jne 100076BF
<-
:100076A1 84C9
test cl, cl
:100076A3 7416
je 100076BB
:100076A5 8A5001
mov dl, byte ptr [eax+01]
:100076A8 8A5E01
mov bl, byte ptr [esi+01]
:100076AB 8ACA
mov cl, dl
:100076AD 3AD3
cmp dl, bl
:100076AF 750E
jne 100076BF
:100076B1 83C002
add eax, 00000002
:100076B4 83C602
add esi, 00000002
:100076B7 84C9
test cl, cl
:100076B9 75DC
jne 10007697
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:100076A3(C)
|
:100076BB 33C0
xor eax, eax
:100076BD EB05
jmp 100076C4
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:1000769F(C), :100076AF(C)
|
:100076BF 1BC0
sbb eax, eax
:100076C1 83D8FF
sbb eax, FFFFFFFF
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:100076BD(U)
|
:100076C4 85C0
test eax, eax
:100076C6 7408
je 100076D0
:100076C8 5E
pop esi
:100076C9 33C0
xor eax, eax
:100076CB 5B
pop ebx
:100076CC 83C40C
add esp, 0000000C
:100076CF C3
ret
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:1000768B(C), :100076C6(C)
|
:100076D0 8B44241C
mov eax, dword ptr [esp+1C]
:100076D4 8B4C240E
mov ecx, dword ptr [esp+0E]
:100076D8 5E
pop esi
:100076D9 5B
pop ebx
:100076DA 8908
mov dword ptr [eax], ecx
* Possible Reference to String Resource ID=00001: "%d Hours"
|
:100076DC B801000000 mov eax,
00000001
:100076E1 83C40C
add esp, 0000000C
:100076E4 C3
ret
====================================================================
在:1000764A处的调用
* Referenced by a CALL at Addresses:
|:1000764A , :1000788A
|
:10011360 6AFF
push FFFFFFFF
:10011362 6880A40210 push
1002A480
:10011367 64A100000000 mov eax, dword
ptr fs:[00000000]
:1001136D 50
push eax
:1001136E 64892500000000 mov dword ptr fs:[00000000],
esp
:10011375 83EC14
sub esp, 00000014
:10011378 8B442430
mov eax, dword ptr [esp+30]
:1001137C 8B4C2428
mov ecx, dword ptr [esp+28]
:10011380 56
push esi
:10011381 8B742428
mov esi, dword ptr [esp+28]
:10011385 50
push eax
:10011386 51
push ecx
:10011387 56
push esi
:10011388 C744241000000000 mov [esp+10], 00000000
:10011390 E89B180000 call
10012C30 <-
见下面
:10011395 83C40C
add esp, 0000000C
:10011398 85C0
test eax, eax
<- 不能让Eax返回值为0
:1001139A 7412
je 100113AE
<- 跳下去就有大麻烦了,因为它会按别的方式计算Rc,我实在是不想跟下去
:1001139C 33C0
xor eax, eax
<- 大家不信可以跟一跟
:1001139E 5E
pop esi
:1001139F 8B4C2414
mov ecx, dword ptr [esp+14]
:100113A3 64890D00000000 mov dword ptr fs:[00000000],
ecx
:100113AA 83C420
add esp, 00000020
:100113AD C3
ret
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1001139A(C)
|
:100113AE 33D2
xor edx, edx
:100113B0 89542410
mov dword ptr [esp+10], edx
:100113B4 89542414
mov dword ptr [esp+14], edx
:100113B8 33C0
xor eax, eax
:100113BA 89542420
mov dword ptr [esp+20], edx
:100113BE 89442408
mov dword ptr [esp+08], eax
:100113C2 8944240C
mov dword ptr [esp+0C], eax
:100113C6 8B542430
mov edx, dword ptr [esp+30]
:100113CA 8D4C2434
lea ecx, dword ptr [esp+34]
:100113CE 51
push ecx
:100113CF 8D44240C
lea eax, dword ptr [esp+0C]
:100113D3 52
push edx
:100113D4 8D4C2418
lea ecx, dword ptr [esp+18]
:100113D8 50
push eax
:100113D9 51
push ecx
:100113DA C644243001 mov [esp+30],
01
:100113DF E83C140000 call
10012820
:100113E4 83C410
add esp, 00000010
:100113E7 85C0
test eax, eax
:100113E9 7434
je 1001141F
:100113EB 8B44240C
mov eax, dword ptr [esp+0C]
:100113EF 85C0
test eax, eax
:100113F1 7409
je 100113FC
:100113F3 50
push eax
:100113F4 E8AA340000 call
100148A3
:100113F9 83C404
add esp, 00000004
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:100113F1(C)
|
:100113FC 8B442414
mov eax, dword ptr [esp+14]
:10011400 85C0
test eax, e
- 标 题:猜数记---BCWIPE注册半破解 (25千字)
- 作 者:Fpc
- 时 间:2001-4-2 19:41:12
- 链 接:http://bbs.pediy.com