其他
VM逆向,一篇就够了(下)
接着上一篇文章(https://bbs.kanxue.com/thread-281119.htm),我们继续了解一些不一样vm。
一
实战三
TLS回调函数
mov ecx,[eax]
指令。如果不是处于调试状态则走另一个分支,触发一个除零异常,跳转到处理函数之后程序正常运行。对抗方法很简单,直接在IsDebuggerPresent结束之后修改eax的值,将1修改为0。分析main函数
翻译
var_8=-8
var_C=-0x0C
v6=idc.get_reg_value('eax')
ebp_=idc.get_reg_value('ebp')
v7=idc.get_wide_word(ebp_+var_8)
v8=idc.get_wide_word(ebp_+var_C)
opcode_base=0xBE4018
value0=idc.get_wide_word(opcode_base+v7*2) #这里需要注意,v7要乘2,因为opcode是word数组
value1=idc.get_wide_word(opcode_base+v8*2)
print('opcode[%d]=~(opcode[%d]&opcode[%d])'%(v6,v7,v8),' opcode[%d]=~( %d & %d )'%(v6,value0,value1))
var_24=-0x24
ebp_=idc.get_reg_value('ebp')
num=idc.get_wide_word(ebp_+var_24)
if(num==0x24):
print('-------------------------------------END-------------------------------------')
print('-------------------------------------END-------------------------------------')
print('-------------------------------------END-------------------------------------')
opcode[7]=~(opcode[8]&opcode[8]) opcode[7]=~( 126 & 126 )
opcode[2808]=~(opcode[7]&opcode[7]) opcode[2808]=~( 65409 & 65409 )
opcode[11]=~(opcode[2772]&opcode[2772]) opcode[11]=~( 49 & 49 ) //取反
opcode[11]=~(opcode[2773]&opcode[11]) opcode[11]=~( 50 & 65486 )
opcode[12]=~(opcode[2773]&opcode[2773]) opcode[12]=~( 50 & 50 )
opcode[12]=~(opcode[2772]&opcode[12]) opcode[12]=~( 49 & 65485 )
opcode[17]=~(opcode[12]&opcode[11]) opcode[17]=~( 65534 & 65533 )
opcode[11]=~(opcode[2774]&opcode[2774]) opcode[11]=~( 51 & 51 )
opcode[11]=~(opcode[2775]&opcode[11]) opcode[11]=~( 52 & 65484 )
opcode[12]=~(opcode[2775]&opcode[2775]) opcode[12]=~( 52 & 52 )
opcode[12]=~(opcode[2774]&opcode[12]) opcode[12]=~( 51 & 65483 )
opcode[18]=~(opcode[12]&opcode[11]) opcode[18]=~( 65532 & 65531 )
opcode[11]=~(opcode[17]&opcode[17]) opcode[11]=~( 3 & 3 )
opcode[11]=~(opcode[18]&opcode[11]) opcode[11]=~( 7 & 65532 )
opcode[12]=~(opcode[18]&opcode[18]) opcode[12]=~( 7 & 7 )
opcode[12]=~(opcode[17]&opcode[12]) opcode[12]=~( 3 & 65528 )
opcode[18]=~(opcode[12]&opcode[11]) opcode[18]=~( 65535 & 65531 )
opcode[11]=~(opcode[2809]&opcode[2809]) opcode[11]=~( 36 & 36 )
opcode[11]=~(opcode[18]&opcode[11]) opcode[11]=~( 4 & 65499 )
opcode[12]=~(opcode[18]&opcode[18]) opcode[12]=~( 4 & 4 )
opcode[12]=~(opcode[2809]&opcode[12]) opcode[12]=~( 36 & 65531 )
opcode[19]=~(opcode[12]&opcode[11]) opcode[19]=~( 65503 & 65535 )
opcode[7]=~(opcode[8]&opcode[8]) opcode[7]=~( 7e & 7e )
opcode[2808]=~(opcode[7]&opcode[7]) opcode[2808]=~( ff81 & ff81 ) //保存最后一位输入至opcode[2808]
opcode[11]=~(opcode[2772]&opcode[2772]) opcode[11]=~( 31 & 31 ) //opcode[11]=~(input[0]&input[0])
opcode[11]=~(opcode[2773]&opcode[11]) opcode[11]=~( 32 & ffce ) //opcode[11]=~(input[1]&opcode[11])
opcode[12]=~(opcode[2773]&opcode[2773]) opcode[12]=~( 32 & 32 ) //opcode[12]=~(input[1]&input[1])
opcode[12]=~(opcode[2772]&opcode[12]) opcode[12]=~( 31 & ffcd ) //opcode[12]=~(input[0]&opcode[12])
opcode[17]=~(opcode[12]&opcode[11]) opcode[17]=~( fffe & fffd ) //opcode[17]=~(opcode[12]&opcode[11])
opcode[11]=~(opcode[2774]&opcode[2774]) opcode[11]=~( 33 & 33 ) //opcode[11]=~(input[2]&input[2])
opcode[11]=~(opcode[2775]&opcode[11]) opcode[11]=~( 34 & ffcc ) //opcode[11]=~(input[3]&opcode[11])
opcode[12]=~(opcode[2775]&opcode[2775]) opcode[12]=~( 34 & 34 ) //opcode[12]=~(input[3]&input[3])
opcode[12]=~(opcode[2774]&opcode[12]) opcode[12]=~( 33 & ffcb ) //opcode[12]=~(input[2]&opcode[12])
opcode[18]=~(opcode[12]&opcode[11]) opcode[18]=~( fffc & fffb ) //opcode[18]=~(opcode[12]&opcode[11])
opcode[11]=~(opcode[17]&opcode[17]) opcode[11]=~( 3 & 3 ) //opcode[11]=~(opcode[17]&opcode[17])
opcode[11]=~(opcode[18]&opcode[11]) opcode[11]=~( 7 & fffc ) //opcode[11]=~(opcode[18]&opcode[11])
opcode[12]=~(opcode[18]&opcode[18]) opcode[12]=~( 7 & 7 ) //opcode[12]=~(opcode[18]&opcode[18])
opcode[12]=~(opcode[17]&opcode[12]) opcode[12]=~( 3 & fff8 ) //opcode[12]=~(opcode[17]&opcode[12])
opcode[18]=~(opcode[12]&opcode[11]) opcode[18]=~( ffff & fffb ) //opcode[18]=~(opcode[12]&opcode[11])
//注意下面是进行比较
opcode[11]=~(opcode[2809]&opcode[2809]) opcode[11]=~( 24 & 24 ) //opcode[11]=~(cpdata[0]&cpdata[0])
opcode[11]=~(opcode[18]&opcode[11]) opcode[11]=~( 4 & ffdb ) //opcode[11]=~(opcode[18]&opcode[11])
opcode[12]=~(opcode[18]&opcode[18]) opcode[12]=~( 4 & 4 ) //opcode[12]=~(opcode[18]&opcode[18])
opcode[12]=~(opcode[2809]&opcode[12]) opcode[12]=~( 24 & fffb ) //opcode[12]=~(cpdata[0]&opcode[12])
opcode[19]=~(opcode[12]&opcode[11]) opcode[19]=~( ffdf & ffff ) //opcode[19]=~(opcode[12]&opcode[11])
opcode[11]=~(input[1]&opcode[11]) //将input[1]与取反之后的input[0]进行与操作 与操作保留都是1的位,而~input[0]的1是由0变来的
1100 1110 & 0011 0010 -->0000 0010 这一步就是将input[0]为0且input[1]为1的位 置1 0000 0010 然后取反(有点异或的意思) 1111 1101
opcode[12]=~(input[1]&input[1]) //input[1]取反 0011 0010 -- 1100 1101
opcode[12]=~(input[0]&opcode[12]) //将input[0]为1且input[1]为0的位 置1 0000 0001 然后取反 1111 1110
opcode[17]=~(opcode[12]&opcode[11]) //保留都是1的位 1111 1100 然后取反 0000 0011 就是 input[0]^input[1]的结果
最后一条指令就是将input[0]为0且input[1]为1的位置1 同时将input[0]为1且input[1]为0的位置1 合并一下就是相异为1 相同为0
上面六条等价为高级指令
opcode[17]=input[0]^input[1]
opcode[18]=input[2]^input[3]
opcode[18]=opcode[17]^opcode[18]
opcode[19]=cpdata[0]^opcode[18]
cpdata[1]==input[1]^input[2]^input[3]^input[4]
…………
cpdata[33]==input[33]^input[34]^input[35]^input[36]
?????这里数据不够了 不知道是循环到input[0]那里还是继续往后取数据,先写一个解出前面的试试
cpdada[36]=input[]
# 创建符号变量
input = [BitVec('input_%d' % i, 16) for i in range(37)]
# 已知的结果
cpdata = [0x0024, 0x000B, 0x006D, 0x000F, 0x0003, 0x0032, 0x0042, 0x001D,
0x002B, 0x0043, 0x0078, 0x0043, 0x0073, 0x0030, 0x002B, 0x004E,
0x0063, 0x0048, 0x0077, 0x002E, 0x0032, 0x0039, 0x001A, 0x0012,
0x0071, 0x007A, 0x0042, 0x0017, 0x0045, 0x0072, 0x0056, 0x000C,
0x005C, 0x004A, 0x0062, 0x0053, 0x0033]
# 添加异或约束
constraints = []
for i in range(34):
constraints.append(cpdata[i] == (input[i] ^ input[i+1] ^ input[i+2] ^ input[i+3]))
# 创建解决器
solver = Solver()
# 添加约束
solver.add(constraints)
# 求解
if solver.check() == sat:
model = solver.model()
solution = [model[input[i]].as_long() for i in range(37)]
print("Solution found:")
print(solution)
else:
print("No solution found.")
#[80, 65, 50, 7, 127, 39, 80, 11, 78, 87, 15, 61, 38, 108, 52, 13, 101, 119, 81, 32, 78, 72, 8, 60, 69, 107, 0, 95, 78, 83, 85, 13, 121, 119, 15, 93, 111]
opcode[2808]=~(opcode[7]&opcode[7]) opcode[2808]=~( ff81 & ff81 )
opcode[11]=~(opcode[2772]&opcode[2772]) opcode[11]=~( 50 & 50 ) //input[0]
opcode[11]=~(opcode[2773]&opcode[11]) opcode[11]=~( 41 & ffaf ) //input[1]
opcode[12]=~(opcode[2773]&opcode[2773]) opcode[12]=~( 41 & 41 )
opcode[12]=~(opcode[2772]&opcode[12]) opcode[12]=~( 50 & ffbe )
opcode[17]=~(opcode[12]&opcode[11]) opcode[17]=~( ffef & fffe )
opcode[11]=~(opcode[2774]&opcode[2774]) opcode[11]=~( 32 & 32 ) //input[2]
opcode[11]=~(opcode[2775]&opcode[11]) opcode[11]=~( 7 & ffcd ) //input[3]
opcode[12]=~(opcode[2775]&opcode[2775]) opcode[12]=~( 7 & 7 )
opcode[12]=~(opcode[2774]&opcode[12]) opcode[12]=~( 32 & fff8 )
opcode[18]=~(opcode[12]&opcode[11]) opcode[18]=~( ffcf & fffa )
opcode[11]=~(opcode[17]&opcode[17]) opcode[11]=~( 11 & 11 )
opcode[11]=~(opcode[18]&opcode[11]) opcode[11]=~( 35 & ffee )
opcode[12]=~(opcode[18]&opcode[18]) opcode[12]=~( 35 & 35 )
opcode[12]=~(opcode[17]&opcode[12]) opcode[12]=~( 11 & ffca )
opcode[18]=~(opcode[12]&opcode[11]) opcode[18]=~( ffff & ffdb )
opcode[11]=~(opcode[2809]&opcode[2809]) opcode[11]=~( 24 & 24 )
opcode[11]=~(opcode[18]&opcode[11]) opcode[11]=~( 24 & ffdb )
opcode[12]=~(opcode[18]&opcode[18]) opcode[12]=~( 24 & 24 )
opcode[12]=~(opcode[2809]&opcode[12]) opcode[12]=~( 24 & ffdb )
opcode[19]=~(opcode[12]&opcode[11]) opcode[19]=~( ffff & ffff )
opcode[11]=~(opcode[2773]&opcode[2773]) opcode[11]=~( 41 & 41 ) //input[1]
opcode[11]=~(opcode[2774]&opcode[11]) opcode[11]=~( 32 & ffbe ) //input[2]
opcode[12]=~(opcode[2774]&opcode[2774]) opcode[12]=~( 32 & 32 )
opcode[12]=~(opcode[2773]&opcode[12]) opcode[12]=~( 41 & ffcd )
opcode[17]=~(opcode[12]&opcode[11]) opcode[17]=~( ffbe & ffcd )
opcode[11]=~(opcode[2775]&opcode[2775]) opcode[11]=~( 7 & 7 ) //input[3]
opcode[11]=~(opcode[2776]&opcode[11]) opcode[11]=~( 35 & fff8 ) //input[4]
opcode[12]=~(opcode[2776]&opcode[2776]) opcode[12]=~( 35 & 35 )
opcode[12]=~(opcode[2775]&opcode[12]) opcode[12]=~( 7 & ffca )
opcode[18]=~(opcode[12]&opcode[11]) opcode[18]=~( fffd & ffcf )
opcode[11]=~(opcode[17]&opcode[17]) opcode[11]=~( 73 & 73 )
opcode[11]=~(opcode[18]&opcode[11]) opcode[11]=~( 32 & ff8c )
opcode[12]=~(opcode[18]&opcode[18]) opcode[12]=~( 32 & 32 )
opcode[12]=~(opcode[17]&opcode[12]) opcode[12]=~( 73 & ffcd )
opcode[18]=~(opcode[12]&opcode[11]) opcode[18]=~( ffbe & ffff )
opcode[11]=~(opcode[2810]&opcode[2810]) opcode[11]=~( b & b )
opcode[11]=~(opcode[18]&opcode[11]) opcode[11]=~( 41 & fff4 )
opcode[12]=~(opcode[18]&opcode[18]) opcode[12]=~( 41 & 41 )
opcode[12]=~(opcode[2810]&opcode[12]) opcode[12]=~( b & ffbe )
opcode[19]=~(opcode[12]&opcode[11]) opcode[19]=~( fff5 & ffbf )
…………
opcode[11]=~(opcode[2806]&opcode[2806]) opcode[11]=~( 60 & 60 ) //input[34]
opcode[11]=~(opcode[2807]&opcode[11]) opcode[11]=~( 43 & ff9f ) //input[35]
opcode[12]=~(opcode[2807]&opcode[2807]) opcode[12]=~( 43 & 43 )
opcode[12]=~(opcode[2806]&opcode[12]) opcode[12]=~( 60 & ffbc )
opcode[17]=~(opcode[12]&opcode[11]) opcode[17]=~( ffdf & fffc )
opcode[11]=~(opcode[2808]&opcode[2808]) opcode[11]=~( 7e & 7e ) //input[36]
opcode[11]=~(opcode[2772]&opcode[11]) opcode[11]=~( 41 & ff81 ) //input[0]
opcode[12]=~(opcode[2772]&opcode[2772]) opcode[12]=~( 41 & 41 )
opcode[12]=~(opcode[2808]&opcode[12]) opcode[12]=~( 7e & ffbe )
opcode[18]=~(opcode[12]&opcode[11]) opcode[18]=~( ffc1 & fffe )
opcode[11]=~(opcode[17]&opcode[17]) opcode[11]=~( 23 & 23 )
opcode[11]=~(opcode[18]&opcode[11]) opcode[11]=~( 3f & ffdc )
opcode[12]=~(opcode[18]&opcode[18]) opcode[12]=~( 3f & 3f )
opcode[12]=~(opcode[17]&opcode[12]) opcode[12]=~( 23 & ffc0 )
opcode[18]=~(opcode[12]&opcode[11]) opcode[18]=~( ffff & ffe3 )
opcode[11]=~(opcode[2843]&opcode[2843]) opcode[11]=~( 62 & 62 )
opcode[11]=~(opcode[18]&opcode[11]) opcode[11]=~( 1c & ff9d )
opcode[12]=~(opcode[18]&opcode[18]) opcode[12]=~( 1c & 1c )
opcode[12]=~(opcode[2843]&opcode[12]) opcode[12]=~( 62 & ffe3 )
opcode[19]=~(opcode[12]&opcode[11]) opcode[19]=~( ff9d & ffe3 )
# 创建符号变量
input = [BitVec('input_%d' % i, 8) for i in range(37)]
# 已知的结果
cpdata = [0x0024, 0x000B, 0x006D, 0x000F, 0x0003, 0x0032, 0x0042, 0x001D,
0x002B, 0x0043, 0x0078, 0x0043, 0x0073, 0x0030, 0x002B, 0x004E,
0x0063, 0x0048, 0x0077, 0x002E, 0x0032, 0x0039, 0x001A, 0x0012,
0x0071, 0x007A, 0x0042, 0x0017, 0x0045, 0x0072, 0x0056, 0x000C,
0x005C, 0x004A, 0x0062, 0x0053, 0x0033]
# 添加异或约束
constraints = []
for i in range(34):
constraints.append(cpdata[i] == (input[i] ^ input[i+1] ^ input[i+2] ^ input[i+3]))
# 创建解决器
solver = Solver()
# 添加约束
solver.add(constraints)
solver.add(cpdata[34] == (input[34] ^ input[35] ^ input[36] ^ input[0]))
solver.add(cpdata[35] == (input[35] ^ input[36] ^ input[0] ^ input[1]))
solver.add(cpdata[36] == (input[36] ^ input[0] ^ input[1] ^ input[2]))
solver.add(input[36]==126) #题目中对最后一位的限制
# 求解
if solver.check() == sat:
model = solver.model()
solution = [model[input[i]].as_long() for i in range(37)]
print("Solution found:")
print(solution)
else:
print("No solution found.")
#[65, 95, 83, 105, 110, 57, 49, 101, 95, 73, 110, 83, 55, 114, 85, 99, 116, 105, 48, 78, 95, 86, 105, 82, 84, 117, 97, 49, 95, 77, 52, 99, 104, 105, 110, 51, 126]
#A_Sin91e_InS7rUcti0N_ViRTua1_M4chin3~
二
初识VMP
什么是VMProtect
优缺点
◆保护程度高,极难破解(没有绝对安全的程序,但如果破解程序所需的成本大于程序本身,程序自然就安全了)。
◆保护后,虚拟机和新命令集将内置到受保护的应用程序中,并且不需要任何其他库和模块即可工作。
◆支持多种语言,以及主流操作系统:Windows、macOS、Linux。
◆执行效率低(参考上面的题目,一条printf语句就对应十几条vm指令)。
◆过于消耗系统资源。
看雪ID:马先越
https://bbs.kanxue.com/user-home-984774.htm
# 往期推荐
球分享
球点赞
球在看
点击阅读原文查看更多