2016-08-27 13 views
1

で逆アセンブルします。テストされたアプリケーションがクラッシュし、コアファイルが見つかりました。 gdbでコアファイルを開いた後に、アプリケーションにデバッグシンボルがないことが示されます。fuzzingセッション中にコアファイルをgdb

バックトレースコマンドは次のことを明らかに:

だから、
Program terminated with signal 11, Segmentation fault. 
#0 0x0000000000000000 in ??() 
    (gdb) bt 
#0 0x0000000000000000 in ??() 
#1 0x00007f8749f065d3 in ??() 
#2 0x00007f874c6a9000 in ??() 
#3 0x00007f8749f06568 in ??() 
#4 0x00007f874c6ab9a0 in ??() 
#5 0x00007f874c6aaa00 in ??() 
#6 0x0000000000000001 in ??() 
#7 0x00007f8749f06664 in ??() 
#8 0x0000000000000000 in ??() 

、私は0x00007f8749f065d3、1(GDB)disassを入力したときに、私は次の出力を得る:

Dump of assembler code from 0x7f8749f065d3 to 0x7f8749f065d4: 
    0x00007f8749f065d3: mov QWORD PTR [rbx+0x70],0x0 
End of assembler dump. 

そして今、私の質問:たとえば

、私は前の行にしています($ 000 07f8749f065d3)、2つの実行行を、0x00007f8749f065d3の前に解析したいと思ったら、どうすればよいですか?

注:私が直感的に入力する(gdb)disass 0x00007f8749f065d3、-2のようなコマンドは役に立ちませんでした。

敬具、

+0

GDBをどのように起動しましたか?コアファイルをどうやって開いたのですか?あなたはそれを正しくしていない可能性があります。 –

+0

シェルで "gdb/path_to_app/crashed_app_name/path_to_core_file/core"とタイプしました。したがって、最初にgdbを1番目の引数としてクラッシュしたアプリへのパスを、2番目の引数にコアファイルへのパスを指定します。 – user3097712

答えて

3

あなたはアセンブラ命令とソース行を関連付ける方法を理解する必要がありますか?あるいは、現在の指示の前に指示を逆アセンブルする方法を意味しますか?

ここに両方の​​質問に対する回答があります。バックトレースコマンドに示さ

16進数は、関数へのエントリポイントのプログラム・カウンタ・アドレスです。アドレスのアセンブラコマンドは、呼び出しやjmpのような単一の命令になります。

gccのようなコンパイラは、ソースコードをアセンブラ命令に変換します。コンパイラは、実行可能イメージに 'DWARF'情報を含めます。 DWARF情報は、一連のアセンブラ命令を特定のソースコード行に関連付けるために使用されます。

このCフラグメント考えてみましょう:disass /mを使用して

は、GDBは、アセンブラでソース行を関連付ける方法を示しています。

