一、安装WinDbg Preview
WinDbg Preview与传统的WinDbg不是一个东西。
可以从Microsoft Store安装WinDbg Preview,可能需要先登录,匿名时可能搜不到WinDbg Preview。
在cmd中执行windbgx,即可打开WinDbg Preview
尽管官方要求从Microsoft Store安装WinDbg Preview,但安装结束后可以用Process Explorer找出WinDbg Preview安装目录,将之复制到别处仍可使用。比如安装到
C:\Program Files\WindowsApps\Microsoft.WinDbg_1.2111.9001.0_neutral__8wekyb3d8bbwe\
复制到
X:\Green\windbgx\1.2111.9001.0\
Win10企业版2016 LTSB没有Microsoft Store,但可以使用绿色版WinDbg Preview,包括TTD技术。
微软这帮缺德货解释为什么只通过Microsoft Store提供WinDbg Preview,官方口径是,他们在快速迭代,通过Microsoft Store可以获取最新版。但我认为这只是托辞,实际是强推Microsoft Store。
参看
《不通过Microsoft Store的GUI界面安装Store App》
http://scz.617.cn:8/windows/202201282230.txt
二、TTD.exe
“Launch executable (advanced)”功能实际调用的是TTD.exe
TTD.exe的很多参数无法通过WinDbg Preview指定,这没关系,可以直接用TTD.exe。
$ tree /A /F .
| TTD.exe
| TTDInject.exe
| TTDLoader.dll
| TTDRecord.dll
| TTDRecordCPU.dll
|
—wow64
TTD.exe
TTDInject.exe
TTDLoader.dll
TTDRecord.dll
TTDRecordCPU.dll
TTD技术关键在于生成.run文件,为生成它只涉及上面列举的文件,wow64是用于32位 PE的。
在管理员级cmd中执行
$ TTD.exe -ring -maxFile 2048 -out “TTDTest_0%.run” -launch TTDTest_0.exe
生成2GB的TTDTest_002.run,虽然很大,但不会增长,情况可控。
执行TTD.exe需要管理员级cmd,分析.run不需要。在普通cmd中执行
$ windbgx TTDTest_002.run
三、tttracer.exe
某些版本的Win10自带一个神秘的tttracer.exe,帮助里没有任何参数介绍
$ where tttracer
C:\Windows\System32\tttracer.exe
tttracer.exe实际就是TTD.exe
TTD技术关键在于生成.run文件,为生成它只需要下面列举的文件,这些文件来自非LTSB版Win10的System32目录,换句话说,全是自带的。
ttdinject.exe
ttdloader.dll
ttdrecord.dll
ttdrecordcpu.dll
tttracer.exe
四、notepad示例
用ResourceHacker查看
C:\Windows\zh-cn\notepad.exe.mui
在Menu项中看到
POPUP “格式(&O)”
{
MENUITEM “自动换行(&W)”, 32
MENUITEM “字体(&F)…”, 33
}
$ tttracer.exe -ring -maxFile 2048 -out “notepad%.run” -launch notepad.exe
$ tttracer.exe -stop all
用”-stop”可以让notepad保持运行,而不是被杀掉。
$ windbgx notepad01.run
r $t0=0n33;dx -g @$cursession.TTD.Calls(“notepad!NPCommand”).Select(c=>new{Time=c.TimeStart,RetAddr=c.ReturnAddress,hWnd=c.Parameters[0],wParam=c.Parameters[1]}).Where(c=>c.wParam==@$t0)
上述命令比TTD执行快多了,找到”2787F:62″,点击或!tt转移过去。pc找到这里
notepad!NPCommand+0x9ee:
00007ff69098aa86 e869b90100 call notepad!memset (00007ff6909a63f4)
附近代码对应
格式
字体
本小节的意思是,能dx就不要TTD执行,否则将失去TTD的强大与效率。
下面这两条命令的效果一样,但后者更高效
ba w1 0x97e64ff730;g-
r $t0=0x97e64ff730;r $t1=8;dx -r1 @$cursession.TTD.Memory(@$t0,@$t0+@$t1,”w”).Last().TimeStart.SeekTo()
五、Calculator示例
Win10的calc与Win7的calc不一样,前者好像是个Store App?我用不惯新版,从Win7 复制旧版calc到Win10用。不过,本小节的目标是新版calc,也就是Calculator.exe。
启动calc,切换到”程序员模式”,切换到16进制模式,然后上TTD。
tttracer.exe -ring -maxFile 2048 -out “calc_%.run” -attach
依次输入
51201314 * 41414141 =
得到结果
0x14add2aaaa10ec14
停止TTD
tttracer.exe -stop
或
tttracer.exe -stop all
假设生成calc_04.run
原始需求是,结合TTD技术寻找前述算术运算相关代码。假设前述calc进程仍在活动中,挂普通调试器进去搜内存,这样方便些。如果直接在.run中搜内存,可能非常慢,还有可能干脆搜不着。
cdb.exe -noinh -snul -hd -o -p
查看进程空间内存布局
.logopen Z:\work\MSDN_46\calc.txt
!address -f:stack,heap
.logclose
查看calc.txt,类似这种输出
BaseAddress EndAddress+1 RegionSize Type State Protect Usage
90`5ca00000 90`5caf7000 0`000f7000 MEM_PRIVATE MEM_RESERVE Stack [~0; 3238.2b4c]
…
905e0fe000 905e100000 000002000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Stack [~17; 3238.df0] 21ef0930000 21ef0940000 000010000 MEM_MAPPED MEM_COMMIT PAGE_READWRITE Heap [ID: 1; Handle: 0000021ef0930000; Type: Segment]
…
21efe47e000 21efe500000 0`00082000 MEM_PRIVATE MEM_RESERVE Heap [ID: 0; Handle: 0000021ef09a0000; Type: SegmentHeap Segment]
在堆区搜索特征字节流
s -[w]b 21ef0930000 21efe500000 14 ec 10 aa aa d2 ad 14
0000021e`fe44c2d0 14 ec 10 aa aa d2 ad 14-00 00 00 00 00 00 08 00 …………….
开始鞭尸
windbgx calc_04.run
.prompt_allow +reg +ea +dis
如果没有自动生成calc_04.idx,用如下命令手工生成
!ttdext.index -force
!ttdext.index -status
移动到.run尾部再查看内存,否则指定内存可能还没被写入期待中的值
!tt 100
理论上当然可以用数据断点加反向执行去找相关代码,但鞭尸时有更快的方案
r $t0=0x21efe44c2d0;r $t1=4;r $t2=0xaa10ec14;dx -g @$cursession.TTD.Memory(@$t0,@$t0+@$t1,”rw”).Where(m=>m.Value==@$t2)
============================================================================
= = (+) Time = (+) PC = (+) Size = (+) Old = (+) New = (+) Access =
= [0x4c1] – 2FA64F:9F4 – 0x7ff7bc7394d8 – 0x4 – 0x2a10ec14 – 0xaa10ec14 – Write =
!tt 2FA64F:9F4
rax=000000002a10ec14 rbx=0000021efd553600 rcx=000000000000001f
rdx=00000000aa10ec14 rsi=0000000000000001 rdi=000000000000001f
rip=00007ff7bc7394d8 rsp=000000905d1fcdc0 rbp=000000905d1fcf10
r8=0000021efe44c2d0 r9=0000000000000001 r10=0000000000003730
r11=000000905d1fce00 r12=00007ff7bc95f1b0 r13=0000000000000001
r14=0000000000000000 r15=0000021ef7ccef20
iopl=0 nv up ei ng nz na po nc
cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000286
Calculator!VSDesignerDllMain+0x120ae8:
00007ff7bc7394d8 418910 mov dword ptr [r8],edx ds:0000021efe44c2d0=2a10ec14
这个位置在写乘法运算的结果,结合TTD.Memory与反向执行,不断定位源头,直至
============================================================================
= = (+) Time = (+) PC = (+) Size = (+) Old = (+) New = (+) Access =
= [0x14] – 2EA868:9A – 0x7ff8594c1421 – 0x10 – 0x0 – 0x100000001 – Write =
= [0x15] – 2EA868:9B – 0x7ff8594c1425 – 0x10 – 0x100000001 – 0x100000001 – Write =
= [0x19] – 2EA8B3:BC – 0x7ff7bc70c218 – 0x4 – 0x0 – 0x2a10ec14 – Write =
…
= [0xd3] – 2ED8F7:8F – 0x7ff7bc6f1146 – 0x10 – 0x0 – 0x100000001 – Write =
!ttdext.tt 2EA8B3:BC
rax=00000000295ba555 rbx=0000000000000001 rcx=000000002a10ec14
rdx=000000002a10ec14 rsi=0000021efe461820 rdi=0000000041414141
rip=00007ff7bc70c218 rsp=000000905d1fcd00 rbp=ffffffffffffe6d4
r8=000000002a10ec14 r9=0000000000000000 r10=0000021efe46182c
r11=0000000000000001 r12=0000021efe44c2b0 r13=0000021efe45ff00
r14=0000021efe45e3d0 r15=0000021efe461830
iopl=0 nv up ei pl nz na po nc
cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000206
Calculator!VSDesignerDllMain+0xf3828:
00007ff7bc70c218 43890c8a mov dword ptr [r10+r9*4],ecx ds:0000021efe46182c=00000000
注意到rdi等于0x41414141,在IDA中简单看看,回TTD中反向执行
g- 0x7ff7bc70c1d8
Time Travel Position: 2EA8B3:A9
rax=0000000051201314 rbx=0000000000000001 rcx=0000000000000000
rdx=0000000000000002 rsi=0000021efe461820 rdi=0000000041414141
rip=00007ff7bc70c1d8 rsp=000000905d1fcd00 rbp=ffffffffffffe6d4
r8=0000000000000000 r9=0000000000000000 r10=0000021efe46182c
r11=0000000000000001 r12=0000021efe44c2b0 r13=0000021efe45ff00
r14=0000021efe45e3d0 r15=0000021efe461830
iopl=0 nv up ei pl zr na po nc
cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
Calculator!VSDesignerDllMain+0xf37e8:
00007ff7`bc70c1d8 480fafc7 imul rax,rdi
借助TTD调试,相对简单地定位了16进制”51201314*41414141=”的现场。
这样验证,普通调试时,设断干扰乘法运算,将GUI输入的0x41414141换成1
ba e1 0x7ff7bc70c1d8 “.if(@rdi==0x41414141){r rax,rdi;r rdi=1};gc”
TTD调试比普通调试慢很多,即便是正向执行,前者也慢。二者是互补关系,不要只依赖TTD调试。
版权声明
本站“技术博客”所有内容的版权持有者为绿盟科技集团股份有限公司(“绿盟科技”)。作为分享技术资讯的平台,绿盟科技期待与广大用户互动交流,并欢迎在标明出处(绿盟科技-技术博客)及网址的情形下,全文转发。
上述情形之外的任何使用形式,均需提前向绿盟科技(010-68438880-5462)申请版权授权。如擅自使用,绿盟科技保留追责权利。同时,如因擅自使用博客内容引发法律纠纷,由使用者自行承担全部法律责任,与绿盟科技无关。