Cleaner 3.2註冊分析 (18千字)

看雪資料發表於2001-12-09

Cleaner 3.2註冊分析
by Fpc/CCG&BCG    @2001/12

tools: trw1.22

[info]
軟體名稱:The Cleaner
整理日期:2001.12.8
最新版本:3.2 Build 3213
檔案大小:1833KB
軟體授權:共享軟體
使用平臺:Win9x/Me/NT/2000
釋出公司:Home Page
軟體簡介:
  一個專門檢測和清除侵入您系統中的特洛伊木馬的專業程式, 內建3093個木馬標識。可線上升級版本和病毒資料庫, 操作簡單, 功能強大! 查殺的各類特洛伊木馬種類最多,幾乎所有較出名的這裡都有,如 Netspy、BO、Netbus、 Girlfriend、Happy99、BackDoor 以及它們的一些不同版本。還有很多種我們大多數網友聽都沒聽過,有了它我們可以將電腦“清潔”得乾乾淨淨,放心大膽地上網。將毒資料庫cleaner.cdb複製到The Cleaner的安裝目錄下,就可以完成升級了。

[protection]
NAG, serial

[level]
1.5/5

[essay]
  好久沒有什麼破解了,找到這個軟體,估計會有點用,下載後安裝、執行。一個NAG跳出來:“你還有30天試用時間”*_*呵呵,還可以輸入註冊碼。好了,使用者名稱:Fpc/CCG&BCG,註冊碼:123654,點註冊,@$%#$%#@!@%&,不正確。它首先檢查註冊碼長度應該是19,還與兩個黑名單比較。這些我們不關心,看它如何計算:其實註冊名用不到,是對輸入的註冊碼作一些轉換和驗證,如果透過即註冊。
  由delphi或bcb編譯,UPX加的殼,懶得脫了~~註冊資訊好象是寫在檔案時,每次執行時檢查。另外不清楚它有沒有網上檢驗。

  輸入註冊碼後跟蹤,很容易到這裡:
...
017F:004933B2  MOV      EAX,[004B50B0]
017F:004933B7  MOV      EAX,[EAX]
017F:004933B9  CALL    004B043C                <- 檢驗註冊碼,重要
017F:004933BE  TEST    AL,AL                    <- al==0表示註冊失敗
017F:004933C0  JZ      004933D9            (JUMP)
017F:004933C2  MOV      EAX,[EBX+01F4]
017F:004933C8  CALL    00492474
017F:004933CD  MOV      DWORD [EBX+0150],01
017F:004933D7  JMP      SHORT 004933F9                <-
017F:004933D9  ADD      BYTE [EBX+0200],01
017F:004933E0  JNC      004933E7
017F:004933E2  CALL    00402E5C
017F:004933E7  PUSH    BYTE +30
017F:004933E9  CALL    `USER32!MessageBeep`            <- 呵呵,小喇叭響一聲        
017F:004933EE  MOV      EAX,[EBX+01F8]
017F:004933F4  CALL    00492B84
017F:004933F9  XOR      EAX,EAX
017F:004933FB  POP      EDX
017F:004933FC  POP      ECX
017F:004933DA  ADD      DWORD [EAX],BYTE +02
017F:004933DD  ADD      [EAX],AL
017F:004933DF  ADD      [EBX+05],ESI
017F:004933E2  CALL    00402E5C
017F:004933E7  PUSH    BYTE +30
017F:004933E9  CALL    `USER32!MessageBeep`
017F:004933EE  MOV      EAX,[EBX+01F8]
017F:004933F4  CALL    00492B84
017F:004933F9  XOR      EAX,EAX
017F:004933FB  POP      EDX
017F:004933FC  POP      ECX
...


  顯然得追進CALL    004B043:


