简单的vm-re框架

虚拟机就是要去模仿一个机器,让机器去执行一个文件(类似用win10去执行一个文件)
首先它需要一些在CPU中的寄存器和内存中的堆栈,这样去模拟一个CPU不断的去读取指令
主要是以循环的形式进行读取
1.在全局变量中分配如下内容:

这里就构成了CPU+内存
2.模拟一个CPU读取指令的形式(dispatcher)去写这样一个主程序
主程序:其实就是一个循环,这个循环不断的去读取指令(伪机器码opcode)这个会存在于内存中或文件中,然后执行指令opcode所对应的一些函数(其实这些函数可以理解为伪汇编的执行过程,比如就像一些add,sub,pop,push,jmp等操作),这样下来就可以与真实的程序执行相差无几
拿到程序之后先查壳,发现无壳之后运行一下查看,只有一个plz input:
我们将其直接拖入ida中进行查看
左侧函数窗口CTRL+F查找main函数
跳转到main函数之后发现有个花指令

将地址0x401594处的0xB8换成0x90(nop的硬编码)即可
然后P一下main函数按Tab进行反汇编
如下:
dispatcher就是去实现模拟CPU读取指令
opcode_team就是存在于内存中(也可存在于文件中)的opcode(伪机器码)
点开dispatcher,如下(这里就是一些模拟汇编的伪汇编函数),依次进行分析:
分析之后的:


分析过程:(不一一举例,举几个例子)

什么也没做,就只是++了eip,说明该函数模拟的是NOP

这里点击过去发现了连续的一个数组和一些字符串数据,说明模拟的是内存和CPU中的寄存器

这里模拟的就是mov reg, data
又比如sub_691070

这个模拟的就是push data,同时我们也在内存中找到了模拟栈
以此类推,将全部伪汇编的函数分析出来,然后写出解析脚本:
分析和注释:
最后理解程序的逻辑之后写出解题脚本:
得到flag值为:

