close

Sandboxie 註冊演演算法分析

【文章作者】: uuk
【軟體名稱】: Sandboxie 3.49.06
【下載地址】: http://www.sandboxie.com/index.php
【加殼方式】
【保護方式】序號
【編寫語言】: Microsoft Visual C++ 7.0
【使用工具】: PEIDIDA Pro with Hex-Rays pluginSyser
【操作平臺】: XP SP3
【軟體介紹】: Sandboxie 允許你在沙盤環境中運行流覽器或其他程式,因此運行所產生的變化可以隨後刪除。可用來消除上網、運行程式的痕跡,也可用來還原我的最愛、主頁、註冊表等。即 使在沙盤進程中下載的檔,也會隨著沙盤的清空而刪除。此軟體在系統託盤中運行,如果想啟動一個沙盤進程,請通過託盤圖示(而不要用原方式)啟動流覽器或 相應程式。
【作者聲明】菜鳥學習演算法,失誤之處敬請諸位大俠賜教!

    Sandboxie3.48版本開始採用新的啟動方式——聯網啟動,但也為不能上網的電腦提供了離線啟動方式。能離線啟動說明註冊的驗證是在本地進行的,方便我們進行演演算法分析。官方離線啟動網址:http://www.sandboxie.com/index.php?OfflineActivation。在之前我已經通過官方的離線啟動網頁得到一個離線啟動碼KeyRF0UD7XH6KREU2TX……E4YJ1PT8RW8PO)。
    通過跟蹤啟動過程,啟動管理程式License.exe調用SbieDll.dllSbieApi_ActivateLicenseSbieApi_ActivateLicense通過IRP_MJ_DEVICE_CONTROL與驅動SbieDrv.sys通信,最終驗證過程在驅動SbieDrv.sys裡。通過IoControlCode定位到函數sub_20744(重命名為ActivateLicense),查看ActivateLicense的交叉引用,發現在驅動載入過程中也被調用了,因此可以確認驗證過程就是sub_20744ActivateLicense反彙編代碼如下:
.text:00020744    push    ebp
.text:00020745    mov     ebp, esp
.text:00020747    sub     esp, 28h
.text:0002074A    push    esi
.text:0002074B    push    24h     ; 36 = 24h
.text:0002074D    push    [ebp+pKey]      ; ActivationKey(UNICODE)
.text:00020750    xor     esi, esi
.text:00020752    push    pPagedPool_tzuk ; PagedPool("tzuk")
.text:00020758    mov     [ebp+var_18], esi
.text:0002075B    mov     [ebp+var_14], esi
.text:0002075E    call    sub_1C1C8     ; mpz_set_str (mpz_t rop, char *str, int base)
.text:0002075E                          ; return eax = rop
    仔細分析sub_1C1C8,會發現它是將字串Key當作36進制數,轉換成16進制的大數(有點像GMP庫裡的mpz_set_str(Key, ActivationKey, 36))。由於是大數操作,所以sub_1C1C8裡有大量的記憶體操作,剛開始分析時就讓我暈頭轉向,同時又是大數運算,比較複雜。我花了不少時間才搞明白它在做什麼,也知道程式中是如何存儲大數的。大數結構如下所示:
