网鼎杯 signal 基础vm逆向及vm逆向分析思路

什么是VM(虚拟机保护)?

 

 

 

分析流程:

 

 

 

vm_start :虚拟机入口函数 ,初始化虚拟机

vm_dispatcher: 调度器,解释op_code,并选择相应的函数执行,当函数执行完后会返回这里,形成一个循环,直到执行完

vm_code:程序可执行代码形成的操作码

 

一般VM分析解题流程

这里借用一位大佬的总结图片

 

 

 

 

来看看2020网鼎杯的signal

 

首先IDA分析

 

 

 发现是一个vm逆向 其中vm  opread_code 位于变量v4当中,首先写一个IDA python 脚本提取出opread_code

from idaapi import *
start_addr=0x403040
list=[]
for i in range(114):
	t=Dword(start_addr)
	list.append(t)
	start_addr+=4
print list
print len(list)

 

 

 整理后

op_code=[10,4,16,8,
3,5,1,4,32,8,
5,3,1,3,2,8,11,1,12,8,4,
4,1,5,3,8,3,33,1,11,8,11,1,4,
9,8,3,32,1,2,81,8,4,36,1,12,8,11,
1,5,2,8,2,37,1,2,54,8,4,65,1,2,32,
8,5,1,1,5,3,8,2,37,1,4,9,8,3,32,1,2,
65,8,12,1,7,34,7,63,7,52,7,50,7,114,7,51,
7,24,7,4294967207,
7,49,7,4294967281,7,
40,7,4294967172,7,4294967233,
7,30,7,122]

接下来分析 vm opread部分

典型的VM switch结构

 

 

 

分析发现:每一个分支里面都有v10 而且都有v10++的操作,我们可以将其理解为汇编中的eip(rip)指针或者索引

 

 

接着分析其他的case 可以依次发现每个case的作用(也就是做一个简单运算)

 

 

 

 

 

 其中a1[]已经被我修改为input

进一步分析我们发现:v6 v7 v8 v9是数组的索引,v5为操作的返回值,进一步重命名变量,以有利于分析

 

 

 其中 case7为必须满足的条件,只要我们的输入满足case7不跳出则能得到flag的值,

我们可以根据case7逆向算出v4[]的值,进而反推出input

这是我们再看看op_code

op_code=[10,4,16,8,
3,5,1,4,32,8,
5,3,1,3,2,8,11,1,12,8,4,
4,1,5,3,8,3,33,1,11,8,11,1,4,
9,8,3,32,1,2,81,8,4,36,1,12,8,11,
1,5,2,8,2,37,1,2,54,8,4,65,1,2,32,
8,5,1,1,5,3,8,2,37,1,4,9,8,3,32,1,2,
65,8,12,1,7,34,7,63,7,52,7,50,7,114,7,51,
7,24,7,4294967207,
7,49,7,4294967281,7,
40,7,4294967172,7,4294967233,
7,30,7,122]

发现在比较操作数7第一次出现的位置之后,都是一些无效指令(大于12),

所以,加密运算应该是在操作数7第一次出现之前完成。

有效的op_code应该是

a=[10, 4, 16, 8, 3, 5, 1, 4, 32, 8, 5, 3, 
1, 3, 2, 8, 11, 1, 12, 8, 4, 4, 1, 5, 3, 8,
 3, 33, 1, 11, 8, 11, 1, 4, 9, 8, 3, 32, 
1, 2, 81, 8, 4, 36, 1, 12, 8, 11, 1, 5, 2,
 8, 2, 37, 1, 2, 54, 8, 4, 65, 1, 2, 32, 8,
 5, 1, 1, 5, 3, 8, 2, 37, 1, 4, 9, 8, 3, 32, 1, 
2, 65, 8, 12, 1]

下面开始写逆算法(加变减,乘法变除法)

op_code=[10,4,16,8,
3,5,1,4,32,8,
5,3,1,3,2,8,11,1,12,8,4,
4,1,5,3,8,3,33,1,11,8,11,1,4,
9,8,3,32,1,2,81,8,4,36,1,12,8,11,
1,5,2,8,2,37,1,2,54,8,4,65,1,2,32,
8,5,1,1,5,3,8,2,37,1,4,9,8,3,32,1,2,
65,8,12,1,7,34,7,63,7,52,7,50,7,114,7,51,
7,24,7,4294967207,
7,49,7,4294967281,7,
40,7,4294967172,7,4294967233,
7,30,7,122]
for i in range(len(op_code)):
          if(op_code[i]==7):
                    v4.append(op_code[i+1])


v4.reverse()

op_code=[10, 4, 16, 8, 3, 5, 1, 4, 32, 8, 5, 3, 1, 3, 2, 8, 11, 1, 12, 8, 4, 4, 1, 5, 3, 8, 3, 33, 1, 11, 8, 11, 1, 4, 9, 8, 3, 32, 1, 2, 81, 8, 4, 36, 1, 12, 8, 11, 1, 5, 2, 8, 2, 37, 1, 2, 54, 8, 4, 65, 1, 2, 32, 8, 5, 1, 1, 5, 3, 8, 2, 37, 1, 4, 9, 8, 3, 32, 1, 2, 65, 8, 12, 1]
op_code.reverse()

v9 = 0
tmp=0
v5=0
flag=[]
for i in range(0,len(op_code)):
          if i ==len(op_code)-1:
                    flag.append(tmp)
                    
          if op_code[i]==1 and op_code[i-1]!=1:
                    v5 = v4[v9]
                    v9+=1
                    flag.append(tmp)
                    
          if op_code[i]==2:
                    if(op_code[i+1]!=3 and op_code[i+1]!=4 and op_code[i+1]!=5):
                              tmp = v5 - op_code[i-1]
                              #print(tmp,v5,a[i-1])
                    
          if op_code[i]==3:
                    if(op_code[i+1]!=2 and op_code[i+1]!=4 and op_code[i+1]!=5):               
                              tmp = v5 + op_code[i-1]  #LOBYTE是al有8位,参与运算的5、33、32是全值,所以LOBYTE可省略
                    
          if op_code[i]==4:
                    if(op_code[i+1]!=3 and op_code[i+1]!=2 and op_code[i+1]!=5):
                              tmp = v5^op_code[i-1]

          if op_code[i]==5:
                    if(op_code[i+1]!=3 and op_code[i+1]!=4 and op_code[i+1]!=2):
                              tmp = int(v5/op_code[i-1])
          if op_code[i]==8:
                    v5 = tmp
                              
          if op_code[i]==11:
                    tmp = v5 +1
          if op_code[i]==12:
                    tmp = v5 -1
                    

flag.reverse()
out=''
for j in flag:
          out +=chr(j)
print("flag{"+out+"}")

                    

52上也有大佬用符号执行做的 我还不会 去学习一下

修改的idb exp 及源文件下载链接 https://files.cnblogs.com/files/nigacat/signal.rar

 

posted @ 2020-06-05 00:17  nigacat  阅读(946)  评论(0编辑  收藏  举报