Rizin
unix-like reverse engineering framework and cli tools
asm_x86_cs.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2013-2019 pancake <pancake@nopcode.org>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include <rz_asm.h>
5 #include <rz_lib.h>
6 #include <capstone/capstone.h>
7 
8 static csh cd = 0;
9 static int n = 0;
10 
11 static bool the_end(void *p) {
12  if (cd) {
13  cs_close(&cd);
14  cd = 0;
15  }
16  return true;
17 }
18 
19 static int check_features(RzAsm *a, cs_insn *insn);
20 
21 #include "cs_mnemonics.c"
22 
23 #include "asm_x86_vm.c"
24 
25 static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
26  static int omode = 0;
27  int mode, ret;
28  ut64 off = a->pc;
29 
30  mode = (a->bits == 64) ? CS_MODE_64 : (a->bits == 32) ? CS_MODE_32
31  : (a->bits == 16) ? CS_MODE_16
32  : 0;
33  if (cd && mode != omode) {
34  cs_close(&cd);
35  cd = 0;
36  }
37  if (op) {
38  op->size = 0;
39  }
40  omode = mode;
41  if (cd == 0) {
42  ret = cs_open(CS_ARCH_X86, mode, &cd);
43  if (ret) {
44  return 0;
45  }
46  }
47  if (a->features && *a->features) {
49  } else {
51  }
52  // always unsigned immediates (kernel addresses)
53  // maybe rizin should have an option for this too?
54 #if CS_API_MAJOR >= 4
56 #endif
57  if (a->syntax == RZ_ASM_SYNTAX_MASM) {
58 #if CS_API_MAJOR >= 4
60 #endif
61  } else if (a->syntax == RZ_ASM_SYNTAX_ATT) {
63  } else {
65  }
66  if (!op) {
67  return true;
68  }
69  op->size = 1;
70  cs_insn *insn = NULL;
71  n = cs_disasm(cd, (const ut8 *)buf, len, off, 1, &insn);
72  if (op) {
73  op->size = 0;
74  }
75  if (a->features && *a->features) {
76  if (!check_features(a, insn)) {
77  op->size = insn->size;
78  rz_asm_op_set_asm(op, "illegal");
79  }
80  }
81  if (op->size == 0 && n > 0 && insn->size > 0) {
82  char *ptrstr;
83  op->size = insn->size;
84  char *buf_asm = sdb_fmt("%s%s%s",
85  insn->mnemonic, insn->op_str[0] ? " " : "",
86  insn->op_str);
87  ptrstr = strstr(buf_asm, "ptr ");
88  if (ptrstr) {
89  memmove(ptrstr, ptrstr + 4, strlen(ptrstr + 4) + 1);
90  }
91  rz_asm_op_set_asm(op, buf_asm);
92  } else {
93  decompile_vm(a, op, buf, len);
94  }
95  if (a->syntax == RZ_ASM_SYNTAX_JZ) {
96  char *buf_asm = rz_strbuf_get(&op->buf_asm);
97  if (!strncmp(buf_asm, "je ", 3)) {
98  memcpy(buf_asm, "jz", 2);
99  } else if (!strncmp(buf_asm, "jne ", 4)) {
100  memcpy(buf_asm, "jnz", 3);
101  }
102  }
103  if (insn) {
104  cs_free(insn, n);
105  }
106  return op->size;
107 }
108 
110  .name = "x86",
111  .desc = "Capstone X86 disassembler",
112  .license = "BSD",
113  .cpus = "generic",
114  .platforms = "generic",
115  .arch = "x86",
116  .bits = 16 | 32 | 64,
117  .endian = RZ_SYS_ENDIAN_LITTLE,
118  .fini = the_end,
119  .mnemonics = mnemonics,
120  .disassemble = &disassemble,
121  .features = "vm,3dnow,aes,adx,avx,avx2,avx512,bmi,bmi2,cmov,"
122  "f16c,fma,fma4,fsgsbase,hle,mmx,rtm,sha,sse1,sse2,"
123  "sse3,sse41,sse42,sse4a,ssse3,pclmul,xop"
124 };
125 
126 static int check_features(RzAsm *a, cs_insn *insn) {
127  const char *name;
128  int i;
129  if (!insn || !insn->detail) {
130  return 1;
131  }
132  for (i = 0; i < insn->detail->groups_count; i++) {
133  int id = insn->detail->groups[i];
134  if (id < 128) {
135  continue;
136  }
137  if (id == X86_GRP_MODE32) {
138  continue;
139  }
140  if (id == X86_GRP_MODE64) {
141  continue;
142  }
143  name = cs_group_name(cd, id);
144  if (!name) {
145  return 1;
146  }
147  if (!strstr(a->features, name)) {
148  return 0;
149  }
150  }
151  return 1;
152 }
153 
154 #ifndef RZ_PLUGIN_INCORE
157  .data = &rz_asm_plugin_x86_cs,
159 };
160 #endif
size_t len
Definition: 6502dis.c:15
RZ_API void rz_asm_op_set_asm(RzAsmOp *op, const char *str)
Definition: aop.c:53
lzma_index ** i
Definition: index.h:629
static int n
Definition: asm_x86_cs.c:9
RZ_API RzLibStruct rizin_plugin
Definition: asm_x86_cs.c:155
RzAsmPlugin rz_asm_plugin_x86_cs
Definition: asm_x86_cs.c:109
static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len)
Definition: asm_x86_cs.c:25
static csh cd
Definition: asm_x86_cs.c:8
static bool the_end(void *p)
Definition: asm_x86_cs.c:11
static int check_features(RzAsm *a, cs_insn *insn)
Definition: asm_x86_cs.c:126
void decompile_vm(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len)
Definition: asm_x86_vm.c:31
@ CS_ARCH_X86
X86 architecture (including x86 & x86-64)
Definition: capstone.h:78
@ CS_MODE_64
64-bit mode (X86, PPC)
Definition: capstone.h:107
@ CS_MODE_32
32-bit mode (X86)
Definition: capstone.h:106
@ CS_MODE_16
16-bit mode (X86)
Definition: capstone.h:105
@ CS_OPT_UNSIGNED
print immediate operands in unsigned form
Definition: capstone.h:177
@ CS_OPT_DETAIL
Break down instruction structure into details.
Definition: capstone.h:171
@ CS_OPT_SYNTAX
Assembly output syntax.
Definition: capstone.h:170
size_t csh
Definition: capstone.h:71
@ CS_OPT_SYNTAX_INTEL
X86 Intel asm syntax - default on X86 (CS_OPT_SYNTAX).
Definition: capstone.h:185
@ CS_OPT_SYNTAX_ATT
X86 ATT asm syntax (CS_OPT_SYNTAX).
Definition: capstone.h:186
@ CS_OPT_ON
Turn ON an option (CS_OPT_DETAIL, CS_OPT_SKIPDATA).
Definition: capstone.h:183
@ CS_OPT_SYNTAX_MASM
X86 Intel Masm syntax (CS_OPT_SYNTAX).
Definition: capstone.h:188
@ CS_OPT_OFF
Turn OFF an option - default for CS_OPT_DETAIL, CS_OPT_SKIPDATA, CS_OPT_UNSIGNED.
Definition: capstone.h:182
@ X86_GRP_MODE64
Definition: x86.h:1939
@ X86_GRP_MODE32
Definition: x86.h:1938
#define RZ_API
#define NULL
Definition: cris-opc.c:27
CAPSTONE_EXPORT size_t CAPSTONE_API cs_disasm(csh ud, const uint8_t *buffer, size_t size, uint64_t offset, size_t count, cs_insn **insn)
Definition: cs.c:798
CAPSTONE_EXPORT const char *CAPSTONE_API cs_group_name(csh ud, unsigned int group)
Definition: cs.c:1178
CAPSTONE_EXPORT cs_err CAPSTONE_API cs_open(cs_arch arch, cs_mode mode, csh *handle)
Definition: cs.c:453
CAPSTONE_EXPORT void CAPSTONE_API cs_free(cs_insn *insn, size_t count)
Definition: cs.c:1017
CAPSTONE_EXPORT cs_err CAPSTONE_API cs_close(csh *handle)
Definition: cs.c:501
CAPSTONE_EXPORT cs_err CAPSTONE_API cs_option(csh ud, cs_opt_type type, size_t value)
Definition: cs.c:646
RZ_API char * sdb_fmt(const char *fmt,...)
Definition: fmt.c:26
const char int mode
Definition: ioapi.h:137
voidpf void * buf
Definition: ioapi.h:138
uint8_t ut8
Definition: lh5801.h:11
void * p
Definition: libc.cpp:67
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
const char * name
Definition: op.c:541
int off
Definition: pal.c:13
@ RZ_ASM_SYNTAX_ATT
Definition: rz_asm.h:51
@ RZ_ASM_SYNTAX_MASM
Definition: rz_asm.h:52
@ RZ_ASM_SYNTAX_JZ
Definition: rz_asm.h:54
@ RZ_LIB_TYPE_ASM
Definition: rz_lib.h:72
RZ_API char * rz_strbuf_get(RzStrBuf *sb)
Definition: strbuf.c:321
#define RZ_SYS_ENDIAN_LITTLE
Definition: rz_types.h:526
#define RZ_VERSION
Definition: rz_version.h:8
#define a(i)
Definition: sha256.c:41
Definition: z80asm.h:102
const char * name
Definition: rz_asm.h:130
const char * version
Definition: rz_asm.h:133
Definition: dis.c:32
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
static const char * mnemonics[]
Definition: z80asm.c:43