struct BigNum{unsigned int size;  unsigned int num[size];}
大數在記憶體中按從低到高的位址存儲從低到高的數。知道了大數的結構,以及記憶體申請和釋放操作,後面的分析就會輕鬆許多。
.text:00020763    cmp     eax, esi        ; 大數 Key = eax
.text:00020765    mov     [ebp+pKey], eax
.text:00020768    jnz     short loc_2077E
.text:0002077E ; ---------------------------------------------------------------------------
.text:0002077E
.text:0002077E loc_2077E:                 ; CODE XREF: ActivateLicense+24 j
.text:0002077E    push    ebx
.text:0002077F    push    edi
.text:00020780    push    offset MOD
.text:00020785    push    offset EXP
.text:0002078A    push    eax
.text:0002078B    push    pPagedPool_tzuk
.text:00020791    call    sub_1C09E    ; mpz_powm (mpz_t rop, mpz_t base, mpz_t exp, mpz_t mod)
.text:00020791               ; return eax = rop
    大致分析sub_1C09E,排除記憶體操作後,發現裡面有一些除法運算,初步確定是在做大數除法,但是在自己用大數計算器驗證時發現結果總是不對,於是以為在sub_1C09E裡有其他小動作。花了好幾個晚上,仔仔細細的研究了裡面不確定的CALL,以及運算過程,最後確定sub_1C09E裡面做的就是大數除法和求模運算。既然是除法,那為什麼測試時結果不對呢?我又去分析了下測試過程,發現我寫的一個字串反轉程式少做一次對換,導致中間的兩個字元沒被反轉(大數在記憶體裡是從小到大存儲,而計算器中是從大到小,所以要反轉)。這樣浪費了幾天時間,但也讓我明白了大數除法的演算法。確定了sub_1C09E裡面的大數運算過程,寫出數學表達示,化簡後發現是類似mpz_powm(Reg, Key, EXP, MOD)的函數。在sub_1C09E之後,註冊資訊就以明碼放在記憶體中,後面就是一些資料的校驗了。想要寫出註冊機就得能反求Reg = Key^EXP mod MOD,我求不出來,於是到論壇上求助http://bbs.pediy.com/showthread.php?t=123926lingyu大俠告知這是RSA2048加密演算法,在這要感謝大俠們的指點! 
下麵是資料校驗過程:
.text:00020796    mov     ebx, eax        ; ebx = Reg = eax
.text:00020798    mov     eax, [ebx]
.text:0002079A    cmp     eax, 4          ; Reg 長度size大於4
.text:0002079D    push    12h
.text:0002079F    pop     esi
.text:000207A0    jbe     loc_20A39
.text:000207A6    mov     cl, [ebx+4]
.text:000207A9    and     cl, 0Fh
.text:000207AC    cmp     cl, 1           ; Reg 最低位為1
.text:000207AF    push    13h
.text:000207B1    pop     esi
.text:000207B2    jnz     loc_20A39
.text:000207B8    push    14h
.text:000207BA    pop     esi
.text:000207BB    lea     eax, ds:0FFFFFFF4h[eax*4] ; size*4-0Ch
.text:000207C2    push    eax
.text:000207C3    lea     edi, [ebx+10h]
.text:000207C6    push    edi
.text:000207C7    call    sub_1B4B8      ; CheckSum 資料校驗
    sub_1B4B8是對註冊資訊Reg進行校驗,返回兩個校驗值,裡面有兩個CALLsub_1B392sub_1B418),看Hex-Rays plugin生成的C代碼,很容易就能自己寫出個checksum生成函數,代碼在附件裡有。也不知道是有現成的函數,還是作者杜撰的。
.text:000207CC    cmp     eax, [ebx+8]  ; 比較校驗值1[ebx+8]
.text:000207CF    jnz     loc_20A39
.text:000207D5    cmp     edx, [ebx+0Ch] ; 比較校驗值2[ebx+0Ch]
.text:000207D8    jnz     loc_20A39
.text:000207DE    cmp     dword ptr [edi], 80000001h ; [ebx+10h]
.text:000207E4    push    21h
.text:000207E6    pop     esi
.text:000207E7    jnz     loc_20A39
.text:000207ED    cmp     dword ptr [ebx+14h], 1 ; [ebx+14h] == 1
.text:000207F1    push    22h
.text:000207F3    pop     esi
.text:000207F4    jnz     loc_20A39
    再後面還有到期時間與當前系統時間的比較,軟體版本的比較,系統碼的比較,在IDA裡很容易就能看得懂,這裡就不詳細說明瞭。註冊資訊的結構如下所示:

 4.jpg  

關於註冊機:RSA2048是很難反求的,只能通過替換公開金鑰的方法進行破解(看雪論壇精華裡看到的)。由於是替換驅動SbieDrv.sys裡的公開金鑰,替換後還得修正檔的CheckSum,不然驅動不能載入。附件裡是我寫的一個簡單的PatchKeygen
    
同時有個疑問:SbieDrv.sys打過補丁後,其數位簽章就變成無效了,既然RSA可以通過替換公開金鑰進行攻擊,那檔的數位簽章可不可以偽造?

arrow
arrow
    全站熱搜

    殘月影 發表在 痞客邦 留言(0) 人氣()