我有這個反編譯的 arm 二進制檔案。評論基于此答案...
...
12de3c0: e59f6400 ldr r6, [pc, #1024] ; load into r6 a word from offset 0x12de7c8 (0x12de3c0 0x8 1024)
12de3c4: e1a0a000 mov sl, r0 ; ignore this
12de3c8: e1a09001 mov r9, r1 ; ignore this
12de3cc: e08f6006 add r6, pc, r6 ; r6 = pc r6; so r6 = 0x12de3cc 0x8 0x035cbf8f = 0x48AA363 ???
12de3d0: e5d60000 ldrb r0, [r6] ; load a byte into r0 from the obtained address (0x48AA363)
...
12de7c8: 035cbf8f cmpeq ip, #572 ; 0x23c
...
但是,我很困惑 0x48AA363 超過了二進制檔案的大小,所以我的假設肯定有誤。我可能在哪里誤解了代碼?
uj5u.com熱心網友回復:
如果您在具有虛擬記憶體的作業系統下運行,則將可執行檔案映射到從非零虛擬地址開始的記憶體是正常的。(因此 NULL 指標 deref 可能會出錯,而不是有效地址!)。這意味著代碼指標(包括執行時的 PC)通常是大數字,遠大于檔案大小。請注意,即使12de3c0
您已經在反匯編中看到的地址也很大。
聯結器通常會在部分之間放置間隙(因此陣列越界更容易出錯,從而更容易除錯,以及其他原因)。因此,與您的部分add r6, pc, r6
相距相當遠的某個地址的 PC 相對尋址(通過 )很可能是或。不太可能,因為加載一個常量位元組沒有意義。.text
.data
.bss
.rodata
您可以使用readelf -a
查看程式頭給出的映射,并找到該地址的位置。假設您的可執行檔案仍然具有節頭,您還可以查看地址所在的節,而不僅僅是來自 ELF 段頭的權限和檔案偏移量。
您還可以在此處設定斷點并運行它,以仔細檢查您的數學并查看ldrb
加載的地址。(并仔細檢查運行時修復(又名文本重定位)或其他什么。盡管在非 PIE 可執行檔案中通常不需要。)
我最初將以上內容寫為評論。在你已經這樣做之后,我發布了這個:
我放置了一個斷點,r6 正好是 0x48AA363。并且該記憶體區域包含一個值為 0 的位元組,可能是一個全域/靜態布林值,因為它后面是
cmp r0, #0
是的,聽起來是一個合理的結論。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/495929.html
上一篇:關于esp堆疊平衡