2012-01-22 18 views
2

私はJon Ericksonの著書「Hacking:The Art of Exploitation」を取り上げています。strcpy()を呼び出すときに、対応するサブルーチン呼び出しがマシンコードのダンプで呼び出されないのはなぜですか?

本の一部では、彼はCコードを与え、gdbを使用して対応するアセンブリを歩き、命令とメモリの動作を説明します。

私はMac OS Xで作業していますので、彼は本で紹介するもの(彼はLinuxを使用しています)とは少し異なります。

とにかく、私はこのCプログラムを持っている:

_main: 
0000000100000ea0 pushq %rbp 
0000000100000ea1 movq %rsp,%rbp 
0000000100000ea4 subq $0x30,%rsp 
0000000100000ea8 movq 0x00000189(%rip),%rax 
0000000100000eaf movq (%rax),%rax 
0000000100000eb2 movq %rax,0xf8(%rbp) 
0000000100000eb6 leaq 0xd4(%rbp),%rax 
0000000100000eba movq %rax,%rcx 
0000000100000ebd movq $0x77202c6f6c6c6548,%rdx 
0000000100000ec7 movq %rdx,(%rcx) 
0000000100000eca movb $0x00,0x0e(%rcx) 
0000000100000ece movw $0x0a21,0x0c(%rcx) 
0000000100000ed4 movl $0x646c726f,0x08(%rcx) 
0000000100000edb movq %rcx,0xe8(%rbp) 
0000000100000edf xorb %cl,%cl 
0000000100000ee1 movq %rax,%rdi 
0000000100000ee4 movb %cl,%al 
0000000100000ee6 callq 0x100000f1e ; symbol stub for: _printf 
0000000100000eeb movl 0xf4(%rbp),%eax 
0000000100000eee movq 0x00000143(%rip),%rcx 
0000000100000ef5 movq (%rcx),%rcx 
0000000100000ef8 movq 0xf8(%rbp),%rdx 
0000000100000efc cmpq %rdx,%rcx 
0000000100000eff movl %eax,0xd0(%rbp) 
0000000100000f02 jne 0x100000f0d 
0000000100000f04 movl 0xd0(%rbp),%eax 
0000000100000f07 addq $0x30,%rsp 
0000000100000f0b popq %rbp 
0000000100000f0c ret 
0000000100000f0d callq 0x100000f12 ; symbol stub for: ___stack_chk_fail 

OK:ここ

1 #include <stdio.h> 
2 #include <string.h> 
3 
4 int main() 
5 { 
6   char str_a[20]; 
7 
8   strcpy(str_a, "Hello, world!\n"); 
9   printf(str_a); 
10 } 

は、対応するコマンドotoolオブジェクト・ダンプ(私は、メイン含まれている)です。

0000000100000ee6 callq 0x100000f1e ; symbol stub for: _printf 

をしかし、ここでのstrcpy()への呼び出しは次のとおりです。あなたは()のprintfサブルーチンコールに気づくでしょうか?

さらに2つの異常があります。まず、strcpy()のgdpにブレークポイントを設定した場合:

break strcpy 

プログラムは実行を途中で止めることなくジップアップします。 strcpy()が実際に呼び出されていないかのようです。

第二に、私はコードをコンパイルした場合:私はそれが欠けているサブルーチンコールに関連しているかどうかわからないんだけど、私は思っ

char_array2.c: In function ‘main’: 
char_array2.c:9: warning: format not a string literal and no format arguments 
char_array2.c:9: warning: format not a string literal and no format arguments 

gcc -g -o char_array2 char_array2.c 

を私は警告を得ましたとにかくそれをデータポイントとして含めるでしょう。

コンパイラがstrcpy()が必要ではないと判断して、それなしで動作するようにコードを最適化したかのように思えます。プログラムは、「Hello、world!」という印字をしています。 strcpy()へのこの欠落した呼び出しは、何が起こっているのか正確に疑問に思います。

本の中のエリクソンの例では、です。strcpy()を呼び出すと、コンパイラとコンパイラの動作に違いがあるかもしれません。私はLLVMの午前:

のi686-りんごdarwin11-LLVM-GCC-4.2

任意のアイデアをありがたく受け取ったことでしょう!

おかげさまで、ありがとうございました。あなたがこの1つを面白いと思うことを願っています。

トム

+0

あなたの説明は完全にもっともらしい聞こえます。どのコンパイラフラグを使用していますか? –

+1

http://gcc.gnu.org/onlinedocs/gcc-4.2.1/gcc/Other-Builtins.html –

+0

ちょうど-gと-o。 –

答えて

9

それはここです:

0000000100000ebd movq $0x77202c6f6c6c6548,%rdx 
0000000100000ec7 movq %rdx,(%rcx) 
0000000100000eca movb $0x00,0x0e(%rcx) 
0000000100000ece movw $0x0a21,0x0c(%rcx) 
0000000100000ed4 movl $0x646c726f,0x08(%rcx) 
+0

ありがとうございます。そこに 'call'や 'callq'命令はないはずですか?謝罪;私はアセンブリに新しく、この本(Linuxベース)で使われている構文は、OS Xで見ているものとはかなり異なっています。 –

+0

'call'や' callq'(または任意の実行の転送)が必要な理由はありません特に引数の1つが文字列リテラルであるときには、 'strcpy'を実行する必要があります。 –

+2

多分もっと精巧にするために、** Cはハイレベルアセンブラ**ではありません。 Cコンパイラの仕事は、コンパイルされたプログラムの観察可能な振る舞いが言語標準によって指定されたものと一致するようにすることです。 (1)同じ翻訳単位で定義され、インライン化できる、(2)その動作が標準とコンパイラによって指定されているなど、関数を呼び出すときに 'call'命令が実行されませんそれ自身で直接インラインで行動を達成することができます。 –

関連する問題