2017-10-08 384 views
0

enter image description here

這是從我的腿上彈問題的彙編代碼,我陷在階段2; 炸彈實驗室要求我們根據彙編代碼找出正確的輸入,否則會爆炸。

從< +20>我知道%rbp -0x30(48)== 0或者它會調用< +32>並炸開炸彈;因此%rbp = 48(DEC)

之後(+26)%rbp - 0x2c(44)必須等於1或它會爆炸炸彈... 但是由於%rbp = 48,炸彈會爆炸到任何地方所以我現在迷惑......

我想我誤解了併發症,JE/JNE或如何計算這些東西......

+0

通過進入「read_six_numbers」我知道輸入是6個數字,並且有一些模式 – James

+2

Do不張貼文字的圖片。從終端複製/粘貼。 –

+1

[請勿放置文字圖像](https://meta.stackoverflow.com/q/303812/995714) –

回答

1

-0x30(%ebp)並不意味着要使用的值%ebp - 0x30。這是一個內存地址來讀取。該指令(cmpl)的後綴爲l,所以它處理的是4字節的數量。所以實際發生的是它從地址%ebp - 0x30中讀取一個4字節的數字並檢查它是否爲零。

(該$前綴意味着它是一個直接的價值,而不是一個地址。這就是爲什麼0x0是從字面上,而不是取消引用。)

+0

非常感謝!但是現在我怎麼才能知道%ebp的價值是什麼,因爲它直接讀取4字節內存。我對此一無所知。 – James

+0

@James好吧,假設代碼在調用'read_six_numbers'之前將'%ebp-0x30'的地址加載到'%rsi'(第一個參數)中,我認爲這是'read_six_numbers'放置結果的地方;即它是6個整數的緩衝區的開始。這與48 = 6 \ * 8的大小(對於6個8字節整數)是一致的......除非這樣做沒有意義,因爲我們只比較4個字節的整數。嗯... – melpomene

+0

它是'%rbp',而不是'%ebp'。這是一個64位指針(對4個字節的內存)。它在這個函數中被用作幀指針,所以它的高32位不全是零,'0x30(%ebp)'會出現段錯誤。 –

1

你不需要知道的rbp值拆除炸彈的引信,它的總是用相對的方式來處理某些內存部分。它設置在啓動由序列:

pushq %rbp 
    movq %rsp, %rbp 
    pushq %r12 
    pushq %rbx 
    subq $0x20, %rsp 

這確實推動老rbp值到棧(保存它),然後將rbp到當前堆棧指針值(rsp)。所以(%rbp)現在包含舊的rbp。然後通過將另外兩個寄存器r12rbx推入堆棧(現在生成rsp == rbp - 16)來保存它們。然後rsp再次被減去32,即rsp == rbp - 48

這是常見的模式,如何爲局部變量分配內存空間,即任何進一步的push指令都將使用低於rbp - 48的內存。內存從rbp - 48rbp - 17(增量)未定義,可以自由用作「局部變量」內存。然後在rbp - 16存儲8字節原始rbx值,在rbp - 8存儲原始r12值,並在rbp存儲舊rbp。 (我的意思是所有的「rbp-x」被用作內存地址來存儲內存中的值)

然後你的代碼調用輸入6個數字,我猜的意思是32位整數(由下面的代碼判斷),所以它提供了地址爲rbp - 48。 6 * 4 = 24 =>輸入值將存儲在地址rbp - 48直到(含)rbp - 25的存儲器中。

注「未使用的內存」從rbp - 24高達rbp - 17的差距,這是另一個8個字節的備用本地存儲,不使用你發佈的代碼,這是由編譯器中加入極有可能的留白,使rspcallq read_six_numbers之前正確對齊。

所以基本上你不需要知道哪兒rsp/rbp點,它指向一些有效的堆棧存儲器(可能是,或代碼將崩潰,而炸彈將爆炸......有點怪設計:))))。您可以在開始時選取任意值,如0x8000rsp),然後用此模擬運行。 (即<+11> leaq -0x30,(%rbp), %rsi然後rsi = 0x7FC8;(爲0x8000 - 8 - 的0x30)

什麼-x(%rbp)意味着各種指令(要注意的「內存操作數」使用的lea VS <any other instruction>語義差別休息時,lea確實只有內存地址計算,而其他指令只是以此爲起點,使用計算得到的地址訪問存儲在內存中的實際值)在其他答案+註釋中進行了描述,並使用x86指令參考指南並通過一些教程再次閱讀,直到它