首页
社区
课程
招聘
[推荐][原创]菜鸟的福音-x64dbg完美追踪方案
2023-11-10 12:09 11153

[推荐][原创]菜鸟的福音-x64dbg完美追踪方案

2023-11-10 12:09
11153

声明:本帖只面向初学者和菜鸟,高手可以略过,一笑置之。
众所周知,破解的关键在于找到关键CALL。破解的两大利器,一个是静态分析的IDA,另一个是动态分析的OD。OD早就不更新了,并且不支持64位系统。现在动态分析主要靠X64dbg了。
X64dbg更新很快,但作者对于帮助文档却惜墨如金,有很多实用的强大功能,都需要自己去摸索。
刚才提到寻找关键CALL,IDA虽然F5生成伪码功能强大,并且可以生成函数调用图,但对于复杂的调用看起来就很不直观。并且IDA只能单个文件静态分析,对于跨模块调用就无能为力。这里着重说下X64dbg的追踪方案。

对于一些简单的程序,可以通过搜索字符串,下API断点等很多方式来查找关键CALL。而有些程序的加密做的比较彻底,导入导出表只有编号没有名称,打开反汇编后一脸懵。并且还在很多地方使用类似call esi的指令来调用,不一行行跟的情况下,很难知道函数间到底是如何调用的。逐行跟的话耗费时间不说,还很考验破解者的功底和耐心。x64dbg提供有追踪功能,也可以生成追踪文件。但如果步进F7追踪的话,生成的文件会很大,并且中间过程每行指令的注释不会保留下来;如果步过F8追踪的话,又会错过很多细节,说不定就会和关键CALL失之交臂。怎样能只追踪我们想要的东西,其它的都略过,或者说先想办法粗定位到关键CALL,然后再逐行分析呢?

重点就在于学会使用条件跟踪。x64dbg提供了强大的表达式功能,奈何帮助文档太拉胯,晦涩难懂,一般人看到都会敬而远之。这里要重点感谢一位大佬,大家可以在网上搜索

X64Dbg 介绍->表达式

,里面对于x64dbg表达式的使用进行了详细讲解,值得反复学习和体会。众所周知,程序就是一堆函数组成,而函数的关键在于参数和返回值。知道了参数和返回值后,对于函数的功能就可以管中窥豹。而利用好条件断点,就可以让我们抓取函数调用时的参数和返回值,让日志只记录我们想要的功能。待找到关键CALL以后,再生成追踪文件进行详细跟。大家都知道函数调用前参数存在ESP+4*n中,而函数返回值存在EAX里。我们就可以根据这些下条件跟踪。


方法就是在日志文本中可以输入{modname@cip} {p:cip} {i:cip} {a:cip} {"EAX"} {a:eax} {a:[eax]} {"[ESP]"} {a:[esp]} {"[ESP+4]"} {a:[esp+4]} {"[ESP+8]"} {a:[esp+8]} {"[ESP+C]"} {a:[esp+C]} {"[ESP+10]"} {a:[esp+10]},日志条件是dis.isbranch(cip) || dis.isret(cip),这样就可以自动记录下每次函数调用时的参数和返回值。最大单步次数默认是50000,可以根据自己机器的情况自行设置。步进转换条件设置成mod.party(dis.branchdest(cip))==1,这样系统模块的调用就变成F8步过,就能过滤掉很多系统内部的无效跟踪。万一发现有部分系统模块跳转用户模块过程漏跟的情况,再设置条件断点,把步进转换条件去掉。如果除了参数和返回值外,还想跟踪寄存器值的变化,也可以在日志文件里加上{"EBX"} {a:ebx} {a:[ebx]} {"ECX"} {a:ecx} {a:[ecx]} {"EDX"} {a:edx} {a:[edx]} {"ESI"} {a:esi} {a:[esi]} {"Edi"} {a:edi} {a:[edi]}等。

如果日志条件想把call和ret的下一条指令也跟踪上,可以写成这样 !mod.party(cip) && (dis.isbranch(cip)|| dis.isret(cip)|| ReadByte(cip-1)==cc || dis.iscall(dis.prev(cip)) || dis.isret(dis.prev(cip)));如果不想跟踪JCC、只想跟踪JMP和CALL,可以把dis.isbranch(cip)改成(dis.isbranch(cip) && !dis.iscond(cip))。

设置后生成的跟踪日志就是这样,记录下来后再通过modname可以帮助我们过滤一些不需要关心的系统模块调用。稍微遗憾的是有些CALL在反汇编窗口里能看到具体名称,但生成日志后就只看到地址、看不到名称了,需要在回看跟踪日志的时候手动添加。比如反汇编窗口中看到的指令是这样call dword ptr ds:[<&_GetWindowLongW@8>],但日志里却是call dword ptr ds:[0x6BC4A574],日志里并不能根据导入导出表自动把常量区的内存地址替换成函数名称。我试尽了表达式里的各种方法都无法实现,希望后续x64dbg版本的更新能把它优化下。另外x64dbg强大的表达式功能还可以实现符合匹配正则表达式和字符串内容的指令才记录跟踪,比如{dis.match(rip,"text.+,0x1")}或者{strstr(dis.text(cip),"call esi"}等,大家可以参考前面提到的X64Dbg 介绍->表达式一文自行体验。


通过条件跟踪的灵活应用,就有助于我们菜鸟知道函数调用的整个过程,快速粗定位到关键CALL,事半功倍。



[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界

最后于 2023-11-15 04:45 被pexufe编辑 ,原因: 发现漏掉JMP分支语句,对日志条件进行了优化
收藏
点赞16
打赏
分享
最新回复 (42)
雪    币: 2200
活跃值: (8990)
能力值: ( LV13,RANK:385 )
在线值:
发帖
回帖
粉丝
TkBinary 5 2023-11-10 13:29
2
1
谢谢.博客是我发的文章. 我用的比较多的是 strstr(utf8(reg/mem/[mem]),"string") != 0
例子:
条件 strstr(utf8(rcx),"xxx.txt") != 0 如CreateFile可以精确断下要打开的文件. 
雪    币: 5823
活跃值: (3519)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
pxhb 2 2023-11-10 13:54
3
2
TkBinary 谢谢.博客是我发的文章. 我用的比较多的是 strstr(utf8(reg/mem/[mem]),"string") != 0 例子: 条件 strstr(utf8(rcx), ...
请教一下,如果是CreateFileW,unicode的情况下,一般是完整路径,我只判断文件名怎么判断
雪    币: 1183
活跃值: (758)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
pexufe 2023-11-10 14:10
4
0
TkBinary 谢谢.博客是我发的文章. 我用的比较多的是 strstr(utf8(reg/mem/[mem]),"string") != 0 例子: 条件 strstr(utf8(rcx), ...

膜拜大佬!您的文章对我帮助和启发很大,自己看x64dbg的帮助文档实在太晦涩难懂了,您的文章浅显易懂又内容丰富,对于我这样的菜鸟太友好啦。第一次发帖,不知道看雪的规则怕违规,否则我一定要把X64Dbg 介绍->表达式,这篇文章的链接贴上去,广而告之。

您说的strstr这个我也尝试了,确实非常简单有效,有了它根据就不需要strmatch插件了。只不过我现在跟的一个程序会生成很多临时文件,都判断的话有点太麻烦了。我这篇只是想帮助大家可以快速的粗定位到关键CALL,想灵活用好x64dbg的表达式,还是要多拜读研究您的那篇文章。

最后于 2023-11-10 14:16 被pexufe编辑 ,原因:
雪    币: 2200
活跃值: (8990)
能力值: ( LV13,RANK:385 )
在线值:
发帖
回帖
粉丝
TkBinary 5 2023-11-10 14:52
5
0
pxhb 请教一下,如果是CreateFileW,unicode的情况下,一般是完整路径,我只判断文件名怎么判断
可以是 utf16. 建议看看他推荐的这篇文章.或者在官方文档中查看也行.
雪    币: 2200
活跃值: (8990)
能力值: ( LV13,RANK:385 )
在线值:
发帖
回帖
粉丝
TkBinary 5 2023-11-10 15:19
6
0
pexufe TkBinary 谢谢.博客是我发的文章. 我用的比较多的是 strstr(utf8(reg/mem/[mem]),&quot;strin ...
好好好,能帮助你就行.共勉.
雪    币: 378
活跃值: (2590)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
appview 2023-11-10 18:52
7
0
稍微大点的软件就不行了
雪    币: 1183
活跃值: (758)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
pexufe 2023-11-10 21:47
8
0
appview 稍微大点的软件就不行了
最好还是配合条件断点等一块使用。你也可以在步进转换条件里加上mod.party(dis.branchdest(cip))==1,这样系统模块内部就会转成步过F8,用户模块才会步进F7。这样可以减少很多系统模块内部的无效跟踪,但我试过有些从系统模块转回用户模块的调用会丢失。
雪    币: 30849
活跃值: (6980)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
ninebell 2023-11-11 07:36
9
1
俺的编译版此处增加读写ini机制
可把楼主一网打尽
你还可以输出各个寄存器中的字符串中信息到log窗口
雪    币: 17901
活跃值: (25552)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
秋狝 2023-11-11 21:56
10
1
感谢分享
雪    币: 640
活跃值: (2126)
能力值: ( LV4,RANK:45 )
在线值:
发帖
回帖
粉丝
钢针 1 2023-11-13 15:42
11
0
大佬,分享学习一下可好?
雪    币: 640
活跃值: (2126)
能力值: ( LV4,RANK:45 )
在线值:
发帖
回帖
粉丝
钢针 1 2023-11-13 16:01
12
0
实际尝试了一下,怎么一直显示设置日志文本或条件时失败呀
雪    币: 30849
活跃值: (6980)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
ninebell 2023-11-26 11:29
13
0
钢针 实际尝试了一下,怎么一直显示设置日志文本或条件时失败呀[em_1]
modname是不是没改对应的模块名呢?
雪    币: 578
活跃值: (2190)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
考拉 2023-11-28 08:40
14
0
学习了,还可以这样玩
雪    币: 1570
活跃值: (1425)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
自由狼 2023-12-2 23:22
15
0


奇怪为什么我的没有步进转换条件那一栏

最后于 2023-12-2 23:50 被自由狼编辑 ,原因:
雪    币: 1183
活跃值: (758)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
pexufe 2023-12-3 00:12
16
0
自由狼 奇怪为什么我的没有步进转换条件那一栏
步进转换条件只有2023.1.25之前的版本才有,新的版本作者把这个功能去掉了。这个功能有利有弊,可以帮助过滤掉一些不相关的系统模块调用,但有时候也会造成漏跟踪。
雪    币: 20773
活跃值: (3486)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
huangyalei 2023-12-3 01:46
17
1
自由狼 奇怪为什么我的没有步进转换条件那一栏
2023.2.23 的版本取消了步进转换功能,然后引入了指令 StepUser 和 StepSystem 来实现用户代码和系统代码的步进
雪    币: 7885
活跃值: (4150)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
sunsjw 1 2023-12-3 10:32
18
0
huangyalei 2023.2.23 的版本取消了步进转换功能,然后引入了指令 StepUser 和 StepSystem 来实现用户代码和系统代码的步进
学习了
雪    币: 30849
活跃值: (6980)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
ninebell 2023-12-3 11:41
19
0
自由狼 奇怪为什么我的没有步进转换条件那一栏

奇怪,为啥我的多出这么多来?

雪    币: 1570
活跃值: (1425)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
自由狼 2023-12-3 12:11
20
0
感谢 学习了,再消化消化这些东西
雪    币: 1570
活跃值: (1425)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
自由狼 2023-12-3 12:14
21
0
暂停条件这里经常用到,也好理解,命令和命令条件总感觉没有理解到位
雪    币: 20773
活跃值: (3486)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
huangyalei 2023-12-3 12:24
22
0
ninebell 奇怪,为啥我的多出这么多来?
这种自行修改的版本,如果不提交PR,跟着作者更新是很折磨人的,除非愿意停留在某个版本上不动,但这样官方的修复及改进也享受不到了
雪    币: 154
活跃值: (812)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
andydau 2023-12-5 06:26
23
0
huangyalei 2023.2.23 的版本取消了步进转换功能,然后引入了指令 StepUser 和 StepSystem 来实现用户代码和系统代码的步进
能详细讲讲这个怎么使用么? 我在命令那里输入之后会闪退。请教如何使用
雪    币: 20773
活跃值: (3486)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
huangyalei 2023-12-5 10:10
24
0
andydau 能详细讲讲这个怎么使用么? 我在命令那里输入之后会闪退。请教如何使用
可以在命令行执行,也可以在跟踪-自动运行命令执行,StepUser会在进入系统模块后暂停,StepSystem反之。至于闪退,我这里偶尔也会有,可能与调试的程序有关吧
雪    币: 2598
活跃值: (3377)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
值得怀疑 2023-12-5 10:32
25
0
huangyalei 这种自行修改的版本,如果不提交PR,跟着作者更新是很折磨人的,除非愿意停留在某个版本上不动,但这样官方的修复及改进也享受不到了
这是他自己改的,故意显摆的
游客
登录 | 注册 方可回帖
返回