軟體解密技術研究 (轉)
ideograph; MARGIN: 9pt 0cm; TEXT-ALIGN: justify">技術研究:namespace prefix = o ns = "urn:schemas--com::office" />
---- PE 脫殼
透過設定Hook,動態跟蹤堆疊,對加過殼的可檔案進行解密還原。
當然,要解密,至少先要----得到一個被過的“正版” 軟體。
然後----編寫簡單的Deger。
僅需要攔截LoadLibray/GetModuleHandle/GetProcAddress,在這三個Hook中執行記錄Library檔名,Procedure(匯入)名。自己按ImportTable結構偽造一個ImportTable,並額外的相關資訊。
為每個匯入函式生成一個Hook函式體,該函式(我們的Hook) 從堆疊中取得返回地址(即該函式的call指令的下一條指令的地址) ,對返回地址的前一條指令(即呼叫該函式的call指令)進行譯碼,一般是如下可能的形式:
call jump_thunk
call [thunk_fun]
call reg ;為簡單,先忽略此形式
call [reg] ;為簡單,先忽略此形式
call [reg + thunk_offset] ;為簡單,先忽略此形式
其它奇奇怪怪的形式完全忽略不考慮,如
push offset ret_address
push fun_address
ret
ret_address:
或:
push offset ret_address
jmp fun_address
ret_address:
關鍵的難點在這裡,很有可能在此處出現問題,因為反向譯碼有可能把一個地址錯誤的當成指令譯碼了(不過這種情況很少) 。如果忽略這些問題,則這一個難點就OK了。
稱返回地址的前一條指令,即呼叫該函式的call指令,為caller_entry。
caller_entry指令的bin code為:op XXXXXXXX,其中XXXXXXXX為轉向地址。我們的hook code都做些什么工作呢?
1. 讀出caller_entry及其附近一些bin code並寫入我們的檔案,為其後進一步分析用,當然該指令中XXXXXXXX會被記錄下來。
2. 由於動態自動跟蹤不可能跟蹤到所有呼叫Import Function的地方,但幾乎可以跟蹤到對至少一個Import Function的一次呼叫。所以改動XXXXXXXX(即jump_thunk或fun_thunk的值)可能不太實際,於是只有----
3. 對 jump jump_thunk,我們走到jump_thunk,這裡一般是
”call [fun_thunk]” 的形式。
4. 把fun_thunk寫入我們的Crack檔案,為進一步分析使用。
5. 在這樣的過程中我們需要儘量遍歷“該正版軟體”所有的操作路徑(如點檔案>儲存/另存,編輯>複製/貼上...
6. 使用者點選Debugger的“遍歷結束” 按鈕,就可以把整個PE Image Dump出來。
然後,點選Debugger的“分析&” ,即可分析我們生成的Crack檔案。
分析過程中的主要操作是:
1. 修改 Dump出來的,主要是PE Header和Section Table。
2. 走到fun_thunk,把[fun_thunk] 改為我們的hook地址。
該脫殼軟體的特點(區別與其它脫殼軟體)基本上只有一點:其它脫殼軟體都是想辦法取得殘留的ImportAddressTable或ImportNameTable,從其中做文章。
而該軟體是從的執行中獲得實際的thunk地址,並自己構造ImportTable。
其實一切都很簡單!
後記:
本人一年前作“軟體加密技術及實現” 為畢業論文,工作一年來,因專注於工作,幾乎已經廢棄了加密的研究。
不久前有朋友說:“你就會加密,你怎知你加密的不能被別人破解?” 於是又老毛病大發,連做夢都想:用什么辦法可以使別人不能破解?想來想去,總不能找到完全之策。最後終於想到了一個:“地址加密” 方法,即把ImportFunction的地址加密,呼叫ImportFunciton時,先解密地址再跳轉到ImportFunciton,具體實現如下:
寫一個Hook Code,把ImportAddressTable中的地址填為該Hook Code的地址,於是對應與每一個ImportAddressTableEntry,都有一個Hook Code的副本,該Hook Code對加密過的地址進行解密,然後再跳轉過去。該Hook Code讓它(cracker) 總不能從 PE Image中得到任何ImportFunction的地址。
我自以為此方法完美無缺,然而不久我又想到了破解方法,即此文所描述的。
於是,很快,我又找到了另外一種方法來對付這種破解----
在HookCode開始,把返回地址(即文中所說的call_entry) 加密,然後為被調函式(即該ImportFunction) 建立一個新的StackFrame,再把call_entry之前傳來的引數複製到新的這個StackFrame中。然後呼叫ImportFuncion。
然而此方法也有問題----我實際上不知道被調函式有幾個引數。
所以我為它建立StackFrame時,只能把該StackFrame建得足夠大,可以容納引數最多的函式----如我假設它至少有100個引數,於是這會浪費較多的堆疊區,幸好這裡不會有遞迴呼叫,否則堆疊有可能。這個問題暫時得到了解決。
然而又出現了另外一個問題----當被調函式返回,我不知道它到底跳過了幾個引數(ImportFunction一般是stdcall,跳過引數區的責任由被調者完成) 。即被調函式返回後,ESP的值與呼叫前不同。
幸好,函式呼叫不會改變ESI,EDI,EBX,EBP的值,我只要選用這其中的一個暫存器,如EBP,然後用他儲存呼叫前的ESP(當然要先把它存入堆疊而後在恢復)。再呼叫ImportFunction,待它返回後,
ParamSize =(StackFrameSize – (EBP – ESP)) 就是被調者跳過的引數區的尺寸。
然而又有問題:此刻怎么返回?我必須跳過引數區呀! 如果我可以生成一條指令ret ParamSize----(ParamSize必須是立即數) ,就可以了。
但又有問題----這樣的程式碼是不可重入的!
沒辦法了嗎?當然有,這樣的程式碼可以完成ret ParamSize的功能:
add ESP, ParamSize
jmp [ESP – ParamSize] ;此刻,該返回地址已經解密.
一切OK!!
此加密方法,徵求破解!!
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10748419/viewspace-960915/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 軟體狗[Dongles]的加密與解密技術加密解密
- 加密技術面面觀 (轉)加密
- 【Java】常用加密技術與程式碼研究總結Java加密
- 密碼學-軟體加密技術和序號產生器制密碼學加密
- 軟體藝術 (轉)
- 加密技術加密
- 資訊加密技術加密
- 線上視訊網站加密技術詳解網站加密
- Python3 加密解密技術詳解Python加密解密
- 加密技術解決資料被竊取加密
- 古老的加密技術加密
- 淺談加密技術加密
- 現代加密技術加密
- 軟磁碟反拷貝加密技術 [1] (4千字)加密
- 軟體技術的森林時代 (轉)
- 微軟的Office2000的加密技術(轉)微軟加密
- 資訊加密技術簡介加密
- 網路安全:加密技術加密
- 湖南文件透明加密軟體哪個好用?什麼加密技術的文件加密軟體適合企業發展?風奧科技加密
- 廣東文件加密軟體哪個好用?政企如何選擇驅動層透明加密技術的文件加密軟體?風奧科技加密
- ISA軟體研究初探
- Ponemon:2021年全球加密技術趨勢研究報告(附下載)加密
- 軟體專案可行性研究報告(轉)
- PHP常見的加密技術PHP加密
- 深入瞭解Rabbit加密技術:原理、實現與應用加密
- 資料庫加密與解密技術之一 FOXPRO篇 (轉)資料庫加密解密
- MFC框架軟體逆向研究框架
- 軟體、軟體危機、軟體工程 (轉)軟體工程
- 什麼是沙盒加密技術?加密
- 軟體專案可行性研究報告編寫(轉)
- redux 原始碼研究:中介軟體Redux原始碼
- ICE中介軟體研究筆記筆記
- 非對稱加密技術:共享祕鑰加密
- 詳細解析DES系列加密技術(二)加密
- Python 程式碼混淆和加密技術Python加密
- 詳細解析DES系列加密技術(一)加密
- Java加密技術(八)——數字證照Java加密
- Java加密技術(十一)——雙向認證Java加密