日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

4.IDA-导航(跳转到地址、导航按钮、栈帧、调用约定、局部变量布局、IDA的栈视图)

發布時間:2024/4/11 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 4.IDA-导航(跳转到地址、导航按钮、栈帧、调用约定、局部变量布局、IDA的栈视图) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.跳轉到地址

使用Jump?Jump to Address命令或在處于活動狀態的反匯編窗口中按下熱鍵G,均可以打開Jump to Address對話框,如果把這個對話框看成Go對話框,可能有助于你記住相關的熱鍵。
IDA會記住你在這個對話框中輸入的值,并通過一個下拉列表顯示,以方便你隨后使用

2.導航按鈕(導航歷史)

導航按鈕,每個按鈕旁邊還有一個歷史記錄下拉列表,你可以迅速訪問導航歷史記錄列表中的任何位置,而不必遍歷整個歷史記錄列表


3.棧幀

調用一個函數時的詳細操作步驟:
(1)調用方將被調用函數所需的任何參數放入到該函數所采用的調用約定指定的位置。如果參數被放到運行時棧上,該操作可能導致程序的棧指針發生改變。 (2)調用方將控制權轉交給被調用的函數,然后,返回地址被保存到程序棧或CPU寄存器中。 (3)如有必要,被調用的函數會配置一個棧指針(EBP),并保存調用方希望保持不變的任何寄存器值。 (4)被調用的函數為它可能需要的任何局部變量分配空間。一般,通過調整程序棧指針在運行時棧上保留空間來完成這一任務。 (5)被調用的函數執行其操作,可能生成一個結果。在執行操作的過程中,被調用的函數可能會訪問調用函數傳遞給它的參數。如果函數返回一個結果,此結果通常被放置到一個特定的寄存器中,或者放置到函數返回后調用方可立即訪問的寄存器中。 (6)函數完成其操作后,任何為局部變量保留的棧空間將被釋放。通常,逆向執行第(4)步中的操作,即可完成這個任務。 (7)如果某個寄存器的值還為調用方保存(第(3)步)著,那么將其恢復到原始值。這包括恢復調用方的幀指針寄存器。 (8)被調用的函數將控制權返還給調用方。根據所使用的調用約定,這一操作可能還會從程序棧中清除一個或多個參數。 (9)調用方一旦重新獲得控制權,它可能需要刪除程序棧中的參數。這時可能需要對棧進行調整,以將程序棧指針恢復到第(1)步以前的值。
第(3)步和第(4)步通常在進入函數時執行,它們共同稱為該函數的序言。同樣,第(6)步到第(8)步一般在函數結束時執行,它們共同構成該函數的尾聲。而第(5)步則代表函數的主體,它們是調用一個函數時執行的全部操作。

4.調用約定

4.1.C調用約定

調用方按從右到左的順序將函數參數放入棧中,在被調用的函數完成其操作時,調用方(而不是被調用方)負責從棧中清除參數。
從右到左在棧中放入參數的一個結果是,如果函數被調用,最左邊的(第一個)參數將始終位于棧頂。這樣,無論該函數需要多少個參數,我們都可輕易找到第一個參數。 如果函數能夠接受變參,則調用方非常適于進行這種調整,因為它清楚地知道,它向函數傳遞了多少個參數,因而能夠輕松做出正確的調整。而被調用的函數事先無法知道自己會收到多少個參數,因而很難對棧做出必要的調整,所以如下測試:

答案:__stdcall不適用于傳入變參,如果在__stdcall函數中傳入變參,系統會自動視為C調用,以下為反匯編

4.2.__stdcall調用約定

使用stdcall調用約定的區別在于:函數結束執行時,應由被調用的函數負責刪除棧中的函數參數。
要完成這個任務,它必須清楚知道棧中有多少個參數,這就決定了只有固定參數。因此,printf這種變參的函數不能使用stdcall調用約定。

根據慣例,微軟對所有由共享庫(DLL)文件輸出的參數數量固定的函數使用stdcall約定

4.3.x86 fastcall約定

