-
Notifications
You must be signed in to change notification settings - Fork 0
/
vm86.inc
179 lines (172 loc) · 4.65 KB
/
vm86.inc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
_GENERAL_FAULT = 00DH
_vm86_monitor:
; in: [esp+4H] - last retframe
; out: cf - set if the fault was not caused by a sensitive instruction (cli/sti/pushf/popf/iret/int) or for hlt
lea esi, [esp+4H]
movzx eax, word [esi+_x86_register.eip]
movzx ebx, word [esi+_x86_register.cs]
_real_segment edx, ebx:eax
mov ebp, ebx
mov ebx, edx
movzx eax, word [esi+_x86_register.esp]
movzx edi, word [esi+_x86_register.ss]
_real_segment edi, edi:eax
xor edx, edx
cmp dword [esi+_x86_register.trap], _GENERAL_FAULT
jnz _vm86_monitor_examine
xor ecx, ecx
mov cl, 010H
_vm86_monitor_loop:
call _vm86_monitor_prefix
jnc _vm86_monitor_examine
cmp byte [ebx], _OPERAND_SIZE
jnz _vm86_monitor_update
mov dl, (not 0H)
_vm86_monitor_update:
inc ebx
loop _vm86_monitor_loop
_vm86_monitor_examine:
push _vm86_monitor_ip
cmp dword [esi+_x86_register.trap], _GENERAL_FAULT
jnz _vm86_monitor_int
cmp byte [ebx], _PUSHF
jz _vm86_monitor_pushf
cmp byte [ebx], _POPF
jz _vm86_monitor_popf
cmp byte [ebx], _INT
jz _vm86_monitor_int
cmp byte [ebx], _IRET
jz _vm86_monitor_iret
cmp byte [ebx], _STI
jz _vm86_monitor_sti
cmp byte [ebx], _CLI
jz _vm86_monitor_cli
cmp byte [ebx], _HLT
jz _vm86_monitor_hlt
pop eax
stc
jmp _vm86_monitor_exit
_vm86_monitor_ip:
sub ebx, ebp
mov dword [esi+_x86_register.eip], ebx
clc
_vm86_monitor_exit:
ret
_vm86_monitor_prefix:
irp _prefix*, _REP,_REPNZ,_CS,_DS,_ES,_SS,_FS,_GS,_LOCK,_OPERAND_SIZE,_ADDRESS_SIZE
{
cmp byte [ebx], _prefix
jz _convert_zero_carry
}
clc
ret
_vm86_monitor_pushf:
inc ebx
mov eax, dword [esi+_x86_register.eflags]
test eax, _EFLAGS_VIF
jz _vm86_monitor_pushf_size
or eax, _EFLAGS_IF
_vm86_monitor_pushf_size:
and eax, (not (_EFLAGS_VM or _EFLAGS_RF))
or eax, (011B shl _EFLAGS_IOPL)
test dl, dl
jz _vm86_monitor_pushf_word
and eax, (not (_EFLAGS_VIF or _EFLAGS_VIP)) ; hide the fact that the real mode program run in a vm ;)
sub word [esi+_x86_register.esp], 4H
mov dword [edi-4H], eax
ret
_vm86_monitor_pushf_word:
sub word [esi+_x86_register.esp], 2H
mov word [edi-2H], ax
ret
_vm86_monitor_popf:
inc ebx
mov ecx, dword [esi+_x86_register.eflags]
and ecx, (_EFLAGS_VIP or _EFLAGS_IF)
test dl, dl
jz _vm86_monitor_popf_word
mov eax, dword [edi]
add word [esi+_x86_register.esp], 4H
jmp _vm86_monitor_popf_next
_vm86_monitor_popf_word:
movzx eax, word [edi]
add word [esi+_x86_register.esp], 2H
_vm86_monitor_popf_next:
and eax, (not (011B shl _EFLAGS_IOPL))
or eax, _EFLAGS_VM
test eax, _EFLAGS_IF
jz _vm86_monitor_popf_if
or eax, _EFLAGS_VIF
_vm86_monitor_popf_if:
or eax, ecx
mov dword [esi+_x86_register.eflags], eax
ret
_vm86_monitor_iret:
xor ebp, ebp
test dl, dl
jz _vm86_monitor_iret_word
mov eax, dword [edi]
mov bp, 4H
jmp _vm86_monitor_iret_next
_vm86_monitor_iret_word:
movzx eax, word [edi]
mov bp, 2H
_vm86_monitor_iret_next:
mov cx, word [edi+ebp]
mov dword [esi+_x86_register.eip], eax
mov word [esi+_x86_register.cs], cx
shl ebp, 1H
add word [esi+_x86_register.esp], bp
add edi, ebp
call _vm86_monitor_popf
mov dword [esp], _vm86_monitor_exit-1H
ret
_vm86_monitor_int:
xor dl, dl
call _vm86_monitor_pushf
mov dx, word [esi+_x86_register.cs]
mov word [edi-4H], dx
lea edx, [ebx+1H]
movzx eax, byte [ebx]
cmp dword [esi+_x86_register.trap], _GENERAL_FAULT
jz _vm86_monitor_int_compute
mov eax, dword [esi+_x86_register.trap]
sub edx, 2H
sub ebx, 2H
_vm86_monitor_int_compute:
sub edx, ebp
mov word [edi-6H], dx
movzx edx, word [eax*4H]
mov cx, word [eax*4H+2H]
mov word [esi+_x86_register.eip], dx
mov word [esi+_x86_register.cs], cx
sub word [esi+_x86_register.esp], 4H
mov dword [esp], _vm86_monitor_exit-1H
_vm86_monitor_cli:
inc ebx
mov eax, dword [esi+_x86_register.eflags]
test byte [_singleton.vme], 1H
jnz _vm86_monitor_cli_vme
mov edx, dword [_current]
xor al, al
mov byte [edx+_process.vif], al
ret
_vm86_monitor_cli_vme:
and eax, (not _EFLAGS_VIF)
mov dword [esi+_x86_register.eflags], eax
ret
_vm86_monitor_sti:
inc ebx
mov eax, dword [esi+_x86_register.eflags]
test byte [_singleton.vme], 1H
jnz _vm86_monitor_sti_vme
mov edx, dword [_current]
mov al, 1H
mov byte [edx+_process.vif], al
ret
_vm86_monitor_sti_vme:
or eax, _EFLAGS_VIF
mov dword [esi+_x86_register.eflags], eax
ret
_vm86_monitor_hlt:
jmp _execute_real_terminate