017F:004B043C  PUSH    EBP
017F:004B043D  MOV      EBP,ESP
017F:004B043F  ADD      ESP,FFFFFDF0
017F:004B0445  PUSH    EBX
017F:004B0446  PUSH    ESI
017F:004B0447  PUSH    EDI
017F:004B0448  XOR      EDX,EDX
017F:004B044A  MOV      [EBP+FFFFFDF4],EDX
017F:004B0450  MOV      [EBP+FFFFFDF0],EDX
017F:004B0456  MOV      [EBP-04],EDX
017F:004B0459  MOV      [EBP-08],EDX
017F:004B045C  MOV      EDI,EAX
017F:004B045E  MOV      ECX,08
017F:004B0463  LEA      EAX,[EBP+FFFFFE08]
017F:004B0469  MOV      EDX,[004010AC]
017F:004B046F  CALL    004042A8
017F:004B0474  XOR      EAX,EAX
017F:004B0476  PUSH    EBP
017F:004B0477  PUSH    DWORD 004B0801
017F:004B047C  PUSH    DWORD [FS:EAX]
017F:004B047F  MOV      [FS:EAX],ESP
017F:004B0482  XOR      EAX,EAX
017F:004B0484  PUSH    EBP
017F:004B0485  PUSH    DWORD 004B07B4
017F:004B048A  PUSH    DWORD [FS:EAX]
017F:004B048D  MOV      [FS:EAX],ESP
017F:004B0490  MOV      EDX,[EDI+534C]
017F:004B0496  LEA      EAX,[EBP-04]
017F:004B0499  MOV      ECX,004B081C
017F:004B049E  CALL    00403D88
017F:004B04A3  LEA      EAX,[EDI+0151B36C]
017F:004B04A9  MOV      EDX,004B082C
017F:004B04AE  CALL    00403B14
017F:004B04B3  LEA      EAX,[EDI+0151B370]
017F:004B04B9  CALL    00403AC0
017F:004B04BE  MOV      EAX,[EBP-04]
017F:004B04C1  CALL    00407B4C        <- 上面的許多call都不重要
017F:004B04C6  TEST    AL,AL            <- 這裡不會跳走
017F:004B04C8  JZ      NEAR 004B0788
017F:004B04CE  MOV      EDX,[EBP-04]
017F:004B04D1  LEA      EAX,[EBP+FFFFFE28]
017F:004B04D7  CALL    00405222


經驗:
  borland編譯結果就是這個特徵,你經常可見到:

mov/lea eax, [SomeAddress]
mov/lea edx, [SomeAddress]
call SomeFuntion
mov...

  eax, edx是重要的兩個暫存器,根據它的 __fastcall 呼叫規則,函式引數首先是透過eax, edx, ecx(通常是記錄位元組個數),如果還有其它的引數,就會用到push壓入堆疊。關於borland逆向工程,你最好有一些delphi/BCB的程式設計經驗,DEDE可以提供豐富的反編譯資訊~~不算是作廣告。動態跟蹤時,多用這些命令:d eax, d edx, d *eax, d *edx, 通常的call不要追進去,因為就算跟進那個call你也看不明白,而遇到引數較多的call,極有可能是作者自己寫的,需要追進,註冊碼的計算可能就在裡面哦~

017F:004B04DC  LEA      EAX,[EBP+FFFFFE28]
017F:004B04E2  CALL    00405527
017F:004B04E7  LEA      EDX,[EDI+0151B36C]
017F:004B04ED  LEA      EAX,[EBP+FFFFFE28]
017F:004B04F3  CALL    004040F8
017F:004B04F8  LEA      EAX,[EBP+FFFFFE28]
017F:004B04FE  CALL    004054C4
017F:004B0503  LEA      EDX,[EBP-08]
017F:004B0506  LEA      EAX,[EBP+FFFFFE28]
017F:004B050C  CALL    004040F8
017F:004B0511  LEA      EAX,[EBP+FFFFFE28]
017F:004B0517  CALL    004054C4
017F:004B051C  LEA      EAX,[EBP+FFFFFE28]
017F:004B0522  CALL    00405328
017F:004B0527  LEA      EAX,[EDI+0151B370]    <- a buffer
017F:004B052D  MOV      EDX,[EBP-08]        <- 輸入的註冊碼,我用Irc來代替
017F:004B0530  CALL    00403B14        <- 複製字串或複製一個字串的指標