48   { 
    0x0000000000400bdf <+0>: push %rbp 
    0x0000000000400be0 <+1>: mov %rsp,%rbp 
    0x0000000000400be3 <+4>: add $0xffffffffffffff80,%rsp 
    0x0000000000400be7 <+8>: mov %edi,-0x74(%rbp) 
    0x0000000000400bea <+11>: mov %rsi,-0x80(%rbp) 
    0x0000000000400bee <+15>: mov %fs:0x28,%rax 
    0x0000000000400bf7 <+24>: mov %rax,-0x8(%rbp) 
    0x0000000000400bfb <+28>: xor %eax,%eax 

49    int s, tnum, opt, num_threads; 
50    struct thread_info *tinfo; 
51    pthread_attr_t attr; 
52    int stack_size; 
53    void *res; 
54 
55    /* The "-s" option specifies a stack size for our threads */ 
56 
57    stack_size = -1; 
    0x0000000000400bfd <+30>: movl $0xffffffff,-0x60(%rbp) 

58    while ((opt = getopt(argc, argv, "s:")) != -1) { 
    0x0000000000400c04 <+37>: jmp 0x400c56 <main+119> 
    0x0000000000400c56 <+119>: mov -0x80(%rbp),%rcx 
    0x0000000000400c5a <+123>: mov -0x74(%rbp),%eax 
    0x0000000000400c5d <+126>: mov $0x401002,%edx 
    0x0000000000400c62 <+131>: mov %rcx,%rsi 
    0x0000000000400c65 <+134>: mov %eax,%edi 
    0x0000000000400c67 <+136>: callq 0x400a00 <[email protected]> 
    0x0000000000400c6c <+141>: mov %eax,-0x5c(%rbp) 
    0x0000000000400c6f <+144>: cmpl $0xffffffff,-0x5c(%rbp) 
    0x0000000000400c73 <+148>: jne 0x400c06 <main+39> 

59     switch (opt) { 
    0x0000000000400c06 <+39>: mov -0x5c(%rbp),%eax 
    0x0000000000400c09 <+42>: cmp $0x73,%eax 
    0x0000000000400c0c <+45>: jne 0x400c2c <main+77> 

60     case 's': 
61      stack_size = strtoul(optarg, NULL, 0); 
    0x0000000000400c0e <+47>: mov 0x2014cb(%rip),%rax  # 0x6020e0 <[email protected]@GLIBC_2.2.5> 
    0x0000000000400c15 <+54>: mov $0x0,%edx 
    0x0000000000400c1a <+59>: mov $0x0,%esi 
    0x0000000000400c1f <+64>: mov %rax,%rdi 
    0x0000000000400c22 <+67>: callq 0x400a10 <[email protected]> 
    0x0000000000400c27 <+72>: mov %eax,-0x60(%rbp) 

62      break; 
    0x0000000000400c2a <+75>: jmp 0x400c56 <main+119> 

一部のソース行は単一の命令であり、その他は複数の命令で構成されています。一部の行についてもアドレスの順序が正しくないことに注意してください。

実行可能ファイルにデバッグ情報がないため、アセンブラ命令をソース行に自動的に関連付ける方法はありません。デバッグ情報の目的は、2つを関連付けることです。 x86のような可変長命令アーキテクチャの場合

、これは前の命令のために後方検索する簡単な方法ではありません。デバッガでは、16のような値を減算して逆アセンブリを実行するのが最適な方法です。現在の指示が正しいと思われる場合、分解の大部分は正しい。私の例では、0x0000000000400c06を考慮に入れることができます。

したがって、16(0x10)を減算すると、0x400bf6になります。

(gdb) disass 0x0000000000400bf6, +20 
Dump of assembler code from 0x400bf6 to 0x400c0a: 
    0x0000000000400bf6 <main+23>: add %cl,-0x77(%rax) 
    0x0000000000400bf9 <main+26>: rex.RB clc 
    0x0000000000400bfb <main+28>: xor %eax,%eax 
    0x0000000000400bfd <main+30>: movl $0xffffffff,-0x60(%rbp) 
    0x0000000000400c04 <main+37>: jmp 0x400c56 <main+119> 
    0x0000000000400c06 <main+39>: mov -0x5c(%rbp),%eax 
    0x0000000000400c09 <main+42>: cmp $0x73,%eax 

上記の逆アセンブリと比較すると、逆アセンブリは 'xor'命令から正しく始まります。あなたがアセンブラをよく知っているなら、あなたは 'rex'のような奇妙な指示に気づくだろう。

gdbがコードをどのように逆アセンブルするかを聞くことは合理的です。その答えは、常に関数の最初の命令から始まり、下方向に働くということです。

良い質問!

+0

こんにちは、マシュー。ご回答ありがとうございます。わかっている。したがって、特定のアドレスを取得し、それをある値で減算してから逆アセンブルします。はい。これもアイデアでしたが、私はgdb命令があるかもしれないと考えました。私は間違っていた。しかし私はあなたのアプローチが好きです。 – user3097712

+0

あなたの歓迎、投票に感謝します。私の答えが役に立ったら、それを「受け入れてください」。私は私の評判を築こうとしています。 –

+0

さて、私はそれをやった:) – user3097712

関連する問題