一个 调了好久好久的虚拟机题目
原本比赛的时候是上午做了个pyc, 下午开始调vm, 调到结束也没弄出来个道道,tcl, 就开始等待大佬们的wp, 好几天过去, 似乎没有???
走投无路的菜鸡只好自己慢慢逆, 然后写下这个题目的wp。 欢迎围观
虎符ctf, vm题目, 个人觉得一个比较不错的虚拟机,指令好多,不太好调。
几个简单的虚拟机题目, 我的博客有一个整理, 对应的文件应该是在里面有,没有的话,博客主页转csdn里对应文章肯定有(这,是个历史遗留问题…)
似乎也没怎么找到比较好的方法,对于虚拟机的题目,就看虚拟机指令然后去还原, 再逆吧,不过发现还是要注意下栈堆机器和寄存器机器是不一样,
这个题目给出的就是一个栈堆机器,所以里面有的处理栈的指令,用了python字节码去标注,(第一题:“没想到吧!还是我。”),
vm
首先题目的main函数比较简单:
注意下打开文件是用的参数。即运行时要指定参数./vm code
, ida调试要在debugger -> process options -> parameters
写上参数code
,
重点在于函数vm(code)
:
比较典型的一个while(1)
和switch(opcode)
的结构做的虚拟机,
然后运行的大体情况, 如下示:
对于详细的可以看附件中的
code.py
文件, 本文简单写下data架构体和opcode, 和一部分循环的结构。
data
.bss:00000000006020A0 : bss_data
bss_data{
Dword vm_eip;
Dword vm_sp;
Qword code; // *(bss_data+1)
Qword vm_stack; // *(bss_data+2)
Qword vm_var_arr; //*(bss_data+3)
Qword vm_reg; // *(bss_data+4)
}
一个bss段的一个结构体, 主要我们运行的时候储存信息:
vm_eip一个数字, 代表偏移量,使用这个配合code地址检索到opcode,opcode = *(&code + vm_eip)
,
vm_sp: 代表栈内数据数目,也配合栈地址形成指向栈顶的指针,
code: 这个就是储存code, 没啥要说的,
vm_stack: 这个是这个栈堆机器操作的栈,
vm_arr: 一片内存空间,主要用于储存三个数组, 一个预定义好了的arr1(在50-91), 一个用户输入的arr2(在100-141), 一个由arr2处理成的arr3(在0-41),对arr的处理是重点
vm_block: 这个储存另一部分数据,主要是用于储存循环时的计数器,是一个python解释器中