天天看點

(六)羽夏看C語言——函數

從彙編層面聊一聊函數到底是什麼,怎麼實作的

  此系列是本人一個字一個字碼出來的,包括示例和實驗截圖。本人非計算機專業,可能對本教程涉及的事物沒有了解的足夠深入,如有錯誤,歡迎批評指正。 如有好的建議,歡迎回報。碼字不易,如果本篇文章有幫助你的,如有閑錢,可以打賞支援我的創作。如想轉載,請把我的轉載資訊附在文章後面,并聲明我的個人資訊和本人部落格位址即可,但必須事先通知我。

你如果是從中間插過來看的,請仔細閱讀 (一)羽夏看C語言——簡述 ,友善學習本教程。

  答案:不會。

  解答:我相信親手做實驗的人都會知道的。

  一個程式必須有一個函數,比如C語言中的<code>main函數</code>,也可以實作别的函數實作功能。本篇文章将從彙編的角度介紹函數,本次實驗的代碼十分簡單。為了防止幹擾,請在項目屬性中關閉<code>增量連結</code>和<code>支援僅我的代碼調試</code>(具體作用請搜尋科普,它們會生成一些彙編代碼來實作相應的功能)。

  得到的反彙編如下:

(六)羽夏看C語言——函數

  通過彙編可以看出,函數生成的彙編采用<code>ebp尋址</code>的方式。前三句彙編進行用<code>ebp尋址的準備</code>和<code>提棧準備緩沖區</code>的操作,提供的緩沖區用來給函數内的局部變量用的。

  有些生成的反彙編可能是這樣的版本:

  有些人可能看不懂以下代碼:

  上面的代碼是将<code>0xCC</code>填充滿整個緩沖區,可幫助檢測到堆棧緩沖區溢出,這是一種常見的攻擊,威脅程式的安全性。<code>0xCC</code>即為我們調試的普通斷點,彙編為<code>int 3</code>,即<code>VS</code>按下<code>F9</code>下斷點(代碼行左邊的小紅點)。

  然後看一下反彙編:

(六)羽夏看C語言——函數
(六)羽夏看C語言——函數

  可以看出函數調用時會通過<code>push</code>傳遞參數,然後<code>call</code>一個位址跳轉到<code>test函數</code>,通過<code>eax</code>作為<code>傳回值</code>。調用完畢後用<code>add esp,8</code>平棧,這個所謂的一種<code>調用約定</code>,被稱為<code>__cdecl</code>。當然調用約定不知這一種,你也可以自定義,不過得從彙編上實作。

  當一個函數被調用時,函數的參數會被傳遞給被調用的函數和傳回值會被傳回給調用函數。函數的調用約定就是描述參數是怎麼傳遞和傳回值,由誰平衡堆棧,這就是所謂的調用約定。

  我們先給出常見的調用約定,其他的調用約定自行科普:

調用約定

__stdcall

__cdecl

__fastcall

__pascal

參數傳遞順序

從右到左

從左到右

使用寄存器和棧

平棧

調用者

子程式

  當然,在<code>IDA</code>中你可能會看到其他調用約定,比如<code>__thiscall</code>等。由于調用約定并不是我想重點講述的,具體細節自行科普。C語言預設的調用約定為<code>__cdecl</code>,是以在 函數調用 部分已有示例。這部分就用<code>__fastcall</code>做個為<code>調用約定</code>示例。

  如下是反彙編:

(六)羽夏看C語言——函數

  (七)羽夏看C語言——模闆(C++)

(六)羽夏看C語言——函數
(六)羽夏看C語言——函數

本作品采用 知識共享署名-非商業性使用-相同方式共享 4.0 國際許可協定 進行許可

本文來自部落格園,作者:寂靜的羽夏 ,一個熱愛計算機技術的菜鳥

轉載請注明原文連結:https://www.cnblogs.com/wingsummer/p/15230787.html

(六)羽夏看C語言——函數

繼續閱讀