2017-03-09 5 views
1

私は読んでいるハッチング:搾取の技術と私はコンパイルされたコードと本の1つの違いを発見しました。プロローグ関数の違い

コード:彼はgccでコンパイルし、gdbで逆アセンブルする本では

void test_function(int a, int b, int c, int d) { 

    int flag; 
    char buffer[10]; 

    flag = 31337; 
    buffer[0] = 'A'; 
} 

int main() { 

    test_function(1, 2, 3, 4); 
} 

、私はソフトウェアのバージョンを知りません。

gcc -g program.c 
gdb -q ./a.out 

そして、彼は:私はgccのバージョン5.4を使用してい

(gdb) disass main 
Dump of assembler code for function main: 
    0x000000000040058b <+0>: push rbp 
    0x000000000040058c <+1>: mov rbp,rsp 
    0x000000000040058f <+4>: mov ecx,0x4 
    0x0000000000400594 <+9>: mov edx,0x3 
    0x0000000000400599 <+14>: mov esi,0x2 
    0x000000000040059e <+19>: mov edi,0x1 
    0x00000000004005a3 <+24>: call 0x400546 <test_function> 
    0x00000000004005a8 <+29>: mov eax,0x0 
    0x00000000004005ad <+34>: pop rbp 
    0x00000000004005ae <+35>: ret  
End of assembler dump. 

(gdb) disass test_function 
Dump of assembler code for function test_function: 
    0x0000000000400546 <+0>: push rbp 
    0x0000000000400547 <+1>: mov rbp,rsp 
    0x000000000040054a <+4>: sub rsp,0x40 
    0x000000000040054e <+8>: mov DWORD PTR [rbp-0x34],edi 
    0x0000000000400551 <+11>: mov DWORD PTR [rbp-0x38],esi 
    0x0000000000400554 <+14>: mov DWORD PTR [rbp-0x3c],edx 
    0x0000000000400557 <+17>: mov DWORD PTR [rbp-0x40],ecx 
    0x000000000040055a <+20>: mov rax,QWORD PTR fs:0x28 
    0x0000000000400563 <+29>: mov QWORD PTR [rbp-0x8],rax 
    0x0000000000400567 <+33>: xor eax,eax 
    0x0000000000400569 <+35>: mov DWORD PTR [rbp-0x24],0x7a69 
    0x0000000000400570 <+42>: mov BYTE PTR [rbp-0x20],0x41 
    0x0000000000400574 <+46>: nop 
    0x0000000000400575 <+47>: mov rax,QWORD PTR [rbp-0x8] 
    0x0000000000400579 <+51>: xor rax,QWORD PTR fs:0x28 
    0x0000000000400582 <+60>: je  0x400589 <test_function+67> 
    0x0000000000400584 <+62>: call 0x400420 <__stack_[email protected]> 
    0x0000000000400589 <+67>: leave 
    0x000000000040058a <+68>: ret  
End of assembler dump. 

(gdb) disass main 
Dump of assembler code for function main(): 
0x08048357 <main+0>: push ebp 
0x08048358 <main+1>: mov ebp,esp 
0x0804835a <main+3>: sub esp,0x18 
0x0804835d <main+6>: and esp,0xfffffff0 
0x08048360 <main+9>: mov eax,0x0 
0x08048365 <main+14>: sub esp,eax 
0x08048367 <main+16>: mov DWORD PTR [esp+12],0x4 
0x0804836f <main+24>: mov DWORD PTR [esp+8],0x3 
0x08048377 <main+32>: mov DWORD PTR [esp+4],0x2 
0x0804837f <main+40>: mov DWORD PTR [esp],0x1 
0x08048386 <main+47>: call 0x8048344 <test_function> 
0x0804838b <main+52>: leave 
0x0804838c <main+53>: ret  

End of assembler dump 
(gdb) disass test_function() 
Dump of assembler code for function test_function: 
0x08048344 <test_function+0>: push ebp 
0x08048345 <test_function+1>: mov ebp,esp 
0x08048347 <test_function+3>: sub esp,0x28 
0x0804834a <test_function+6>: mov DWORD PTR [ebp-12],0x7a69 
0x08048351 <test_function+13>: mov BYTE PTR [ebp-40],0x41 
0x08048355 <test_function+17>: leave 
0x08048356 <test_function+18>: ret  

は代わりに、これは私の(同じコマンドを使用して)出力され 彼はコマンドを使用しています.0とgdbバージョン7.11.1。

私は2つの質問があります:関数が異なるproloqueされるのはなぜ

  • を?ブックコンパイラと私の与えた指示の違いは何ですか? (私はレジスタの名前について話していない、なぜ私のメインプロローグが押して移動するだけであるのか話している)

  • 可能なスタックオーバーフローとコンパイラのためにtest_functionの違い他の人よりも)知っているし、それにパッチを当てる?そうであれば、欠陥が存在し、それをどのような方法でパッチするかをどのように知っていますか?

EDIT:私は書籍版は、32ビットアーキテクチャ上でコンパイルされた知っています。私の質問は、同じことをしなければならない場合は、コンパイラの異なる命令についてでした、なぜ彼らは異なっていますか?

+0

コンパイラは時間とともに変化し、特にGCCはバージョン間で必ずしも同じコードを生成しないくらい頻繁に更新されます。あなたのバージョンは、おそらく、著者が本の作成に使ったものよりも新しいものです。 – StoryTeller

+3

あなたはx86-64用にコンパイルしていますが、この本はx86(32ビット)用にコンパイルされています。 – EOF

+0

あなたの編集に応じて、呼び出し規約が異なるため、64ビットと32ビットで異なる理由があります。もう1つの違いは、あなたが本に書かれているものとは異なるコンパイラを使用していることです。また、スタックチェックインをビルドしています(DebianやUbuntuの新しいバージョンを使用している場合は珍しくありません) –

答えて

1

本のバージョンは32ビットアーキテクチャでコンパイルされ、64ビットは1つのコンパイルでコンパイルされました。-m32スイッチを使用して32ビットの実行ファイルを生成します。

+0

質問が不明かもしれません。私は書籍のバージョンが32ビットアーキテクチャでコンパイルされたことを知っている、私の質問は、コンパイラの異なる命令について、彼らは同じことをしなければならない場合は、なぜ彼らは異なるのですか? – Erika

関連する問題