Rizin
unix-like reverse engineering framework and cli tools
asm_x86_vm.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2018 deroad <wargio@libero.it>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 /*
5  "Missing" vm ops:
6 
7  0F 01 C0 vmxoff
8  0F 01 C1 vmcall
9  0F 01 C2 vmlaunch
10  0F 01 C3 vmresume
11  0F 01 C4 vmxon
12  0F 78 /r vmread r/m32,r32
13  0F 79 /r vmwrite r32,r/m32
14  0F C7 /6 m64 vmptrld m64
15  0F C7 /7 m64 vmptrst m64
16  66 0F C7 /6 m64 vmclear m64
17  0F A6 /r xbts r32,r/m32
18  0F A7 /r ibts r/m32,r32
19  0F 37 getsec
20  F0 FA clx
21  F0 FB stx
22  ? smret
23  ? smcall
24  ? skinit
25  ? stgi
26 
27 */
28 
29 #define VPCEXT2(y, x) ((y)[2] == (x))
30 
31 void decompile_vm(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
32  const char *buf_asm = "invalid";
33  if (len > 3 && buf[0] == 0x0F && buf[1] == 0x3F && (VPCEXT2(buf, 0x01) || VPCEXT2(buf, 0x05) || VPCEXT2(buf, 0x07) || VPCEXT2(buf, 0x0D) || VPCEXT2(buf, 0x10))) {
34  if (a->syntax == RZ_ASM_SYNTAX_ATT) {
35  buf_asm = sdb_fmt("vpcext $0x%x, $0x%x", buf[3], buf[2]);
36  } else {
37  buf_asm = sdb_fmt("vpcext %xh, %xh", buf[2], buf[3]);
38  }
39  op->size = 4;
40  } else if (len > 4 && buf[0] == 0x0F && buf[1] == 0xC6 && buf[2] == 0x28 && buf[3] == 0x00 && buf[4] == 0x00) {
41  /* 0F C6 28 00 00 vmgetinfo */
42  buf_asm = "vmgetinfo";
43  op->size = 5;
44  } else if (len > 4 && buf[0] == 0x0F && buf[1] == 0xC6 && buf[2] == 0x28 && buf[3] == 0x00 && buf[4] == 0x01) {
45  /* 0F C6 28 00 01 vmsetinfo */
46  buf_asm = "vmsetinfo";
47  op->size = 5;
48  } else if (len > 4 && buf[0] == 0x0F && buf[1] == 0xC6 && buf[2] == 0x28 && buf[3] == 0x00 && buf[4] == 0x02) {
49  /* 0F C6 28 00 02 vmdxdsbl */
50  buf_asm = "vmdxdsbl";
51  op->size = 5;
52  } else if (len > 4 && buf[0] == 0x0F && buf[1] == 0xC6 && buf[2] == 0x28 && buf[3] == 0x00 && buf[4] == 0x03) {
53  /* 0F C6 28 00 03 vmdxenbl */
54  buf_asm = "vmdxenbl";
55  op->size = 5;
56  } else if (len > 4 && buf[0] == 0x0F && buf[1] == 0xC6 && buf[2] == 0x28 && buf[3] == 0x01 && buf[4] == 0x00) {
57  /* 0F C6 28 01 00 vmcpuid */
58  buf_asm = "vmcpuid";
59  op->size = 5;
60  } else if (len > 4 && buf[0] == 0x0F && buf[1] == 0xC6 && buf[2] == 0x28 && buf[3] == 0x01 && buf[4] == 0x01) {
61  /* 0F C6 28 01 01 vmhlt */
62  buf_asm = "vmhlt";
63  op->size = 5;
64  } else if (len > 4 && buf[0] == 0x0F && buf[1] == 0xC6 && buf[2] == 0x28 && buf[3] == 0x01 && buf[4] == 0x02) {
65  /* 0F C6 28 01 02 vmsplaf */
66  buf_asm = "vmsplaf";
67  op->size = 5;
68  } else if (len > 4 && buf[0] == 0x0F && buf[1] == 0xC6 && buf[2] == 0x28 && buf[3] == 0x02 && buf[4] == 0x00) {
69  /* 0F C6 28 02 00 vmpushfd */
70  buf_asm = "vmpushfd";
71  op->size = 5;
72  } else if (len > 4 && buf[0] == 0x0F && buf[1] == 0xC6 && buf[2] == 0x28 && buf[3] == 0x02 && buf[4] == 0x01) {
73  /* 0F C6 28 02 01 vmpopfd */
74  buf_asm = "vmpopfd";
75  op->size = 5;
76  } else if (len > 4 && buf[0] == 0x0F && buf[1] == 0xC6 && buf[2] == 0x28 && buf[3] == 0x02 && buf[4] == 0x02) {
77  /* 0F C6 28 02 02 vmcli */
78  buf_asm = "vmcli";
79  op->size = 5;
80  } else if (len > 4 && buf[0] == 0x0F && buf[1] == 0xC6 && buf[2] == 0x28 && buf[3] == 0x02 && buf[4] == 0x03) {
81  /* 0F C6 28 02 03 vmsti */
82  buf_asm = "vmsti";
83  op->size = 5;
84  } else if (len > 4 && buf[0] == 0x0F && buf[1] == 0xC6 && buf[2] == 0x28 && buf[3] == 0x02 && buf[4] == 0x04) {
85  /* 0F C6 28 02 04 vmiretd */
86  buf_asm = "vmiretd";
87  op->size = 5;
88  } else if (len > 4 && buf[0] == 0x0F && buf[1] == 0xC6 && buf[2] == 0x28 && buf[3] == 0x03 && buf[4] == 0x00) {
89  /* 0F C6 28 03 00 vmsgdt */
90  buf_asm = "vmsgdt";
91  op->size = 5;
92  } else if (len > 4 && buf[0] == 0x0F && buf[1] == 0xC6 && buf[2] == 0x28 && buf[3] == 0x03 && buf[4] == 0x01) {
93  /* 0F C6 28 03 01 vmsidt */
94  buf_asm = "vmsidt";
95  op->size = 5;
96  } else if (len > 4 && buf[0] == 0x0F && buf[1] == 0xC6 && buf[2] == 0x28 && buf[3] == 0x03 && buf[4] == 0x02) {
97  /* 0F C6 28 03 02 vmsldt */
98  buf_asm = "vmsldt";
99  op->size = 5;
100  } else if (len > 4 && buf[0] == 0x0F && buf[1] == 0xC6 && buf[2] == 0x28 && buf[3] == 0x03 && buf[4] == 0x03) {
101  /* 0F C6 28 03 03 vmstr */
102  buf_asm = "vmstr";
103  op->size = 5;
104  } else if (len > 4 && buf[0] == 0x0F && buf[1] == 0xC6 && buf[2] == 0x28 && buf[3] == 0x04 && buf[4] == 0x00) {
105  /* 0F C6 28 04 00 vmsdte */
106  buf_asm = "vmsdte";
107  op->size = 5;
108  }
109  rz_asm_op_set_asm(op, buf_asm);
110 }
111 
112 #undef VPCEXT2
size_t len
Definition: 6502dis.c:15
RZ_API void rz_asm_op_set_asm(RzAsmOp *op, const char *str)
Definition: aop.c:53
void decompile_vm(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len)
Definition: asm_x86_vm.c:31
#define VPCEXT2(y, x)
Definition: asm_x86_vm.c:29
RZ_API char * sdb_fmt(const char *fmt,...)
Definition: fmt.c:26
voidpf void * buf
Definition: ioapi.h:138
uint8_t ut8
Definition: lh5801.h:11
@ RZ_ASM_SYNTAX_ATT
Definition: rz_asm.h:51
#define a(i)
Definition: sha256.c:41
Definition: dis.c:32