2012-02-08 124 views
19

所以有一點背景。我是一個帶有c和彙編代碼的初學者,我們有一個「炸彈」任務(用c編寫),它調用需要某些密碼的方法,但代碼不可見,我需要通過查看彙編代碼來確定正確的密碼。解碼和理解彙編代碼

該代碼指示此方法的密碼是6個數字,它作爲「輸入」傳遞給方法階段2(我試圖避免觸發)。

我感到困惑的部分是從+64跳到+42。它似乎是一個循環,但我不確定每次傳遞如何影響堆棧。它看起來像循環退出,如果最後兩個數字是相同的,它與增加和減少4有關,但我不確定地址是如何遍歷的。 如果任何人都可以翻譯究竟究竟發生了什麼,或者如果我需要查看任何特定的寄存器/位置,這將有很大幫助。還有4個更多的階段,每個階段都應該更復雜一點,所以我希望能夠很好地理解如何讀取這些內容。

此外,如果任何人有一個很好的資源(如可打印表)與彙編代碼關鍵字,這也將有所幫助,也是如果有任何區別32位和64位寄存器,我需要擔心除了的寄存器名稱..

82   phase_2(input); 
(gdb) disas phase_2 
Dump of assembler code for function phase_2: 
0x000000000040106b <phase_2+0>: push %rbp 
0x000000000040106c <phase_2+1>: push %rbx 
0x000000000040106d <phase_2+2>: sub $0x28,%rsp 
0x0000000000401071 <phase_2+6>: mov %rsp,%rsi 
0x0000000000401074 <phase_2+9>: callq 0x401457 <read_six_numbers> 
0x0000000000401079 <phase_2+14>:  cmpl $0x0,(%rsp) 
0x000000000040107d <phase_2+18>:  jne 0x401086  <phase_2+27> 
0x000000000040107f <phase_2+20>:  cmpl $0x1,0x4(%rsp) 
0x0000000000401084 <phase_2+25>:  je  0x40108b <phase_2+32> 
0x0000000000401086 <phase_2+27>:  callq 0x401421 <explode_bomb> 
0x000000000040108b <phase_2+32>:  lea 0x8(%rsp),%rbx 
0x0000000000401090 <phase_2+37>:  lea 0x18(%rsp),%rbp 
0x0000000000401095 <phase_2+42>:  mov -0x8(%rbx),%eax 
0x0000000000401098 <phase_2+45>:  add -0x4(%rbx),%eax 
0x000000000040109b <phase_2+48>:  cmp %eax,(%rbx) 
0x000000000040109d <phase_2+50>:  je  0x4010a4 <phase_2+57> 
0x000000000040109f <phase_2+52>:  callq 0x401421 <explode_bomb> 
0x00000000004010a4 <phase_2+57>:  add $0x4,%rbx 
0x00000000004010a8 <phase_2+61>:  cmp %rbp,%rbx 
0x00000000004010ab <phase_2+64>:  jne 0x401095 <phase_2+42> 
0x00000000004010ad <phase_2+66>:  add $0x28,%rsp 
0x00000000004010b1 <phase_2+70>:  pop %rbx 
0x00000000004010b2 <phase_2+71>:  pop %rbp 
0x00000000004010b3 <phase_2+72>:  retq 
+0

如果你使用的是Windows,我建議這樣的:http://www.ollydbg.de/使用gdb(我剛剛找到)使用TUI,http://stackoverflow.com/a/2422063/1149736比:'layout asm''start'' layout regs'' ni'' ni'' ni' :) and follow follow stack http://www.chemie.fu-berlin.de/chemnet/use/info/gdb/gdb_7 .html – Vyktor 2012-02-08 00:39:28

+9

你有一個很酷的老師:) – 2012-02-09 09:32:35

回答

45

這裏是C等效階段2的:

int t[6]; 
read_six_numbers (t); 
if ((t[0] != 0) || (t[1] != 1)) { 
    explode_bomb(); 
} 

for (int i = 2; i < 6; i++) { 
     if (t[i] != t[i - 2] + t[i - 1]) { 
      explode_bomb(); 
    } 
} 

所以密碼是0,1,1,2,3,5,

如何d我是否這樣做?通過逐漸用C替換組件。

您會注意到堆棧指針(rsp)從不改變。您可以將堆棧看作32位數字的數組。這是每次移動4個字節時移動到下一個元素。即0(%RSP),4(%RSP),...等同於T [0],T [1],...

我會告訴你,你有位的可能逐步轉變麻煩與:

   lea 0x8(%rsp),%rbx 
       lea 0x18(%rsp),%rbp 
<phase_2+42>: mov -0x8(%rbx),%eax 
       add -0x4(%rbx),%eax 
       cmp %eax,(%rbx) 
       je  <phase_2+57> 
       callq explode_bomb 
<phase_2+57>: add $0x4,%rbx 
       cmp %rbp,%rbx 
       jne phase_2+42 
------------------------------------------------------ 
        rbx = rsp + 8; 
        rbp = rsp + 24; 
<phase_2+42>:  eax = [rbx - 8]; 
        eax += [rbx - 4]; 
        if (eax == [rbx]) goto <phase_2+57>; 
        explode_bomb(); 
<phase_2+57>:  rbx += 4; 
        if (rbx != rbp) goto phase_2+42; 
------------------------------------------------------ 
rbx = rsp + 8; 
rbp = rsp + 24; 
do { 
    eax = [rbx - 8] + [rbx - 4]; 
     if (eax != [rbx]) { 
     explode_bomb(); 
    } 
     rbx += 4; 
} while (rbx != rbp); 
------------------------------------------------------ 
rbx = 8; 
do { 
    eax = [rsp + rbx - 8] + [rsp + rbx - 4]; 
     if (eax != [rsp + rbx]) { 
     explode_bomb(); 
    } 
     rbx += 4; 
} while (rbx < 24); 
------------------------------------------------------ 
i = 2; 
do { 
    eax = t[i - 2] + t[i - 1]; 
     if (eax != t[i]) { 
     explode_bomb(); 
    } 
     i += 1; 
} while (i < 6); 
------------------------------------------------------ 
for (int i = 2; i < 6; i++) { 
    if (t[i] != t[i - 2] + t[i - 1]) { 
      explode_bomb(); 
     } 
} 

如果您花時間瞭解這些轉換,您將能夠轉換和理解任何程序集。

+1

寫得很好,+1。 – 2012-08-02 13:21:31