TTD调试进阶之ttd-bindings

语言: CN / TW / HK

阅读: 23

windbgx或WinDbg Preview是一个东西,但与windbg不是一回事。TTD与windbgx相关,与windbg无关。windbgx从Microsoft Store安装,windbg有独立安装包。

关于TTD历史,参看

《TTD历史回顾》

http://scz.617.cn:8/windows/202207191506.txt

TTD录制的.run文件格式未公开,之前只能在WinDbg Preview中操作.run,很难对之进行脚本操作,比如,想对position进行大小比较,很费劲。

Bindings for Microsoft WinDBG TTD

https://github.com/commial/ttd-bindings

上文作者对TTDReplay.dll进行逆向工程,逆出一套编程解析处理.run文件的API。没有完整逆向,但基本功能都有,比windbgx的GUI还多出一些功能。

C++ bindings功能较多,Python bindings功能弱一些,后者无法设置CallRetCallback、MemCallback。

作者提供了.cpp、py的使用示例,对于逆向工程人员来说,浅显易懂,可以照猫画虎实现自定义功能。

TTD::ReplayEngine ttdengine = TTD::ReplayEngine();

ttdengine.Initialize( trace_path );

打开.run文件,初始化TTD引擎

TTD::Cursor ttdcursor = ttdengine.NewCursor();

ttdcursor.SetPosition( position.Major, position.Minor );

顾名思义,ttdcursor相当于!tt,可以来回切换position

目前支持两种回调函数,一种是call、ret指令触发,另一种就是内存断点。此处的内存断点是TTD的特有支持,不是用硬件断点那套,支持任意长度的内存断点,支持读、写、执行。

————————————————————————–

MemBreakpoint.addr = ImageBbase;

MemBreakpoint.size = imageSize;

MemBreakpoint.flags = TTD::BP_FLAGS::EXEC;

ttdcursor.AddMemoryWatchpoint( &MemBreakpoint );

ttdcursor.SetMemoryWatchpointCallback( ( TTD::PROC_MemCallback )MemCallback, 0 );

static bool MemCallback

(

unsigned __int64 callback_value,

TTD::TTD_Replay_MemoryWatchpointResult *mem,

struct TTD::TTD_Replay_IThreadView *thread_info

)

{

g_mutex.lock();

g_hit_set.insert( mem->addr );

g_mutex.unlock();

return FALSE;

}

————————————————————————–

这是example_cov中的MemCallback,比较简单,只记录了mem->addr。

TTD::TTD_Replay_ICursorView_ReplayResult replay_ret;

ttdcursor.ReplayForward( &replay_ret, &end, -1 );

ReplayForward第二形参指定end position;第三形参-1对应stepCount,若为1,就是单步执行。

无论单步、非单步,之前设置的回调函数都会命中,可以在回调函数中做很多动作,相当于交互式调试时条件断点命中后执行的命令。由于可以C++编程,肯定比断点命令强大太多。

TTD不支持wt,会报错

Operation not supported in current debug session

参看example_calltree,可以自己实现wt的效果。要求如下DLL就位

dbghelp.dll

TTDReplay.dll

TTDReplayCPU.dll

example_calltree的输出类似这种

[1] -> Calculator+0x23c080 (ABE36:C6)

| [2] -> Calculator+0x230450 (ABE36:E8)

| | [3] -> ucrtbase!calloc (ABE36:F5)

| | [3] <- ucrtbase!_calloc_base+0x61 (ABE39:87) ret=0x2ca4c833c80

| [2] <- Calculator+0x230484 (ABE39:8B) ret=0x2ca4c833c80

| [2] -> ucrtbase!free (ABE39:EA)

| | [3] -> ntdll!RtlFreeHeap (ABE39:F4)

| | [3] <- ntdll!RtlFreeHeap+0x66 (ABE3C:42) ret=0x1

| [2] <- ucrtbase!_free_base+0x27 (ABE3C:46) ret=0x1

[1] <- Calculator+0x23c292 (ABE3C:4B) ret=0x1

受限于UWP的Mitigation Policies,DynamoRIO缺省无法录制Win10 Calculator。理论上可以改DynamoRIO,使用反射式DLL加载,而非LoadLibrary,使之支持UWP,但我懒得搞。

参看example_cov,可以对UWP生成为Lighthouse所支持的.log文件,从而对UWP进行Coverage Diff。即使不考虑UWP情形,对普通进程而言,DynamoRIO录制也不如TTD录制+example_cov截取,后者可以精确指定position范围,从而让Coverage Diff更有意义。

example_cov的输出类似这种

Calculator+0xacb0

Calculator+0xacb3

Calculator+0xacb7

Calculator+0xacbb

参看example_tenet,生成为Tenet所支持.trace文件。用了一下Tenet,感觉意义不大。

example_tenet的输出类似这种

Rsp=0xd695bfd998,Rip=0x7ff6b3fdc080,mw=0xd695bfd998:9d2efdb3f67f0000

Rip=0x7ff6b3fdc085,mw=0xd695bfd9a8:70dabf95d6000000

mw表示发生内存写操作,等号后面是内存地址,冒号后面是16进制字节流。

example_tenet对小范围的position有效,对全范围使用时有坑,出现漏指令的现象;可能与单步执行有关,可能与多线程有关,总之,极不靠谱。

假设用TTD录制Win10 Calculator的乘法运算,想找出乘法运算的汇编指令。用常规TTD反向执行找出来过,参看

《MSDN系列(46)–WinDbg Preview TTD入门》

SDN系列(46)——WinDbg Preview TTD入门

WinDbg Preview TTD小白入门

之前对Win7 calc试过Coverage Diff,Win7 calc有符号,它的算术运算逻辑比较独立,用Coverage Diff很快就定位到乘法运算。参看

《MSDN系列(47)–Lighthouse/DynamoRIO/Coverage Diff入门》

Lighthouse/DynamoRIO/Coverage Diff入门

对Win10 Calculator测试Coverage Diff,没有符号,它的算术运算逻辑不那么独立,乘法运算位于某个公共函数中,该公共函数被频繁调用,很难制造a.log不覆盖该公共函数、b.log覆盖该公共函数的效果,处理Win7 calc的套路在此不适用。

有ttd-bindings之后,找出乘法运算多了新思路。合理推测应有”imul rega,regb”,事先不知道哪两个寄存器,只是逻辑推断可能出现这样的场景。编程遍历”!tt 0″与”!tt 100″之间的代码,当某个通用寄存器值为a、另一个通用寄存器值为b时,记录

此时的rip、position。若特征值a、b足够特异,log文件中的记录条数不会太多,人工检视即可定位乘法运算。

可以对着ttd-bindings的源码自己逆一下TTDReplay.dll,或许有新发现。现阶段推荐用C++ bindings,Python bindings实在太弱了。

本文向逆向工程人员推荐ttd-bindings,有用,好用,值得用,将TTD利用方式推进到新高度。

版权声明

本站“技术博客”所有内容的版权持有者为绿盟科技集团股份有限公司(“绿盟科技”)。作为分享技术资讯的平台,绿盟科技期待与广大用户互动交流,并欢迎在标明出处(绿盟科技-技术博客)及网址的情形下,全文转发。

上述情形之外的任何使用形式,均需提前向绿盟科技(010-68438880-5462)申请版权授权。如擅自使用,绿盟科技保留追责权利。同时,如因擅自使用博客内容引发法律纠纷,由使用者自行承担全部法律责任,与绿盟科技无关。