AddRemove 4GOOD 註冊演算法+序號產生器

看雪資料發表於2003-07-25

AddRemove 4GOOD 2.0 完全破解 演算法分析+序號產生器

最近一直在從古董光碟上找軟體練習,這個軟體至少也得有兩三年的歲數了。以前一直在爆破,或者直接從記憶體中看出明碼來,這次終於靜下心來把演算法仔細分析了一下,寫出序號產生器來的感覺,爽!興奮之餘寫下這篇文章,請各位大哥指正。

好,閒話少說,書歸正題。執行軟體,點選"Order Info",填入NAME: RoBa, CODE: 87654321

下bpx hmemcpy (我用的98),點Unlock,按22次F12到了AR4的領空,再按F10直到如下:

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040192E(C)
|
:00401949 E8D2FCFFFF              call 00401620<-這個是關鍵的CALL
:0040194E 85C0                    test eax, eax
:00401950 0F84A2000000            je 004019F8<-eax為0就完蛋了
:00401956 8D45E8                  lea eax, dword ptr [ebp-18]
:00401959 8D4DEC                  lea ecx, dword ptr [ebp-14]
:0040195C C745E800000000          mov [ebp-18], 00000000
:00401963 C745EC00000000          mov [ebp-14], 00000000
:0040196A 50                      push eax
:0040196B 51                      push ecx
:0040196C 6A00                    push 00000000
:0040196E 683F000F00              push 000F003F
:00401973 6A00                    push 00000000
:00401975 6A00                    push 00000000
:00401977 6A00                    push 00000000

在401949處F8跟進CALL,直接就來到這裡:

* Referenced by a CALL at Addresses:
|:00401611   , :00401949  
|
:00401620 64A100000000            mov eax, dword ptr fs:[00000000]
:00401626 55                      push ebp
:00401627 8BEC                    mov ebp, esp
:00401629 6AFF                    push FFFFFFFF

* Possible StringData Ref from Code Obj ->"pn@"
                                 |
:0040162B 68A5174000              push 004017A5
:00401630 B9FFFFFFFF              mov ecx, FFFFFFFF
:00401635 50                      push eax
:00401636 64892500000000          mov dword ptr fs:[00000000], esp
:0040163D 83EC0C                  sub esp, 0000000C
:00401640 2BC0                    sub eax, eax
:00401642 57                      push edi
:00401643 BF60834000              mov edi, 00408360
:00401648 F2                      repnz
:00401649 AE                      scasb
:0040164A F7D1                    not ecx
:0040164C 49                      dec ecx<-ecx為註冊名的長度(下面簡稱長度)
:0040164D 83F906                  cmp ecx, 00000006<-與6比較
:00401650 7311                    jnb 00401663<-大於6就跳
                                             <-所以我把RoBa改為RoBa1986
                                           
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0040177F(U), :00401790(U)
|
:00401652 33C0                    xor eax, eax<-eax被幹掉了

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040176E(U)
|
:00401654 8B4DF4                  mov ecx, dword ptr [ebp-0C]
:00401657 5F                      pop edi
:00401658 64890D00000000          mov dword ptr fs:[00000000], ecx
:0040165F 8BE5                    mov esp, ebp
:00401661 5D                      pop ebp
:00401662 C3                      ret<-如果長度小於6直接返回去就死翹翹了
<-所以我把RoBa改為RoBa1986

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401650(C)
|
:00401663 BF60834000              mov edi, 00408360
:00401668 B9FFFFFFFF              mov ecx, FFFFFFFF
:0040166D 2BC0                    sub eax, eax
:0040166F F2                      repnz
:00401670 AE                      scasb<-上面這幾句會出現好幾次,看不懂
:00401671 F7D1                    not ecx<-總之得到ecx為長度+1
:00401673 2BD2                    sub edx, edx
:00401675 8D41FF                  lea eax, dword ptr [ecx-01]<-eax為長度
:00401678 B90C000000              mov ecx, 0000000C<-ecx為0000000C(即十進位制12)
:0040167D F7F1                    div ecx<-eax為長度除以ecx的整數部分
<-edx為長度除以ecx的餘數

* Possible StringData Ref from Data Obj ->"87ae2401my69"<-一個小密碼錶
                                 |
:0040167F A15C834000              mov eax, dword ptr [0040835C]<-eax為密碼錶第一個字元的地址
:00401684 8D4DF0                  lea ecx, dword ptr [ebp-10]<-[ebp-10]即為長度+1
:00401687 8A0410                  mov al, byte ptr [eax+edx]<-得到密碼錶中第(edx+1)個字元
:0040168A 50                      push eax<-壓入堆疊

* Possible StringData Ref from Data Obj ->"6582-"
                                 |
:0040168B 689C854000              push 0040859C<-把字串"6582-"壓入

* Reference To: MFC40.Ordinal:01E3, Ord:01E3h
                                 |
:00401690 E8F13C0000              Call 00405386
:00401695 50                      push eax
:00401696 8D4DEC                  lea ecx, dword ptr [ebp-14]
:00401699 C745FC00000000          mov [ebp-04], 00000000
:004016A0 51                      push ecx

* Reference To: MFC40.Ordinal:0332, Ord:0332h
                                 |