017F:004B0535  MOV      EAX,[EBP-08]        <- Irc
017F:004B0538  MOV      EDX,004B084C        <- 一個黑名單上的註冊碼
017F:004B053D  CALL    00403E4C        <- 比較
017F:004B0542  JZ      004B0553        <- 一致就去死

017F:004B0544  MOV      EAX,[EBP-08]
017F:004B0547  MOV      EDX,004B0868
017F:004B054C  CALL    00403E4C        <- 比較另一個黑名單
017F:004B0551  JNZ      004B057D        <- 不在其上則繼續

017F:004B0553  LEA      EAX,[EDI+0151B36C]
017F:004B0559  MOV      EDX,004B082C
017F:004B055E  CALL    00403B14
017F:004B0563  LEA      EAX,[EDI+0151B370]
017F:004B0569  CALL    00403AC0
017F:004B056E  XOR      EBX,EBX
017F:004B0570  XOR      EAX,EAX
017F:004B0572  POP      EDX
017F:004B0573  POP      ECX
017F:004B0574  POP      ECX
017F:004B0575  MOV      [FS:EAX],EDX
017F:004B0578  JMP      004B07C0

017F:004B057D  MOV      EAX,[EBP-08]        <- 好了,到這裡
017F:004B0580  CALL    00403D3C        <- eax=[eax-4],取Irc長度
017F:004B0585  CMP      EAX,BYTE +13
017F:004B0588  JZ      004B05B4        <- 為19則繼續

017F:004B058A  LEA      EAX,[EDI+0151B36C]    <- 否則繼續
017F:004B0590  MOV      EDX,004B082C
017F:004B0595  CALL    00403B14
017F:004B059A  LEA      EAX,[EDI+0151B370]
017F:004B05A0  CALL    00403AC0
017F:004B05A5  XOR      EBX,EBX
017F:004B05A7  XOR      EAX,EAX
017F:004B05A9  POP      EDX
017F:004B05AA  POP      ECX
017F:004B05AB  POP      ECX
017F:004B05AC  MOV      [FS:EAX],EDX
017F:004B05AF  JMP      004B07C0

017F:004B05B4  MOV      EAX,[EBP-08]        <- 繼續
017F:004B05B7  CALL    00403D3C
017F:004B05BC  MOV      ESI,EAX            <- Irc長度儲存到esi
017F:004B05BE  TEST    ESI,ESI
017F:004B05C0  JNG      004B05E4        <- 不會跳

017F:004B05C2  MOV      EBX,01            <- ebx作為迴圈變數
017F:004B05C7  MOV      EAX,[EBP-08]
017F:004B05CA  CMP      BYTE [EAX+EBX-01],2D    <- Irc[i]=='-'?
017F:004B05CF  JNZ      004B05E0        <- 不等比較下一個

017F:004B05D1  LEA      EAX,[EBP-08]
017F:004B05D4  MOV      ECX,01
017F:004B05D9  MOV      EDX,EBX
017F:004B05DB  CALL    00403F80        <- 這個call刪除當前位置的字元('-'),位置由edx決定,個數由ecx決定
017F:004B05E0  INC      EBX
017F:004B05E1  DEC      ESI
017F:004B05E2  JNZ      004B05C7        <- 未完繼續,此迴圈刪除Irc中的'-',如果有的話

                        <- 下面這一段會按順序取出Irc中的字元,每次取2位元組,共8次
017F:004B05E4  LEA      EAX,[EBP+FFFFFE08]
017F:004B05EA  PUSH    EAX            <- eax是指向緩衝區的指標
017F:004B05EB  MOV      ECX,02            <- ecx=2
017F:004B05F0  MOV      EDX,01            <- edx=1
017F:004B05F5  MOV      EAX,[EBP-08]        <- Irc
017F:004B05F8  CALL    00403F40        <- 取字元到緩衝區去,位置由edx決定,長度由ecx決定

017F:004B05FD  LEA      EAX,[EBP+FFFFFE0C]
017F:004B0603  PUSH    EAX
017F:004B0604  MOV      ECX,02
017F:004B0609  MOV      EDX,03
017F:004B060E  MOV      EAX,[EBP-08]
017F:004B0611  CALL    00403F40        <-

