簡體   English   中英

解析堆棧和寄存器(EBP、EIP、ESP)並找出與每個幀相關的函數

[英]Parsing the Stack and Registers (EBP, EIP, ESP) and figuring out which function is related to each frame

因此,假設我可以訪問程序的寄存器。 我可以訪問 esp、ebp 和 eip。 eip指向需要執行的下一條指令,ebp指向另一個幀指針,esp指向棧頂。 我理解這一點,但是我不理解堆棧的其余部分或如何解析它。

例如,如果我想獲取幀的局部變量,我是否應該減去ebp - esp (知道ebp是比esp更大的地址),然后遍歷這些地址並取消引用它們? 這是從該特定框架獲取局部變量的正確方法嗎?

另一個問題是,找出與每個幀相關的函數的最佳方法是什么? 如果我將ebp地址減去 1,然后取消引用該值,我是否應該獲得返回地址“0x804...”? 這個地址和函數有什么關系? 例如,如果富()具有較高的PC地址0x8045555和低的PC地址0x8045550 ,是返回地址,我會得到要在這些地址之間?

非常感謝高級,如果我不夠清楚,請告訴我..

注意:如果有人有更好的標題建議,我沒有找到更好的。

詳細信息取決於您的 CPU 指令集架構(您顯然使用的是 32 位 x86)和您的編譯器工具鏈(我無法猜測)。 通常,您不想自己重新編寫代碼來遍歷堆棧幀,因為它既復雜又脆弱,並且取決於編譯器的優化和調試設置。

如果您正在嘗試調試程序,您應該首先讓您平台的調試器嘗試整理您的堆棧。 例如,使用gdb ,您可以運行bt來獲得“回溯”。

如果您嘗試從相關程序內部執行此操作,並且您使用的是 GNU C 庫,那么您可以使用backtrace(3)函數。

如果您只是想了解事情的真正運作方式,這里有一篇有用的博客文章: http : //eli.thegreenplace.net/2011/02/04/where-the-top-of-the-stack-is-on-x86 /

為了更深入地理解,請嘗試 Wikipedia 的x86 Calling Conventions文章。 更深入地講,如果您使用的是基於 ELF 的架構,例如 Linux,請參閱ELF ABI 規范

寄存器和堆棧中的數據只是一系列字節。 數據由將字節放入序列中的各種指令和應用程序構成,但是有關字節結構的信息不是字節序列的一部分,而是可能可用或可能不可用的附加信息。

例如,當源代碼被編譯並且二進制代碼由編譯器生成時,二進制代碼中將包含額外的描述信息。 附加描述信息的數量將取決於所選擇的編譯器選項和所用工具鏈中各種其他工具的功能。

例如,如果選項是使用附加信息(如函數名稱)創建調試版本,並且工具鏈支持使用附加信息顯示二進制代碼,那么您可以很好地查看變量、函數名稱和步進通過源代碼級別的代碼。

另一方面,如果選項是在沒有附加信息的情況下創建優化的構建,那么即使工具鏈可能支持使用附加信息顯示二進制代碼以在更易讀的視圖中呈現二進制代碼,因為信息是不存在,工具鏈無法在源代碼級別顯示二進制代碼,顯示源代碼、變量、函數名稱等行。

因此,為了完成您想要做的事情,您需要擁有附加信息,以便您可以將二進制代碼與附加信息結合起來。 如果沒有附加信息,您所擁有的只是內存中的一堆字節。 您可以通過各種方式顯示這些字節,例如將它們解釋為匯編代碼或將它們解釋為文本字符串。 然而,如果沒有額外的信息,你只是在猜測,無論受過多少教育。

不同平台和操作系統上的不同編譯器和工具鏈會生成不同類型的附加信息。 因此,您需要了解有關您的工具鏈提供的特定信息的信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM