web-dev-qa-db-ja.com

GDBでメモリ範囲を分解するにはどうすればいいですか?

私はプログラムを逆アセンブルして、syscall Assembly命令(INT命令、私は信じる)とGDBのハンドラーを見て、ファイルを開閉する小さなプログラム(以下を参照)を作成しようとしています。

呼び出しを実行するまで、GDBを使用してfopenの呼び出しに従うことができました。

GDBに「逆アセンブル0x ....」(呼び出しのアドレス)を伝えようとすると、「指定されたアドレスを含む関数はありません」と応答しました。

GDBにそのメモリアドレスを強制的に逆アセンブルする(またはアセンブラで表示する)ことは可能ですか?もしそうなら、どのように?

#include <stdio.h>
#include <stdlib.h>

int main() {
    FILE* f;
    f = fopen("main.c", "r");
    if (!f) { 
      perror("open");
      return -1;
    }
    fclose(f);
    return 0;
}
58
Patrick

実際のメインのみを分解しますか?もしそうならこれを試してください:

(gdb) info line main 
(gdb) disas STARTADDRESS ENDADDRESS

そのようです:

[email protected] /cygdrive/c/prog/dsa
$ gcc-3.exe -g main.c

[email protected] /cygdrive/c/prog/dsa
$ gdb a.exe
GNU gdb 6.8.0.20080328-cvs (cygwin-special)
...
(gdb) info line main
Line 3 of "main.c" starts at address 0x401050 <main> and ends at 0x401075 <main+
(gdb) disas 0x401050 0x401075
Dump of assembler code from 0x401050 to 0x401075:
0x00401050 <main+0>:    Push   %ebp
0x00401051 <main+1>:    mov    %esp,%ebp
0x00401053 <main+3>:    sub    $0x18,%esp
0x00401056 <main+6>:    and    $0xfffffff0,%esp
0x00401059 <main+9>:    mov    $0x0,%eax
0x0040105e <main+14>:   add    $0xf,%eax
0x00401061 <main+17>:   add    $0xf,%eax
0x00401064 <main+20>:   shr    $0x4,%eax
0x00401067 <main+23>:   shl    $0x4,%eax
0x0040106a <main+26>:   mov    %eax,-0xc(%ebp)
0x0040106d <main+29>:   mov    -0xc(%ebp),%eax
0x00401070 <main+32>:   call   0x4010c4 <_alloca>
End of assembler dump.

ただし、システム割り込み呼び出しは表示されません。 (アセンブリでシステムコールを最後に試行してからしばらく経ちました。INT21hただし、最後に思い出すのは

45
nont

ええ、逆アセンブルはここで使用するのに最適なコマンドではありません。必要なコマンドは「x/i」です(手順として調べてください):

(gdb) x/i 0xdeadbeef
95
Michael Snyder

これはあなたの質問に対する直接的な答えではありませんが、バイナリを単に逆アセンブルしたいだけなので、おそらくobjdumpを使うことができます:

objdump -d program

これにより、解体が可能になります。あなたは付け加えられます -Sソース注釈が必要な場合。

30
Falaina

fopen()はCライブラリ関数であるため、コードにsyscall命令は表示されず、通常の関数呼び出しのみが表示されます。ある時点でopen(2)を呼び出しますが、トランポリンを介して呼び出します。カーネルによってすべてのプロセスに提供されるVDSOページにジャンプするだけです。次に、VDSOはシステムコールを行うためのコードを提供します。最新のプロセッサでは、SYSCALLまたはSYSENTER命令が使用されますが、x86プロセッサではINT 80hも使用できます。

7
Joel

-Sスイッチを追加することにより、gccにアセンブリコードに直接出力させることができます。

gcc -S hello.c
6
askjhdf

必要なのがINTC呼び出しで逆アセンブリを表示することだけである場合、誰かが述べたようにobjdump -dを使用しますが、コンパイル時には-staticオプションを使用します。それ以外の場合、fopen関数はelfにコンパイルされず、実行時にリンクされます。

3
Al.

Gdbを使用する必要はありません。 GCCが行います。

 gcc -S foo.c

これにより、アセンブリであるfoo.sが作成されます。

gcc -m32 -c -g -Wa,-a,-ad foo.c > foo.lst

上記のバージョンは、Cとアセンブリによって生成されたリストファイルを作成します。 GCC FAQ

1
Milhous

gdbの逆アセンブルには、ソースコードを指示とともに含める/ mがあります。これはobjdump -Sと同等ですが、目的の1つの関数(またはアドレス範囲)のみに限定されるという特別な利点があります。

1
Lakshman Kumar