はどうかと言うと
0x405130より前の*はどういう意味ですか?
私はgdbの逆アセンブラに精通していませんがjmp *0x405130
、ポインタを介した間接ジャンプのようです。0x405130にあるものを逆アセンブルする代わりに、そこに4バイトのメモリをダンプする必要があります。そこに別のアドレスが見つかることは間違いありません。その場所を逆アセンブルすると、printf()
のコードが見つかります(逆アセンブルがどれほど読みやすいかは別の話です)。
つまり、は、それ自体ではなく_imp__printf
、へのポインタです。printf()
printf()
以下のコメントの詳細については、後で編集してください。
少し突っついているのは、Intelアセンブリ構文を使用する場合の命令jmp *0x405130
のGAS / AT&Tアセンブリ構文であることを示しています。jmp [0x405130]
これを不思議に思うのは、gdbコマンドx/xw 0x405130
がそのアドレスに含まれていることを示しているということです0x00005274
(これは、0x405130を分解したときに取得したものと一致しているようです)。ただし、それはjmp [0x405130]
アドレスにジャンプしようとすることを意味します0x00005274
が、これは正しくないようです(そして、そのアドレスを分解しようとすると、gdbは同じように言いました。
_imp_printf
エントリが、最初の実行が0x405130をジャンプするときに、OSがトラップをフィールドして動的リンクを修正する0x00005274アドレスにヒットする、ある種の遅延バインディング手法を使用している可能性があります。修正後、OSは0x405130の正しいリンクアドレスで実行を再開します。しかし、これは私の側のまったくの当て推量です。使用しているシステムがこのようなことをするかどうかはわかりませんが(実際、どのシステムで実行されているかさえわかりません)、技術的には可能です。このようなことが起こっている場合、最初の呼び出しprintf()
が行われるまで、0x405130に正しいアドレスが表示されません。
printf()
実際に何が起こっているのかを確認するには、アセンブリレベルでの呼び出しを1ステップ実行する必要があると思います。
GDBセッションで更新された情報:
これがあなたが直面している問題です-あなたはシステムがDLLをロードしてDLLへのリンクを修正する前のプロセスを見ています。これは、GDBでデバッグされたMinGWでコンパイルされた単純な「helloworld」プログラムのデバッグセッションです。
C:\temp>\mingw\bin\gdb test.exe
GNU gdb (GDB) 7.1
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "mingw32".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from C:\temp/test.exe...done.
(gdb) disas main
Dump of assembler code for function main:
0x004012f0 <+0>: push %ebp
0x004012f1 <+1>: mov %esp,%ebp
0x004012f3 <+3>: sub $0x8,%esp
0x004012f6 <+6>: and $0xfffffff0,%esp
0x004012f9 <+9>: mov $0x0,%eax
0x004012fe <+14>: add $0xf,%eax
0x00401301 <+17>: add $0xf,%eax
0x00401304 <+20>: shr $0x4,%eax
0x00401307 <+23>: shl $0x4,%eax
0x0040130a <+26>: mov %eax,-0x4(%ebp)
0x0040130d <+29>: mov -0x4(%ebp),%eax
0x00401310 <+32>: call 0x401850 <_alloca>
0x00401315 <+37>: call 0x4013d0 <__main>
0x0040131a <+42>: movl $0x403000,(%esp)
0x00401321 <+49>: call 0x4018b0 <printf>
0x00401326 <+54>: mov $0x0,%eax
0x0040132b <+59>: leave
0x0040132c <+60>: ret
End of assembler dump.
逆アセンブルprintf()
すると、同様の間接ジャンプが発生することに注意してください。
(gdb) disas printf
Dump of assembler code for function printf:
0x004018b0 <+0>: jmp *0x4050f8 ; <<-- indirect jump
0x004018b6 <+6>: nop
0x004018b7 <+7>: nop
End of assembler dump.
そして、その_imp__printf
シンビオールはコードとしては意味がありません...
(gdb) disas 0x4050f8
Dump of assembler code for function _imp__printf:
0x004050f8 <+0>: clc ; <<-- how can this be printf()?
0x004050f9 <+1>: push %ecx
0x004050fa <+2>: add %al,(%eax)
End of assembler dump.
またはポインタとして...
(gdb) x/xw 0x4050f8
0x4050f8 <_imp__printf>: 0x000051f8 ; <<-- 0x000051f8 is an invalid pointer
main()
それでは、にブレークポイントを設定して、それに実行してみましょう。
(gdb) break main
Breakpoint 1 at 0x40131a: file c:/temp/test.c, line 5.
(gdb) run
Starting program: C:\temp/test.exe
[New Thread 11204.0x2bc8]
Error while mapping shared library sections:
C:\WINDOWS\SysWOW64\ntdll32.dll: No such file or directory.
Breakpoint 1, main () at c:/temp/test.c:5
5 printf( "hello world\n");
printf()
同じように見えます:
(gdb) disas printf
Dump of assembler code for function printf:
0x004018b0 <+0>: jmp *0x4050f8
0x004018b6 <+6>: nop
0x004018b7 <+7>: nop
End of assembler dump.
しかし、_imp__printf
見た目は異なります-動的リンクが修正されました:
(gdb) x/xw 0x4050f8
0x4050f8 <_imp__printf>: 0x77bd27c2
そして、現在指しているものを分解する_imp__printf
と、あまり読みにくいかもしれませんが、明らかに今はコードです。これはprintf()
、MSVCRT.DLLに実装されているとおりです。
(gdb) disas _imp__printf
Dump of assembler code for function printf:
0x77bd27c2 <+0>: push $0x10
0x77bd27c4 <+2>: push $0x77ba4770
0x77bd27c9 <+7>: call 0x77bc84c4 <strerror+554>
0x77bd27ce <+12>: mov $0x77bf1cc8,%esi
0x77bd27d3 <+17>: push %esi
0x77bd27d4 <+18>: push $0x1
0x77bd27d6 <+20>: call 0x77bcca49 <msvcrt!_lock+4816>
0x77bd27db <+25>: pop %ecx
0x77bd27dc <+26>: pop %ecx
0x77bd27dd <+27>: andl $0x0,-0x4(%ebp)
0x77bd27e1 <+31>: push %esi
0x77bd27e2 <+32>: call 0x77bd400d <wscanf+3544>
0x77bd27e7 <+37>: mov %eax,-0x1c(%ebp)
0x77bd27ea <+40>: lea 0xc(%ebp),%eax
0x77bd27ed <+43>: push %eax
0x77bd27ee <+44>: pushl 0x8(%ebp)
0x77bd27f1 <+47>: push %esi
0x77bd27f2 <+48>: call 0x77bd3330 <wscanf+251>
0x77bd27f7 <+53>: mov %eax,-0x20(%ebp)
0x77bd27fa <+56>: push %esi
0x77bd27fb <+57>: pushl -0x1c(%ebp)
0x77bd27fe <+60>: call 0x77bd4099 <wscanf+3684>
0x77bd2803 <+65>: add $0x18,%esp
0x77bd2806 <+68>: orl $0xffffffff,-0x4(%ebp)
0x77bd280a <+72>: call 0x77bd281d <printf+91>
0x77bd280f <+77>: mov -0x20(%ebp),%eax
0x77bd2812 <+80>: call 0x77bc84ff <strerror+613>
0x77bd2817 <+85>: ret
0x77bd2818 <+86>: mov $0x77bf1cc8,%esi
0x77bd281d <+91>: push %esi
0x77bd281e <+92>: push $0x1
0x77bd2820 <+94>: call 0x77bccab0 <msvcrt!_lock+4919>
0x77bd2825 <+99>: pop %ecx
0x77bd2826 <+100>: pop %ecx
0x77bd2827 <+101>: ret
0x77bd2828 <+102>: int3
0x77bd2829 <+103>: int3
0x77bd282a <+104>: int3
0x77bd282b <+105>: int3
0x77bd282c <+106>: int3
End of assembler dump.
適切な記号が使用可能かどうか(またはGDBがそれらの記号を適切に読み取ることができるかどうか)がわからないため、おそらくあなたが望むよりも読みにくいでしょう。
ただし、別の回答で述べたように、オープンソースであるかどうかに関係なく、通常、コンパイラでCランタイムルーチンのソースを取得できます。MinGWにはWindowsのものであるためMSVDRT.DLLのソースは付属していませんが、Visual StudioディストリビューションでMSVDRT.DLLのソース(またはそれにかなり近いもの)を入手できます-無料のVC++Expressでさえ付属していると思いますランタイムソース(しかし、私はそれについて間違っているかもしれません)。