對某軟體的 時間限制 的 ida 靜態分析 與破解

來源:互聯網
上載者:User

本文是本菜鳥對 ida 靜態分析的一次實踐。對於本文中所涉及ida 的使用知識,請參閱壇主《加密與解密》第三版 3.2.1--3.2.14  中的相關內容。

 

 

閑話不敘。

癥狀:程式運行一小時後,運行開始不正常。一些字元開始跳動。無其它提示。

思路:從擷取系統時間的 API 入手,尋找時間比較的相關代碼。

開工。

查殼,無。開發語言: Borland c++ builder 1999

 

運行以加深對程式的瞭解。啟動程式,直接將系統時間後移一小時,程式出現異常。說明修改系統時間可影響到程式對已耗用時間的判斷。

將程式用ida 載入。在 "functions window" 視窗( 找不到則 菜單 windows-> functions window 或 alt+ 1),尋找時間相關的API。在 functions window 視窗中,系統api 用紅底加粗標識。對 "start"列進行排序,可將 api 集中起來,方便尋找。(原理?大概因為api 都在匯入表中吧)

找到了兩個可能相關的函數: getlocaltime 和 getticktime 。前者用來擷取系統目前時間,後者用來擷取系統啟動以來的時間。後者不受修改系統時間的影響。結合前面測試得知程式受修改系統時間的影響,故不考慮 getticktime。

在 getlocaltime 上右鍵,下斷點。


 

 

f9 運行程式,程式被斷下來。

 

 

 中,code xref : 對此函數進行了調用的函數。綠色部分列舉了兩個。在函數名上右鍵,"jump to xref to operand "。可以看到共有四處調用:

 

以上四處,第二處 Sysutils::CurrentYear 顧名思義,只能取到 年份,幫不考慮。其它的三處,需要繼續上溯,直到使用者代碼。

 

先看 sysutils:now ,轉到了

 

 

 

 繼續上溯對 now 的調用。

 

可以看到調用比較多。通常情況下,我們需要對每一個進行跟蹤。但這時我們看到了一個高度興趣的東東: FormShow。筆者編寫過 vb ,知道寫圖形介面程式的第一步就是 FormShow。估計delphi 也是這樣吧。不需要做艱難的決定。直接跟蹤。雙擊“_TFNewGoMain_FormShow+33”。到達下面的介面。

 

 

.text:00408E43 call    @Sysutils@Now$qqrv              ; Sysutils::Now(void)
.text:00408E48 fstp    dbl_CEEC9C
查閱手冊得知,Sysutils::Now() 返回了一個浮點數值。整數部分儲存1900年以來的天數,小數部分儲存今天已經消逝的時間比例。在 delphi 語言中,浮點數是儲存在浮點寄存器 fpu registers 中的。

fstp 指令的意思是將浮點數指令寄存器中的資料儲存到 變數 dbl_CEEC9C 中。

右鍵 dbl_CEEC9C,選擇 rename, 將變數dbl_CEEC9C 標記為 my_dbl_CEEC9_now,以方便識別。

現在我們對程式的設計思路比較清楚了。按現在的分析,程式在啟動時記錄了系統時間。並不斷地檢查,如果超過了一小時,就開始搗亂。我們只需要找到讀取my_dbl_CEEC9_now 的代碼,就能跟蹤到關鍵代碼了。

 右鍵 my_dbl_CEEC9_now ,"jump to xref operator",看到了如下的八處調用。

 

 

根據 type 列知道,對 my_dbl_CEEC9_now 的操作,有四處讀(r),三處寫(w),我們首先考慮 讀的代碼。

 

 幸運的是,我們第一次就到了合適的位置。見到了經典的比較和跳轉。

以上三處代碼:

 

.text:00404195 call    @Sysutils@Now$qqrv              ; Sysutils::Now(void)
.text:0040419A fstp    [ebp+var_380]                     ; 取目前時間
.text:004041A0 fld     my_dbl_CEEC9C_now             ;取啟動時儲存的時間
.text:004041A6 fadd    ds:dbl_404AA0                     ;啟動時儲存的時間加上一個值(一個多小時)
......

 

.text:004041ED fxch    st(1)                                   ;交換目前時間(st0) 和啟動時儲存的時間(st1)
.text:004041EF fucompp                                         ;比較!
......

 

.text:004041F4 setnbe  dl
.text:004041F7 and     edx, 1
.text:004041FA test    dl, dl
.text:004041FC jz      short loc_40422A                   ;小等於則跳!.text:004041FE call    sub_4AD208                          ; 幹擾函數

 以上代碼中,ds:dbl_404AA0  是一個全域變數。儲存了限定的時間長度。

00404AA0 dbl_404AA0 dq 0.04166666666666666       ; DATA XREF: sub_403E30+376r

 

0.04166666666666666  = 1/24,正好一小時,即我們想要的值。 觀察對 my_dbl_CEEC9_now 的其它幾處調用。可以看到,其它的三處 read 和上面的代碼基本一樣。三處 write 查了查,沒什麼關係,就不研究了。

對此程式的分析到此結果,接下來只需要對幾處變數對修改即可。本文主要介紹 ida 的靜態分析,代碼修改就不贅述了。 

如果你使用 hex-rays  的反編譯功能,分析時要注意的是delphi 語言的參數傳遞的一個特點。delphi 語言中,函數參數的傳遞是按照 eax,edx,ecx,棧變數 的順序來傳遞的。可以看到,一些明明沒有參數的函數,hex-rays 反編譯的c 代碼中卻添加了三個參數。這就是 eax,edx,edx。所以,在反編譯的c 代碼中,要認真辨別相關函數是否確實通過這些寄存器傳遞了參數。 改成三小時( 3/24 = 0.125 )試試。

查看記憶體 00404AA0  55 55 55 55 55 55 A5 3F改為00404AA0  00 00 00 00 00 00 c0 3F 

 

參考資料:

線上浮點數轉換

http://babbage.cs.qc.edu/IEEE-754/Decimal.html delphi 的函數呼叫慣例,浮點數的處理都和不同

 

 

 

 

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.