5

我包含了iOS標籤,但是我在Core i7 MacBook Pro(x86-64,對吧?)的模擬器上運行,所以我認爲這並不重要。通用寄存器的內容是什麼?

我目前正在調試Flurry視頻廣告的崩潰。我有一個設置Objective-C異常的斷點。當斷點被打時,我在objc_msgSend。這個callstack包含了私人Flurry和iOS方法的組合,沒有任何公開的,也沒有我寫的東西。調用從objc_msgSend棧幀輸出register read如下:

(lldb) register read 
General Purpose Registers: 
     eax = 0x1ac082d0 
     ebx = 0x009600b5 "spaceWillDismiss:interstitial:" 
     ecx = 0x03e2cddb "makeKeyAndVisible" 
     edx = 0x0000003f 
     edi = 0x0097c6f3 "removeWindow" 
     esi = 0x00781e65 App`-[FlurryAdViewController removeWindow] + 12 
     ebp = 0xbfffd608 
     esp = 0xbfffd5e8 
     ss = 0x00000023 
    eflags = 0x00010202 App`-[FeedTableCell setupVisibleCommentAndLike] + 1778 at FeedTableCell.m:424 
     eip = 0x049bd09b libobjc.A.dylib`objc_msgSend + 15 
     cs = 0x0000001b 
     ds = 0x00000023 
     es = 0x00000023 
     fs = 0x00000000 
     gs = 0x0000000f 

我有這個輸出幾個問題。

  • 我假設$ ebx包含導致崩潰的選擇器,$ edi是最後一個執行方法。是這樣嗎?
  • $ eip是我墜毀的地方。通常情況是這樣嗎?
  • $ eflags引用一個實例方法,據我所知,這個方法與這次崩潰無關。那是什麼?
  • 有沒有其他信息可以從這些寄存器中剔除?

回答

1

我無法專門針對iOS/Objective-C框架佈局,所以我無法回答您關於EBX和EDI的問題。但我可以幫助您瞭解EIP和EFLAGS,併爲您提供有關ESP/EBP和選擇器寄存器的一般提示。 (順便說一句,模擬器模擬32位x86環境,你可以告訴,因爲你的寄存器是32位長。)

EIP是instruction pointer寄存器,也被稱爲程序計數器,其中包含當前正在執行的機器指令的地址。因此,它會指向你的程序崩潰的地方,或者更一般地,你的程序是,當遇到斷點,核心轉儲等

EIP保存和恢復來實現函數調用(在機器代碼級別 - 內聯可能會導致高級語言調用不執行實際調用)。在內存不安全的語言中,堆棧緩衝區溢出可能會覆蓋指令指針保存的值,導致返回指令返回到錯誤的地方。如果幸運的話,覆蓋的值會在下一次內存抓取時觸發段錯誤,但EIP的值將是任意的,並且無法幫助您調試問題。如果你不幸,攻擊者製作新的EIP以指向有用的代碼,那麼許多環境在恢復保存/覆蓋的EIP之前使用「堆棧cookie」或「canaries」來檢測這些覆蓋,在這種情況下,EIP值可能是有用。

EFLAGS不是內存地址,可以說是不是通用寄存器。 EFLAGS的每一位都是可以通過各種指令設置或測試的標誌。最重要的標誌是進位,零和符號標誌,它們由算術指令設置並用於條件分支。你的調試器將它誤解爲內存地址並將其顯示爲最接近的函數,但這實際上並不涉及到你的崩潰。 (該+ 1778是贈品:這意味着EFLAGS點1778個字節到函數,但功能是不可能實際上是1778個字節長。)

ESP是堆棧指針和EBP(通常)幀指針(也稱爲基地指針)。這些寄存器將當前幀綁定在調用堆棧上。您的調試器通常會根據這些指針向您顯示堆棧變量和當前調用堆棧的值。如果發生損壞,有時您可以手動檢查堆棧以恢復EBP並手動展開調用堆棧。請注意,代碼可以在沒有幀指針的情況下編譯(幀指針省略),將EBP釋放用於其他用途;這在x86上很常見,因爲通用寄存器非常少。

SS,CS,DS,ES,FS和GS保持段選擇器,在尋呼前實施segmentation之前的惡劣日子中使用。今天,FS和GS通常被操作系統用於進程和線程狀態塊;它們是x86-64中唯一的選擇器寄存器。選擇器寄存器通常對調試沒有幫助。

相關問題