flag{Such_A_EZVM}
再遇见vm-re的题目,先查找到opcode(伪机器码),然后找到dispatcher(就是模拟CPU读取指令的分发器),然后边分析那些伪汇编函数(就是模仿汇编指令的函数)边查找模拟的CPU的栈,寄存器,全局变量(多是字符串)等
参考资料:
846K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2T1K9h3I4A6j5X3W2D9K9g2)9J5k6h3y4G2L8g2)9J5c8Y4k6A6k6r3g2G2i4K6u0r3b7W2j5I4e0Y4j5@1x3e0q4C8y4@1S2v1
f4cK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6T1L8r3!0Y4i4K6u0W2j5%4y4V1L8W2)9J5k6h3&6W2N6q4)9J5c8Y4N6W2K9i4S2A6L8W2)9#2k6U0b7K6z5o6M7$3x3K6f1%4i4K6u0r3j5i4u0@1K9h3y4D9k6g2)9J5c8X3c8W2N6r3q4A6L8s2y4Q4x3V1j5I4x3o6R3@1z5o6R3%4y4U0t1`.
int __cdecl main(int argc, const char **argv, const char **envp)
{
unsigned int i; // [esp+10h] [ebp-8h]
sub_6914F0();
while ( 1 )
{
LABEL_2:
for ( i = 0; ; i += 2 )
{
if ( i >= 0x58 )
goto LABEL_2;
if ( dword_6D48F0[4 * i] == opcode_team[ei_p] )// opcode_team存在于内存中的伪机器码(指令)
break;
}
dispatcher[i](); // 模拟一个CPU不断的去执行指令(其实就是根据opcode去执行一些模拟汇编的一些函数)
}
}
int __cdecl main(int argc, const char **argv, const char **envp)
{
unsigned int i; // [esp+10h] [ebp-8h]
sub_6914F0();
while ( 1 )
{
LABEL_2:
for ( i = 0; ; i += 2 )
{
if ( i >= 0x58 )
goto LABEL_2;
if ( dword_6D48F0[4 * i] == opcode_team[ei_p] )// opcode_team存在于内存中的伪机器码(指令)
break;
}
dispatcher[i](); // 模拟一个CPU不断的去执行指令(其实就是根据opcode去执行一些模拟汇编的一些函数)
}
}
opcode_team = [0x01, 0x03, 0x03, 0x05, 0x00, 0x00, 0x11, 0x00, 0x00, 0x01, 0x01, 0x11, 0x0C, 0x00, 0x01, 0x0D, 0x0A, 0x00, 0x01, 0x03, 0x01, 0x05, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x01, 0x02, 0x00, 0x01, 0x00, 0x11, 0x0C, 0x00, 0x02, 0x0D, 0x2B, 0x00, 0x14, 0x00, 0x02, 0x01, 0x01, 0x61, 0x0C, 0x00, 0x01, 0x10, 0x1A, 0x00, 0x01, 0x01, 0x7A, 0x0C, 0x00, 0x01, 0x0F, 0x1A, 0x00, 0x01, 0x01, 0x47, 0x0A, 0x00, 0x01, 0x01, 0x01, 0x01, 0x06, 0x00, 0x01, 0x0B, 0x24, 0x00, 0x01, 0x01, 0x41, 0x0C, 0x00, 0x01, 0x10, 0x24, 0x00, 0x01, 0x01, 0x5A, 0x0C, 0x00, 0x01, 0x0F, 0x24, 0x00, 0x01, 0x01, 0x4B, 0x0A, 0x00, 0x01, 0x01, 0x01, 0x01, 0x07, 0x00, 0x01, 0x01, 0x01, 0x10, 0x09, 0x00, 0x01, 0x03, 0x01, 0x00, 0x03, 0x00, 0x00, 0x01, 0x01, 0x01, 0x06, 0x02, 0x01, 0x0B, 0x0B, 0x00, 0x02, 0x07, 0x00, 0x02, 0x0D, 0x00, 0x02, 0x00, 0x00, 0x02, 0x05, 0x00, 0x02, 0x01, 0x00, 0x02, 0x0C, 0x00, 0x02, 0x01, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x0D, 0x00, 0x02, 0x05, 0x00, 0x02, 0x0F, 0x00, 0x02, 0x00, 0x00, 0x02, 0x09, 0x00, 0x02, 0x05, 0x00, 0x02, 0x0F, 0x00, 0x02, 0x03, 0x00, 0x02, 0x00, 0x00, 0x02, 0x02, 0x00, 0x02, 0x05, 0x00, 0x02, 0x03, 0x00, 0x02, 0x03, 0x00, 0x02, 0x01, 0x00, 0x02, 0x07, 0x00, 0x02, 0x07, 0x00, 0x02, 0x0B, 0x00, 0x02, 0x02, 0x00, 0x02, 0x01, 0x00, 0x02, 0x02, 0x00, 0x02, 0x07, 0x00, 0x02, 0x02, 0x00, 0x02, 0x0C, 0x00, 0x02, 0x02, 0x00, 0x02, 0x02, 0x00, 0x01, 0x02, 0x01, 0x13, 0x01, 0x02, 0x04, 0x00, 0x00, 0x0C, 0x00, 0x01, 0x0E, 0x5B, 0x00, 0x01, 0x01, 0x22, 0x0C, 0x02, 0x01, 0x0D, 0x59, 0x00, 0x01, 0x01, 0x01, 0x06, 0x02, 0x01, 0x0B, 0x4E, 0x00, 0x01, 0x03, 0x00, 0x05, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x01, 0x03, 0x01, 0x05, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00]
opcode_key = {
0: 'nop',
1: 'mov reg data',
2: 'push data',
3: 'push_reg',
4: 'pop_reg',
5: 'printf',
6: 'add_reg_reg1',
7: 'sub_reg_reg1',
8: 'mul',
9: 'div',
10: 'xor',
11: 'jmp',
12: 'cmp',
13: 'je',
14: 'jne',
15: 'jg',
16: 'jl',
17: 'scanf_strlen',
18: 'mem_init',
19: 'stack_to_reg',
20: 'load_input',
0xff: 'exit'}
count = 0
code_index = 1
for x in opcode_team:
if count % 3 == 0:
print(str(code_index)+':', end='')
print(opcode_key[x], end=' ')
code_index += 1
elif count % 3 == 1:
print(str(x)+',', end=' ')
else:
print(str(x))
count += 1
opcode_team = [0x01, 0x03, 0x03, 0x05, 0x00, 0x00, 0x11, 0x00, 0x00, 0x01, 0x01, 0x11, 0x0C, 0x00, 0x01, 0x0D, 0x0A, 0x00, 0x01, 0x03, 0x01, 0x05, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x01, 0x02, 0x00, 0x01, 0x00, 0x11, 0x0C, 0x00, 0x02, 0x0D, 0x2B, 0x00, 0x14, 0x00, 0x02, 0x01, 0x01, 0x61, 0x0C, 0x00, 0x01, 0x10, 0x1A, 0x00, 0x01, 0x01, 0x7A, 0x0C, 0x00, 0x01, 0x0F, 0x1A, 0x00, 0x01, 0x01, 0x47, 0x0A, 0x00, 0x01, 0x01, 0x01, 0x01, 0x06, 0x00, 0x01, 0x0B, 0x24, 0x00, 0x01, 0x01, 0x41, 0x0C, 0x00, 0x01, 0x10, 0x24, 0x00, 0x01, 0x01, 0x5A, 0x0C, 0x00, 0x01, 0x0F, 0x24, 0x00, 0x01, 0x01, 0x4B, 0x0A, 0x00, 0x01, 0x01, 0x01, 0x01, 0x07, 0x00, 0x01, 0x01, 0x01, 0x10, 0x09, 0x00, 0x01, 0x03, 0x01, 0x00, 0x03, 0x00, 0x00, 0x01, 0x01, 0x01, 0x06, 0x02, 0x01, 0x0B, 0x0B, 0x00, 0x02, 0x07, 0x00, 0x02, 0x0D, 0x00, 0x02, 0x00, 0x00, 0x02, 0x05, 0x00, 0x02, 0x01, 0x00, 0x02, 0x0C, 0x00, 0x02, 0x01, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x0D, 0x00, 0x02, 0x05, 0x00, 0x02, 0x0F, 0x00, 0x02, 0x00, 0x00, 0x02, 0x09, 0x00, 0x02, 0x05, 0x00, 0x02, 0x0F, 0x00, 0x02, 0x03, 0x00, 0x02, 0x00, 0x00, 0x02, 0x02, 0x00, 0x02, 0x05, 0x00, 0x02, 0x03, 0x00, 0x02, 0x03, 0x00, 0x02, 0x01, 0x00, 0x02, 0x07, 0x00, 0x02, 0x07, 0x00, 0x02, 0x0B, 0x00, 0x02, 0x02, 0x00, 0x02, 0x01, 0x00, 0x02, 0x02, 0x00, 0x02, 0x07, 0x00, 0x02, 0x02, 0x00, 0x02, 0x0C, 0x00, 0x02, 0x02, 0x00, 0x02, 0x02, 0x00, 0x01, 0x02, 0x01, 0x13, 0x01, 0x02, 0x04, 0x00, 0x00, 0x0C, 0x00, 0x01, 0x0E, 0x5B, 0x00, 0x01, 0x01, 0x22, 0x0C, 0x02, 0x01, 0x0D, 0x59, 0x00, 0x01, 0x01, 0x01, 0x06, 0x02, 0x01, 0x0B, 0x4E, 0x00, 0x01, 0x03, 0x00, 0x05, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x01, 0x03, 0x01, 0x05, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00]
opcode_key = {
0: 'nop',
1: 'mov reg data',
2: 'push data',
3: 'push_reg',
4: 'pop_reg',
5: 'printf',
6: 'add_reg_reg1',
7: 'sub_reg_reg1',
8: 'mul',
9: 'div',
10: 'xor',
11: 'jmp',
12: 'cmp',
13: 'je',
14: 'jne',
15: 'jg',
16: 'jl',
17: 'scanf_strlen',
18: 'mem_init',
19: 'stack_to_reg',
20: 'load_input',
0xff: 'exit'}
count = 0
code_index = 1
for x in opcode_team:
if count % 3 == 0:
print(str(code_index)+':', end='')
print(opcode_key[x], end=' ')
code_index += 1
elif count % 3 == 1:
print(str(x)+',', end=' ')
else:
print(str(x))
count += 1
//打印出来的结果如下
1:mov reg data 3, 3
2:printf 0, 0
3:scanf_strlen 0, 0
4:mov reg data 1, 17
5:cmp 0, 1
6:je 10, 0
7:mov reg data 3, 1
8:printf 0, 0
9:exit 0, 0
10:mov reg data 2, 0
11:mov reg data 0, 17
12:cmp 0, 2
13:je 43, 0
14:load_input 0, 2
15:mov reg data 1, 97
16:cmp 0, 1
17:jl 26, 0
18:mov reg data 1, 122
19:cmp 0, 1
20:jg 26, 0
21:mov reg data 1, 71
22:xor 0, 1
23:mov reg data 1, 1
24:add_reg_reg1 0, 1
25:jmp 36, 0
26:mov reg data 1, 65
27:cmp 0, 1
28:jl 36, 0
29:mov reg data 1, 90
30:cmp 0, 1
31:jg 36, 0
32:mov reg data 1, 75
33:xor 0, 1
34:mov reg data 1, 1
35:sub_reg_reg1 0, 1
36:mov reg data 1, 16
37:div 0, 1
38:push_reg 1, 0
39:push_reg 0, 0
40:mov reg data 1, 1
41:add_reg_reg1 2, 1
42:jmp 11, 0
43:push data 7, 0
44:push data 13, 0
45:push data 0, 0
46:push data 5, 0
47:push data 1, 0
48:push data 12, 0
49:push data 1, 0
50:push data 0, 0
51:push data 0, 0
52:push data 13, 0
53:push data 5, 0
54:push data 15, 0
55:push data 0, 0
56:push data 9, 0
57:push data 5, 0
58:push data 15, 0
59:push data 3, 0
60:push data 0, 0
61:push data 2, 0
62:push data 5, 0
63:push data 3, 0
64:push data 3, 0
65:push data 1, 0
66:push data 7, 0
67:push data 7, 0
68:push data 11, 0
69:push data 2, 0
70:push data 1, 0
71:push data 2, 0
72:push data 7, 0
73:push data 2, 0
74:push data 12, 0
75:push data 2, 0
76:push data 2, 0
77:mov reg data 2, 1
78:stack_to_reg 1, 2
79:pop_reg 0, 0
80:cmp 0, 1
81:jne 91, 0
82:mov reg data 1, 34
83:cmp 2, 1
84:je 89, 0
85:mov reg data 1, 1
86:add_reg_reg1 2, 1
87:jmp 78, 0
88:mov reg data 3, 0
89:printf 0, 0
90:exit 0, 0
91:mov reg data 3, 1
92:printf 0, 0
93:exit 0, 0
94:nop
//打印出来的结果如下
1:mov reg data 3, 3
2:printf 0, 0
3:scanf_strlen 0, 0
4:mov reg data 1, 17
5:cmp 0, 1
6:je 10, 0
7:mov reg data 3, 1
8:printf 0, 0
9:exit 0, 0
10:mov reg data 2, 0
11:mov reg data 0, 17
12:cmp 0, 2
13:je 43, 0
14:load_input 0, 2
15:mov reg data 1, 97
16:cmp 0, 1
17:jl 26, 0
18:mov reg data 1, 122
19:cmp 0, 1
20:jg 26, 0
21:mov reg data 1, 71
22:xor 0, 1
23:mov reg data 1, 1
24:add_reg_reg1 0, 1
25:jmp 36, 0
26:mov reg data 1, 65
27:cmp 0, 1
28:jl 36, 0
29:mov reg data 1, 90
30:cmp 0, 1
31:jg 36, 0
32:mov reg data 1, 75
33:xor 0, 1
34:mov reg data 1, 1
[培训]传播安全知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2021-7-29 11:52
被SYJ-Re编辑
,原因: