SMC是英文Self-Modifying Code的縮寫形式,顧名思義,就是“代碼自修改”也就是說可以在一段代碼執行之前先對它進行修改。
SMC技術在DOS時代非常流行,因為DOS時代更接近系統底層。所以即便是現在實現SMC技術,都以彙編碼最為方便。
‘利用SMC技術的這個特點,在設計加密方案時,可以把代碼以加密形式儲存在可執行檔中,然後在程式執行時再動態解密,這樣可以有效地對付靜態分析。因此要想瞭解被加密的代碼的功能,只有動態跟蹤或者分析出解密函數的位置編寫程式來解密這些代碼。’
實際運用中,SMC技術用途是相當廣泛的,並不僅僅是用來反跟蹤。這是靠運用者的思維來決定。
然而,可能會有人說SMC今天已淘汰。但這並不影響要求像我這樣的初學者瞭解SMC技術,至少要知道SMC這個概念。
下面用老羅的一個常式來說明SMC技術的運用:
是用彙編,雖然SMC並不是彙編的專利!
可能路過的朋友對長篇的彙編碼感到煩亂,不過沒關係
我在這裡作一點指引:
我們可以把這個常式結構理解為
1,invoke ShowMessage
2,修改ShowMessage proc
3,invoke ShowMessage
好了
我們看老羅的源碼吧:
聲明:
對於Ring3程式來說,.code段預設是不可寫!所以MASM裡通過連結改變其屬性:
ml /c /coff %1.asm
link /subsystem:windows /section:.text,RWE %1.obj
/section:.text,RWE 這句指定了程式碼片段(.text)的屬性是RWE,含義是:R(ReadAble),W(WriteAble),E(ExecuteAble)!
;***********************************************;程式名稱:示範SMC原理;作者:羅聰;日期:2002-10-2;出處:http://laoluoc.yeah.net(老羅的繽紛天地);注意事項:如欲轉載,請保持本程式的完整,並註明:;轉載自“老羅的繽紛天地”(http://laoluoc.yeah.net);***********************************************.386.model flat, stdcalloption casemap:noneinclude \masm32\include\windows.incinclude \masm32\include\kernel32.incinclude \masm32\include\user32.incincludelib \masm32\lib\kernel32.libincludelib \masm32\lib\user32.libShowMessage protoReplaceMent proto.dataszMsg1 db "這是未執行SMC之前的代碼!", 0szMsg2 db "SMC已經執行!", 0szCaption db "SMC demo by LC, 2002", 0Replace_Len dd 0.codemain: ;第一次執行子程式ShowMessage,此時還沒執行SMC操作 invoke ShowMessage lea eax, ReplaceMentEnd ;標號ReplaceMent的結束 lea edx, ReplaceMentStart ;標號ReplaceMent的開始 sub eax, edx ;標號ReplaceMent的長度 mov Replace_Len, eax ;把長度儲存起來 ;關鍵代碼!!!!!!!!! lea esi, ReplaceMentStart ;標號ReplaceMent的開始 lea edi, ShowMessageStart ;原程式ShowMessage的標號的開始 mov ecx, Replace_Len ;標號ReplaceMent的長度 rep movsb ;這裡是最關鍵的語句!!!執行SMC操作! ;第二次執行子程式ShowMessage,此時已經執行了SMC操作。 ;換句話說,ShowMessage的內容已經不是第一次運行時的內容了: invoke ShowMessage invoke ExitProcess, 0ShowMessage proc ;這裡用“::”的話,就能夠使標號成為全域性的 ShowMessageStart:: invoke MessageBox, NULL, addr szMsg1, addr szCaption, MB_OK ShowMessageEnd:: ;用nop來預留空間,以便後面的SMC能夠成功執行; ;否則如果空間不夠,將有可能產生不可預測的錯誤: nop nop nop nop nop nop nop nop retShowMessage endpReplaceMent proc ;將要用來SMC的代碼: ReplaceMentStart:: ;invoke MessageBox, NULL, addr szMsg2, addr szCaption, MB_OK or MB_ICONINFORMATION push MB_OK or MB_ICONINFORMATION lea eax, szCaption push eax lea eax, szMsg2 push eax push NULL lea eax, MessageBox call eax ReplaceMentEnd:: retReplaceMent endpend main
第二次執行ShowMessage proc時結果已經是跟第一次執行的不同了
因為在第二次執行之前ShowMessaeg proc內容已經被改變
所以結果當然不同
就是我們爆破軟體那樣,通過手工修改一定地區代碼實現返回不同結果!
這裡就是 Self-Modifying Code,讓機器自己修改。
所以,SMC是非常實用,至少有必要瞭解的東西!