fastcall約定是stdcall約定的一個變體,它向CPU寄存器(而非程序棧)最多傳遞兩個參數,前兩個參數(左邊的兩個)將分別位于ECX和EDX寄存器中。剩余的其他參數則以類似于stdcall約定的方式從右到左放入棧上
如: [cpp]?view plaincopy
  • int?__fastcall?fast(int?a,int?b,int?c,int?d)??
  • {??
  • ????return?0;??
  • }??
  • ??
  • int?_tmain(int?argc,?_TCHAR*?argv[])??
  • {??
  • ????int?a?=?fast(1,2,3,4);??
  • 由于有兩個參數被傳遞到寄存器中,只需要retn 8即可,如下匯編

    4.4.C++調用約定

    C++類需要使用this指針,該指針必須由調用方提供,因此,它被作為參數提供。C++語言標準并未規定應如何向非靜態成員函數傳遞this指針,因此,不同編譯器使用不同的技巧來傳遞this指針,Microsoft Visual C++提供thiscall調用約定,它將this傳遞到ECX寄存器中,并且和在stdcall中一樣,它要求函數清除棧中的參數

    GNU g++編譯器將this看成是任何非靜態成員函數的第一個隱含參數,而在所有其他方面與使用cdecl約定相同。因此,對使用g++編譯的代碼來說,在調用非靜態成員函數之前,this被放置到棧頂,且調用方負責在函數返回時刪除棧中的參數(至少有一個參數)

    4.5.系統調用

    通常,系統調用會造成狀態轉換,由用戶模式進入內核模式,x86操作系統一般使用sysenter指令,系統調用的參數位于運行時棧上,并在啟動系統調用之前,在EAX寄存器中放入一個系統調用編號


    5.局部變量布局

    存在規定如何向函數傳遞參數的調用約定,但不存在規定函數的局部變量布局的約定~即通過檢查函數的源代碼,通常無法確定函數的局部變量布局。
    編譯器的第一個任務是,計算出函數的局部變量所需的空間。(以下的計算都不是真實的,因為編譯器會額外分配更多的棧空間,可能是因為對齊,或者是因為緩沖區大小) 以下面代碼為例: [cpp]?view plaincopy
  • int?fun(int?a,int?b,int?c)??
  • {??
  • ????int?x;??
  • ????char?buf[64];??
  • ????int?y;??
  • ????int?z;??
  • ??
  • ????return?0;??
  • }??
  • ??
  • int?_tmain(int?argc,?_TCHAR*?argv[])??
  • {??
  • ????fun(1,2,3);??
  • 如果沒有使用幀指針寄存器(即ESP為幀指針) 可直接這樣寫: [cpp]?view plaincopy
  • sub?esp,?76??
  • 其中的“偏移量”欄顯示的是引用棧幀中的任何局部變量或參數所需的基址+位移地址:
    但是,在X86中,EBP寄存器通常專門用作棧幀指針,得到的棧幀布局如圖:


    6.IDA棧視圖

    IDA會根據變量相對于被保存的返回地址的位置,為變量取名。局部變量位于被保存的返回地址之上,而函數參數則位于被保存的返回地址之下。
    0.局部變量默認命名 局部變量名稱以var_為前綴,后面跟一個表示變量與被保存的幀指針之間距離(以字節為單位)的十六進制后綴。 如局部變量var_C是一個4字節(dword)變量,它位于所保存的幀指針之上,距離為12字節([ebp-oCh])。

    1.函數參數默認命名 函數參數名則以arg_為前綴,后面跟一個表示其與最頂端的參數之間的相對距離的十六進制后綴 因此,最頂端的4字節參數名為arg_0,而隨后的參數則分別為arg_4、arg_8、arg_C
    arg_0對應ebp+8, 依次類推 我們可以右擊匯編中的arg_0(不是摘要中的,是匯編代碼中的),菜單中就顯示了arg_0的實際位置:
    DA只會為那些在函數中直接引用的棧變量自動生成名稱。如果DA無法確定任何對[ebp+8](第一個參數的位置)的內存引用,那么arg_0就不會在摘要棧視圖中列出
    特別注意的是: var_局部變量的定義順序和你在代碼中的聲明順序關系不大,你必須通過反匯編窗口中的一系列線索,將IDA生成的變量名稱與源代碼中使用的名稱對應起來。 注意觀察的和傳入參數的關系來關聯局部變量
    2.雙擊變量,會跳轉到變量的詳細視圖
    顯示的兩個特殊值分別為s和r(前面均帶有空格)。這些偽變量是IDA表示被保存的返回地址(r)和被保存的寄存器值(s僅代表EBP)的特殊方法

    總結

    以上是生活随笔為你收集整理的4.IDA-导航(跳转到地址、导航按钮、栈帧、调用约定、局部变量布局、IDA的栈视图)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。