017F:004B0616  LEA      EAX,[EBP+FFFFFE10]
017F:004B061C  PUSH    EAX
017F:004B061D  MOV      ECX,02
017F:004B0622  MOV      EDX,05
017F:004B0627  MOV      EAX,[EBP-08]
017F:004B062A  CALL    00403F40

017F:004B062F  LEA      EAX,[EBP+FFFFFE14]
017F:004B0635  PUSH    EAX
017F:004B0636  MOV      ECX,02
017F:004B063B  MOV      EDX,07
017F:004B0640  MOV      EAX,[EBP-08]
017F:004B0643  CALL    00403F40

017F:004B0648  LEA      EAX,[EBP+FFFFFE18]
017F:004B064E  PUSH    EAX
017F:004B064F  MOV      ECX,02
017F:004B0654  MOV      EDX,09
017F:004B0659  MOV      EAX,[EBP-08]
017F:004B065C  CALL    00403F40

017F:004B0661  LEA      EAX,[EBP+FFFFFE1C]
017F:004B0667  PUSH    EAX
017F:004B0668  MOV      ECX,02
017F:004B066D  MOV      EDX,0B
017F:004B0672  MOV      EAX,[EBP-08]
017F:004B0675  CALL    00403F40

017F:004B067A  LEA      EAX,[EBP+FFFFFE20]
017F:004B0680  PUSH    EAX
017F:004B0681  MOV      ECX,02
017F:004B0686  MOV      EDX,0D
017F:004B068B  MOV      EAX,[EBP-08]
017F:004B068E  CALL    00403F40

017F:004B0693  LEA      EAX,[EBP+FFFFFE24]
017F:004B0699  PUSH    EAX
017F:004B069A  MOV      ECX,02
017F:004B069F  MOV      EDX,0F
017F:004B06A4  MOV      EAX,[EBP-08]
017F:004B06A7  CALL    00403F40        <- 取字元到這裡完成了

017F:004B06AC  LEA      EAX,[EBP-08]
017F:004B06AF  CALL    00403AC0        <- 初始化

017F:004B06B4  PUSH    EDI
017F:004B06B5  MOV      ESI,004B087C        <- 這裡是 16 位元組的0x0
017F:004B06BA  LEA      EDI,[EBP+FFFFFDF8]
017F:004B06C0  MOV      ECX,04
017F:004B06C5  REP MOVSD             <- 陣列初始化
017F:004B06C7  POP      EDI

017F:004B06C8  MOV      EBX,08
017F:004B06CD  LEA      ESI,[EBP+FFFFFE08]    <- esi初始化為指向Irc的前兩個位元組,見上面

017F:004B06D3  PUSH    BYTE +0A
017F:004B06D5  LEA      EAX,[EBP-0C]
017F:004B06D8  PUSH    EAX            <- 緩衝區
017F:004B06D9  MOV      EAX,[ESI]        <- eax指向Irc的兩個位元組
017F:004B06DB  CALL    00403F00
017F:004B06E0  LEA      ECX,[EBP+FFFFFDF8]
017F:004B06E6  MOV      EDX,10
017F:004B06EB  CALL    004B023C
017F:004B06F0  LEA      EAX,[EBP+FFFFFDF0]
017F:004B06F6  LEA      EDX,[EBP+FFFFFDF8]
017F:004B06FC  MOV      ECX,10
017F:004B0701  CALL    00403CEC
017F:004B0706  MOV      EAX,[EBP+FFFFFDF0]
017F:004B070C  CALL    00407904        <- 這幾個call實現str->Hex, 結果在eax,即:假設這兩位元組是"FA",則eax=0xFA

017F:004B0711  MOV      EDX,EAX
017F:004B0713  LEA      EAX,[EBP+FFFFFDF4]    <- 緩衝區
017F:004B0719  CALL    00403C64        <- 儲存edx

