首頁 > 曲藝

不是吧,雙程序?

作者:由 風雲處 發表于 曲藝日期:2022-05-18

雙程序是什麼

不是吧,雙程序?

不是吧,雙程序?

使用工具:

IDA6。8(反彙編分析)

notepad(記錄)

vc6。0(解碼)

OD(除錯)

關鍵步驟:

一、程式碼自解密

IDA載入看入口點和匯入表,沒有發現任何有用的東西,考慮該程式已經加密處理。

不是吧,雙程序?

不是吧,雙程序?

進入sub_44701F函式,發現該函式主要是解碼。

不是吧,雙程序?

OD動態跟蹤發現如下圖所示,004473A8處的長跳轉代表本段解碼完成。

不是吧,雙程序?

此時可以從dump出記憶體用IDA觀察,此時函式已經完成解密,但由於匯入函式全部經由LoadLibrary和GetProcAddress動態載入,匯入表中也找不到有用資訊。

不是吧,雙程序?

二、識別真正流程

繼續OD動態跟蹤,在此處發現DialogBoxParamW,有過MFC程式設計經驗的朋友應該不陌生,說明我們已經找到關鍵點了(其實不然)。

不是吧,雙程序?

跟蹤發現此處的JE跳轉會實現,也就是DialogBoxParamW根本沒有執行,但程式執行起來的視窗是哪兒來的呢?

其實作者手動建立了一個程序,該程序和主程序基本相同,JE前的call判斷是主程序還是子程序。如果是主程序就直接跳過,是子程序則進入執行DialogBoxParamW。

不是吧,雙程序?

由於子程序無法直接附加(如下圖),從原理分析,可以直接將004016AF處的JE用NOP替換,強制進入主程序的流程。

不是吧,雙程序?

此時,視窗回撥函式為sub_00401740,其中和註冊有關的是sub_401A40如下。

不是吧,雙程序?

不是吧,雙程序?

和註冊有關的邏輯在紅線之間,最多19個0xFF以下的數相加,結果等於0x127514D,明顯不可能成立。

思路錯誤。

既然附加不了,可以dump子程序記憶體,用IDA分析。再看sub_401A40,發現就剩一個頭了,真正的邏輯在sub_402300。

不是吧,雙程序?

三、第一個關鍵演算法

實際除錯時可以在4016AF處將JE用NOP代替,將401A43處修改為jmp402303,即可繞過,直接除錯主程序。

另外,此題動態記憶體執行程式碼較多,建議關鍵位置下好“硬體執行”斷點,便於除錯。

不是吧,雙程序?

不是吧,雙程序?

sub_402300函式比較長,IDA中F5後還有800多行,結合動態除錯,找到關鍵位置。

不是吧,雙程序?

考慮對第9、10位的數字進行列舉,動態除錯找到待解碼和比較的資料,編寫程式碼如下。

#include

unsigned m_DE0000[] = { 0x83F08EA7,0x3F0FBA29,0xE747E97C,0x93D03647,0xEC72CD2C,0x93C0BA2E,0x90A578A3,0x2A40BA2F, 0xDB3FF233,0x9031FB09,0xD1477258,0x905E3DAC,0xAB817C35,0x6BD43434,0xC49E84E4,0x83B426AF,0x51C0BA3A,0x280080B8,0x93BE3FF3,0x8E36BA3B,0xE9C0BA3C,0x93C0BA29,0x93C0B2C5,0x1680CD3F};

unsigned m_4340B0[] = { 0x1070EC81,0x55530000,0xBC8B5756,0x00108424,0xBBF63300,0x00000001,0x0725C68B,0x79800000,0xC8834805,0x07B140F8,0xC68BC82A,0x07E28399,0xF8C1C203,0x38148A03,0xD322FAD2,0x10349488,0x46000002,0x7C40FE83,0x0002BDCF,0x05BA0000,0xBE000000,0x00000014,0x000008B9,0x8DC03300};

int main()

{

unsigned xx = 0;

unsigned yy,zz1,zz2;

for(xx=0;xx =0xff;xx++)

{

yy = 0x1010101*xx;

zz1=(m_DE0000[0]+yy)^m_4340B0[0];

zz2=(m_DE0000[1]+yy)^m_4340B0[1];

if(zz1 == (zz2-1))

{

printf(“%02X\n”,xx);

printf(“%08X\n”,zz1);

}

}

return 0;

}

得到結果。

不是吧,雙程序?

因此註冊碼前10位為“75A29C09E1”。前10位輸入此註冊碼,可以看到解碼結果為正常的反彙編,說明是正確的。

不是吧,雙程序?

四、第二個關鍵演算法

還是sub_402300中,剛解碼的函式對輸入註冊碼第10位以後的字串進行處理,處理結果與“!HelloHaniella!”比較,返回值與sub_402240的返回值比較。

不是吧,雙程序?

此處,可將記憶體中已解碼的函式dump出來,用IDA分析。

IDA載入,發現非常直觀,但也非常長,F5後還有2838行,難以下手。

不是吧,雙程序?

不是吧,雙程序?

百度搜索常量,發現是DES的置換表,該程式將DES中所有的東西都放在一個函式中,顯得特別龐大,也加大了分析難度。

將函式的輸入輸出與標準DES對比,發現不一樣。接下來就是對照標準DES和該函式,修改DES和該函式一樣。

不同點1: ByteToBit

該函式中,如下

不是吧,雙程序?

不是吧,雙程序?

故,修改標準DES中對應函式,如下

不是吧,雙程序?

不同點2 :子秘鑰使用順序

該函式中,與子秘鑰的異或操作從最後一個開始

不是吧,雙程序?

故修改標準DES加密操作中對應位置如下

不是吧,雙程序?

相對的,修改解密操作程式碼

不是吧,雙程序?

不同點3 :ByteToBit1

不是吧,雙程序?

故修改標準DES中程式碼如下

不是吧,雙程序?

不同點4 :調整R、L順序

除錯發現,最後的R和L順序反了,故修改程式碼。在加密操作最後和解密操作最前均加上如下程式碼。

不是吧,雙程序?

這四處修改後,DES演算法加密結果和該函式一致,且能正常解密。

此加密結果還要經過如下過程,將偶數字節0、1互換。

不是吧,雙程序?

然後再轉換為16進位制Byte,與“!HelloHaniella!”比較。故解密可以將此字串轉化為bit,然後偶數位取反,再透過修改後的DES演算法解密,結果即為註冊碼10位以後的正確結果。

分兩次,各8位,分別得到結果“80217C048420956C” 和 “15DA309FF2B69170” ,如下。

不是吧,雙程序?

不是吧,雙程序?

五、結論

組合兩個關鍵演算法的結果,得到註冊碼“75A29C09E180217C048420956C15DA309FF2B69170”,輸入程式,結果如下。

不是吧,雙程序?

當然,由於作者沒有考慮到結尾的0x00,導致結尾加上(0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00)解密後的結果“FAB17827375A8685”後依然正確,如下。理論上講有無數個 即“75A29C09E180217C048420956C15DA309FF2B69170(FAB17827375A8685迴圈)”。

不是吧,雙程序?

題目連結:看雪CTF2017年中賽第11題

長按關注