Windows符号地址定义

时间:2017-09-20 18:45:03

标签: windows windbg system-calls windows-kernel dependency-walker

我使用ETW提取了一个在Windows中调用的系统调用地址的转储文件。我对地址有些疑惑。我只是使用NtOpenFile作为未来的例子。

1 -

我使用cvdump转储从Microsoft符号服务器(ntkrnlmp.pdb)收到的内核PDB文件。它的NtOpenfile条目是这样的:

S_PUB32: [000D:000DF320], Flags: 00000002, NtOpenFile

然后我使用Dependency Walker(DP)打开ntoskrnl.exe。我向下滚动,看到NtOpenFile的条目:

enter image description here

然后我使用这段代码收到内核基地址:

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结果中添加地址是正确的)。为什么呢?

2 -

为什么win32k.sys中的函数不像NtGdiFlush那样存在于DP打开的.sys文件中?在Windows 10中,还有另一个名为win32kfull.sys的文件,其中包含这些符号但不包含在Windows 7中。

第3 -

我根本无法映射像NtQueryVirtualMemory这样的函数。它存在于ntkrnlmp.pdb转储中,但正如我在第1部分所述,地址似乎错了!它也存在于由DP打开的ntoskrnl.exe中作为ZwQueryVirtualMemory。但它与windbg.exe提取的NtQueryVirtualMemory地址不同 这些如何映射到彼此?如何使用DP或PDB文件提取此功能的地址?

4 -

如何使用windbg找到win32k.sys系统调用地址(如NtGdiFlush' s地址)? 命令kd> x /D nt!Nt*没有给我这些符号地址。

1 个答案:

答案 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>