017F:004B071E  MOV      EDX,[EBP+FFFFFDF4]
017F:004B0724  LEA      EAX,[EBP-08]        <- 目標位置
017F:004B0727  CALL    00403D44        <- strcat
017F:004B072C  ADD      ESI,BYTE +04
017F:004B072F  DEC      EBX
017F:004B0730  JNZ      004B06D3

  到這裡,Irc變成了Hex值,並儲存在[ebp-8],稱為IrcA。我輸入的是:1236-5465-4123-1236,[ebp-8]=12 36 54 65 41 23 12 36
 
  繼續:
 
017F:004B0732  PUSH    DWORD 8C33        <- 引數
017F:004B0737  LEA      EAX,[EBP+FFFFFDF4]
017F:004B073D  PUSH    EAX            <- 目標緩衝區,稱為IrcB
017F:004B073E  MOV      ECX,3182        <- 引數
017F:004B0743  MOV      EDX,03D5        <- 引數
017F:004B0748  MOV      EAX,[EBP-08]        <- IrcA
017F:004B074B  CALL    00474658        <- (1)這裡計算註冊的關鍵,需要跟進去

017F:004B0750  MOV      EDX,[EBP+FFFFFDF4]    <- IrcB
017F:004B0756  LEA      EAX,[EBP-08]
017F:004B0759  CALL    00403B58        <- 又是複製一個指標
017F:004B075E  XOR      EDX,EDX
017F:004B0760  MOV      EAX,[EBP-08]        <- eax指向一個轉換後的8位元組資料
017F:004B0763  CALL    0040797C        <- (2)驗證註冊資料,追進

017F:004B0768  MOV      [EBP-0C],EAX        <- eax是錯誤值,否則相當於str->int
017F:004B076B  CMP      DWORD [EBP-0C],BYTE +00
017F:004B076F  JZ      004B0780        <- jump to BAD CRAcker

017F:004B0771  MOV      EAX,[EBP-0C]
017F:004B0774  MOV      ECX,7A
017F:004B0779  CDQ   
017F:004B077A  IDIV    ECX
017F:004B077C  TEST    EDX,EDX
017F:004B077E  JZ      004B0784        <- 還需要能被122整除

017F:004B0780  XOR      EBX,EBX            <- BAD Guy
017F:004B0782  JMP      SHORT 004B078A

017F:004B0784  MOV      BL,01            <- Good Guy
017F:004B0786  JMP      SHORT 004B078A
017F:004B0788  XOR      EBX,EBX
017F:004B078A  MOV      EDX,EBX
... 不重要了


(1)先看 CALL    00474658:

017F:0047465E  PUSH    EBX
017F:0047465F  PUSH    ESI
017F:00474660  PUSH    EDI

017F:00474661  XOR      EBX,EBX            <- 初始化
017F:00474663  MOV      [EBP-0C],EBX        <- [ebp-c]=0
017F:00474666  MOV      [EBP-04],ECX        <- [ebp-4]=0x3182
017F:00474669  MOV      ESI,EDX            <- esi=0x3D5
017F:0047466B  MOV      EDI,EAX            <- [edi]=IrcA
017F:0047466D  XOR      EAX,EAX            <- eax=0

017F:0047466F  PUSH    EBP
017F:00474670  PUSH    DWORD 004746E6
017F:00474675  PUSH    DWORD [FS:EAX]
017F:00474678  MOV      [FS:EAX],ESP
017F:0047467B  MOV      EAX,[EBP+08]
017F:0047467E  CALL    00403AC0

017F:00474683  MOV      EAX,EDI
017F:00474685  CALL    00403D3C        <- 取長度
017F:0047468A  TEST    AL,AL            <- al=8
017F:0047468C  JNA      004746D0        <- 不跳

017F:0047468E  MOV      [EBP-05],AL        <- [ebp-5]=8
017F:00474691  MOV      BL,01            <- bl=1,迴圈變數

017F:00474693  LEA      EAX,[EBP-0C]        <- 緩衝區
017F:00474696  XOR      EDX,EDX
017F:00474698  MOV      DL,BL
017F:0047469A  MOV      DL,[EDI+EDX-01]        <- dl=IrcA[i]
017F:0047469E  MOV      ECX,ESI            <- ecx=esi
017F:004746A0  SHR      ECX,08            <- ecx>>=8
017F:004746A3  XOR      DL,CL            <- dl^=cl
017F:004746A5  CALL    00403C64        <- 儲存edx到緩衝區

