2

Windbgを学んでいます。練習のために、プロセスを作成する 64 ビットの fre アプリをデバッグしています。CreateProcess にブレークポイントを追加しました (bp KERNEL32!CreateProcessWStub) ブレークポイントにヒットしたら、コード (u) を逆アセンブルすると、次のようになります。

Breakpoint 0 hit
KERNEL32!CreateProcessWStub:
000007f9`f8024ab4 4c8bdc          mov     r11,rsp
0:000> u @rip L20
KERNEL32!CreateProcessWStub:
000007f9`f8024ab4 4c8bdc          mov     r11,rsp
000007f9`f8024ab7 4883ec58        sub     rsp,58h
000007f9`f8024abb 488b8424a8000000 mov     rax,qword ptr [rsp+0A8h]
000007f9`f8024ac3 498943f0        mov     qword ptr [r11-10h],rax
000007f9`f8024ac7 488b8424a0000000 mov     rax,qword ptr [rsp+0A0h]
000007f9`f8024acf 498943e8        mov     qword ptr [r11-18h],rax
000007f9`f8024ad3 488b842498000000 mov     rax,qword ptr [rsp+98h]
000007f9`f8024adb 498943e0        mov     qword ptr [r11-20h],rax
000007f9`f8024adf 488b842490000000 mov     rax,qword ptr [rsp+90h]
000007f9`f8024ae7 498943d8        mov     qword ptr [r11-28h],rax
000007f9`f8024aeb 8b842488000000  mov     eax,dword ptr [rsp+88h]
000007f9`f8024af2 89442428        mov     dword ptr [rsp+28h],eax
000007f9`f8024af6 8b842480000000  mov     eax,dword ptr [rsp+80h]
000007f9`f8024afd 89442420        mov     dword ptr [rsp+20h],eax
000007f9`f8024b01 ff1591951100    call    qword ptr [KERNEL32!_imp_CreateProcessW (000007f9`f813e098)]
000007f9`f8024b07 4883c458        add     rsp,58h

_imp_CreateProcessW へのその呼び出しは誤解を招く可能性があります。その呼び出しで正しいポイントまで (t) をトレースすると、それが表示されるからです。

KERNEL32!CreateProcessWStub+0x4d:
000007f9`f8024b01 ff1591951100    call    qword ptr [KERNEL32!_imp_CreateProcessW (000007f9`f813e098)] ds:000007f9`f813e098={KERNELBASE!CreateProcessW (000007f9`f7578960)}

したがって、_imp_CreateProcessW アドレスは相対アドレスのように見えます (リンカーによって残されましたか?)。そして、最終アドレスを解決するためにデータ セグメント レジスタ (ds) が何らかの方法で使用されていること (この場合は、KERNELBASE!CreateProcessW (000007f9`f7578960)) です。 TCB のアドレスを保持する fs および gs レジスタを除く)

私の質問は次のとおりです。

  • そこで何が起こっているのですか?

  • CreateProcessW が kernel32.dll に存在しないのはなぜですか (スタブのみ)。MSDN によると、CreateProcess は kernel32.dll にある

  • impで始まるシンボルの背後にある物語は何ですか。それらはリンカーアーティファクトですか?

ありがとう!!!

注: 最初に .symfix と .reload を実行します。その時点 (呼び出しの直前) のレジスタの値:

0:000> r
rax=0000000000000000 rbx=0000000000000048 rcx=0000000000000000
rdx=0000000000535138 rsi=0000000000000000 rdi=0000000000000000
rip=000007f9f8024b01 rsp=00000000004df550 rbp=0000000000000000
 r8=0000000000000000  r9=0000000000000000 r10=0000000000000000
r11=00000000004df5a8 r12=0000000000000000 r13=000007f7abfb1258
r14=0000000000000000 r15=0000000000000000
iopl=0         nv up ei pl nz na po nc
cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000206
4

1 に答える 1

0

IIRC __imp_ とスタブは、SxS を処理するために導入されました。すべてではないにしてもほとんどの kernel32 および kernelbase 呼び出しが __imp_ を呼び出すことに気付くでしょう。スタブに関しては、簡単な例は次のとおりです。

IsDebuggerPresent()

これに対してGetProcAddressを実行すると、 IsDebuggerPresentStub のアドレスが返され、 IsDebuggerPresentにジャンプし、次の場所にジャンプします。

_imp__IsDebuggerPresent

本質的に、あなたは正しいです。_imp__XXX は、VFT のように機能します。

于 2014-05-14T21:13:53.500 に答える