:004016A1 E8EC3C0000              Call 00405392
:004016A6 C645FC02                mov [ebp-04], 02
:004016AA E8EE000000              call 0040179D
:004016AF BF60834000              mov edi, 00408360
:004016B4 B9FFFFFFFF              mov ecx, FFFFFFFF
:004016B9 C745F000000000          mov [ebp-10], 00000000
:004016C0 2BC0                    sub eax, eax
:004016C2 F2                      repnz
:004016C3 AE                      scasb
:004016C4 F7D1                    not ecx
:004016C6 49                      dec ecx
:004016C7 7478                    je 00401741

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040173F(C)
|
:004016C9 F645F001                test [ebp-10], 01<-迴圈開始
:004016CD 7559                    jne 00401728<-這裡不知是怎麼回事
<-如果[ebp-10]為偶數就跳過
<-也就是說只有奇數位參加計算
:004016CF 8B45F0                  mov eax, dword ptr [ebp-10]
:004016D2 8A8060834000            mov al, byte ptr [eax+00408360]<-得到要計算的字元
:004016D8 3C7F                    cmp al, 7F<-與7F比較
:004016DA 0F8F93000000            jg 00401773<-大於就跳
:004016E0 3C20                    cmp al, 20<-與20比較
:004016E2 0F8C9C000000            jl 00401784<-小於就跳
<-鍵盤輸入的字元都在這個範圍吧?
:004016E8 6698                    cbw
:004016EA B102                    mov cl, 02<-cl=2
:004016EC F6F9                    idiv cl<-al為al除以2的整數部分
:004016EE 0420                    add al, 20<-al=al+20;
:004016F0 3C5A                    cmp al, 5A<-與5A比較,ASC(5A)='Z'
:004016F2 7E06                    jle 004016FA<-小於等於就跳
:004016F4 3C61                    cmp al, 61<-與61比較,ASC(61)='a'
:004016F6 7D02                    jge 004016FA<-大於等於就跳
:004016F8 0406                    add al, 06<-如果al在5A與61之間則+6

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004016F2(C), :004016F6(C)
|
:004016FA 3C39                    cmp al, 39<-與39比較,ASC(39)='9'
:004016FC 7E06                    jle 00401704<-小於等於就跳
:004016FE 3C41                    cmp al, 41<-與41比較,ASC(41)='A'
:00401700 7D02                    jge 00401704<-大於等於就跳
:00401702 0408                    add al, 08<-如果al在39與41之間則+8

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004016FC(C), :00401700(C)
|
:00401704 50                      push eax<-把結果壓入堆疊
:00401705 8D4DE8                  lea ecx, dword ptr [ebp-18]
:00401708 8D45EC                  lea eax, dword ptr [ebp-14]
:0040170B 50                      push eax
:0040170C 51                      push ecx

* Reference To: MFC40.Ordinal:0332, Ord:0332h
                                 |
:0040170D E8803C0000              Call 00405392
:00401712 50                      push eax
:00401713 8D4DEC                  lea ecx, dword ptr [ebp-14]
:00401716 C645FC03                mov [ebp-04], 03

* Reference To: MFC40.Ordinal:02F8, Ord:02F8h
                                 |
:0040171A E86D3C0000              Call 0040538C
:0040171F C645FC02                mov [ebp-04], 02
:00401723 E86D000000              call 00401795

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004016CD(C)
|
:00401728 BF60834000              mov edi, 00408360
:0040172D B9FFFFFFFF              mov ecx, FFFFFFFF
:00401732 FF45F0                  inc [ebp-10]<-[ebp-10]+1
:00401735 2BC0                    sub eax, eax
:00401737 F2                      repnz
:00401738 AE                      scasb
:00401739 F7D1                    not ecx
:0040173B 49                      dec ecx<-得到註冊名長度
:0040173C 3B4DF0                  cmp ecx, dword ptr [ebp-10]<-將長度與[ebp-10]比較
:0040173F 7788                    ja 004016C9<-大於則跳回去算下一個數
<-可以看出[ebp-10]為迴圈變數

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004016C7(C)
|
:00401741 6860844000              push 00408460<-d 408460可看到假碼
:00401746 8B45EC                  mov eax, dword ptr [ebp-14]
:00401749 50                      push eax<-d eax即可看到正確的註冊碼

* Reference To: MSVCRT40._mbscmp, Ord:02ECh
                                 |
:0040174A FF1510A84000            Call dword ptr [0040A810]
:00401750 83C408                  add esp, 00000008
:00401753 8B4DF0                  mov ecx, dword ptr [ebp-10]
:00401756 C745FCFFFFFFFF          mov [ebp-04], FFFFFFFF
:0040175D 83F801                  cmp eax, 00000001
:00401760 194DF0                  sbb dword ptr [ebp-10], ecx
:00401763 F75DF0                  neg [ebp-10]
:00401766 E844000000              call 004017AF
:0040176B 8B45F0                  mov eax, dword ptr [ebp-10]
:0040176E E9E1FEFFFF              jmp 00401654
...........

可以看到註冊碼由三部分組成: 固定字串"6582-"+在密碼錶中得到的一個字元+註冊名經過運算得到的字元

一個簡易的序號產生器: (Borland Pascal 7.0)(寫得很爛,高手莫笑)

Program CrackADDREMOVE;
var name,code,st :string;
   ch :char;
   len,p :integer;
begin
    st:='87ae2401my69';
    repeat
          write('Please input the name:');
          readln(name);
          len:=length(name);
    until len>=6;
    ch:=st[(len mod 12)+1];
    code:='6582-'+ch;
    for p:=1 to len do
    if (p mod 2)=1 then
    begin
       ch:=name[p];
       ch:=chr(ord(ch) div 2+32);
       if (ch>'Z') and (ch<'a') then ch:=chr(ord(ch)+6);
       if (ch>'9') and (ch<'A') then ch:=chr(ord(ch)+8);
       code:=code+ch;
    end;
    writeln('Your Register Code is:',code);
    writeln;
    writeln('Crack by RoBa         Thank you');
end.

我實在不明白程式碼中出現很多次的 repnz  scasb 是什麼意思,請大俠指教。


相關文章