017F:004746AA  MOV      EDX,[EBP-0C]
017F:004746AD  MOV      EAX,[EBP+08]
017F:004746B0  CALL    00403D44        <- strcat

017F:004746B5  MOV      EAX,[EBP+08]        <- 無用的指令,可能是為對齊
017F:004746B8  XOR      EAX,EAX
017F:004746BA  MOV      AL,BL
017F:004746BC  MOVZX    EAX,BYTE [EDI+EAX-01]    <- eax=IrcA[i]
017F:004746C1  ADD      ESI,EAX            <- esi+=eax
017F:004746C3  IMUL    ESI,[EBP-04]        <- esi*=0x3182
017F:004746C7  ADD      ESI,[EBP+0C]        <- esi+=0x8C33
017F:004746CA  INC      EBX
017F:004746CB  DEC      BYTE [EBP-05]
017F:004746CE  JNZ      00474693        <- 未完繼續
...

  不清楚這一段是否可逆,可以描述為:
int esi=0x3D5;
char IrcA[8]="....";
char IrcB[8];
for(short i=0; i<8; i++)
{
    IrcB[i]=IrcA[i]^(esi>>8&0xFF);
    esi+=IrcA[i];
    esi*=0x3182;
    esi+=0x8C33;
}
    


  (2)繼續看CALL    0040797C:
017F:0040797C  PUSH    EBX
017F:0040797D  PUSH    ECX
017F:0040797E  MOV      EBX,EDX
017F:00407980  MOV      EDX,ESP
017F:00407982  CALL    00402C40            <- trace into
017F:00407987  CMP      DWORD [ESP],BYTE +00
017F:0040798B  JZ      0040798F
017F:0040798D  MOV      EAX,EBX
017F:0040798F  POP      EDX
017F:00407990  POP      EBX
017F:00407991  RET   

簡單起見,這段程式碼檢查IrcB每個字元是否是數字,不是則失敗,並將其轉為int到eax,結果要小於0x0CCCCCCC:

017F:00402C40  PUSH    EBX
017F:00402C41  PUSH    ESI
017F:00402C42  PUSH    EDI
017F:00402C43  MOV      ESI,EAX
017F:00402C45  PUSH    EAX
017F:00402C46  TEST    EAX,EAX
017F:00402C48  JZ      00402C9B
017F:00402C4A  XOR      EAX,EAX
017F:00402C4C  XOR      EBX,EBX
017F:00402C4E  MOV      EDI,0CCCCCCC
017F:00402C53  MOV      BL,[ESI]
017F:00402C55  INC      ESI
017F:00402C56  CMP      BL,20
017F:00402C59  JZ      00402C53
017F:00402C5B  MOV      CH,00
017F:00402C5D  CMP      BL,2D
017F:00402C60  JZ      00402CA7
017F:00402C62  CMP      BL,2B
017F:00402C65  JZ      00402CA9
017F:00402C67  CMP      BL,24
017F:00402C6A  JZ      00402CAE
017F:00402C6C  TEST    BL,BL
017F:00402C6E  JZ      00402CA2                <- 這裡不能去

017F:00402C70  SUB      BL,30
017F:00402C73  CMP      BL,09            <- 是否為數字
017F:00402C76  JA      00402CA2
017F:00402C78  CMP      EAX,EDI            <- eax不能比edi大
017F:00402C7A  JA      00402CA2

