UNCTF - 2019 EasyVm
整体而言是一个比较好分析的一个VM
题目,对得起其easy
的名字?
拖入IDA
进行反编译,可以清楚的发现对应的结构特点
我们跟进到创建栈空间的函数可发现其对应的操作函数集合
我们可以发现里面的运算,可以进行简单的标注一下。
我们在这个函数的集合中可以发现第一个run_vm
中存在有switch - case
结构,因此可以推断出来这个函数就是在执行对应的操作指令判断,来进行执行后面的函数
进行简单的一下调试我们可以观察到其栈空间的分配规律:
同时我们可以注意到operate
函数下方的opcode
并没有按顺序进行执行,而是先跳到了opcede+9
处的指令
简单的调试,我们可以获取到其对应的执行流程以及对应的指令操作的代表功能
对应指令翻译:
操作码 | 对应指令集合 |
---|---|
*(a1+16) | 寄存器r1(占1字节) |
*(a1+17) | 寄存器r2(占1字节) |
*(a1+18) | 寄存器r3(占1字节) |
*(a1+19) | 寄存器r4(占1字节) |
*(a1+20) | 寄存器r5(占4字节) |
0xA0 | r1++ |
0xA1 | r2++ |
0xA2 | r3++ |
0xA3 | r1 -= r3 |
0xA4 | r1 ^= r2 |
0xA5 | r2 ^= r1 |
0xA6 | r1 = 0xCD |
0xA7 | r2 = r1 |
0xA8 | r3 = 0xCD |
0xA9 | r1 = input[r3] |
0xAA | r2 = input[r3] |
0xAB | func1() |
0xAC | func2() |
0xAD | func3() |
0xAE | 判断r5的值 |
0xAF | 判断r5的值 |
可以得到程序对每个输入的字符进行的执行流程为:
1 |
|
因此我们可以写出对应的翻译脚本与解密脚本进行解密:
1 |
|
因此我们可以得到flag
为:UNCTF{942a4115be2359ffd675fa6338ba23b6}
UNCTF - 2019 EasyVm
https://equinox-shame.github.io/2022/07/22/UNCTF - 2019 EasyVm/