2012-08-29 255 views
0

我必須爲一個類做一些二進制分析,而且我被困在其中一個程序中。當我設置一些斷點和disas,我看到它看起來像這樣:GDB彙編程序調試

Dump of assembler code for function main: 
    0x080484e2 <+0>: push %ebp 
    0x080484e3 <+1>: mov %esp,%ebp 
    0x080484e5 <+3>: sub $0x48,%esp 
    0x080484e8 <+6>: and $0xfffffff0,%esp 
    0x080484eb <+9>: mov $0x0,%eax 
    0x080484f0 <+14>: sub %eax,%esp 
    0x080484f2 <+16>: cmpl $0x1,0x8(%ebp) 
    0x080484f6 <+20>: jg  0x8048504 <main+34> 
    0x080484f8 <+22>: movl $0x7,(%esp) 
=> 0x080484ff <+29>: call 0x804833c <[email protected]> 
    0x08048504 <+34>: mov 0xc(%ebp),%eax 
    0x08048507 <+37>: add $0x4,%eax 
    0x0804850a <+40>: mov (%eax),%eax 
    0x0804850c <+42>: mov %eax,(%esp) 
    0x0804850f <+45>: call 0x804832c <[email protected]> 
    0x08048514 <+50>: mov %eax,-0x10(%ebp) 
    0x08048517 <+53>: cmpl $0xd,-0x10(%ebp) 
    0x0804851b <+57>: jne 0x804853b <main+89> 
    0x0804851d <+59>: lea -0x38(%ebp),%eax 
    0x08048520 <+62>: mov %eax,(%esp) 
    0x08048523 <+65>: call 0x8048414 <makebuf> 
    0x08048528 <+70>: lea -0x38(%ebp),%eax 
    0x0804852b <+73>: mov %eax,0x4(%esp) 
    0x0804852f <+77>: movl $0x804863b,(%esp) 
** 0x08048536 <+84>: call 0x804831c <[email protected]> 
    0x0804853b <+89>: movl $0x1,(%esp) 
    0x08048542 <+96>: call 0x804833c <[email protected]> 
End of assembler dump. 

(我在星星已經編輯旁邊呼叫的位置對printf @ PLT)。 它看起來像一個程序,它調用exit(),然後生成一個字符串,然後打印出該字符串,然後執行另一個exit()。我認爲,如果我可以繞過這個第一次呼叫退出(),它會打印出我的挑戰答案。是否有正確的方法來設置呼叫發生的位置來執行NOP?如果是這樣,NOP的操作碼是什麼?我試過設置爲0x0和0x00000000。任何幫助將不勝感激!謝謝。

+0

如果這是家庭作業相關的,你應該標記了一個問題,'Homework'。它仍然會被評估。 – HeatfanJohn

+0

你說'它在我看來'。相反,你應該說,'當我單步做它......' – KevinDTimm

回答

0

0x90是x86的NOP指令。因此0x90是一條NOP指令,0x9090是兩條NOP指令,0x90909090將是4條NOP指令。

仔細檢查call 0x804833c指令的長度。我不相信它是4字節長。

3

看看行

0x080484f2 <+16>: cmpl $0x1,0x8(%ebp) 
0x080484f6 <+20>: jg  0x8048504 <main+34> 

,並確定如何可以讓程序跳過第一個出口 - 無需注射

+0

我真的不知道任何集會。我試着從我所處的斷點開始,並跳到一條進一步的指令,但我得到一個seg錯誤。我應該在這兩行之前插入一箇中斷,並跳過所有這些指令? –

+0

我認爲,因爲這是'對於一個班級',那麼推斷代碼正在做什麼是練習的目的。所以,您需要學習適當的程序集才能成功完成作業。 – KevinDTimm

+0

我很清楚在這裏學習,而不只是要求答案......有沒有辦法只編輯gdb中的指令參數? –

1

它不會退出,因爲這行:

cmpl $0x1,0x8(%ebp) 

在這一行中,程序檢查第一個參數的值與一個函數,如果它更大,跳轉。
另外,如果你想在這裏看到printf的格式,你可以在gdb中輸入printf "%s", 0x804863b
更新:
如果此過程是主要的,那麼0x8($ebp)包含所謂的argc,這是您的程序的輸入數量。所以你需要做的是當你運行程序給它輸入。如./a.out blah
你也可以在gdb中輸入x/2wx $esp來檢查這個值。

+0

那麼,我需要將其更改爲與1以外的某個數字進行比較?或操縱作爲參數傳遞的值?這怎麼能實現? –

+0

開始程序時給它輸入。我已經更新了答案。 – Rsh

1

您可能不希望僅撥出電話退出。這次你可能可以避開它,但是在兩次退出呼叫中,他們都會在呼叫之前將退出代碼放入堆棧。根據程序的其餘部分,這些堆棧值可能會或可能不會被使用。

所以你的選擇是NOP出MOV和CALL,或強制跳轉總是按照你想要的方式。

或者最好的方法是弄清楚什麼參數使得它做你想做的。

另外x86的標準NOP操作碼是0x90。

+0

好吧,既然你說,使用NOPing了電話不操作運行程序的一種很好的方式,這將是強制將比較總是導致跳的好辦法?有沒有辦法讓它始終迴歸真實? –

+0

你可以用jmp替換一個jg,你只需要確保你的數學和指令大小排隊。 或者你可以放棄jmp的mov和電話。這樣棧不會被改變。 在這個特定的情況下,你可能只會打電話而不願意,但是不要習慣於不確定堆棧是否正常。 – jcombs

1

如果這是關於家庭作業,那麼你應該知道什麼是允許做的。

如果允許修補,那麼最好的辦法是將操作碼從jg改爲jng,你必須查看英特爾手冊以查看將要更改的內容,但通常是一個字節。

如果補丁是不允許的,那麼你將必須找到將設置被比較的變量,並找出如何使這一功能,將其設置爲別的功能。

+0

我被允許做任何事情,讓我得到我需要的東西。我想我會對補丁進行一些研究。謝謝! –