接着上一篇文章(https://bbs./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))
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[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]
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[]
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~
什么是VMProtect优缺点◆保护程度高,极难破解(没有绝对安全的程序,但如果破解程序所需的成本大于程序本身,程序自然就安全了)。 ◆保护后,虚拟机和新命令集将内置到受保护的应用程序中,并且不需要任何其他库和模块即可工作。 ◆支持多种语言,以及主流操作系统:Windows、macOS、Linux。 ◆执行效率低(参考上面的题目,一条printf语句就对应十几条vm指令)。 ◆过于消耗系统资源。 看雪ID:马先越 https://bbs./user-home-984774.htm |
|
来自: 芥子c1yw3tb42g > 《待分类》