我正在学习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寄存器)
我的问题是:
那里发生了什么?
为什么在kernel32.dll中不存在CreateProcessW(只有存根)。 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
答案 0 :(得分:0)
IIRC __imp_和存根被引入以照顾SxS。您会注意到大多数(如果不是全部)kernel32& kernelbase调用最终调用__imp_。 如果关于存根,一个简单的例子是
IsDebuggerPresent()
对此执行 GetProcAddress 将返回 IsDebuggerPresentStub 的地址,该地址将跳转到 IsDebuggerPresent ,然后跳转到:
_imp__IsDebuggerPresent
从本质上讲,你是对的。 _imp__XXX的工作方式有点像VFT。