关于WOW64的一点记录

1.关于TEB的地址:32位的TEB地址在64位TEB地址加上0x2000的偏移处。验证如下:

1
2
3
4
5
6
7
8
9
10
11
0:000> r @$teb
$teb=000000007efdb000
0:000:x86> dg @fs
P Si Gr Pr Lo
Sel Base Limit Type l ze an es ng Flags
---- ----------------- ----------------- ---------- - -- -- -- -- --------
0053 7efdd000 00000fff Data RW Ac 3 Bg By P Nl 000004f3
0:000:x86> ? 7efdd000 - 7efdb000
Evaluate expression: 8192 = 00002000

2.从32位切换到到64位的时候,系统会保存32位的寄存器状态。这些状态保存在Teb->TlsShots[1]中。继续用Windbg验证:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
0:000> dt _teb @$teb -a5 TlsSlots
ntdll!_TEB
+0x1480 TlsSlots :
[00] (null)
[01] 0x00000000`001cfd20 Void
[02] (null)
[03] 0x00000000`001ca930 Void
[04] (null)
0:000> !wow64exts.r
No wow64 context address specified, dumping wow64 context from cpu area...
Teb64 Address: 0x7efdb000, CpuArea Address: 0x1cfd20
Context Address: 0x1cfd24
eax=00000000 ebx=00000000 ecx=00000000 edx=00000000 esi=77200094 edi=00000000
eip=772000a6 esp=000ee0ac ebp=000ee150 iopl=0 nv up ei pl zr na po nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246

3.从64位切换到到32位的时候,会保存64位的RSP,保持的地址是Teb->TlsShots[0]。切换回64位的时候,这个地址被清0。

1
2
3
4
5
6
7
0:000> dt ntdll!_TEB @r12 -a5 TlsSlots
+0x1480 TlsSlots :
[00] 0x00000000`001ce530 Void
[01] 0x00000000`001cfd20 Void
[02] (null)
[03] (null)
[04] (null)

NTInternalsTips

EtwLogView —— 实时查看ETW的工具

最近玩XPerf玩的比较多,也经常和cradiator(blog)讨论xperf和etw的话题。上周吃饭的时候就讨论到,貌似没找到一款实时记录查看etw的工具。当时我的观点是,只是看etw的原始记录很难分析出什么东西,必须配合很细工具,例如xperfview。这样才能有效的发挥出etw的威力,所以实时工具用处不大。而cradiator认为,除了这些常规的用法外,如果能实时记录查看etw的信息,那么把etw当作平时的log输出方式也是不错的选择。这样的好处就是,不需要额外的加入log机制,使用etw就足够强大,其次如果遇上了问题,这些etw的记录又可以作为event,帮助xperfview的分析。然后这家伙就怂恿我写一个:-)

经过上面的一番介绍,应该就能知道EtwLogView的用处何在了。他是一个“实时”记录查看etw的工具。之所以用上了引号。是因为这个实时是有不确定性的。例如,如果一个provider输出了大量的事件信息。那么这个工具就会遇上麻烦,因为更新记录,和刷新界面的速度很可能跟不上provider的输出速度。这样,这个实时就大打折扣。不过就像cradiator所说的,只用来监控自己的事件,倒没什么问题。

现在EtwLogView是1.0版本,勉强算是可以先用着吧。

首先需要在Windows7系统和管理员权限运行工具,然后就可以创建Session,创建的时候需要选择Session的Provider。可以在List选择,也可以自己输入(必须为GUID格式)。如果想监视多个Provider,那么每个GUID之间需要用分号隔开。

20130613010933

20130613011032

另外,如果想更灵活的设置Session,可以使用xperf创建Session。然后打开EtwLogView,选择打开Session。在文本框中输入Session名,如果有多个Session需要监视,那么可以用分号隔开Session名。

20130613011054

ETW输出的信息很多,我主要列出了12列,并且可以根据自己的需要选择显示的列。

20130613011110

目前的功能就这么多,如果真的有的上再来看看能加上哪些功能吧。

下载EtwLogView

Debugging

几个有趣的未文档化Windbg的扩展命令

这里使用的是Windbg最新版本,版本号是6.2.9200,可以在Windows8的SDK中获得。

1.eflags 用更加友好的方式显示被设置的标志寄存器

1
2
3
4
5
6
7
8
9
10
11
12
13
0:000> r efl
efl=00000246
0:000> !eflags
BIT_1_RESERVED
PARITY_FLAG
ZERO_FLAG
INTERRUPTS_ENABLED
0:000> r zf
zf=1
0:000> r if
if=1

2.frame 用module!function的方式设置栈帧

1
2
3
4
5
6
7
8
9
10
11
12
13
14
0:000> kn L3
# ChildEBP RetAddr
00 0018df2c 7586d7db kernel32!CreateFileW
01 0018e024 7586d9d1 apphelp!IdentifyCandidates+0x176
02 0018e054 7586d87b apphelp!ApphelpQueryExe+0xb8
0:000> .frame
00 0018df2c 7586d7db kernel32!CreateFileW
0:000> !frame apphelp!ApphelpQueryExe
Frame Set to 0x00000002
0:000> .frame
02 0018e054 7586d87b apphelp!ApphelpQueryExe+0xb8

3.hashblob 计算指定内存的hash,hash方式包括md5和sha1

1
2
3
4
5
6
7
8
0:000> !hashblob
Not enough parameters 0
!hashblob <hash> <Start> <End>
<hash>: 1 for MD5
<hash>: 2 for SHA1
0:000> !hashblob 1 001f0000 001f0100
DCC4E0B6659F6887DEC24A9FF2D57DC8

4.imports 列出指定模块的导入函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
0:000> !imports notepad
notepad notepad Imports from file: ADVAPI32.dll
RegSetValueExW
RegQueryValueExW
...
notepad Imports from file: KERNEL32.dll
FindNLSString
GlobalAlloc
GlobalUnlock
GlobalLock
GetTimeFormatW
GetDateFormatW
GetLocalTime
...

5.inframe 找出指定地址所在的栈帧范围

1
2
3
4
5
6
7
ChildEBP RetAddr
0018df2c 7586d7db kernel32!CreateFileW
0018e024 7586d9d1 apphelp!IdentifyCandidates+0x176
0:000> !inframe 0018df8c
0018df8c 0 00001714 0018df34 < 0018df8c < 0018e02c
Frame: 1

6.inmodule 找出指定地址所在的模块

1
2
0:000> !inmodule 7586d9d1
0x7586d9d1: apphelp!ApphelpQueryExe

7.url 用默认浏览器打开指定网页

1
2
3
4
5
0:000> !url
Please provide a valid URL (http://... or https://... )
USAGE: !url <url>
0:000> !url http://0cch.net

Tips