• 标 题:猜数记---BCWIPE注册半破解 (25千字)
  • 作 者:Fpc
  • 时 间:2001-4-2 19:41:12
  • 链 接:http://bbs.pediy.com

猜数记---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