017F:00402C7C  LEA      EAX,[EAX+EAX*4]
017F:00402C7F  ADD      EAX,EAX
017F:00402C81  ADD      EAX,EBX            <- eax=eax*10+bl
017F:00402C83  MOV      BL,[ESI]
017F:00402C85  INC      ESI
017F:00402C86  TEST    BL,BL
017F:00402C88  JNZ      00402C70
017F:00402C8A  DEC      CH
017F:00402C8C  JZ      00402C9E
017F:00402C8E  TEST    EAX,EAX
017F:00402C90  JL      00402CA2
017F:00402C92  POP      ECX
017F:00402C93  XOR      ESI,ESI
017F:00402C95  MOV      [EDX],ESI
017F:00402C97  POP      EDI
017F:00402C98  POP      ESI
017F:00402C99  POP      EBX
017F:00402C9A  RET   
017F:00402C9B  INC      ESI
017F:00402C9C  JMP      SHORT 00402CA2
017F:00402C9E  NEG      EAX
017F:00402CA0  JNG      00402C92
017F:00402CA2  POP      EBX
017F:00402CA3  SUB      ESI,EBX
017F:00402CA5  JMP      SHORT 00402C95
017F:00402CA7  INC      CH
017F:00402CA9  MOV      BL,[ESI]
017F:00402CAB  INC      ESI
017F:00402CAC  JMP      SHORT 00402C6C
017F:00402CAE  MOV      EDI,0FFFFFFF
017F:00402CB3  MOV      BL,[ESI]
017F:00402CB5  INC      ESI
017F:00402CB6  TEST    BL,BL
017F:00402CB8  JZ      00402C9B
017F:00402CBA  CMP      BL,61
017F:00402CBD  JC      00402CC2
017F:00402CBF  SUB      BL,20
017F:00402CC2  SUB      BL,30
017F:00402CC5  CMP      BL,09
017F:00402CC8  JNA      00402CD5
017F:00402CCA  SUB      BL,11
017F:00402CCD  CMP      BL,05
017F:00402CD0  JA      00402CA2
017F:00402CD2  ADD      BL,0A
017F:00402CD5  CMP      EAX,EDI
017F:00402CD7  JA      00402CA2
017F:00402CD9  SHL      EAX,04
017F:00402CDC  ADD      EAX,EBX
017F:00402CDE  MOV      BL,[ESI]
017F:00402CE0  INC      ESI
017F:00402CE1  TEST    BL,BL
017F:00402CE3  JNZ      00402CBA
017F:00402CE5  JMP      SHORT 00402C92

  很明顯,我們需要找一個數,能被122整除,比0x0CCCCCCC小,這個數作為IrcB,反推出IrcA,從而得到註冊碼。
  隨機找到一個數:95830268=0x5B640FC,則IrcB[8]="95830268",將上面的程式稍動一下:

int esi=0x3D5;
char IrcA[8];
char IrcB[8]="95830268";
for(short i=0; i<8; i++)
{
    IrcA[i]=IrcB[i]^(esi>>8&0xFF);
    esi+=IrcA[i];
    esi*=0x3182;
    esi+=0x8C33;
}
  執行後得到註冊碼,註冊透過。
 

附:
//序號產生器,BCB 5.0編譯透過
//---------------------------------------------------------------------------

#include <vcl.h>
//--- head added
#include <iostream.h>
#include <conio.h>
#include <stdlib.h>
//--- added stoped
#pragma hdrstop

//---------------------------------------------------------------------------

#pragma argsused
int main(int argc, char* argv[])
{
    int Acc=0x3D5;
    unsigned int Nul=0;                //多餘的變數防止出現符號擴充套件
    char buff[100];
    unsigned char IrcA[9];              //需要定義為unsigned
    char IrcB[9]="95830268";
    cout<<"The Cleaner 3.2 Build 3213 KeyMaker"<<endl;
    cout<<"cracked by Fpc/CCG&BCG"<<endl<<endl;;
    cout<<"InPut Your Name: ";
    cin>>buff;
    cout<<"Your Code is  : ";
    randomize();
    Nul=122*rand()%819600;
    sprintf(IrcB, "%08d", Nul);
    for(short i=0; i<8; i++)
    {
        Nul=0;
        IrcA[i]=IrcB[i]^((Acc>>8)&0xFF);
        Nul=IrcA[i];
        Acc+=Nul;
        Acc*=0x3182;
        Acc+=0x8C33;
        sprintf(buff, "%02X", IrcA[i]);
        cout<<buff;
        if(i%2 && i!=7)
        cout<<'-';
    }
    cout<<endl<<endl<<"any key to quit...";
    getch();
    return 0;
}

相關文章