ResScope1.92演算法分析
看雪資料發表於2004-07-21
ResScope,一個將比exeScope更強的軟體資源分析工具,很不錯的軟體。
delphi程式,無殼無反除錯無校驗,我喜歡,:)。
透過字串容易找到這裡,很容易看到,讀取登錄檔中的使用者名稱和註冊碼,分別計算後進行再比較。
程式碼:
CODE:0051B6EB mov cl, 1 CODE:0051B6ED mov edx, offset aSoftwareRest_3 ; "SOFTWARE\\RESTOOLS\\ResScope" CODE:0051B6F2 mov eax, [ebp+var_8] CODE:0051B6F5 call @Registry@TRegistry@OpenKey$qqrx17System@AnsiStringo ; Registry::TRegistry::OpenKey(System::AnsiString,bool) CODE:0051B6FA test al, al CODE:0051B6FC jz loc_51B888 CODE:0051B702 lea eax, [ebp+var_C] CODE:0051B705 call @System@@LStrClr$qqrr17System@AnsiString ; System::__linkproc__ LStrClr(System::AnsiString &) CODE:0051B70A lea eax, [ebp+var_10] CODE:0051B70D call @System@@LStrClr$qqrr17System@AnsiString ; System::__linkproc__ LStrClr(System::AnsiString &) CODE:0051B712 mov edx, offset aReguser_2 ; "reguser" CODE:0051B717 mov eax, [ebp+var_8] CODE:0051B71A call @Registry@TRegistry@ValueExists$qqrx17System@AnsiString ; Registry::TRegistry::ValueExists(System::AnsiString) CODE:0051B71F test al, al CODE:0051B721 jz short loc_51B733 CODE:0051B723 lea ecx, [ebp+var_C] CODE:0051B726 mov edx, offset aReguser_2 ; "reguser" CODE:0051B72B mov eax, [ebp+var_8] CODE:0051B72E call @TRegistry@ReadString$qqrx10AnsiString ; TRegistry::ReadString(AnsiString) CODE:0051B733 CODE:0051B733 loc_51B733: ; CODE XREF: sub_51B6A0+81j CODE:0051B733 mov edx, offset aRegcode_1 ; "regcode" CODE:0051B738 mov eax, [ebp+var_8] CODE:0051B73B call @Registry@TRegistry@ValueExists$qqrx17System@AnsiString ; Registry::TRegistry::ValueExists(System::AnsiString) CODE:0051B740 test al, al CODE:0051B742 jz short loc_51B754 CODE:0051B744 lea ecx, [ebp+var_10] CODE:0051B747 mov edx, offset aRegcode_1 ; "regcode" CODE:0051B74C mov eax, [ebp+var_8] CODE:0051B74F call @TRegistry@ReadString$qqrx10AnsiString ; TRegistry::ReadString(AnsiString) CODE:0051B754 CODE:0051B754 loc_51B754: ; CODE XREF: sub_51B6A0+A2j CODE:0051B754 mov eax, [ebp+var_10] CODE:0051B757 call @System@@LStrLen ; System::__linkproc__ LStrLen CODE:0051B75C cmp eax, 30h CODE:0051B75F jnz loc_51B888 CODE:0051B765 mov eax, [ebp+var_C] CODE:0051B768 call @System@@LStrLen ; System::__linkproc__ LStrLen CODE:0051B76D test eax, eax CODE:0051B76F jle loc_51B888 CODE:0051B775 lea eax, [ebp+var_14] ; 儲存返回值 CODE:0051B775 ; 指向18位元組長PCHAR CODE:0051B778 push eax CODE:0051B779 mov cl, 1 CODE:0051B77B mov dl, 1 CODE:0051B77D mov eax, [ebp+var_C] ; "reguser" CODE:0051B780 call sub_51A06C ; 處理使用者名稱 CODE:0051B785 mov eax, [ebp+var_14] ; 處理使用者名稱得到的18位元組長的串,先入棧,待會好比較 CODE:0051B788 push eax CODE:0051B789 lea ecx, [ebp+var_18] ; 儲存返回值。。 CODE:0051B78C mov dl, 1 CODE:0051B78E mov eax, [ebp+var_10] ; "regcode" CODE:0051B791 call sub_519298 ; 註冊碼變換函式 CODE:0051B796 mov edx, [ebp+var_18] CODE:0051B799 pop eax CODE:0051B79A call @System@@LStrCmp$qqrv ; System::__linkproc__ LStrCmp(void) CODE:0051B79F jnz short loc_51B7A5 ;
這個軟體的爆破起來不是很容易
程式碼:
CODE:00525CBB mov eax, ds:off_525214 ; * Reference to class THexDumpPass CODE:00525CC0 call sub_425EEC ; * Reference to: Classes.TComponent.Create(TComponent;boolean;TComponent); CODE:00525CC5 mov ebx, eax CODE:00525CC7 lea eax, [ebp+var_130] CODE:00525CCD call sub_518E18 ; 使用者名稱進行變換轉為一串字元 CODE:00525CD2 mov edx, [ebp+var_130] CODE:00525CD8 mov eax, ebx CODE:00525CDA mov ecx, [eax] CODE:00525CDC call dword ptr [ecx+18h] ; Classes::TComponent::SetName()
在此處設定使用者名稱變換而來得串設定元件名字,然後使用註冊碼變換而來得串來FindComponent(),如果註冊碼正確,兩個串應該相等,則能得到正確的控制程式碼,
儲存起來,然後在校驗註冊時候使用該控制程式碼,若沒找到則例外出錯。
下面來看看註冊演算法:
使用peid來探測一下用了什麼演算法,一下出來8種演算法,夠嚇人,不過還有不少沒探測出來,:)。
DEDE反彙編看看,注意到類名中有大量的類似TCipher_MD5、TCipher_Blowfish、TCipher_IDEA類似這樣的類名,
熟悉的人一眼就看出來使用DEC控制元件,這是Hagen Reddmann寫的Delphi Encryption Compendium 控制元件,控制元件支援20餘種Hash,40多種分組密碼演算法,
而且附帶原始碼,是很好的學習演算法的教程。
在分析過程中可以用delphi編譯一個小例子,然後跟蹤看看,並參考原始碼效果很好。
先來看看處理使用者名稱的函式
CODE:0051B780 call sub_51A06C ; 處理使用者名稱
使用者ID的生成是呼叫CPUID指令獲取cpu資訊,然後編碼至16位元組。與使用者名稱連線起來,透過簡單演算法變換為18h位元組,
程式碼:
CODE:0051A0C3 mov edx, ds:dword_578440 ; 使用者ID,類似"92F1L8EACT2FFNFF"一串字元。。。 CODE:0051A0C9 call @System@@LStrCat$qqrv ; System::__linkproc__ LStrCat(void) CODE:0051A4A6 push offset unk_575B10 ; IVector,初始化向量 CODE:0051A4AB mov edx, offset byte_575B08 ; keyCAST..64位金鑰 CODE:0051A4B0 lea eax, [ebp+var_F4_TCast128Data] ; 0012FAF8 CODE:0051A4B0 ; TCast128Data= record CODE:0051A4B0 ; InitBlock: array[0..7] of byte; { initial IV } CODE:0051A4B0 ; LastBlock: array[0..7] of byte; { current IV } CODE:0051A4B0 ; xKey: array[0..31] of DWord; CODE:0051A4B0 ; Rounds: integer; CODE:0051A4B0 ; end; CODE:0051A4B6 mov ecx, 8 ; sizeof(Key) CODE:0051A4BB call Cast128Init ; 注意此處Cast128非呼叫DEC的函式,乃是獨立的類。 ; 注意其sbox乃是作者隨機生成
採用CBC模式呼叫Cast128演算法,即密碼分組連結模式即每次分組加密結果,與下組明文xor後,作為輸入。
程式碼:
CODE:0051A50E lea edx, [ebp+eax+var_48] ; 輸入串,輸出也儲存再該地址 CODE:0051A512 lea eax, [ebp+var_F4_TCast128Data] ; 金鑰初始化結果 CODE:0051A518 call Cast128EncryptCBC ; procedure Cast128EncryptCBC(var Data: TCast128Data; InData, OutData: pointer); CODE:0051A518 ; { encrypts the data in a 64bit block using the CBC chaining mode }
下面就是呼叫DEC中的密碼演算法來進行加密
程式碼:
CODE:0051A6FB mov edx, ds:off_4F31E0 ; Reference to class TCipher_3Way,這個可由DEDE反彙編程式碼中看到 CODE:0051A701 mov eax, [ebp+var_14] CODE:0051A704 call @TCipherManager@@SetClass ; TCipherManager::__linkproc__ SetClass CODE:0051A709 xor ecx, ecx CODE:0051A70B mov edx, [ebp+var_18] CODE:0051A70E mov eax, [ebp+var_14] CODE:0051A711 call @TCipherManager@@InitKey ; procedure TCipherManager.InitKey(const Key: String; IVector: Pointer); CODE:0051A716 push 18h ; 待Encode串長度 CODE:0051A718 lea ecx, [ebp+var_60] ; 返回串 CODE:0051A71B lea edx, [ebp+var_48] ; Source串,由Cast128而來 CODE:0051A71E mov eax, [ebp+var_14] CODE:0051A721 call @TCipherManager@@EncodeBuffer ; procedure TCipherManager.EncodeBuffer CODE:0051A721 ; (const Source; var Dest; DataSize: Integer);
下面級連的還有
程式碼:
CODE:0051A7F6 mov edx, ds:off_4F29DC ; * Reference to class TCipher_Blowfish (注: pbox,sbox非標) CODE:0051A8F1 mov edx, ds:off_4F2940 ; * Reference to class TCipher_Gost (注: Gost_Data非標) CODE:0051AA15 mov edx, ds:off_4F2A7C ; * Reference to class TCipher_IDEA CODE:0051AB39 mov edx, ds:off_4F3144 ; * Reference to class TCipher_Q128 (注: Q128_Data非標) CODE:0051AC5D mov edx, ds:off_4F2B18 ; * Reference to class TCipher_SAFER (注: DEC庫中預設沒有新增入列表,需修改程式碼註冊該Cipher類到控制元件) CODE:0051AD58 mov edx, ds:off_4F2E34 ; * Reference to class TCipher_SAFER_K128 CODE:0051AE7C mov edx, ds:off_4F2BB4 ; * Reference to class TCipher_SAFER_K40 CODE:0051AF77 mov edx, ds:off_4F2CF4 ; * Reference to class TCipher_SAFER_K64
對使用者名稱的變換用了10種演算法,不過呼叫DEC庫格式比較標準,跟蹤起來也什麼困難.
下面看註冊碼變換演算法
程式碼:
CODE:0051B791 call sub_519298 ; 註冊碼變換函式 註冊碼為30h字元,先解碼後為18h位元組資料,每2字元變換為一個位元組 然後 CODE:005193C2 push offset unk_575AE0 ; GOST初始化向量 CODE:005193C7 mov edx, offset unk_575AE8 ; GOST金鑰 20h位元組 CODE:005193CC lea eax, [ebp+var_98] ; TGOSTData= record CODE:005193CC ; InitBlock: array[0..7] of byte; { initial IV } CODE:005193CC ; LastBlock: array[0..7] of byte; { current IV } CODE:005193CC ; XKey: array[0..7] of DWord; CODE:005193CC ; end; CODE:005193D2 mov ecx, 20h CODE:005193D7 call GOSTInit ; procedure GOSTInit(var Data: TGOSTData; Key: pointer; Len: integer; IV: pointer ; 注意此處Cast128非呼叫DEC的函式,乃是獨立的類。其Gost_Data非標
同樣採用CBC模式解碼資料,每次處理8位元組,共處理3次。
程式碼:
CODE:00519429 lea edx, [ebp+eax+var_50] ; 輸出 CODE:0051942D lea eax, [ebp+var_98] ; var Data: TGOSTData CODE:00519433 call GOSTDecryptCBC ; //procedure GOSTDecryptCBC(var Data: TGOSTData; InData, OutData: pointer); CODE:00519433 ; { decrypts the data in a 64bit block using the CBC chaining mode }
同樣下面級連了一串變換,不過此處呼叫的都是@TCipherManager@@DecodeBuffer,解碼函式
程式碼:
CODE:005195FB mov edx, ds:off_4F327C ; * Reference to class TCipher_Twofish (注: Twofish_Data,Twofish_8x8值非標) CODE:00519714 mov edx, ds:off_4F300C ; * Reference to class TCipher_TEAN CODE:00519810 mov edx, ds:off_4F2F74 ; * Reference to class TCipher_TEA CODE:0051990C mov edx, ds:off_4F33B4 ; * Reference to class TCipher_Square CODE:00519A2D mov edx, ds:off_4F3318 ; * Reference to class TCipher_Shark CODE:00519B29 mov edx, ds:off_4F30A8 ; * Reference to class TCipher_SCOP CODE:00519C4A mov edx, ds:off_4F2D94 ; * Reference to class TCipher_SAFER_SK64 CODE:00519D6B mov edx, ds:off_4F2C54 ; * Reference to class TCipher_SAFER_SK40 CODE:00519E67 mov edx, ds:off_4F2ED4 ; * Reference to class TCipher_SAFER_SK128
最後將使用者名稱變換輸出結果和註冊碼變換輸出進行比較。
對於1.75版只使用了Cast128和Gost兩種演算法,而1.92版堆疊了大概有18種密碼學演算法,
但由於該庫格式又比較固定,總體說來所以不難做出序號產生器。基本上就照著作者的流程,使用者名稱變換部分全部照抄,
註冊碼變換部分從後往前逆向使用。類似這樣,只是把DecodeBuffer改為EncodeBuffer就可以了,類似
程式碼:
CipherManager1.Algorithm := 'Twofish'; CipherManager1.InitKey(keystr, nil); CipherManager1.EncodeBuffer(Source,Out,$18);
另外注意其中有些DEC庫函式的s盒被更改,所以還需要修改DEC控制元件中的cipher.inc裡面的值,重新編譯該控制元件。
感謝DiKeN/IPB提供ResScope1.75序號產生器原始碼,省下了我不少時間,:)。
yesky1/IPB
7.21
相關文章
- 演算法分析2024-10-09演算法
- 加解密演算法分析2020-06-29解密演算法
- 如何分析排序演算法2022-06-16排序演算法
- CryptCD 3演算法分析2015-11-15演算法
- SFR演算法原理分析2024-08-21演算法
- 演算法分析__級數求和2019-03-05演算法
- 演算法分析__時間估算2019-03-05演算法
- 演算法分析__遞推方程2019-03-05演算法
- ETH-Pow演算法分析2019-02-20演算法
- 演算法複雜度分析2021-09-19演算法複雜度
- 演算法分析基本概念2018-05-14演算法
- 演算法複雜性分析2013-09-25演算法
- 計程車管理
1.2 演算法分析2004-08-16演算法
- supercleaner註冊演算法分析2015-11-15演算法
- 排名演算法(二)--淘寶搜尋排序演算法分析2018-12-31演算法排序
- 演算法分析__遞迴跟蹤2019-03-05演算法遞迴
- 演算法複雜度分析(下)2018-09-30演算法複雜度
- 演算法複雜度分析(上)2018-09-27演算法複雜度
- 關聯分析(二)--Apriori演算法2018-12-29演算法
- 演算法設計與分析(fd)2020-12-28演算法
- 演算法的複雜度分析2022-06-14演算法複雜度
- React原始碼分析 - Diff演算法2018-03-08React原始碼演算法
- 一致 Hash 演算法分析2018-01-07演算法
- 空間分析演算法——Spatial Jion2014-12-17演算法
- CCproxy6.0的演算法分析2004-07-10演算法
- Teleport
pro 演算法簡單分析2004-07-15演算法
- System
commander 8 演算法分析2004-07-17演算法
- 護花使者 2.0演算法分析2015-11-15演算法
- 中華通訊錄演算法分析2015-11-15演算法
- 單詞背背佳1.0演算法分析2015-11-15演算法
- SpeedFlash註冊演算法分析(VB)2015-11-15演算法
- [原創]破解-分析Crackme演算法2009-06-13演算法
- 演算法分析是一種享受---IP-Tools中的密碼學演算法詳細分析2004-12-10演算法密碼學
- 關聯分析Apriori演算法和FP-growth演算法初探2018-08-04演算法
- javascript資料結構與演算法--基本排序演算法分析2015-04-01JavaScript資料結構演算法排序
- 解密Oracle資料存取演算法(附程式碼、演算法分析)2006-12-06解密Oracle演算法
- loveasm的crackme演算法分析-----CRC32演算法的妙用2015-11-15ASM演算法
- 演算法分析__時間複雜度2019-03-05演算法時間複雜度