轉:淺析SMC技術

來源:互聯網
上載者:User
今天讓我們來看Win32ASM裡面的進階一點的技術——SMC(噹噹噹噹……)!!!

SMC是什麼意思?它的英文名叫“Self Modifying Code”,顧名思義,就是“代碼自修改”(?)(不好意思,小弟的英語六級還沒過,只能翻譯成這樣啦……)

“代碼自修改”?哇,好高深啊!其實不然……

我 們知道,Win32應用程式是運行在保護模式下的,每個Win32應用程式都有相互獨立的4GB地址空間,並且已經摒棄了16位時代的把代碼分為 Data、Code等段的記憶體模式的做法;現在它們只有一種記憶體模式,即FLAT模式,意思是“平坦”的記憶體模式——再也沒有煩人的64KB的段大小限制 啦。如此一來,所有的Win32應用程式都能各自運行在一個連續、平坦、巨大的4GB空間中,作為程式員,也不用再跟段寄存器打交道,您可以用任意的段寄 存器定址任意的地址空間,是不是很方便呢?

不過且慢,Win32時代的編程雖然比之Win16時代已經方便了不止一個數量級,但是畢竟還有一些規則是需要遵守的。最明顯的之一就是不能在程式啟動並執行過程中隨便更改程式碼片段!

(咦?剛剛不是說了Win32裡面沒有段的概念了嗎?怎麼這裡又來了一個“程式碼片段”了?別急,請聽我細細道來……)

雖然Win32下已經沒有了“段”,但是您還是可以給自己的程式分成不同的“段”,一個“分段”的開始即是上一個“分段”的結束。Win32隻有兩種性質的分段:Data和Code。

實 際上,在Win32裡面的分段並不是像DOS下一樣,為不同的段分別指出不同的段寄存器,因為Windows下只有一個4GB的段,Windows程式中 的分段表現在當程式裝載時,賦予不同的段不同的屬性,比如說當你的程式載入時,對於Ring3程式來說,.code段是不可寫的,而.data段是可寫 的,如果你嘗試像在DOS下一樣寫自己的代碼部分,你將會得到一個“很cool”的藍屏錯誤。

怎麼樣?頭暈了嗎?如果沒有的話,讓我們繼續!^_^

上面已經提到程式碼片段是不能在程式運行途中更改的了,那麼怎麼又來了一個“SMC”技術呢?它是如何?的?

其實關鍵就在於連結時的參數,只要指定了程式碼片段的屬性是可寫的,那麼就OK啦!(預設的參數是不可寫的)。也就是說,我們在編譯、連結帶有SMC的Win32ASM時應該這樣做:

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技術的Win32ASM例子,很容易理解的,記得要用上面的方法來編譯和連結哦!

;***********************************************
;程式名稱:示範SMC原理
;作者:羅聰
;日期:2002-10-2
;出處:http://laoluoc.yeah.net(老羅的繽紛天地)
;注意事項:如欲轉載,請保持本程式的完整,並註明:
;轉載自“老羅的繽紛天地”(http://laoluoc.yeah.net)
;***********************************************

.386
.model flat, stdcall
option casemap:none

include "masm32"include"windows.inc
include "masm32"include"kernel32.inc
include "masm32"include"user32.inc
includelib "masm32"lib"kernel32.lib
includelib "masm32"lib"user32.lib

ShowMessage    proto
ReplaceMent    proto

.data
szMsg1        db    "這是未執行SMC之前的代碼!", 0
szMsg2        db    "SMC已經執行!", 0
szCaption     db    "SMC demo by LC, 2002", 0
Replace_Len   dd    0

.code
main:
    ;第一次執行子程式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, 0

ShowMessage    proc
    ;這裡用“::”的話,就能夠使標號成為全域性的
    ShowMessageStart::
        invoke MessageBox, NULL, addr szMsg1, addr szCaption, MB_OK
    ShowMessageEnd::

    ;用nop來預留空間,以便後面的SMC能夠成功執行;
    ;否則如果空間不夠,將有可能產生不可預測的錯誤:
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop

    ret
ShowMessage    endp

ReplaceMent    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::

    ret
ReplaceMent endp

end main

轉自:http://www.luocong.com/articles/show_article.asp?Article_ID=18

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.