保護機制小窺 ---- 十三少不妨來看看
保護機制小窺
【宣告】
我寫文章以交流為主,希望大家在轉載時能保持文章的完整性。
【前言】
這次以介紹保護機制為主,就不寫什麼脫殼方法了,其實以前我也誤導了不少善良的觀眾。瞭解一個加殼軟體最主要的應該是瞭解其保護機制,這也是我後來才領悟的一點。以下介紹的一點保護機制的知識。這裡只為了讓大家和我一起來共同學習和了解保護機制的知識。
水貨作者: ljttt
出廠日期: 2001-01-01 (水貨的東東一般都這樣寫出廠日期的)
①、首先,我們來看個比較簡單的自身保護方法。這段程式碼如下:
0040CC54: 03F3
add esi,ebx
<--esi指向某段程式碼,ecx為程式碼的長度(DWORD)
0040CC56: 8B06
mov eax,dword ptr [esi]
<--取出程式碼中的 4 個位元組
0040CC58: 33D0
xor edx,eax
<--XOR異或
0040CC5A: F7D2
not edx
<--取反
0040CC5C: 33D1
xor edx,ecx
<--與ecx(程式碼長度)異或
0040CC5E: 03D0
add edx,eax
<--與程式碼中的 4 個位元組相加
0040CC60: 83C604
add esi,00000004
<--定位到程式碼中的下 4 個位元組
0040CC63: 49
dec ecx
<--程式碼長度減一
0040CC64: 75F0
jnz 0040CC56
<--迴圈
先來描述一下這段程式碼的功能:可以看到這段程式碼用 ESI 作為指標,用 ECX 儲存長度。把 ESI 指向的資料進行異或取反,最後在 EDX 中得到一個“值”。
那麼它和自身保護有什麼聯絡呢?我來簡單說一下,如果 ESI = 0040CC54, ECX = 0040CC64 - 0040CC54。那麼這段程式碼是不是就是把自身的程式碼進行運算(異或取反)呢?
OK !
那麼如果你這段程式碼中間設下一個斷點,會有什麼變化呢?運算得到的“值”會和原來未設斷時的相同嗎?
我們以SoftICE來簡單介紹一下吧。當你在SoftICE的除錯環境下,設下一個斷點時,那麼這個斷點所在的程式碼的第一個位元組就會變成 0xCC。
這樣由於設下斷點,程式碼就被改變了,那麼運算的“值”就和未設斷時不一樣了。你可能想到有了這個值,就可以用比較的方法來判斷是否自身是否被設下斷點了。不錯,這是一種方法,但是這很容易被......在加殼軟體中,一般會把這個“值”作為還原密匙,來還原下一段程式碼。
也就是所謂的 SMC 技巧來還原始碼。
(但是如果你在SoftICE中用 D 指令來顯示這行程式碼,卻沒有發現變化。呵呵,但是,如果你再啟動另一個偵錯程式TRW2000,來顯示這行程式碼,再看看?呵呵,明白了嗎?)
②、SMC技巧來還原始碼。
在加殼軟體中,分段還原始碼是一種很普遍的方法了。也許你有過這樣的經歷。(怎麼,弄得象散文了?!)你跟蹤過某個軟體,發現了某段程式碼,比如 CPUID (相應的十六進位制程式碼為
0x0F 0xA2)。卻發現當你用十六進位制編輯軟體來查詢 0x0F 0xA2 時,卻怎麼也找不到,Why?
其實道理很簡單,就是在程式的可執行檔案中儲存的是加密了的資料,只有程式在執行時才會由程式在某處由一段還原始碼來解密這段加密資料,(還原後的資料就是你在偵錯程式中可以“看”到的真實的程式碼)。然後,程式才執行這段還原後的程式碼。現在你清楚了吧!比如象
① 中 介紹的那段程式碼是用來形成還原密匙的,只有密匙正確時,也就是說它先四下“打量”一下,當“發現”自身沒有被修改(或者被設下斷點)時,才“悄悄地”還原出另一段被加密了的程式碼。然後繼續!
有點意思吧!在加殼軟體中,如果它“想”保護某段程式碼,就會加密它,然後在程式執行時用另一段程式碼形成密匙來還原它!這樣就防止你靜態分析它,當然為了防止你用動態跟蹤的方法,所以它還結合了
① 中介紹的自身保護方法。這樣,如果你誤入陷阱(在其自身保護的某處設下了一個斷點),那麼還原出的程式碼就是一堆垃圾程式碼。如果這樣,你可不要寫信給作者,說他程式編得有問題哦?!
(當然 SMC 技巧可以被用作多種用途。不要大家有先入為主的概念,SMC的技巧既可以被加殼軟體用作自身保護的一種方法,也可以被Cracker作為一種破解的方法,所以......怎麼用,還在於你!......你想用來編“病毒”.....老天,為什麼天才總有點反叛因子!)
前面介紹了簡單的自身保護技巧,也許你早就想好了對付它的方法,比如:
不設任何斷點,用單步跟蹤的方法
或者先跟蹤一次記下正確的密匙,下次跟蹤時任意設斷,只在它取密匙時“給”個正確的給它。
或者用 BPM 斷點只跟蹤資料、不跟蹤程式碼的方法進行動態跟蹤。
你還可以想得更多。。。。
當然,為了更好地保護自身,所以在加殼軟體中也不會只是這麼簡單地保護自己,你猜加殼軟體中又會用到什麼保護方法可以防止以上方法呢?
③、一種反跟蹤方法:API呼叫的變形。
你也許喜歡首先在某個關鍵的API函式處設斷,然後才進入程式程式碼中進行跟蹤。但是在加殼軟體中這種方法可就要小心了。
我們來看看這段程式碼:
015F:00411B6A 33C0
XOR EAX,EAX
<--ESI指向API函式地址的入口,如CreateFileA(
)
015F:00411B6C AC
LODSB
<--獲取一個位元組
015F:00411B6D 3C50
CMP AL,50
<--判斷是否為 50
015F:00411B6F 720F
JB 00411B80
<--小於 50 ,則跳轉到 00411B80
015F:00411B71 3C57
CMP AL,57
<--判斷是否為 57
015F:00411B73 770B
JA 00411B80
<--大於 57 ,則跳轉到 00411B80
......
015F:00411BD3 897A01 MOV
[EDX+01],EDI
015F:00411BD6 8B831F7B0000 MOV
EAX,[EBX+00007B1F]
015F:00411BDC 8B8B237B0000 MOV
ECX,[EBX+00007B23]
015F:00411BE2 8B93277B0000 MOV
EDX,[EBX+00007B27]
015F:00411BE8 8BBB3B7B0000 MOV
EDI,[EBX+00007B3B]
015F:00411BEE 8BB3377B0000 MOV
ESI,[EBX+00007B37]
015F:00411BF4 8BAB337B0000 MOV
EBP,[EBX+00007B33]
015F:00411BFA 8B9B2B7B0000 MOV
EBX,[EBX+00007B2B]
015F:00411C00 E900000000 JMP
00411C05
<--此處的跳轉將被修改為API函式地址內的一條指令處
(說明:進入這段程式碼時,ESI指向了某個 API 函式的入口地址,ESP指向的堆疊中壓入了該 API 函式需要的各個引數。由於程式碼較長,沒有完整列出)
以上這段程式碼的作用,就是透過分析(或者說反彙編) API 函式開始的部分程式碼,然後把這部分程式碼“複製”到自己的程式空間中執行後,再進入該 API 函式的內部某處程式碼繼續執行
API 函式。
這樣,當你在此 API 函式入口處(比如: bpx CreateFileA)設斷時,就會“攔”不到它,為什麼?因為,它不從 API 函式入口處執行。而是繞了個彎從“側門”進入的。瞧,加殼軟體多有意思!也許,這時你會想,那麼就在
API 函式的內部某處程式碼設斷不就行了嗎?你要小心,加殼軟體有善良的,也有喜歡“惡作劇”的,它透過分析 API 函式開始部分的程式碼,一方面進行“反彙編”,另一方面,如果你在它分析的程式碼中設下了斷點時,也可能他會痛下殺手,因為斷點的程式碼為
0xCC,它可不喜歡在 API 函式中出現這種指令。如果你由此當機了..........
④、反動態跟蹤的方法。
當然,加殼軟體也可能不只是把眼光放在防範你設斷點,也可能直接就把“眼光”放在防範除錯狀態上了。比如最直接的就是檢測你的當前環境中是否載入了偵錯程式或者是某些工具軟體。比如:
This method is most known as 'MeltICE' because it has been freely distributed
via www.winfiles.com. However it was first used by NuMega people to allow Symbol
Loader to check if SoftICE was active or not (the code is located inside nmtrans.dll).
The way it works is very simple:
It tries to open SoftICE drivers handles (SICE, SIWVID for Win9x, NTICE for
WinNT)
with the CreateFileA API.
Here is a sample (checking for 'SICE'):
BOOL IsSoftIce95Loaded()
{
HANDLE hFile;
hFile = CreateFile( "\\\\.\\SICE", GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if( hFile != INVALID_HANDLE_VALUE )
{
CloseHandle(hFile);
return TRUE;
}
return FALSE;
}
以上是摘自FrogsICE的文件。利用 CreateFile( ) 開啟一些特殊的“檔案”,如果返回值不是 -1,它就可以“發現”載入了SoftICE。當然這種方法由於可以在WIN98/NT下通用,所以很常見。
類似的,如果你把檢測的字串 \\.\SICE 改成
\\.\NTICE 檢測NT下的SoftICE
\\.\FILEMON 檢測FileMon
\\.\REGMON 檢測RegMon
\\.\TRW
檢測Trw
\\.\TRWDEBUG 檢測Trw
\\.\ICEDUMP 檢測IceDump
就可以“發現”其他的跟蹤了。
另一種常見的檢測SoftICE的方法如下,同樣摘自FrogsICE的文件。
* * SOFTICE SHOULD NOT BE LOADED SO THAT FROGSICE CAN DETECT THIS METHOD * *
This method of detection of SoftICE (as well as the following one) is
used by the majority of packers/encryptors found on Internet.
It seeks the signature of BoundsChecker in SoftICE
mov ebp, 04243484Bh ;
'BCHK'
mov ax, 04h
int 3
cmp al,4
jnz SoftICE_Detected
其實檢測SoftICE方法有很多,在 FrogsICE 的文件中介紹了一些,這裡的介紹只是窺其一斑而已。如果你有最“新”的反跟蹤方法,可一定要通知我哦。^_^
⑤、自身保護和反動態跟蹤相結合:
最後我們來看看這段程式碼:
015F:0040DDD8 01FF
ADD EDI,EDI
015F:0040DDDA C783CB18000090010000MOV DWORD PTR [EBX+000018CB],00000190
015F:0040DDE4 8BEB
MOV EBP,EBX
015F:0040DDE6 BA561E0000 MOV
EDX,00001E56
015F:0040DDEB 03D3
ADD EDX,EBX
015F:0040DDED 52
PUSH EDX
015F:0040DDEE 6467FF360000 PUSH
DWORD PTR FS:[0000] <--SEH
015F:0040DDF4 646789260000 MOV
FS:[0000],ESP
<--SEH
015F:0040DDFA 89A3A3760000 MOV
[EBX+000076A3],ESP
015F:0040DE00 BECD1E0000 MOV
ESI,00001ECD
015F:0040DE05 03F3
ADD ESI,EBX
015F:0040DE07 8BFE
MOV EDI,ESI
<--EDI=40DECD
015F:0040DE09 B90F0A0000 MOV
ECX,00000A0F
<--ECX=0xA0F,ECX儲存的是迴圈次數
015F:0040DE0E 8B93FC760000 MOV
EDX,[EBX+000076FC]
;--------------------------------------------------------------------------------------------------
;以下這一段程式碼同 1 中介紹的程式碼類似。
;也就是把程式碼段 ( 015F:40D8E6 - 015F: 40DECA ) 之間的程式碼和 EDX 的初始值進行運算來形成一個“密匙”
;結果仍然儲存在 EDX 中。
;--------------------------------------------------------------------------------------------------
015F:0040DE14 56
PUSH ESI
<--迴圈開始處
015F:0040DE15 51
PUSH ECX
<--入棧儲存,ECX儲存的是迴圈的次數=A0F。
015F:0040DE16 B979010000 MOV
ECX,00000179
015F:0040DE1B BEE6180000 MOV
ESI,000018E6
015F:0040DE20 03F3
ADD ESI,EBX
<--ESI=40C000+18E6=40D8E6。(40C000是程式入口)
015F:0040DE22 8B06
MOV EAX,[ESI]
<--取程式碼中的 4 個位元組
015F:0040DE24 33D0
XOR EDX,EAX
015F:0040DE26 33D1
XOR EDX,ECX
015F:0040DE28 83C604 ADD
ESI,04
015F:0040DE2B 49
DEC ECX
<--迴圈次數減一,ECX初始值為179
015F:0040DE2C 75F4
JNZ 0040DE22
<--這一段是和前面介紹的相同的方法進行自身保護
015F:0040DE2E 59
POP ECX
<--出棧
015F:0040DE2F 5E
POP ESI
<--出棧
;--------------------------------------------------------------------------------------------------
;這段程式碼用 EDX 中的“密匙”來還原 EDI 指向中的被加密了的程式碼,EDI初始值為 40DECD
;--------------------------------------------------------------------------------------------------
015F:0040DE30 AD
LODSD
015F:0040DE31 33C2
XOR EAX,EDX
015F:0040DE33 AB
STOSD
;--------------------------------------------------------------------------------------------------
;這段程式碼用來進行反跟蹤
;--------------------------------------------------------------------------------------------------
015F:0040DE34 0F018BA57A0000 SIDT
FWORD PTR [EBX+00007AA5] <--取IDTR的內容
015F:0040DE3B 8BB3A77A0000 MOV
ESI,[EBX+00007AA7] <--取IDT表基地址
015F:0040DE41 894E08 MOV
[ESI+08],ECX
<--修改 int 1 的處理程式地址為 ECX,讓你死翹翹。
;--------------------------------------------------------------------------------------------------
;把“密匙”進行變換。
;--------------------------------------------------------------------------------------------------
015F:0040DE44 3393521E0000 XOR
EDX,[EBX+00001E52]
015F:0040DE4A 8BF7
MOV ESI,EDI
015F:0040DE4C EB70
JMP 0040DEBE
......(省略)
015F:0040DEBE FF834E1E0000 INC
DWORD PTR [EBX+00001E4E]
015F:0040DEC4 33D1
XOR EDX,ECX
;--------------------------------------------------------------------------------------------------
; 判斷迴圈是否結束,即此時後面的所有被加密的程式碼都已經被還原
;--------------------------------------------------------------------------------------------------
015F:0040DEC6 49
DEC ECX
<--迴圈次數減一,ECX初始值為A0F
015F:0040DEC7 0F8547FFFFFF JNZ
0040DE14
<--迴圈結束處
015F:0040DECD 5F
POP EDI
<--被加密了的程式碼
015F:0040DECE 44
INC ESP
<--未還原的程式碼
這段程式碼比較長,所以要看懂它得花點時間。這是一種把“反動態跟蹤”和“自身保護”結合的一種方法。
可以看到 015F:0040DECD 之後的程式碼已經被加密了,這段程式碼就是用來還原被加密了的程式碼的。當這段程式碼迴圈結束後,後面的被加密了的程式碼就已經還原出來了,這就是
SMC 技巧的應用。在這段程式碼中“密匙”是由前面所有的程式碼來運算得到的。並且每迴圈一次就變換一次。這就是 1 中介紹的自身保護。防止你修改它的程式碼或者設下斷點跟蹤。
另外,程式中還加入了一種“反動態跟蹤”的方法,就是修改了 單步中斷 的中斷處理程式的地址。這樣,你的跟蹤環境就被破壞了。
015F:0040DE34 0F018BA57A0000 SIDT
FWORD PTR [EBX+00007AA5] <--取IDTR的內容
015F:0040DE3B 8BB3A77A0000 MOV
ESI,[EBX+00007AA7] <--取IDT表基地址
015F:0040DE41 894E08 MOV
[ESI+08],ECX
<--修改 int 1 的處理程式地址為 ECX,讓你死翹翹。
這就是加殼軟體的特點,攻防結合。所以一不小心,你就可能落入了它設下的陷阱,見到了“如來佛”。所以為了防止被它送到西天。你就得下點功夫,瞭解自身保護、反跟蹤的特點和技巧。加殼軟體一般就是這樣一個陷阱重重的地方。當然加殼軟體的保護機制也有它的弱點,只要你的程式指令機器“讀”得懂,那麼動態跟蹤不行,就有靜態分析,或者動靜結合。所以才會各種相應的脫殼機的出現。當然這是一個“矛”和“盾”的關係,孰強孰弱,我想關鍵在於運用得當和推陳出新。比如,我常會結合MD5/RSA/BLOWFISH等加密演算法進行註冊碼計算,怎麼樣?!哈哈,然後用IF指令進行註冊判斷!?...................
【後記】
由於這些保護機制的方法出現的頻率比較多,所以介紹一下也無妨。其實,這些東西很早就有了。但是對於生產水貨的我,常常喜歡來點新瓶裝舊酒。另外,我對ANTI-DEBUG瞭解得還不全面,也希望能夠拋磚引玉,能引出更多的高手,讓大家來進行打假。
【有個問題】
最近上網,總是拔不上來。
後來我開啟了"拔號號出現終端視窗"的功能,發現拔號後會出現兩種提示。比如:
Welcome to xxx xxx !
Welcome to yyy yyy !
如果出現第一種,那麼我總是拔不上來,即使正常的密碼也上不來,會出現而如果出現第二種提示,那麼我總能拔上來。真奇怪!這會是什麼原因?最近,上網實在是件痛苦的事件,總是很難拔上來,一般只有到0:00點以後才會正常。
相關文章
- 保護模式:段機制2024-03-12模式
- 用Java的加密機制來保護你的資料2007-09-25Java加密
- Linux中的保護機制2019-07-21Linux
- SpringCloud Eureka自我保護機制2018-05-01SpringGCCloud
- 《springcloud 四》服務保護機制2019-04-10SpringGCCloud
- 保護主機安全,我來buff加成2024-03-28
- 從驗證到不變性保護機制2021-09-06
- Windows安全保護機制下對埠的操作2017-11-09Windows
- spring cloud微服務架構-Eureka保護機制2020-01-17SpringCloud微服務架構
- 淺談資料庫系統安全保護機制2011-07-06資料庫
- 還在愁webpack如何配置嗎?不妨來這裡看看(未完待續...)2018-04-30Web
- BayMaxProtector-集崩潰保護與頁面降級於一體的大白保護機制2018-01-22
- 公安部正制定網路安全保護條例大資料保護機制將完善2017-07-03大資料
- Docker學不會?不妨看看這篇文章2021-07-11Docker
- 利用SEH異常處理機制繞過GS保護2017-12-25
- 初窺 Python 的 import 機制2021-02-07PythonImport
- 來看看維護大型隧道的機器人長什麼樣2016-11-29機器人
- 技術淺析:前端沙箱資料安全保護的機制2024-01-31前端
- Spring Cloud系列教程第九篇-Eureka自我保護機制2020-07-04SpringCloud
- [原創]利用SEH異常處理機制繞過GS保護2018-04-20
- 轉載 利用SEH異常處理機制繞過GS保護2018-04-19
- 基於鹽+Sha演算法的安全密碼保護機制2017-11-07演算法密碼
- Python RPC 不會?不妨看看這篇文章2021-08-06PythonRPC
- 研究人員發現macOS隱私保護重大漏洞 攻擊者可繞過蘋果隱私保護核心機制2021-08-09Mac蘋果
- Java併發(二十三)----同步模式之保護性暫停2024-02-04Java模式
- 逆向被虛擬機器所保護的二進位制檔案2020-08-19虛擬機
- WinRip 2.0保護機制分析及其補丁製作
(9千字)2015-11-15
- 硬碟保護卡破解--小哨兵篇 (轉)2007-12-13硬碟
- 二十三、iOS簽名機制(二)2018-12-26iOS
- Spring Cloud Eureka原始碼分析之心跳續約及自我保護機制2022-01-09SpringCloud原始碼
- Nature: 咖啡保護心血管的機制找到了!可清除“壞膽固醇”!2022-03-03
- 保護自己之手機定位資訊收集2020-08-19
- 保護Solaris系統安全小竅門(轉)2007-08-11
- DNS伺服器保護方法:幾點保護DNS伺服器的有效方法小結2019-01-22DNS伺服器
- 驅動除錯——挫敗 QQ.EXE 的核心模式保護機制(part I)2018-05-29除錯模式
- 使用jwt來保護你的介面服務2021-08-10JWT
- Angular 測試小窺2018-04-15Angular
- 認證計費系統是什麼?不妨看看這篇文章2019-10-18