2017-07-02 73 views
-1

如果這個彙編代碼將打印1,2,6,24,120,720作爲六個數字,我感到非常困惑。我試圖在GDB中多次嘗試,並且我看到eax值從1,2,3和6起波動,然後由於某種原因,它不會循環兩次以上。我真的堅持這一點,任何幫助,將不勝感激。這與其他二元彈階段2的帖子無關,因爲這個不同。二進制炸彈階段2

0x000000000040129f <+0>:  push %rbp 
0x00000000004012a0 <+1>:  push %rbx 
0x00000000004012a1 <+2>:  sub $0x28,%rsp 
0x00000000004012a5 <+6>:  mov %rsp,%rsi 
0x00000000004012a8 <+9>:  callq 0x40185a <read_six_numbers> 
0x00000000004012ad <+14>:  cmpl $0x1,(%rsp) 
0x00000000004012b1 <+18>:  je  0x4012be <phase_2+31> 
0x00000000004012b3 <+20>:  mov $0x0,%eax 
0x00000000004012b8 <+25>:  callq *0x2034e2(%rip)  # <explode> 
0x00000000004012be <+31>:  mov %rsp,%rbx 
0x00000000004012c1 <+34>:  mov $0x1,%ebp 
0x00000000004012c6 <+39>:  mov (%rbx),%eax 
0x00000000004012c8 <+41>:  lea (%rax,%rax,2),%eax 
0x00000000004012cb <+44>:  mov %eax,%edx 
0x00000000004012cd <+46>:  xor 0x4(%rbx),%edx 
0x00000000004012d0 <+49>:  mov %ebp,%ecx 
0x00000000004012d2 <+51>:  sar %cl,%eax 
0x00000000004012d4 <+53>:  cmp %eax,%edx 
0x00000000004012d6 <+55>:  je  0x4012e3 <phase_2+68> 
0x00000000004012d8 <+57>:  mov $0x0,%eax 
0x00000000004012dd <+62>:  callq *0x2034bd(%rip)  <explode> 
0x00000000004012e3 <+68>:  add $0x1,%ebp 
0x00000000004012e6 <+71>:  add $0x4,%rbx 
0x00000000004012ea <+75>:  cmp $0x6,%ebp 
0x00000000004012ed <+78>:  jne 0x4012c6 <phase_2+39> 
0x00000000004012ef <+80>:  add $0x28,%rsp 
0x00000000004012f3 <+84>:  pop %rbx 
0x00000000004012f4 <+85>:  pop %rbp 
0x00000000004012f5 <+86>:  retq 

這是我在我的第二次迭代寄存器中得到的。現在不會有另一個迭代,因爲rax和rdx不相等,所以不會執行最後的跳轉。這讓我感到困惑,因爲我認爲它應該能夠循環回來直到出現6個數字。

rax   0x1 1 
rbx   0x7fffffffe1f4 140737488347636 
rcx   0x2 2 
rdx   0x5 5 
rsi   0x402e7d 4206205 
rdi   0x7fffffffdb21 140737488345889 
rbp   0x2 0x2 
rsp   0x7fffffffe1f0 0x7fffffffe1f0 
r8    0x3e9258ee40 268743274048 
r9    0x100 256 
r10   0xb 11 
r11   0xb 11 
r12   0x400e30 4197936 
r13   0x7fffffffe320 140737488347936 
r14   0x0 0 
r15   0x0 0 
rip   0x4012d8 0x4012d8 <phase_2+57> 
eflags   0x202 [ IF ] 
cs    0x33 51 
ss    0x2b 43 
ds    0x0 0 
es    0x0 0 
fs    0x0 0 
+0

'read_six_numbers'返回什麼?該功能如何工作?這是你已經知道的一件事嗎?緊接着的指令是將堆棧頂部的值與1進行比較。如果該值不是* 1,則跳轉到「+ 31」。你應該能夠從那裏一行一行地追蹤代碼。 –

+0

[理解炸彈實驗室]可能的副本(https://stackoverflow.com/questions/26435018/understanding-bomb-lab) –

+0

@Bo persson它不是一回事。 Cody什麼意思是什麼read_six_numbers返回?它只是要求六個數字,第一個必須是1,然後如果是,那麼它跳到31。問題是,當我試圖在第二次迭代中追蹤它時,它不會滿足最後跳躍的條件,並且最終會在gdb中發生爆炸。 – user181421

回答

0

所以,你已經確定:

  • 第一個數字是1
  • 有環路通過數字迭代
  • 存在必須是真實的條件

讓我們看看循環。應該很明顯ebp是計數器,而rbx是一個指針。

現在,條件。兩個操作數如何設置?對於eax,我們可以看到它是從當前編號的(%rbx)加載的,然後對它執行一些操作。我們並不關心什麼,因爲第一個數字是已知的,所以我們不能改變結果。其他操作數是edx。這也是以某種方式從當前數字計算出來的,但也是xor - 用下一個數字(xor 0x4(%rbx),%edx一行)。

有了這些信息,我們輸入1 0 0 0 0 0作爲第一個猜測。請注意0​​與0保持不變。讓程序運行直到比較,並檢查eaxedx中的內容。這將是13,這不是不幸的。如上所述,我們不能更改eax,但我們可以通過使用xor與下一個數字來更改edx。由於xor的工作原理,eax^edx將成爲我們的下一個號碼。你可以讓gdb打印它爲p $eax^$edx。現在,重新啓動程序並輸入該數字來代替第一個零佔位符。讓循環運行一次迭代並重復該過程以獲得其餘的數字。

+0

謝謝傑斯特!它運作良好! – user181421