用彙編的眼光看C++(之特殊函數)

來源:互聯網
上載者:User

【 聲明:著作權,歡迎轉載,請勿用於商業用途。  聯絡信箱:feixiaoxing @163.com】  

    這裡說的函數主要指的是inline函數、static函數。inline函數比較特殊,它既具有宏的性質,同時也能讓編譯器對它進行函數檢查。static函數同樣也比較特殊,它只可以被同檔案的函數使用。如果static函數在include檔案中,那麼這個標頭檔只要被使用一次,那麼這個函數就要在exec檔案中重新出現一次。現在大家可能理解起來有點困難,但是請大家稍微等待一下,下面我們將會用樣本進行說明。最後,我們用一個替換的技巧對函數指標進行修改,讓你調用的函數發生修改,這樣給大家都函數的定義加深一下印象。

    (1)內嵌函式

inline int add(int a, int b){return a + b;}

    那麼這個函數在應用的時候,會怎麼編譯呢,可以看一下?

0040114A   mov         eax,10040114F   add         eax,200401152   mov         dword ptr [ebp-4],eax

    inline函數是一種特殊的函數。在進行函數編譯的時候,編譯器會對內嵌函式這段代碼按照函數的要求進行格式檢查。但是編譯產生執行代碼的過程中,編譯器會把這段代碼按照宏的性質複製到call的函數當中。所以在call函數中,我們發現這段調用代碼並不是call的形式,而是直接按照語句的形式。但是這種inline函數中的程式碼數不能過多,因為我們內聯的目的就是就是減少call的機會。

注意:

    a) 函數在編譯的時候需要開啟INLINE最佳化開關,【PROJECT】->【setting】->【C/C++】->【optimizations】,在內聯擴充中選擇第二項

    b)編譯的時候會建置錯誤,那麼刪除編譯指令/ZI即可,結果是源碼無法單步調試,只能彙編級單步調試

    (2) static函數是什麼屬性

static int add(int a, int b){return a + b;}

    a) 如果在不同的源檔案都有這樣一個add函數呢 ?

    如果在不同的檔案裡面函式宣告為static函數,那麼沒有關係,各個static函數只為各個檔案使用,不存在multi definition的問題。

    b)如果標頭檔有這樣一個static函式宣告和定義?

    標頭檔中有一個static函數的話,那麼調用這個函數的每個檔案都為這個static函數重新編譯一下。結果和a)的結果是一樣的,大家可以自己試試看一下,對static函數地址列印一下,看看是不是add函數的地址是一樣的。

    

    (3)一個修改函數地址的範例

#include <windows.h>int add(int a, int b){return a + b;}int sub(int a, int b){return a - b;}void set(){HANDLE hProcess = GetCurrentProcess();DWORD pOldFlag = 0;BOOL result = 0;result = VirtualProtectEx(hProcess, (LPVOID)add, 0x10, PAGE_EXECUTE_READWRITE, &pOldFlag);if(result != 0){printf("%d\n", GetLastError());}}void process(){char* n = (char*) add;char* t = (char*) sub;*n  =  0xFF;*(n+1) = 0x25;*(int*)(n +2) = (int)&t;int data = add(3,2);assert(1 == data);return;}

    簡單介紹一下,上面的程式碼封裝括四個函數,add函數和sub函數主要為了替換測試使用,set函數是修改程式碼片段訪問屬性的一段代碼,而process函數就是我們測試使用的一段代碼。其實這段代碼的意思不難,目的在於你在call add函數,發現實際上在call的是sub函數。那麼我們是怎麼做到的呢,關鍵在兩個方面:(1)修改add 函數程式碼片段的訪問屬性;(2)修改add函數第一個位元組的內容,那麼我們需要把函數add處地內容修改為jmp sub,那麼就要先修改屬性,後修改內容。

【預告: 下面一片部落客要涉及class記憶體分布問題】

  

聯繫我們

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