閒話破解

看雪資料發表於2003-08-24

Think like a cracker

  以前在E文的破文中,經常可以見到一句話:“Think like a cracker”。隨著破解的東西多了,慢慢積累一些經驗,覺得這話大有深意。

  以我的理解,大概是指要善於揣摩保護者的想法。我也沒法描述清楚,只是有點感覺,在破解的時候,要多從具體的程式碼中跳出來想想,把握大局,判斷形勢,決定正確的方向。能把這方面的東西表現在破文裡,我想會更有意思。

  以下是以前破解的一個軟體,比較舊了(整理以前的筆記得來的,做不到總用剛破解的東西來寫文章)。

  是個股票分析類的軟體,叫StockNT吧。背景如下:
  
  使用者可從Internet下載,功能有限制(好象是資料不能更新)。使用者向作者付款後,可從其網站下載一個叫formal.ini的檔案,拷入安裝目錄,然後再聯機註冊,成功後即為正版使用者。不能從別的機器複製,只能用以上方式成為正式使用者。只能在一臺機器上註冊,若要把軟體安裝到別的機器上,必須先“聯機登出”,安裝後重新註冊。


1.先來研究一下formal.ini。斷在CreateFileA,很快就可以找到訪問該檔案的程式碼。簡單  的分析之後,可得到以下結論:

  檔案長度僅18個字元,只使用了前16個,為16進位制數字。可以用UltraEdit自己做一  
   個,便於分析。假設檔案內容為0123456789abcdef01,

   將前16字元轉換為數字,結果為:
  
  76543210,fedcba98兩個dword。

  其使用方式為:

  42A939  push 2
           push eax           //指向包含上述2個dword的buffer
           call f_Compute     //我取的名字:-)
           mov eax,[ebp-28h]  //還是放在那個buffer中的第一個值(計算結果)
           pop ecx
           cmp eax,[ebp-24h]//與第2個值比較
           pop ecx
           jnz l_TrialVersion

   即經過call的處理後得到的2個dword必須相等。

  現在來推測一下:雖然這個檔案是付款之後才可獲得,但還未“聯機註冊”,不會含有與使用者相關的真正資訊。也許,只是一個簡單的計數,表示“第XXX個使用者”。做的保護,只為避免誰都可以做一個formal.ini去註冊。這個函式內的計算比較複雜,難以迅速弄清其演算法。
   如何做出一個這樣的檔案?很容易想到暴力窮舉。根據以上的推測,可以相信:我們只需給出一個dword的值,計算另一個dword即可。

   在上述地址設斷點,斷下後在SoftIce中手工輸入程式碼:初始化一個dword為0x76543210,另一個為1。在迴圈中遞增第2個值,找到符合條件的值或到達0xFFFFFFFF後,呼叫int 3。按F5開始計算,等待一段時間後,SoftIce彈出,得到的結果為0xEA0D4CAD。所以,可做出一個正確的formal.ini檔案,內容為:

   01234567DAC4D0AE01//最後的"01"未用

2.首先,我不打算真的去“聯機註冊”(破解時,是在不能上網的機器上做的)。很快可以發現,有了formal.ini之後,執行時程式會訪問安裝目錄下的Reg\Register.ini檔案,這才是真正的keyfile。同樣,從訪問檔案的程式碼可以看到,這個檔案長度為36字元,格式與formal.ini相似,有2行。將檔案內容讀出後經過變換,與正確值對比。正確值是由使用者機器的一些特徵資料計算而來的,包括硬碟資訊(與分割槽相關的資料),一些系統檔案的時間戳,系統時間等等)。這就是所謂的只能安裝在一臺機器上的由來。

  結合靜態分析,對程式碼稍加跟蹤,可得到全部用於比較的正確值。問題是,這裡做的是密文比較。Register.ini的資料經過與formal.ini一樣的處理(每次取一行的16字元轉換為數字),經上述的f_Compute的計算後才用於對比。拿到正確的結果,如何得到被f_Compute處理以前的資料?此函式計算太複雜,層層呼叫子函式,難以看清其計算方式,更不要說寫出個反函式。

   利用前面formal.ini的資料做個測試,把結果作為引數放入buffer,f_Compute得到的結果並非是原來的引數,即此函式不是既可加密又可解密的雙向函式,沒有捷徑可走。

   現在該怎麼辦?再來猜一猜,Think like a cracker呵呵。既然使用者在獲取formal.ini後,可以透過聯機註冊成為正式使用者,那麼,註冊成功後,程式自己必定會有建立Reg目錄,生成Register.ini的動作,也就是說,f_Compute的反函式必定已存在於程式碼之中。我們只要找到這個函式,把用於比較的正確值作為引數輸入,經該函式處理的結果就是Register.ini的正確內容。

   如何找到該函式?有很多線索:與WinSock相關的函式呼叫,對CreateDirectoryA的呼叫,對"Register.ini"字串的使用等等。總之,找到了,在這個過程中隨時可用formal.ini的資料來測試。要注意的是,要手動修改WinSock相關函式呼叫的返回值,否則我們的目標函式執行不到(實際上,只要執行了該函式,破解也就成功了:-)。

  最後得到Register,ini的正確資料為:

  37BC43727C4B3BA801
  E10226146C01741601//每行最後2個字元未用

  多說兩句,我不太喜歡列出大段的程式碼,我覺得對閱讀者沒什麼用。儘量說明破解過程中的一些思路想法可能更有意思。各位大蝦以為如何?


相關文章