简单的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的栈,寄存器,全局变量(多是字符串)等
参考资料:
https://www.bilibili.com/video/BV1Nv411k7HJ
https://blog.csdn.net/weixin_43876357/article/details/108488762
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
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
最后于 2021-7-29 11:52
被SYJ-Re编辑
,原因: