type
status
date
slug
summary
tags
category
icon
password
DWARF分析器
通过Richar师傅的思路
参考通过DWARF Expression将代码隐藏在栈展开过程中这篇文章,可以得知有可能是在DWRAF中恢复寄存器的表达式中做了手脚。通过
readelf -wf nothing
查看得到大量信息。其中有4段DW_CFA_val_expression
非常长就是恢复寄存器所运行的表达式,具体指令含义请参考文档DWARF 5 Standard(2.5 DWARF Expressions)。显然这种长度手工分析已经不可能了,因此这里写了一个简单的分析器,他可以把这些栈操作变成c代码,然后通过编译器的-O3
优化,可以得到较为简单的表达式。分析器代码如下:
生成的c文件:
通过
gcc
加上-O3
参数编译,再通过逆向工具反编译,得到的结果如下观察这四段表达式,可以发现他们都在根据
R12
的低8位进行选择不同的功能。可以列得下表(具体数据每个附件不一样):R12&0xff | R12 | R13 | R14 | R15 |
0 | 1 | R13+11448659141604722329 | R14 | R15 |
1 | 1 | R13 | R14^(r13+6754348585825892801)^(r13>>30)^(r15<<24) | R15 |
2 | 1 | R13 | R15 | R14 |
3 | 1 | R13 | R14^5050961714944838468 | R15^17385842772293075248 |
4 | R12>>8 | R13 | R14 | R15 |
5 | 0 | R13 | R14 | R15 |
6 | r13 == 14610338879684656475 ? (r12 >> 8) : 2 | R13 | R14 | R15 |
7 | 1 | r14!=9785931681412827268 | r15!=6634550174467950632 | R14 | R15 |
根据逆向结果,发现每次都会取
v10+i
的地方的内容放入寄存器r12
中,因此v10
里面存的是是操作码。每次执行完后又会i+=r12
,因此返回的r12
是对应下一个操作码与当前的操作码的偏移。结合上表,4号功能是无条件转移,5号功能是结束运行,6号功能是条件跳转(条件是r13 == 14610338879684656475
)。根据这些信息,可以把加密过程写出如下代码。注意:每个不同的附件的下面常量都是不一样的。
解密脚本
动态调试(最原始的方法)
首先断在字符串后面
为啥断在这里?经过大量的IDA调试信息发现每次都会取
v10+i
的地方的内容放入寄存器r12
中,因此v10
里面存的是是操作码。每次执行完后又会i+=r12
,因此返回的r12
是对应下一个操作码与当前的操作码的偏移。然后
其它两处在这里
目的就是为了断到调试器的位置,还是就是进行寄存器操作的位置
然后经过人肉逻辑,r13就类似一个计时器,开始为零,然后每次减去0x1D43FD94705BDE2
R14、R15初始的时候分别是输入flag前半部分和后半部分,再输出加密后的R14和R15,实际加密处理是根据R13数值得到的一个值进行异或。
最后再根据脚本解题
有关Notion安装或者使用上的问题,欢迎您在底部评论区留言,一起交流~
- Author:5m10v3
- URL:https://5m10v3.top/article/814f78eb-ab2f-4fe9-9d07-46bf2d5c7bd8
- Copyright:All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!