windbg-ttd

1.Windbg-TTD

1.1 简介

​ TTD是”Time Travel Debugging”的缩写,是Windbg preview提供的针对单个进程的用户态trace录制工具。录制完成后生成.run文件可以在调试器中向前向后重放,不需要再重新运行程序就能让你的调试器状态回退,并且还能分享trace文件给别人。

1.2 基础用法

从一个简单的除零错误例子出发,目标的源码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>

int foo(int a, int b, int c) {

int x = a * b;
int y = x / c;

return y;
}

int main() {

foo(1, 3, 0);

printf("hello world\r\n");

return 0;
}

在WindbgPreview中的载入操作序列如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
File
Launch executable (advanced)
Executable
X:\TTD\TTDTest_0.exe
Start directory
X:\TTD
Target architecture
Autodetect
Record with Time Travel Debugging (选中)
Configure and Record
Save location
X:\TTD\
Record

刚载入会默认断在ntdll模块下的LdrInitializeThunk函数下,输入g即可在异常位置停住,并录制完成,如下图所示:

除零异常现场

可以看见在地址0x71d5f4fa2c处发生了一个除零异常,此时可以有如下三种方式来定位目标被赋值的位置:

1.2.1 数据断点 + 反向执行

1
2
ba w1 0x71d5f4fa2c			// 设置内存一字节写入断点
g- // 反向执行

此时可以定位到0被赋值的位置,如下图所示:

数据断点+反向执行结果

1.2.2 TTD.Memory

.idx文件是基于.run文件生成的,可以删除并重新生成。有了.idx文件,可以用dx命令查询对地址0x71d5f4fa2c进行写操作的所有代码,效率比”数据断点+反向执行”高。

1
r $t0=0x71d5f4fa2c;r $t1=8;dx -r2 @$cursession.TTD.Memory(@$t0,@$t0+@$t1,"w").Where(m=>m.Value==0)	// 查询所有对指定内存的写入操作

得到查询结果如下:

TTD.Memory查询结果

此时不能直接使用u 0x7ff718a613ac来查看代码,这样不会跟踪到上下文,可以使用!tt {TimeStart}指令来进行时间点切换,如下图所示:

tt来切换时间点

1.2.3 Timelines GUI

可以点击工具栏中的Timelines来调出GUI页面,可以利用Add Timeline来设置事件,如图所示:

Add Timeline设置事件

本例中要想可以加入对0x7ff718a613ac地址的写入事件,如下图所示:
Timeline写入事件

添加成功后会在时间线中出现褐色的时间点,此时双击即可看见时间点信息,再使用!tt命令即可切换至现场。


windbg-ttd
http://helloymf.github.io/2023/07/23/windbg-ttd/
作者
JNZ
许可协议