看世界盃,漫步ASProtect ----- ASProtect的加密演算法初步分析
近來有時間分析了一下ASProtect,略有所得,也有不少疑問。
原來ASProtect的幾個函式的作用對保護強度提高不小。一改以前我見過的殼重技巧輕演算法的毛病,的確在有些方面值得學習。
其利用的原理如下:
1)程式在程式設計時可以根據需要選擇使用ASProtect提供的幾個函式。
比如:
SetRegistrationKey(...),
GetRegistrationInformation(...),
GetHardwareID(...)
這幾個函式由於使用了匯出方式的宣告所以會在ExportTable中出現,ASProtect在加殼時可以透過分析ExportTable識別出程式使用了哪些其提供的函式,從而對這些函式的入口進行掛鉤,從而使其加殼後的外殼程式碼可以象回撥函式一樣呼叫這些函式與程式進行通訊。
比如見以下程式碼:
0041333E loc_41333E:
;
CODE XREF: sub_413253+B0j
0041333E
mov eax, ds:4155CCh
00413343
cmp dword ptr [eax+0Ch], 0
00413347 jz
short loc_413360
00413349
mov eax, ds:41555Ch
0041334E
mov eax, [eax]
00413350
call @System@@LStrToPChar$qqrv
; System __linkproc__ LStrToPChar(void)
00413355
push eax
00413356
mov eax, ds:4155CCh
0041335B
mov eax, [eax+0Ch]
0041335E call
eax
00413360
00413360 loc_413360:
; CODE XREF:
sub_413253+F4j
00413360
mov eax, ds:4155CCh
00413365
cmp dword ptr [eax+30h], 0 ;
eax 是一內部結構指標
00413369
jz short loc_413389
0041336B
push 41105Ch
00413370
mov eax, ds:4155CCh
00413375 mov
eax, [eax+30h]
00413378
call eax
; 這裡將呼叫 GetDecryptProc(...)
0041337A
push 41105Ch
0041337F
mov eax, ds:4155CCh
2)程式在程式設計時還可以加入ASProtect提供的兩個宏定義,這兩個宏定義實際上將起到特殊的標誌作用,有點類似"塊開始"和"塊結束"的作用。在ASProtect將在加殼時將對"這些塊"中的程式碼進行加密。對這些程式碼塊的加、解密使用了的密碼學演算法。目前還不十分清楚其使用的演算法,初步分析這裡可能用到了TWOFISH。因為發現了一些特徵:
初始化部分有以下常數設定:
0040C4AE
mov dword ptr [ebx+48h], 67452301h
0040C4B5
mov dword ptr [ebx+4Ch],
0EFCDAB89h
0040C4BC
mov dword ptr [ebx+50h], 98BADCFEh
0040C4C3
mov dword ptr [ebx+54h], 10325476h
0040C4CA mov
dword ptr [ebx+58h], 0C3D2E1F0h
0040C4D1
mov dword ptr [ebx+5Ch], 76543210h
0040C4D8 mov
dword ptr [ebx+60h], 0FEDCBA98h
0040C4DF
mov dword ptr [ebx+64h], 89ABCDEFh
0040C4E6
mov dword ptr [ebx+68h],
1234567h
0040C4ED
mov dword ptr [ebx+6Ch], 3C2D1E0Fh
而運算部分有大量類似MD5演算法的運算。由於程式碼太長,不列舉了。
3)在ASProtect中我們看到其提供了Registration_Keys加密方式。ASProtect可以對你提供的"Registration_Information"進行加密,形成"Registeration_Key",(按照幫助中介紹的你還可以使用自己的"加解密演算法",但是RegKey必須至少173個字元,才有安全性)。這個"RegKey"將以登錄檔檔案(.reg)檔案方式儲存。在加殼後的外殼程式碼執行時將解密"RegKey"從而得到"RegInfo",當然這分為兩種方式:一種方式,程式程式設計時使用了其提供的回撥函式SetRegistrationKey(...),那麼外殼程式碼執行時將呼叫該函式從而得到"RegKey"來解密出"RegInfo",如果程式沒有使用這個函式,外殼程式碼將從登錄檔中相應鍵名處提取鍵值作為"RegKey"來解密出"RegInfo"。初步分析其可能使用了RSA演算法。
其解密部分的程式碼:
0040B4D4 loc_40B4D4:
; CODE XREF: license+156j
0040B4D4
; license+15Fj
0040B4D4 lea
edi, [ebp+lpInterBlock]
0040B4DA
inc edi
0040B4DB
mov esi, edi
0040B4DD
push esi
0040B4DE
lea eax, [ebp+lpInterStruct+8]
0040B4E4 push
eax
0040B4E5
lea eax, [ebp+lpInterStruct+88h]
0040B4EB
push eax
0040B4EC
push esi
0040B4ED
call decrypt_engine
; Criper Text to Plain Text...
從 decrypt_engine 函式的入口引數看有四個:
1)加密資料地址指標....(函式按每一塊進行解密).....即
m
2)可能是RSA.N
3)可能是RSA.E
4)用於輸出解密資料地址指標....
目前還有幾個問題還沒有來得及分析:
1)還沒有見到TEA演算法,不過在CASPR中介紹中至少提到這個演算法,不知道這個演算法在哪裡,用於作什麼?
2)在我瞭解了ASProtect會利用宏定義定義出"程式碼塊"以後,我想象ASProtect中其會把"程式碼塊"挖出來",與"RegInfo"一起加密形式成"RegKey"。不過實際發現這些"程式碼塊"並沒有被"挖"出來,而是使用一種演算法(可能是TWOFISH)解密,不知道這個KEY到底儲存在哪裡?不知道是否儲存在"RegKey"中。我想大概如此。^_^
我想我們可以把ASProtect看成一個"軟鎖"。"鎖"中的資料包括用於解密的程式碼塊的KEY和用於解密"RegInfo"的KEY,即我們所見到的字串形式的"RegKey"。在外殼程式碼執行時ASProtect將提取"鎖"中的資料用於解密。
如果某程式分為"註冊版本"和"試用版本",其使用ASProtect外殼+內部函式組合方式加密。其註冊版本將提供.reg登錄檔檔案形式的"RegKey"作為開鎖的"鑰匙",那麼我們能否在沒有"鑰匙"的情況下破門而入呢?
由於RegKey中包含了用於解密程式中提取出來的"程式碼塊"的KEY,那麼在沒有RegKey的情況下自然我們也就缺少了這個KEY,因此程式中的被提取出來的"程式碼塊"就無法正確解密。如果在此情況下脫殼,那麼那些加密了的程式碼塊中的資料依然是無用的資料,因此脫殼的軟體就成了破碎的脫殼版本了。因此在沒有鑰匙的情況下看來破門而入的想法不太樂觀。
3)那麼我們想能否推算出RegKey呢?目前我還不太清楚。有時間再分析了。
好,寫到此處,不想浪費時間了。不知道以後的"幻影"是否也會.....。:-)
如果你看了我的這個貼子的話,知道我目前的幾個問題,可以和我聯絡。
Email:ljtt@yeah.net。(不要來信要我脫殼之類的)