我使用ETW提取了一个在Windows中调用的系统调用地址的转储文件。我对地址有些疑惑。我只是使用NtOpenFile作为未来的例子。
我使用cvdump转储从Microsoft符号服务器(ntkrnlmp.pdb)收到的内核PDB文件。它的NtOpenfile条目是这样的:
S_PUB32: [000D:000DF320], Flags: 00000002, NtOpenFile
然后我使用Dependency Walker(DP)打开ntoskrnl.exe。我向下滚动,看到NtOpenFile的条目:
然后我使用这段代码收到内核基地址:
hNtdll = GetModuleHandle("ntdll.dll");
NtQuerySystemInformation = (NtQuerySystemInformationFunc)GetProcAddress(hNtdll, "NtQuerySystemInformation");
NtQuerySystemInformation(SystemModuleInformation, &ModuleInfo, sizeof(ModuleInfo), NULL);
KernelBase = (ULONG64)ModuleInfo.Modules[0].ImageBase;
内核基地址为:fffff802f7616000
使用windbg提取的NtOpenFile的实际地址为fffff802f7b0e320 nt!NtOpenFile
使用从pdb文件中提取的地址添加内核库会给我错误的地址(从DP结果中添加地址是正确的)。为什么呢?
为什么win32k.sys中的函数不像NtGdiFlush那样存在于DP打开的.sys文件中?在Windows 10中,还有另一个名为win32kfull.sys的文件,其中包含这些符号但不包含在Windows 7中。
我根本无法映射像NtQueryVirtualMemory这样的函数。它存在于ntkrnlmp.pdb转储中,但正如我在第1部分所述,地址似乎错了!它也存在于由DP打开的ntoskrnl.exe中作为ZwQueryVirtualMemory。但它与windbg.exe提取的NtQueryVirtualMemory地址不同 这些如何映射到彼此?如何使用DP或PDB文件提取此功能的地址?
如何使用windbg找到win32k.sys系统调用地址(如NtGdiFlush' s地址)?
命令kd> x /D nt!Nt*
没有给我这些符号地址。
答案 0 :(得分:1)
我不清楚你的用例是什么,如果它只是从pdb文件获取api的地址你可以使用批处理模式下windbg包附带的 dbh.exe 工具
它将pdb加载到默认基数(通常为0x10000000)并为您提供相对于该基数的api的地址
示例
:\>dbh e:\SYMBOLS\ntkrpamp.pdb\E4AF624F009A4D99A4F85690E0164DBC2\ntkrpamp.pdb n ntopenfile
name : NtOpenFile
addr : 1232d81
size : 0
flags : 400000
type : 0
modbase : 1000000
value : 0
reg : 0
scope : SymTagPublicSymbol (a)
tag : SymTagPublicSymbol (a)
index : 1
您也可以使用sysinternals livekd.exe确认
:\>livekd -b -c \"? nt!NtOpenFile;? nt; ? (nt!NtOpenFile-nt);q\" | grep -B 3 quit:
Evaluate expression: -2096693887 = 8306fd81
Evaluate expression: -2098999296 = 82e3d000
Evaluate expression: 2305409 = 00232d81
quit:
:\>dbh e:\SYMBOLS\ntkrpamp.pdb\E4AF624F009A4D99A4F85690E0164DBC2\ntkrpamp.pdb n ntopenfile
name : NtOpenFile
addr : 1232d81
size : 0
flags : 400000
type : 0
modbase : 1000000
value : 0
reg : 0
scope : SymTagPublicSymbol (a)
tag : SymTagPublicSymbol (a)
index : 1
:\>
从所有加载的模块中找到api,你可以使用像*这样的通配符。等
kd> x *!*ntgdiflu*
76cc5fd2 GDI32!NtGdiFlush (<no parameter info>)
98257991 win32k!NtGdiFlush (<no parameter info>)
9824c664 win32k!NtGdiFlushUserBatch (<no parameter info>)
kd> x Win*!*ntgdiflu*
98257991 win32k!NtGdiFlush (<no parameter info>)
9824c664 win32k!NtGdiFlushUserBatch (<no parameter info>)
kd>
将cvdump的S_PUB32值吐出添加到段偏移量
似乎并不那么简单似乎在优化函数分块等所有发生之前写入了S_PUB32值
其标题中的cvdump有两个不同的标题信息
一个似乎是嵌入在最终可执行文件中的实际标头 一个似乎是原始标题预优化?或者写完这个标题后会做什么
E:\cvdump>cvdump.exe -headers ntkrpamp.pdb | grep -i original -A 500 | grep -i #8 -A 10 | grep -i virtual
1A604E virtual size
166000 virtual address
E:\cvdump>cvdump.exe -headers ntkrpamp.pdb | grep -i #8 -A 10 | grep -i virtual
1AD618 virtual size
16C000 virtual address
1A604E virtual size
166000 virtual address
将S_PUB32值添加到原始段偏移量 在这种情况下
E:\cvdump>cvdump.exe -p ntkrpamp.pdb | grep -i ntopenfile
S_PUB32: [0008:000620C8], Flags: 00000002, _NtOpenFile@24
0x620c8 被添加到 0x166000 虚拟地址original header's section #8
(这不会反映在dumpbin.exe / headers中,所以dumpbin有点无用)< / p>
现在omapf似乎在最终的可执行文件中显示了实际的函数偏移量
E:\cvdump>cvdump.exe -omapf ntkrpamp.pdb | grep -i 1c80c8
001C80C8 00232D81
该模式似乎与我尝试的一些功能一致
检查一些随机api
E:\cvdump>cvdump.exe -p ntkrpamp.pdb | grep -i rtlfreehot
S_PUB32: [0008:0011C32E], Flags: 00000002, _RtlFreeHotPatchData@4
E:\cvdump>cvdump.exe -headers ntkrpamp.pdb | grep -i original -A 500 | grep -i #8 -A 10 | grep -i virtual
1A604E virtual size
166000 virtual address
E:\cvdump>python -c "print \"%x\" % (0x11c32e+0x166000)"
28232e
E:\cvdump>cvdump.exe -omapf ntkrpamp.pdb | grep -i 28232e
0028232E 002E88C0
E:\cvdump>dbh ntkrpamp.pdb n RtlFreeHotPatchData
name : RtlFreeHotPatchData
addr : 12e88c0
size : 0
flags : 400000
type : 0
modbase : 1000000
value : 0
reg : 0
scope : SymTagPublicSymbol (a)
tag : SymTagPublicSymbol (a)
index : 1
E:\cvdump>
如果fpo数据可用,你可以得到函数大小prolog no of params no of locals etc
E:\cvdump>cvdump.exe -fpo ntkrpamp.pdb | grep -i 28232e
0028232E 2E 1 3 0 N N fpo 0
这与windbg .fnent函数输出完全匹配
kd> .fnent nt!RtlFreeHotPatchData
Debugger function entry 030b5b70 for:
(831258c0) nt!RtlFreeHotPatchData | (831258
Exact matches:
nt!RtlFreeHotPatchData (<no parameter info>)
OffStart: 002e88c0
ProcSize: 0x2e
Prologue: 0x3
Params: 0n0 (0x0 bytes)
Locals: 0n1 (0x4 bytes)
Registers: 0n0
kd>