Rizin
unix-like reverse engineering framework and cli tools
analysis_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_analysis.h>
5 #include <rz_lib.h>
6 #include <capstone/capstone.h>
7 #include <capstone/x86.h>
8 
9 #if 0
10 CYCLES:
11 ======
12 register access = 1
13 memory access = 2
14 jump = 3
15 call = 4
16 #endif
17 
18 #define CYCLE_REG 0
19 #define CYCLE_MEM 1
20 #define CYCLE_JMP 2
21 
22 // TODO: when capstone-4 is released, add proper check here
23 
24 #if CS_NEXT_VERSION > 0
25 #define HAVE_CSGRP_PRIVILEGE 1
26 #else
27 #define HAVE_CSGRP_PRIVILEGE 0
28 #endif
29 
30 #if CS_API_MAJOR < 2
31 #error Old Capstone not supported
32 #endif
33 
34 #define opexprintf(op, fmt, ...) rz_strbuf_setf(&op->opex, fmt, ##__VA_ARGS__)
35 #define INSOP(n) insn->detail->x86.operands[n]
36 #define INSOPS insn->detail->x86.op_count
37 #define ISIMM(x) insn->detail->x86.operands[x].type == X86_OP_IMM
38 #define ISMEM(x) insn->detail->x86.operands[x].type == X86_OP_MEM
39 
40 #define BUF_SZ 64
41 
42 #define AR_DIM 4
43 
44 #define SRC_AR 0
45 #define DST_AR 1
46 #define DST_R_AR 1
47 #define DST_W_AR 2
48 #define SRC2_AR 2
49 #define DST2_AR 2
50 #define DSTADD_AR 3
51 #define ARG0_AR 0
52 #define ARG1_AR 1
53 #define ARG2_AR 2
54 
55 typedef struct x86_cs_context_t {
57  int omode;
58  cs_insn *insn;
60 
61 struct Getarg {
62  csh handle;
63  cs_insn *insn;
64  int bits;
65 };
66 
67 static void hidden_op(cs_insn *insn, cs_x86 *x, int mode) {
68  unsigned int id = insn->id;
69  int regsz = 4;
70  switch (mode) {
71  case CS_MODE_64:
72  regsz = 8;
73  break;
74  case CS_MODE_16:
75  regsz = 2;
76  break;
77  default:
78  regsz = 4; // 32 bit
79  break;
80  }
81 
82  switch (id) {
83  case X86_INS_PUSHF:
84  case X86_INS_POPF:
85  case X86_INS_PUSHFD:
86  case X86_INS_POPFD:
87  case X86_INS_PUSHFQ:
88  case X86_INS_POPFQ:
89  x->op_count = 1;
90  cs_x86_op *op = &x->operands[0];
91  op->type = X86_OP_REG;
92  op->reg = X86_REG_EFLAGS;
93  op->size = regsz;
94 #if CS_API_MAJOR >= 4
95  if (id == X86_INS_PUSHF || id == X86_INS_PUSHFD || id == X86_INS_PUSHFQ) {
96  op->access = 1;
97  } else {
98  op->access = 2;
99  }
100 #endif
101  break;
102  case X86_INS_PUSHAW:
103  case X86_INS_PUSHAL:
104  case X86_INS_POPAW:
105  case X86_INS_POPAL:
106  default:
107  break;
108  }
109 }
110 
111 static void opex(RzStrBuf *buf, X86CSContext *ctx, int mode) {
112  cs_insn *insn = ctx->insn;
113  int i;
114  PJ *pj = pj_new();
115  if (!pj) {
116  return;
117  }
118  pj_o(pj);
119  cs_x86 *x = &insn->detail->x86;
120  if (x->op_count == 0) {
121  hidden_op(insn, x, mode);
122  }
123  pj_ka(pj, "operands");
124  for (i = 0; i < x->op_count; i++) {
125  cs_x86_op *op = x->operands + i;
126  pj_o(pj);
127  pj_ki(pj, "size", op->size);
128 #if CS_API_MAJOR >= 4
129  pj_ki(pj, "rw", op->access); // read, write, read|write
130 #endif
131  switch (op->type) {
132  case X86_OP_REG:
133  pj_ks(pj, "type", "reg");
134  pj_ks(pj, "value", cs_reg_name(ctx->handle, op->reg));
135  break;
136  case X86_OP_IMM:
137  pj_ks(pj, "type", "imm");
138  pj_kN(pj, "value", op->imm);
139  break;
140  case X86_OP_MEM:
141  pj_ks(pj, "type", "mem");
142  if (op->mem.segment != X86_REG_INVALID) {
143  pj_ks(pj, "segment", cs_reg_name(ctx->handle, op->mem.segment));
144  }
145  if (op->mem.base != X86_REG_INVALID) {
146  pj_ks(pj, "base", cs_reg_name(ctx->handle, op->mem.base));
147  }
148  if (op->mem.index != X86_REG_INVALID) {
149  pj_ks(pj, "index", cs_reg_name(ctx->handle, op->mem.index));
150  }
151  pj_ki(pj, "scale", op->mem.scale);
152  pj_kN(pj, "disp", op->mem.disp);
153  break;
154  default:
155  pj_ks(pj, "type", "invalid");
156  break;
157  }
158  pj_end(pj); /* o operand */
159  }
160  pj_end(pj); /* a operands */
161  if (x->rex) {
162  pj_kb(pj, "rex", true);
163  }
164  if (x->modrm) {
165  pj_kb(pj, "modrm", true);
166  }
167  if (x->sib) {
168  pj_ki(pj, "sib", x->sib);
169  }
170  if (x->disp) {
171  pj_kN(pj, "disp", x->disp);
172  }
173  if (x->sib_index != X86_REG_INVALID) {
174  pj_ki(pj, "sib_scale", x->sib_scale);
175  pj_ks(pj, "sib_index", cs_reg_name(ctx->handle, x->sib_index));
176  }
177  if (x->sib_base != X86_REG_INVALID) {
178  pj_ks(pj, "sib_base", cs_reg_name(ctx->handle, x->sib_base));
179  }
180  pj_end(pj);
181 
184  pj_free(pj);
185 }
186 
187 static bool is_xmm_reg(cs_x86_op op) {
188  switch (op.reg) {
189  case X86_REG_XMM0:
190  case X86_REG_XMM1:
191  case X86_REG_XMM2:
192  case X86_REG_XMM3:
193  case X86_REG_XMM4:
194  case X86_REG_XMM5:
195  case X86_REG_XMM6:
196  case X86_REG_XMM7:
197  case X86_REG_XMM8:
198  case X86_REG_XMM9:
199  case X86_REG_XMM10:
200  case X86_REG_XMM11:
201  case X86_REG_XMM12:
202  case X86_REG_XMM13:
203  case X86_REG_XMM14:
204  case X86_REG_XMM15:
205  case X86_REG_XMM16:
206  case X86_REG_XMM17:
207  case X86_REG_XMM18:
208  case X86_REG_XMM19:
209  case X86_REG_XMM20:
210  case X86_REG_XMM21:
211  case X86_REG_XMM22:
212  case X86_REG_XMM23:
213  case X86_REG_XMM24:
214  case X86_REG_XMM25:
215  case X86_REG_XMM26:
216  case X86_REG_XMM27:
217  case X86_REG_XMM28:
218  case X86_REG_XMM29:
219  case X86_REG_XMM30:
220  case X86_REG_XMM31: return true;
221  default: return false;
222  }
223 }
224 
236 static char *getarg(struct Getarg *gop, int n, int set, char *setop, int sel, ut32 *bitsize) {
237  static char buf[AR_DIM][BUF_SZ];
238  char *out = buf[sel];
239  char *setarg = setop ? setop : "";
240  cs_insn *insn = gop->insn;
241  csh handle = gop->handle;
242  cs_x86_op op;
243 
244  if (!insn->detail) {
245  return NULL;
246  }
247  if (n < 0 || n >= INSOPS) {
248  return NULL;
249  }
250  out[0] = 0;
251  op = INSOP(n);
252  if (bitsize) {
253  *bitsize = op.size * 8;
254  }
255  switch (op.type) {
256 #if CS_API_MAJOR == 3
257  case X86_OP_FP:
258  return "invalid";
259 #endif
260  case X86_OP_INVALID:
261  return "invalid";
262  case X86_OP_REG:
263  if (set == 1) {
264  snprintf(out, BUF_SZ, "%s,%s=",
265  cs_reg_name(handle, op.reg), setarg);
266  return out;
267  }
268  return (char *)cs_reg_name(handle, op.reg);
269  case X86_OP_IMM:
270  if (set == 1) {
271  snprintf(out, BUF_SZ, "%" PFMT64u ",%s=[%d]",
272  (ut64)op.imm, setarg, op.size);
273  return out;
274  }
275  snprintf(out, BUF_SZ, "%" PFMT64u, (ut64)op.imm);
276  return out;
277  case X86_OP_MEM: {
278  // address = (base + (index * scale) + offset)
279  char buf_[BUF_SZ] = { 0 };
280  int component_count = 0;
281  const char *base = cs_reg_name(handle, op.mem.base);
282  const char *index = cs_reg_name(handle, op.mem.index);
283  int scale = op.mem.scale;
284  st64 disp = op.mem.disp;
285 
286  if (disp != 0) {
287  snprintf(out, BUF_SZ, "0x%" PFMT64x ",", (disp < 0) ? -disp : disp);
288  component_count++;
289  }
290 
291  if (index) {
292  if (scale > 1) {
293  snprintf(buf_, BUF_SZ, "%s%s,%d,*,", out, index, scale);
294  } else {
295  snprintf(buf_, BUF_SZ, "%s%s,", out, index);
296  }
297  strncpy(out, buf_, BUF_SZ);
298  component_count++;
299  }
300 
301  if (base) {
302  snprintf(buf_, BUF_SZ, "%s%s,", out, base);
303  strncpy(out, buf_, BUF_SZ);
304  component_count++;
305  }
306 
307  if (component_count > 1) {
308  if (component_count > 2) {
309  snprintf(buf_, BUF_SZ, "%s+,", out);
310  strncpy(out, buf_, BUF_SZ);
311  }
312  if (disp < 0) {
313  snprintf(buf_, BUF_SZ, "%s-", out);
314  } else {
315  snprintf(buf_, BUF_SZ, "%s+", out);
316  }
317  strncpy(out, buf_, BUF_SZ);
318  } else {
319  // Remove the trailing ',' from esil statement.
320  if (*out) {
321  int out_len = strlen(out);
322  out[out_len > 0 ? out_len - 1 : 0] = 0;
323  }
324  }
325 
326  // set = 2 is reserved for lea, where the operand is a memory address,
327  // but the corresponding memory is not loaded.
328  if (set == 1) {
329  snprintf(buf_, BUF_SZ, "%s,%s=[%d]", out, setarg, op.size == 10 ? 8 : op.size);
330  strncpy(out, buf_, BUF_SZ);
331  } else if (set == 0) {
332  if (!*out) {
333  strcpy(out, "0");
334  }
335  snprintf(buf_, BUF_SZ, "%s,[%d]", out, op.size == 10 ? 8 : op.size);
336  strncpy(out, buf_, BUF_SZ);
337  }
338  out[BUF_SZ - 1] = 0;
339  }
340  return out;
341  }
342  return NULL;
343 }
344 
345 static int cond_x862r2(int id) {
346  switch (id) {
347  case X86_INS_JE:
348  return RZ_TYPE_COND_EQ;
349  case X86_INS_JNE:
350  return RZ_TYPE_COND_NE;
351  case X86_INS_JB:
352  case X86_INS_JL:
353  return RZ_TYPE_COND_LT;
354  case X86_INS_JBE:
355  case X86_INS_JLE:
356  return RZ_TYPE_COND_LE;
357  case X86_INS_JG:
358  case X86_INS_JA:
359  return RZ_TYPE_COND_GT;
360  case X86_INS_JAE:
361  return RZ_TYPE_COND_GE;
362  case X86_INS_JS:
363  case X86_INS_JNS:
364  case X86_INS_JO:
365  case X86_INS_JNO:
366  case X86_INS_JGE:
367  case X86_INS_JP:
368  case X86_INS_JNP:
369  case X86_INS_JCXZ:
370  case X86_INS_JECXZ:
371  break;
372  }
373  return 0;
374 }
375 
376 /* reg indices are based on Intel doc for 32-bit ModR/M byte */
377 static const char *reg32_to_name(ut8 reg) {
378  const char *const names[] = { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi" };
379  return reg < RZ_ARRAY_SIZE(names) ? names[reg] : "unk";
380 }
381 
382 static void anop_esil(RzAnalysis *a, RzAnalysisOp *op, ut64 addr, const ut8 *buf, int len, csh *handle, cs_insn *insn) {
383  int rs = a->bits / 8;
384  const char *pc = (a->bits == 16) ? "ip" : (a->bits == 32) ? "eip"
385  : "rip";
386  const char *sp = (a->bits == 16) ? "sp" : (a->bits == 32) ? "esp"
387  : "rsp";
388  const char *bp = (a->bits == 16) ? "bp" : (a->bits == 32) ? "ebp"
389  : "rbp";
390  const char *si = (a->bits == 16) ? "si" : (a->bits == 32) ? "esi"
391  : "rsi";
392  struct Getarg gop = {
393  .handle = *handle,
394  .insn = insn,
395  .bits = a->bits
396  };
397  char *src;
398  char *src2;
399  char *dst;
400  char *dst2;
401  char *dst_r;
402  char *dst_w;
403  char *dstAdd;
404  char *arg0;
405  char *arg1;
406  char *arg2;
407 
408  // counter for rep prefix
409  const char *counter = (a->bits == 16) ? "cx" : (a->bits == 32) ? "ecx"
410  : "rcx";
411 
412  if (op->prefix & RZ_ANALYSIS_OP_PREFIX_REP) {
413  esilprintf(op, "%s,!,?{,BREAK,},", counter);
414  }
415 
416  switch (insn->id) {
417  case X86_INS_FNOP:
418  case X86_INS_NOP:
419  case X86_INS_PAUSE:
420  esilprintf(op, ",");
421  break;
422  case X86_INS_HLT:
423  break;
424  case X86_INS_FBLD:
425  case X86_INS_FBSTP:
426  case X86_INS_FCOMPP:
427  case X86_INS_FDECSTP:
428  case X86_INS_FEMMS:
429  case X86_INS_FFREE:
430  case X86_INS_FICOM:
431  case X86_INS_FICOMP:
432  case X86_INS_FINCSTP:
433  case X86_INS_FNCLEX:
434  case X86_INS_FNINIT:
435  case X86_INS_FNSTCW:
436  case X86_INS_FNSTSW:
437  case X86_INS_FPATAN:
438  case X86_INS_FPREM:
439  case X86_INS_FPREM1:
440  case X86_INS_FPTAN:
441 #if CS_API_MAJOR >= 4
442  case X86_INS_FFREEP:
443 #endif
444  case X86_INS_FRNDINT:
445  case X86_INS_FRSTOR:
446  case X86_INS_FNSAVE:
447  case X86_INS_FSCALE:
448  case X86_INS_FSETPM:
449  case X86_INS_FSINCOS:
450  case X86_INS_FNSTENV:
451  case X86_INS_FXAM:
452  case X86_INS_FXSAVE:
453  case X86_INS_FXSAVE64:
454  case X86_INS_FXTRACT:
455  case X86_INS_FYL2X:
456  case X86_INS_FYL2XP1:
457  case X86_INS_FISTTP:
458  case X86_INS_FSQRT:
459  case X86_INS_FXCH:
460  break;
461  case X86_INS_FTST:
462  case X86_INS_FUCOMI:
463  case X86_INS_FUCOMPP:
464  case X86_INS_FUCOMP:
465  case X86_INS_FUCOM:
466  break;
467  case X86_INS_FABS:
468  break;
469  case X86_INS_FLDCW:
470  case X86_INS_FLDENV:
471  case X86_INS_FLDL2E:
472  case X86_INS_FLDL2T:
473  case X86_INS_FLDLG2:
474  case X86_INS_FLDLN2:
475  case X86_INS_FLDPI:
476  case X86_INS_FLDZ:
477  case X86_INS_FLD1:
478  case X86_INS_FLD:
479  break;
480  case X86_INS_FIST:
481  case X86_INS_FISTP:
482  case X86_INS_FST:
483  case X86_INS_FSTP:
484  case X86_INS_FSTPNCE:
485  case X86_INS_FXRSTOR:
486  case X86_INS_FXRSTOR64:
487  break;
488  case X86_INS_FIDIV:
489  case X86_INS_FIDIVR:
490  case X86_INS_FDIV:
491  case X86_INS_FDIVP:
492  case X86_INS_FDIVR:
493  case X86_INS_FDIVRP:
494  break;
495  case X86_INS_FSUBR:
496  case X86_INS_FISUBR:
497  case X86_INS_FSUBRP:
498  case X86_INS_FSUB:
499  case X86_INS_FISUB:
500  case X86_INS_FSUBP:
501  break;
502  case X86_INS_FMUL:
503  case X86_INS_FIMUL:
504  case X86_INS_FMULP:
505  break;
506  case X86_INS_CLI:
507  esilprintf(op, "0,if,:=");
508  break;
509  case X86_INS_STI:
510  esilprintf(op, "1,if,:=");
511  break;
512  case X86_INS_CLC:
513  esilprintf(op, "0,cf,:=");
514  break;
515  case X86_INS_CMC:
516  esilprintf(op, "cf,!,cf,=");
517  break;
518  case X86_INS_STC:
519  esilprintf(op, "1,cf,:=");
520  break;
521  case X86_INS_CLAC:
522  case X86_INS_CLGI:
523  case X86_INS_CLTS:
524 #if CS_API_MAJOR >= 4
525  case X86_INS_CLWB:
526 #endif
527  case X86_INS_STAC:
528  case X86_INS_STGI:
529  break;
530  // cmov
531  case X86_INS_SETNE:
532  case X86_INS_SETNO:
533  case X86_INS_SETNP:
534  case X86_INS_SETNS:
535  case X86_INS_SETO:
536  case X86_INS_SETP:
537  case X86_INS_SETS:
538  case X86_INS_SETL:
539  case X86_INS_SETLE:
540  case X86_INS_SETB:
541  case X86_INS_SETG:
542  case X86_INS_SETAE:
543  case X86_INS_SETA:
544  case X86_INS_SETBE:
545  case X86_INS_SETE:
546  case X86_INS_SETGE: {
547  dst = getarg(&gop, 0, 1, NULL, DST_AR, NULL);
548  switch (insn->id) {
549  case X86_INS_SETE: esilprintf(op, "zf,%s", dst); break;
550  case X86_INS_SETNE: esilprintf(op, "zf,!,%s", dst); break;
551  case X86_INS_SETO: esilprintf(op, "of,%s", dst); break;
552  case X86_INS_SETNO: esilprintf(op, "of,!,%s", dst); break;
553  case X86_INS_SETP: esilprintf(op, "pf,%s", dst); break;
554  case X86_INS_SETNP: esilprintf(op, "pf,!,%s", dst); break;
555  case X86_INS_SETS: esilprintf(op, "sf,%s", dst); break;
556  case X86_INS_SETNS: esilprintf(op, "sf,!,%s", dst); break;
557  case X86_INS_SETB: esilprintf(op, "cf,%s", dst); break;
558  case X86_INS_SETAE: esilprintf(op, "cf,!,%s", dst); break;
559  case X86_INS_SETL: esilprintf(op, "sf,of,^,%s", dst); break;
560  case X86_INS_SETLE: esilprintf(op, "zf,sf,of,^,|,%s", dst); break;
561  case X86_INS_SETG: esilprintf(op, "zf,!,sf,of,^,!,&,%s", dst); break;
562  case X86_INS_SETGE: esilprintf(op, "sf,of,^,!,%s", dst); break;
563  case X86_INS_SETA: esilprintf(op, "cf,zf,|,!,%s", dst); break;
564  case X86_INS_SETBE: esilprintf(op, "cf,zf,|,%s", dst); break;
565  }
566  } break;
567  // cmov
568  case X86_INS_FCMOVBE:
569  case X86_INS_FCMOVB:
570  case X86_INS_FCMOVNBE:
571  case X86_INS_FCMOVNB:
572  case X86_INS_FCMOVE:
573  case X86_INS_FCMOVNE:
574  case X86_INS_FCMOVNU:
575  case X86_INS_FCMOVU:
576  break;
577  case X86_INS_CMOVA:
578  case X86_INS_CMOVAE:
579  case X86_INS_CMOVB:
580  case X86_INS_CMOVBE:
581  case X86_INS_CMOVE:
582  case X86_INS_CMOVG:
583  case X86_INS_CMOVGE:
584  case X86_INS_CMOVL:
585  case X86_INS_CMOVLE:
586  case X86_INS_CMOVNE:
587  case X86_INS_CMOVNO:
588  case X86_INS_CMOVNP:
589  case X86_INS_CMOVNS:
590  case X86_INS_CMOVO:
591  case X86_INS_CMOVP:
592  case X86_INS_CMOVS: {
593  const char *conditional = NULL;
594  src = getarg(&gop, 1, 0, NULL, SRC_AR, NULL);
595  dst = getarg(&gop, 0, 1, NULL, DST_AR, NULL);
596  switch (insn->id) {
597  case X86_INS_CMOVA:
598  // mov if CF = 0 *AND* ZF = 0
599  conditional = "cf,zf,|,!";
600  break;
601  case X86_INS_CMOVAE:
602  // mov if CF = 0
603  conditional = "cf,!";
604  break;
605  case X86_INS_CMOVB:
606  // mov if CF = 1
607  conditional = "cf";
608  break;
609  case X86_INS_CMOVBE:
610  // mov if CF = 1 *OR* ZF = 1
611  conditional = "cf,zf,|";
612  break;
613  case X86_INS_CMOVE:
614  // mov if ZF = 1
615  conditional = "zf";
616  break;
617  case X86_INS_CMOVG:
618  // mov if ZF = 0 *AND* SF = OF
619  conditional = "zf,!,sf,of,^,!,&";
620  break;
621  case X86_INS_CMOVGE:
622  // mov if SF = OF
623  conditional = "sf,of,^,!";
624  break;
625  case X86_INS_CMOVL:
626  // mov if SF != OF
627  conditional = "sf,of,^";
628  break;
629  case X86_INS_CMOVLE:
630  // mov if ZF = 1 *OR* SF != OF
631  conditional = "zf,sf,of,^,|";
632  break;
633  case X86_INS_CMOVNE:
634  // mov if ZF = 0
635  conditional = "zf,!";
636  break;
637  case X86_INS_CMOVNO:
638  // mov if OF = 0
639  conditional = "of,!";
640  break;
641  case X86_INS_CMOVNP:
642  // mov if PF = 0
643  conditional = "pf,!";
644  break;
645  case X86_INS_CMOVNS:
646  // mov if SF = 0
647  conditional = "sf,!";
648  break;
649  case X86_INS_CMOVO:
650  // mov if OF = 1
651  conditional = "of";
652  break;
653  case X86_INS_CMOVP:
654  // mov if PF = 1
655  conditional = "pf";
656  break;
657  case X86_INS_CMOVS:
658  // mov if SF = 1
659  conditional = "sf";
660  break;
661  }
662  if (src && dst && conditional) {
663  esilprintf(op, "%s,?{,%s,%s,}", conditional, src, dst);
664  }
665  } break;
666  case X86_INS_STOSB:
667  if (a->bits < 32) {
668  rz_strbuf_appendf(&op->esil, "al,di,=[1],df,?{,1,di,-=,},df,!,?{,1,di,+=,}");
669  } else {
670  rz_strbuf_appendf(&op->esil, "al,edi,=[1],df,?{,1,edi,-=,},df,!,?{,1,edi,+=,}");
671  }
672  break;
673  case X86_INS_STOSW:
674  if (a->bits < 32) {
675  rz_strbuf_appendf(&op->esil, "ax,di,=[2],df,?{,2,di,-=,},df,!,?{,2,di,+=,}");
676  } else {
677  rz_strbuf_appendf(&op->esil, "ax,edi,=[2],df,?{,2,edi,-=,},df,!,?{,2,edi,+=,}");
678  }
679  break;
680  case X86_INS_STOSD:
681  rz_strbuf_appendf(&op->esil, "eax,edi,=[4],df,?{,4,edi,-=,},df,!,?{,4,edi,+=,}");
682  break;
683  case X86_INS_STOSQ:
684  rz_strbuf_appendf(&op->esil, "rax,rdi,=[8],df,?{,8,edi,-=,},df,!,?{,8,edi,+=,}");
685  break;
686  case X86_INS_LODSB:
687  rz_strbuf_appendf(&op->esil, "%s,[1],al,=,df,?{,1,%s,-=,},df,!,?{,1,%s,+=,}", si, si, si);
688  break;
689  case X86_INS_LODSW:
690  rz_strbuf_appendf(&op->esil, "%s,[2],ax,=,df,?{,2,%s,-=,},df,!,?{,2,%s,+=,}", si, si, si);
691  break;
692  case X86_INS_LODSD:
693  rz_strbuf_appendf(&op->esil, "esi,[4],eax,=,df,?{,4,esi,-=,},df,!,?{,4,esi,+=,}");
694  break;
695  case X86_INS_LODSQ:
696  rz_strbuf_appendf(&op->esil, "rsi,[8],rax,=,df,?{,8,rsi,-=,},df,!,?{,8,rsi,+=,}");
697  break;
698  case X86_INS_PEXTRB:
699  rz_strbuf_appendf(&op->esil, "TODO");
700  break;
701  // string mov
702  // PS: MOVSD can correspond to one of the two instruction (yes, intel x86
703  // has the same pneumonic for two different opcodes!). We can decide which
704  // of the two it is based on the operands.
705  // For more information, see:
706  // https://mudongliang.github.io/x86/html/file_module_x86_id_203.html
707  // (vs)
708  // https://mudongliang.github.io/x86/html/file_module_x86_id_204.html
709  case X86_INS_MOVSD:
710  // Handle "Move Scalar Double-Precision Floating-Point Value"
711  if (is_xmm_reg(INSOP(0)) || is_xmm_reg(INSOP(1))) {
712  src = getarg(&gop, 1, 0, NULL, SRC_AR, NULL);
713  dst = getarg(&gop, 0, 1, NULL, DST_AR, NULL);
714  if (src && dst) {
715  esilprintf(op, "%s,%s", src, dst);
716  }
717  break;
718  }
719  // fallthrough
720  case X86_INS_MOVSB:
721  case X86_INS_MOVSQ:
722  case X86_INS_MOVSW:
723  if (op->prefix & RZ_ANALYSIS_OP_PREFIX_REP) {
724  int width = INSOP(0).size;
725  src = (char *)cs_reg_name(*handle, INSOP(1).mem.base);
726  dst = (char *)cs_reg_name(*handle, INSOP(0).mem.base);
727  rz_strbuf_appendf(&op->esil,
728  "%s,[%d],%s,=[%d],"
729  "df,?{,%d,%s,-=,%d,%s,-=,},"
730  "df,!,?{,%d,%s,+=,%d,%s,+=,}",
731  src, width, dst, width,
732  width, src, width, dst,
733  width, src, width, dst);
734  } else {
735  int width = INSOP(0).size;
736  src = (char *)cs_reg_name(*handle, INSOP(1).mem.base);
737  dst = (char *)cs_reg_name(*handle, INSOP(0).mem.base);
738  esilprintf(op, "%s,[%d],%s,=[%d],df,?{,%d,%s,-=,%d,%s,-=,},"
739  "df,!,?{,%d,%s,+=,%d,%s,+=,}",
740  src, width, dst, width, width, src, width,
741  dst, width, src, width, dst);
742  }
743  break;
744  // mov
745  case X86_INS_MOVSS:
746  case X86_INS_MOV:
747  case X86_INS_MOVAPS:
748  case X86_INS_MOVAPD:
749  case X86_INS_MOVZX:
750  case X86_INS_MOVUPS:
751  case X86_INS_MOVABS:
752  case X86_INS_MOVHPD:
753  case X86_INS_MOVHPS:
754  case X86_INS_MOVLPD:
755  case X86_INS_MOVLPS:
756  case X86_INS_MOVBE:
757  case X86_INS_MOVSX:
758  case X86_INS_MOVSXD:
759  case X86_INS_MOVQ:
760  case X86_INS_MOVDQU:
761  case X86_INS_MOVDQA:
762  case X86_INS_MOVDQ2Q: {
763  switch (INSOP(0).type) {
764  case X86_OP_MEM:
765  if (op->prefix & RZ_ANALYSIS_OP_PREFIX_REP) {
766  int width = INSOP(0).size;
767  src = (char *)cs_reg_name(*handle, INSOP(1).mem.base);
768  dst = (char *)cs_reg_name(*handle, INSOP(0).mem.base);
769  const char *counter = (a->bits == 16) ? "cx" : (a->bits == 32) ? "ecx"
770  : "rcx";
771  esilprintf(op, "%s,!,?{,BREAK,},%s,NUM,%s,NUM,"
772  "%s,[%d],%s,=[%d],df,?{,%d,%s,-=,%d,%s,-=,},"
773  "df,!,?{,%d,%s,+=,%d,%s,+=,},%s,--=,%s,"
774  "?{,8,GOTO,}",
775  counter, src, dst, src, width, dst,
776  width, width, src, width, dst, width, src,
777  width, dst, counter, counter);
778  } else {
779  src = getarg(&gop, 1, 0, NULL, SRC_AR, NULL);
780  dst = getarg(&gop, 0, 1, NULL, DST_AR, NULL);
781  esilprintf(op, "%s,%s", src, dst);
782  }
783  break;
784  case X86_OP_REG:
785  default:
786  if (INSOP(0).type == X86_OP_MEM) {
787  op->direction = 1; // read
788  }
789  if (INSOP(1).type == X86_OP_MEM) {
790  // MOV REG, [PTR + IREG*SCALE]
791  op->ireg = cs_reg_name(*handle, INSOP(1).mem.index);
792  op->disp = INSOP(1).mem.disp;
793  op->scale = INSOP(1).mem.scale;
794  }
795  {
796  int width = INSOP(1).size;
797 
798  src = getarg(&gop, 1, 0, NULL, SRC_AR, NULL);
799  // dst is name of register from instruction.
800  dst = getarg(&gop, 0, 0, NULL, DST_AR, NULL);
801  const char *dst64 = rz_reg_32_to_64(a->reg, dst);
802  if (a->bits == 64 && dst64) {
803  // Here it is still correct, because 'e** = X'
804  // turns into 'r** = X' (first one will keep higher bytes,
805  // second one will overwrite them with zeros).
806  if (insn->id == X86_INS_MOVSX || insn->id == X86_INS_MOVSXD) {
807  esilprintf(op, "%d,%s,~,%s,=", width * 8, src, dst64);
808  } else {
809  esilprintf(op, "%s,%s,=", src, dst64);
810  }
811 
812  } else {
813  if (insn->id == X86_INS_MOVSX || insn->id == X86_INS_MOVSXD) {
814  esilprintf(op, "%d,%s,~,%s,=", width * 8, src, dst);
815  } else {
816  esilprintf(op, "%s,%s,=", src, dst);
817  }
818  }
819  }
820  break;
821  }
822  } break;
823  case X86_INS_MOVD:
824  if (is_xmm_reg(INSOP(0))) {
825  if (!is_xmm_reg(INSOP(1))) {
826  src = getarg(&gop, 1, 0, NULL, SRC_AR, NULL);
827  dst = getarg(&gop, 0, 0, NULL, DST_AR, NULL);
828  esilprintf(op, "%s,%sl,=", src, dst);
829  }
830  }
831  if (is_xmm_reg(INSOP(1))) {
832  if (!is_xmm_reg(INSOP(0))) {
833  src = getarg(&gop, 1, 0, NULL, SRC_AR, NULL);
834  dst = getarg(&gop, 0, 1, NULL, DST_AR, NULL);
835  esilprintf(op, "%sl,%s", src, dst);
836  }
837  }
838  break;
839  case X86_INS_ROL:
840  case X86_INS_RCL:
841  // TODO: RCL Still does not work as intended
842  // - Set flags
843  {
844  src = getarg(&gop, 1, 0, NULL, SRC_AR, NULL);
845  dst = getarg(&gop, 0, 0, NULL, DST_AR, NULL);
846  esilprintf(op, "%s,%s,<<<,%s,=", src, dst, dst);
847  }
848  break;
849  case X86_INS_ROR:
850  case X86_INS_RCR:
851  // TODO: RCR Still does not work as intended
852  // - Set flags
853  {
854  src = getarg(&gop, 1, 0, NULL, SRC_AR, NULL);
855  dst = getarg(&gop, 0, 0, NULL, DST_AR, NULL);
856  esilprintf(op, "%s,%s,>>>,%s,=", src, dst, dst);
857  }
858  break;
859  case X86_INS_CPUID:
860  // https://c9x.me/x86/html/file_module_x86_id_45.html
861  // GenuineIntel
862  esilprintf(op, "0xa,eax,=,0x756E6547,ebx,=,0x6C65746E,ecx,=,0x49656E69,edx,=");
863  break;
864  case X86_INS_SHLD:
865  case X86_INS_SHLX:
866  // TODO: SHLD is not implemented yet.
867  {
868  ut32 bitsize;
869  src = getarg(&gop, 1, 0, NULL, SRC_AR, NULL);
870  dst = getarg(&gop, 0, 1, "<<", DST_AR, &bitsize);
871  esilprintf(op, "%s,%s,$z,zf,:=,$p,pf,:=,%d,$s,sf,:=", src, dst, bitsize - 1);
872  }
873  break;
874  case X86_INS_SAR:
875  // TODO: Set CF. See case X86_INS_SHL for more details.
876  {
877 #if 0
878  ut64 val = 0;
879  switch (gop.insn->detail->x86.operands[0].size) {
880  case 1:
881  val = 0x80;
882  break;
883  case 2:
884  val = 0x8000;
885  break;
886  case 4:
887  val = 0x80000000;
888  break;
889  case 8:
890  val = 0x8000000000000000;
891  break;
892  default:
893  val = 0x80;
894  }
895  src = getarg (&gop, 1, 0, NULL, SRC_AR);
896  dst = getarg (&gop, 0, 0, NULL, DST_AR);
897  esilprintf (op, "%s,1,%s,>>,0x%"PFMT64x",%s,&,|,%s,=,1,%s,&,cf,=,1,REPEAT", src, dst, val, dst, dst, dst);
898 #endif
899  ut32 bitsize;
900  src = getarg(&gop, 1, 0, NULL, SRC_AR, NULL);
901  dst_r = getarg(&gop, 0, 0, NULL, DST_R_AR, NULL);
902  dst_w = getarg(&gop, 0, 1, NULL, DST_W_AR, &bitsize);
903  esilprintf(op, "0,cf,:=,1,%s,-,1,<<,%s,&,?{,1,cf,:=,},%s,%s,>>>>,%s,$z,zf,:=,$p,pf,:=,%d,$s,sf,:=",
904  src, dst_r, src, dst_r, dst_w, bitsize - 1);
905  }
906  break;
907  case X86_INS_SARX: {
908  dst = getarg(&gop, 0, 1, NULL, 0, NULL);
909  src = getarg(&gop, 1, 0, NULL, 1, NULL);
910  src2 = getarg(&gop, 1, 0, NULL, 2, NULL);
911  esilprintf(op, "%s,%s,>>>>,%s,=", src2, src, dst);
912  } break;
913  case X86_INS_SHL:
914  case X86_INS_SAL: {
915  ut64 val = 0;
916  switch (gop.insn->detail->x86.operands[0].size) {
917  case 1:
918  val = 0x80;
919  break;
920  case 2:
921  val = 0x8000;
922  break;
923  case 4:
924  val = 0x80000000;
925  break;
926  case 8:
927  val = 0x8000000000000000;
928  break;
929  default:
930  RZ_LOG_ERROR("x86: unknown operand size: %d\n", gop.insn->detail->x86.operands[0].size);
931  val = 256;
932  break;
933  }
934  ut32 bitsize;
935  src = getarg(&gop, 1, 0, NULL, SRC_AR, NULL);
936  dst = getarg(&gop, 0, 0, NULL, DST_AR, NULL);
937  dst2 = getarg(&gop, 0, 1, "<<", DST2_AR, &bitsize);
938  esilprintf(op, "0,%s,!,!,?{,1,%s,-,%s,<<,0x%llx,&,!,!,^,},%s,%s,$z,zf,:=,$p,pf,:=,%d,$s,sf,:=,cf,=",
939  src, src, dst, val, src, dst2, bitsize - 1);
940  } break;
941  case X86_INS_SALC:
942  esilprintf(op, "$z,DUP,zf,=,al,=");
943  break;
944  case X86_INS_SHR:
945  case X86_INS_SHRD:
946  case X86_INS_SHRX:
947  // TODO: Set CF: See case X86_INS_SAL for more details.
948  {
949  ut32 bitsize;
950  src = getarg(&gop, 1, 0, NULL, SRC_AR, NULL);
951  dst_r = getarg(&gop, 0, 0, NULL, DST_R_AR, NULL);
952  dst_w = getarg(&gop, 0, 1, NULL, DST_W_AR, &bitsize);
953  esilprintf(op, "0,cf,:=,1,%s,-,1,<<,%s,&,?{,1,cf,:=,},%s,%s,>>,%s,$z,zf,:=,$p,pf,:=,%d,$s,sf,:=",
954  src, dst_r, src, dst_r, dst_w, bitsize - 1);
955  }
956  break;
957  case X86_INS_CBW:
958  esilprintf(op, "al,ax,=,7,ax,>>,?{,0xff00,ax,|=,}");
959  break;
960  case X86_INS_CWDE:
961  esilprintf(op, "ax,eax,=,15,eax,>>,?{,0xffff0000,eax,|=,}");
962  break;
963  case X86_INS_CDQ:
964  esilprintf(op, "0,edx,=,31,eax,>>,?{,0xffffffff,edx,=,}");
965  break;
966  case X86_INS_CDQE:
967  esilprintf(op, "eax,rax,=,31,rax,>>,?{,0xffffffff00000000,rax,|=,}");
968  break;
969  case X86_INS_AAA:
970  esilprintf(op, "0,cf,:=,0,af,:=,9,al,>,?{,10,al,-=,1,ah,+=,1,cf,:=,1,af,:=,}"); // don't
971  break;
972  case X86_INS_AAD:
973  arg0 = "0,zf,:=,0,sf,:=,0,pf,:=,10,ah,*,al,+,ax,=";
974  arg1 = "0,al,==,?{,1,zf,:=,},2,al,%,0,==,?{,1,pf,:=,},7,al,>>,?{,1,sf,:=,}";
975  esilprintf(op, "%s,%s", arg0, arg1);
976  break;
977  case X86_INS_AAM:
978  arg0 = "0,zf,:=,0,sf,:=,0,pf,:=,10,al,/,ah,=,10,al,%,al,=";
979  arg1 = "0,al,==,?{,1,zf,:=,},2,al,%,0,==,?{,1,pf,:=,},7,al,>>,?{,1,sf,:=,}";
980  esilprintf(op, "%s,%s", arg0, arg1);
981  break;
982  // XXX: case X86_INS_AAS: too tough to implement. BCD is deprecated anyways
983  case X86_INS_CMP:
984  case X86_INS_CMPPD:
985  case X86_INS_CMPPS:
986  case X86_INS_CMPSW:
987  case X86_INS_CMPSD:
988  case X86_INS_CMPSQ:
989  case X86_INS_CMPSB:
990  case X86_INS_CMPSS:
991  case X86_INS_TEST: {
992  ut32 bitsize;
993  src = getarg(&gop, 1, 0, NULL, SRC_AR, NULL);
994  dst = getarg(&gop, 0, 0, NULL, DST_AR, &bitsize);
995 
996  if (!bitsize || bitsize > 64) {
997  break;
998  }
999 
1000  if (insn->id == X86_INS_TEST) {
1001  esilprintf(op, "0,%s,%s,&,==,$z,zf,:=,$p,pf,:=,%u,$s,sf,:=,0,cf,:=,0,of,:=",
1002  src, dst, bitsize - 1);
1003  } else if (insn->id == X86_INS_CMP) {
1004  esilprintf(op,
1005  "%s,%s,==,$z,zf,:=,%u,$b,cf,:=,$p,pf,:=,%u,$s,sf,:=,"
1006  "%s,0x%" PFMT64x ",-,!,%u,$o,^,of,:=,3,$b,af,:=",
1007  src, dst, bitsize, bitsize - 1, src, 1ULL << (bitsize - 1), bitsize - 1);
1008  } else {
1009  char *rsrc = (char *)cs_reg_name(*handle, INSOP(1).mem.base);
1010  char *rdst = (char *)cs_reg_name(*handle, INSOP(0).mem.base);
1011  const int width = INSOP(0).size;
1012  esilprintf(op,
1013  "%s,%s,==,$z,zf,:=,%u,$b,cf,:=,$p,pf,:=,%u,$s,sf,:=,%s,0x%" PFMT64x ","
1014  "-,!,%u,$o,^,of,:=,3,$b,af,:=,df,?{,%d,%s,-=,%d,%s,-=,}{,%d,%s,+=,%d,%s,+=,}",
1015  src, dst, bitsize, bitsize - 1, src, 1ULL << (bitsize - 1), bitsize - 1,
1016  width, rsrc, width, rdst, width, rsrc, width, rdst);
1017  }
1018  } break;
1019  case X86_INS_LEA: {
1020  src = getarg(&gop, 1, 2, NULL, SRC_AR, NULL);
1021  dst = getarg(&gop, 0, 1, NULL, DST_AR, NULL);
1022  esilprintf(op, "%s,%s", src, dst);
1023  } break;
1024  case X86_INS_PUSHAW:
1025  // pushal, popal - push/pop EAX,EBX,ECX,EDX,ESP,EBP,ESI,EDI
1026  case X86_INS_PUSHAL: {
1027  esilprintf(op,
1028  "0,%s,+,"
1029  "%d,%s,-=,%s,%s,=[%d],"
1030  "%d,%s,-=,%s,%s,=[%d],"
1031  "%d,%s,-=,%s,%s,=[%d],"
1032  "%d,%s,-=,%s,%s,=[%d],"
1033  "%d,%s,-=,%s,=[%d],"
1034  "%d,%s,-=,%s,%s,=[%d],"
1035  "%d,%s,-=,%s,%s,=[%d],"
1036  "%d,%s,-=,%s,%s,=[%d]",
1037  sp,
1038  rs, sp, "eax", sp, rs,
1039  rs, sp, "ecx", sp, rs,
1040  rs, sp, "edx", sp, rs,
1041  rs, sp, "ebx", sp, rs,
1042  rs, sp, "esp", rs,
1043  rs, sp, "ebp", sp, rs,
1044  rs, sp, "esi", sp, rs,
1045  rs, sp, "edi", sp, rs);
1046  } break;
1047  case X86_INS_ENTER:
1048  case X86_INS_PUSH: {
1049  dst = getarg(&gop, 0, 0, NULL, DST_AR, NULL);
1050  esilprintf(op, "%s,%d,%s,-,=[%d],%d,%s,-=",
1051  dst ? dst : "eax", rs, sp, rs, rs, sp);
1052  } break;
1053  case X86_INS_PUSHF:
1054  case X86_INS_PUSHFD:
1055  case X86_INS_PUSHFQ:
1056  esilprintf(op, "%d,%s,-=,eflags,%s,=[%d]", rs, sp, sp, rs);
1057  break;
1058  case X86_INS_LEAVE:
1059  esilprintf(op, "%s,%s,=,%s,[%d],%s,=,%d,%s,+=",
1060  bp, sp, sp, rs, bp, rs, sp);
1061  break;
1062  case X86_INS_POPAW:
1063  case X86_INS_POPAL: {
1064  esilprintf(op,
1065  "%s,[%d],%d,%s,+=,%s,=,"
1066  "%s,[%d],%d,%s,+=,%s,=,"
1067  "%s,[%d],%d,%s,+=,%s,=,"
1068  "%s,[%d],%d,%s,+=,"
1069  "%s,[%d],%d,%s,+=,%s,=,"
1070  "%s,[%d],%d,%s,+=,%s,=,"
1071  "%s,[%d],%d,%s,+=,%s,=,"
1072  "%s,[%d],%d,%s,+=,%s,=,"
1073  "%s,=",
1074  sp, rs, rs, sp, "edi",
1075  sp, rs, rs, sp, "esi",
1076  sp, rs, rs, sp, "ebp",
1077  sp, rs, rs, sp,
1078  sp, rs, rs, sp, "ebx",
1079  sp, rs, rs, sp, "edx",
1080  sp, rs, rs, sp, "ecx",
1081  sp, rs, rs, sp, "eax",
1082  sp);
1083  } break;
1084  case X86_INS_POP: {
1085  switch (INSOP(0).type) {
1086  case X86_OP_MEM: {
1087  dst = getarg(&gop, 0, 1, NULL, DST_AR, NULL);
1088  esilprintf(op,
1089  "%s,[%d],%s,%d,%s,+=",
1090  sp, rs, dst, rs, sp);
1091  break;
1092  }
1093  case X86_OP_REG:
1094  default: {
1095  dst = getarg(&gop, 0, 0, NULL, DST_AR, NULL);
1096  esilprintf(op,
1097  "%s,[%d],%s,=,%d,%s,+=",
1098  sp, rs, dst, rs, sp);
1099  break;
1100  }
1101  }
1102  } break;
1103  case X86_INS_POPF:
1104  case X86_INS_POPFD:
1105  case X86_INS_POPFQ:
1106  esilprintf(op, "%s,[%d],eflags,=", sp, rs);
1107  break;
1108  case X86_INS_RET:
1109  case X86_INS_RETF:
1110  case X86_INS_RETFQ:
1111  case X86_INS_IRET:
1112  case X86_INS_IRETD:
1113  case X86_INS_IRETQ:
1114  case X86_INS_SYSRET: {
1115  int cleanup = 0;
1116  if (INSOPS > 0) {
1117  cleanup = (int)INSOP(0).imm;
1118  }
1119  esilprintf(op, "%s,[%d],%s,=,%d,%s,+=",
1120  sp, rs, pc, rs + cleanup, sp);
1121  } break;
1122  case X86_INS_INT3:
1123  esilprintf(op, "3,$");
1124  break;
1125  case X86_INS_INT1:
1126  esilprintf(op, "1,$");
1127  break;
1128  case X86_INS_INT:
1129  esilprintf(op, "%d,$",
1130  RZ_ABS((int)INSOP(0).imm));
1131  break;
1132  case X86_INS_SYSCALL:
1133  case X86_INS_SYSENTER:
1134  case X86_INS_SYSEXIT:
1135  break;
1136  case X86_INS_INTO:
1137  case X86_INS_VMCALL:
1138  case X86_INS_VMMCALL:
1139  esilprintf(op, "%d,$", (int)INSOP(0).imm);
1140  break;
1141  case X86_INS_JL:
1142  case X86_INS_JLE:
1143  case X86_INS_JA:
1144  case X86_INS_JAE:
1145  case X86_INS_JB:
1146  case X86_INS_JBE:
1147  case X86_INS_JCXZ:
1148  case X86_INS_JECXZ:
1149  case X86_INS_JRCXZ:
1150  case X86_INS_JO:
1151  case X86_INS_JNO:
1152  case X86_INS_JS:
1153  case X86_INS_JNS:
1154  case X86_INS_JP:
1155  case X86_INS_JNP:
1156  case X86_INS_JE:
1157  case X86_INS_JNE:
1158  case X86_INS_JG:
1159  case X86_INS_JGE:
1160  case X86_INS_LOOP:
1161  case X86_INS_LOOPE:
1162  case X86_INS_LOOPNE: {
1163  const char *cnt = (a->bits == 16) ? "cx" : (a->bits == 32) ? "ecx"
1164  : "rcx";
1165  dst = getarg(&gop, 0, 2, NULL, DST_AR, NULL);
1166  switch (insn->id) {
1167  case X86_INS_JL:
1168  esilprintf(op, "of,sf,^,?{,%s,%s,=,}", dst, pc);
1169  break;
1170  case X86_INS_JLE:
1171  esilprintf(op, "of,sf,^,zf,|,?{,%s,%s,=,}", dst, pc);
1172  break;
1173  case X86_INS_JA:
1174  esilprintf(op, "cf,zf,|,!,?{,%s,%s,=,}", dst, pc);
1175  break;
1176  case X86_INS_JAE:
1177  esilprintf(op, "cf,!,?{,%s,%s,=,}", dst, pc);
1178  break;
1179  case X86_INS_JB:
1180  esilprintf(op, "cf,?{,%s,%s,=,}", dst, pc);
1181  break;
1182  case X86_INS_JO:
1183  esilprintf(op, "of,?{,%s,%s,=,}", dst, pc);
1184  break;
1185  case X86_INS_JNO:
1186  esilprintf(op, "of,!,?{,%s,%s,=,}", dst, pc);
1187  break;
1188  case X86_INS_JE:
1189  esilprintf(op, "zf,?{,%s,%s,=,}", dst, pc);
1190  break;
1191  case X86_INS_JGE:
1192  esilprintf(op, "of,!,sf,^,?{,%s,%s,=,}", dst, pc);
1193  break;
1194  case X86_INS_JNE:
1195  esilprintf(op, "zf,!,?{,%s,%s,=,}", dst, pc);
1196  break;
1197  case X86_INS_JG:
1198  esilprintf(op, "sf,of,!,^,zf,!,&,?{,%s,%s,=,}", dst, pc);
1199  break;
1200  case X86_INS_JS:
1201  esilprintf(op, "sf,?{,%s,%s,=,}", dst, pc);
1202  break;
1203  case X86_INS_JNS:
1204  esilprintf(op, "sf,!,?{,%s,%s,=,}", dst, pc);
1205  break;
1206  case X86_INS_JP:
1207  esilprintf(op, "pf,?{,%s,%s,=,}", dst, pc);
1208  break;
1209  case X86_INS_JNP:
1210  esilprintf(op, "pf,!,?{,%s,%s,=,}", dst, pc);
1211  break;
1212  case X86_INS_JBE:
1213  esilprintf(op, "zf,cf,|,?{,%s,%s,=,}", dst, pc);
1214  break;
1215  case X86_INS_JCXZ:
1216  esilprintf(op, "cx,!,?{,%s,%s,=,}", dst, pc);
1217  break;
1218  case X86_INS_JECXZ:
1219  esilprintf(op, "ecx,!,?{,%s,%s,=,}", dst, pc);
1220  break;
1221  case X86_INS_JRCXZ:
1222  esilprintf(op, "rcx,!,?{,%s,%s,=,}", dst, pc);
1223  break;
1224  case X86_INS_LOOP:
1225  esilprintf(op, "1,%s,-=,%s,?{,%s,%s,=,}", cnt, cnt, dst, pc);
1226  break;
1227  case X86_INS_LOOPE:
1228  esilprintf(op, "1,%s,-=,%s,?{,zf,?{,%s,%s,=,},}",
1229  cnt, cnt, dst, pc);
1230  break;
1231  case X86_INS_LOOPNE:
1232  esilprintf(op, "1,%s,-=,%s,?{,zf,!,?{,%s,%s,=,},}",
1233  cnt, cnt, dst, pc);
1234  break;
1235  }
1236  } break;
1237  case X86_INS_CALL: {
1238  if (a->read_at && a->bits != 16) {
1239  ut8 thunk[4] = { 0 };
1240  if (a->read_at(a, (ut64)INSOP(0).imm, thunk, sizeof(thunk))) {
1241  /* 8b xx x4 mov <reg>, dword [esp]
1242  c3 ret
1243  */
1244  if (thunk[0] == 0x8b && thunk[3] == 0xc3 && (thunk[1] & 0xc7) == 4 /* 00rrr100 */
1245  && (thunk[2] & 0x3f) == 0x24) { /* --100100: ignore scale in SIB byte */
1246  ut8 reg = (thunk[1] & 0x38) >> 3;
1247  esilprintf(op, "0x%" PFMT64x ",%s,=", addr + op->size,
1248  reg32_to_name(reg));
1249  break;
1250  }
1251  }
1252  }
1253  arg0 = getarg(&gop, 0, 0, NULL, ARG0_AR, NULL);
1254  esilprintf(op,
1255  "%s,%s,"
1256  "%d,%s,-=,%s,"
1257  "=[],"
1258  "%s,=",
1259  arg0, pc, rs, sp, sp, pc);
1260  } break;
1261  case X86_INS_LCALL: {
1262  arg0 = getarg(&gop, 0, 0, NULL, ARG0_AR, NULL);
1263  arg1 = getarg(&gop, 1, 0, NULL, ARG1_AR, NULL);
1264  if (arg1) {
1265  esilprintf(op,
1266  "2,%s,-=,cs,%s,=[2]," // push CS
1267  "%d,%s,-=,%s,%s,=[]," // push IP/EIP
1268  "%s,cs,=," // set CS
1269  "%s,%s,=", // set IP/EIP
1270  sp, sp, rs, sp, pc, sp, arg0, arg1, pc);
1271  } else {
1272  esilprintf(op,
1273  "%s,%s,-=,%d,%s,=[]," // push IP/EIP
1274  "%s,%s,=", // set IP/EIP
1275  sp, sp, rs, sp, arg0, pc);
1276  }
1277  } break;
1278  case X86_INS_JMP:
1279  case X86_INS_LJMP: {
1280  src = getarg(&gop, 0, 0, NULL, SRC_AR, NULL);
1281  esilprintf(op, "%s,%s,=", src, pc);
1282  }
1283  // TODO: what if UJMP?
1284  switch (INSOP(0).type) {
1285  case X86_OP_IMM:
1286  if (INSOP(1).type == X86_OP_IMM) {
1287  ut64 seg = INSOP(0).imm;
1288  ut64 off = INSOP(1).imm;
1289  esilprintf(
1290  op,
1291  "0x%" PFMT64x ",cs,=,"
1292  "0x%" PFMT64x ",%s,=",
1293  seg, off, pc);
1294  } else {
1295  ut64 dst = INSOP(0).imm;
1296  esilprintf(op, "0x%" PFMT64x ",%s,=", dst, pc);
1297  }
1298  break;
1299  case X86_OP_MEM:
1300  if (INSOP(0).mem.base == X86_REG_RIP) {
1301  /* nothing here */
1302  } else {
1303  cs_x86_op in = INSOP(0);
1304  if (in.mem.index == 0 && in.mem.base == 0 && in.mem.scale == 1) {
1305  if (in.mem.segment != X86_REG_INVALID) {
1306  esilprintf(
1307  op,
1308  "4,%s,<<,0x%" PFMT64x ",+,[],%s,=",
1309  INSOP(0).mem.segment == X86_REG_ES ? "es"
1310  : INSOP(0).mem.segment == X86_REG_CS ? "cs"
1311  : INSOP(0).mem.segment == X86_REG_DS ? "ds"
1312  : INSOP(0).mem.segment == X86_REG_FS ? "fs"
1313  : INSOP(0).mem.segment == X86_REG_GS ? "gs"
1314  : INSOP(0).mem.segment == X86_REG_SS ? "ss"
1315  : "unknown_segment_register",
1316  (ut64)INSOP(0).mem.disp,
1317  pc);
1318  } else {
1319  esilprintf(
1320  op,
1321  "0x%" PFMT64x ",[],%s,=",
1322  (ut64)INSOP(0).mem.disp, pc);
1323  }
1324  }
1325  }
1326  break;
1327  case X86_OP_REG: {
1328  src = getarg(&gop, 0, 0, NULL, SRC_AR, NULL);
1329  op->src[0] = rz_analysis_value_new();
1330  op->src[0]->reg = rz_reg_get(a->reg, src, RZ_REG_TYPE_GPR);
1331  // XXX fallthrough
1332  }
1333  // case X86_OP_FP:
1334  default: // other?
1335  break;
1336  }
1337  break;
1338  case X86_INS_IN:
1339  case X86_INS_INSW:
1340  case X86_INS_INSD:
1341  case X86_INS_INSB:
1342  if (ISIMM(1)) {
1343  op->val = INSOP(1).imm;
1344  }
1345  break;
1346  case X86_INS_OUT:
1347  case X86_INS_OUTSB:
1348  case X86_INS_OUTSD:
1349  case X86_INS_OUTSW:
1350  if (ISIMM(0)) {
1351  op->val = INSOP(0).imm;
1352  }
1353  break;
1354  case X86_INS_VXORPD:
1355  case X86_INS_VXORPS:
1356  case X86_INS_VPXORD:
1357  case X86_INS_VPXORQ:
1358  case X86_INS_VPXOR:
1359  case X86_INS_XORPS:
1360  case X86_INS_KXORW:
1361  case X86_INS_PXOR:
1362  case X86_INS_XOR: {
1363  ut32 bitsize;
1364  src = getarg(&gop, 1, 0, NULL, SRC_AR, NULL);
1365  dst = getarg(&gop, 0, 1, "^", DST_AR, &bitsize);
1366  dst2 = getarg(&gop, 0, 0, NULL, DST2_AR, NULL);
1367  const char *dst_reg64 = rz_reg_32_to_64(a->reg, dst2); // 64-bit destination if exists
1368  if (a->bits == 64 && dst_reg64) {
1369  // (64-bit ^ 32-bit) & 0xFFFF FFFF -> 64-bit, it's alright, higher bytes will be eliminated
1370  // (consider this is operation with 32-bit regs in 64-bit environment).
1371  esilprintf(op, "%s,%s,^,0xffffffff,&,%s,=,$z,zf,:=,$p,pf,:=,%d,$s,sf,:=,0,cf,:=,0,of,:=",
1372  src, dst_reg64, dst_reg64, bitsize - 1);
1373  } else {
1374  esilprintf(op, "%s,%s,$z,zf,:=,$p,pf,:=,%d,$s,sf,:=,0,cf,:=,0,of,:=",
1375  src, dst, bitsize - 1);
1376  }
1377  } break;
1378  case X86_INS_BSF: {
1379  src = getarg(&gop, 1, 0, NULL, SRC_AR, NULL);
1380  dst = getarg(&gop, 0, 0, NULL, DST_AR, NULL);
1381  int bits = INSOP(0).size * 8;
1382 
1383  /*
1384  * Here we first set ZF depending on the source operand
1385  * (and bail out if it's 0), then test each bit in a loop
1386  * by creating a mask on the stack and applying it, returning
1387  * result if bit is set.
1388  */
1389  esilprintf(op, "%s,!,?{,1,zf,=,BREAK,},0,zf,=,"
1390  "%d,DUP,%d,-,1,<<,%s,&,?{,%d,-,%s,=,BREAK,},12,REPEAT",
1391  src, bits, bits, src, bits, dst);
1392  } break;
1393  case X86_INS_BSR: {
1394  src = getarg(&gop, 1, 0, NULL, SRC_AR, NULL);
1395  dst = getarg(&gop, 0, 0, NULL, DST_AR, NULL);
1396  int bits = INSOP(0).size * 8;
1397 
1398  /*
1399  * Similar to BSF, except we naturally don't
1400  * need to subtract anything to create
1401  * a mask and return the result.
1402  */
1403  esilprintf(op, "%s,!,?{,1,zf,=,BREAK,},0,zf,=,"
1404  "%d,DUP,1,<<,%s,&,?{,%s,=,BREAK,},12,REPEAT",
1405  src, bits, src, dst);
1406  } break;
1407  case X86_INS_BSWAP: {
1408  dst = getarg(&gop, 0, 0, NULL, DST_AR, NULL);
1409  if (INSOP(0).size == 4) {
1410  esilprintf(op, "0xff000000,24,%s,NUM,<<,&,24,%s,NUM,>>,|,"
1411  "8,0x00ff0000,%s,NUM,&,>>,|,"
1412  "8,0x0000ff00,%s,NUM,&,<<,|,"
1413  "%s,=",
1414  dst, dst, dst, dst, dst);
1415  } else {
1416  esilprintf(op, "0xff00000000000000,56,%s,NUM,<<,&,"
1417  "56,%s,NUM,>>,|,40,0xff000000000000,%s,NUM,&,>>,|,"
1418  "40,0xff00,%s,NUM,&,<<,|,24,0xff0000000000,%s,NUM,&,>>,|,"
1419  "24,0xff0000,%s,NUM,&,<<,|,8,0xff00000000,%s,NUM,&,>>,|,"
1420  "8,0xff000000,%s,NUM,&,<<,|,"
1421  "%s,=",
1422  dst, dst, dst, dst, dst, dst, dst, dst, dst);
1423  }
1424  } break;
1425  case X86_INS_OR:
1426  // The OF and CF flags are cleared; the SF, ZF, and PF flags are
1427  // set according to the result. The state of the AF flag is
1428  // undefined.
1429  {
1430  ut32 bitsize;
1431  src = getarg(&gop, 1, 0, NULL, SRC_AR, NULL);
1432  dst = getarg(&gop, 0, 1, "|", DST_AR, &bitsize);
1433  esilprintf(op, "%s,%s,%d,$s,sf,:=,$z,zf,:=,$p,pf,:=,0,of,:=,0,cf,:=",
1434  src, dst, bitsize - 1);
1435  }
1436  break;
1437  case X86_INS_INC:
1438  // The CF flag is not affected. The OF, SF, ZF, AF, and PF flags
1439  // are set according to the result.
1440  {
1441  ut32 bitsize;
1442  src = getarg(&gop, 0, 1, "++", SRC_AR, &bitsize);
1443  esilprintf(op, "%s,%d,$o,of,:=,%d,$s,sf,:=,$z,zf,:=,$p,pf,:=,3,$c,af,:=", src, bitsize - 1, bitsize - 1);
1444  }
1445  break;
1446  case X86_INS_DEC:
1447  // The CF flag is not affected. The OF, SF, ZF, AF, and PF flags
1448  // are set according to the result.
1449  {
1450  ut32 bitsize;
1451  src = getarg(&gop, 0, 1, "--", SRC_AR, &bitsize);
1452  esilprintf(op, "%s,%d,$o,of,:=,%d,$s,sf,:=,$z,zf,:=,$p,pf,:=,3,$b,af,:=", src, bitsize - 1, bitsize - 1);
1453  }
1454  break;
1455  case X86_INS_PSUBB:
1456  case X86_INS_PSUBW:
1457  case X86_INS_PSUBD:
1458  case X86_INS_PSUBQ:
1459  case X86_INS_PSUBSB:
1460  case X86_INS_PSUBSW:
1461  case X86_INS_PSUBUSB:
1462  case X86_INS_PSUBUSW: {
1463  src = getarg(&gop, 1, 0, NULL, SRC_AR, NULL);
1464  dst = getarg(&gop, 0, 1, "-", DST_AR, NULL);
1465  esilprintf(op, "%s,%s", src, dst);
1466  } break;
1467  case X86_INS_SUB: {
1468  ut32 bitsize;
1469  src = getarg(&gop, 1, 0, NULL, SRC_AR, NULL);
1470  dst = getarg(&gop, 0, 1, "-", DST_AR, &bitsize);
1471 
1472  if (!bitsize || bitsize > 64) {
1473  break;
1474  }
1475 
1476  // Set OF, SF, ZF, AF, PF, and CF flags.
1477  // We use $b rather than $c here as the carry flag really
1478  // represents a "borrow"
1479  esilprintf(op, "%s,%s,%s,0x%" PFMT64x ",-,!,%u,$o,^,of,:=,%u,$s,sf,:=,$z,zf,:=,$p,pf,:=,%u,$b,cf,:=,3,$b,af,:=",
1480  src, dst, src, 1ULL << (bitsize - 1), bitsize - 1, bitsize - 1, bitsize);
1481  } break;
1482  case X86_INS_SBB:
1483  // dst = dst - (src + cf)
1484  {
1485  ut32 bitsize;
1486  src = getarg(&gop, 1, 0, NULL, SRC_AR, NULL);
1487  dst = getarg(&gop, 0, 0, NULL, DST_AR, &bitsize);
1488  esilprintf(op, "cf,%s,+,%s,-=,%d,$o,of,:=,%d,$s,sf,:=,$z,zf,:=,$p,pf,:=,%d,$b,cf,:=",
1489  src, dst, bitsize - 1, bitsize - 1, bitsize);
1490  }
1491  break;
1492  case X86_INS_LIDT:
1493  break;
1494  case X86_INS_SIDT:
1495  break;
1496  case X86_INS_RDRAND:
1497  case X86_INS_RDSEED:
1498  case X86_INS_RDMSR:
1499  case X86_INS_RDPMC:
1500  case X86_INS_RDTSC:
1501  case X86_INS_RDTSCP:
1502  case X86_INS_CRC32:
1503  case X86_INS_SHA1MSG1:
1504  case X86_INS_SHA1MSG2:
1505  case X86_INS_SHA1NEXTE:
1506  case X86_INS_SHA1RNDS4:
1507  case X86_INS_SHA256MSG1:
1508  case X86_INS_SHA256MSG2:
1509  case X86_INS_SHA256RNDS2:
1510  case X86_INS_AESDECLAST:
1511  case X86_INS_AESDEC:
1512  case X86_INS_AESENCLAST:
1513  case X86_INS_AESENC:
1514  case X86_INS_AESIMC:
1516  // AES instructions
1517  break;
1518  case X86_INS_AND:
1519  case X86_INS_ANDN:
1520  case X86_INS_ANDPD:
1521  case X86_INS_ANDPS:
1522  case X86_INS_ANDNPD:
1523  case X86_INS_ANDNPS: {
1524  ut32 bitsize;
1525  src = getarg(&gop, 1, 0, NULL, SRC_AR, NULL);
1526  dst = getarg(&gop, 0, 1, "&", DST_AR, &bitsize);
1527  dst2 = getarg(&gop, 0, 0, NULL, DST2_AR, NULL);
1528  const char *dst_reg64 = rz_reg_32_to_64(a->reg, dst2); // 64-bit destination if exists
1529  if (a->bits == 64 && dst_reg64) {
1530  // (64-bit & 32-bit) & 0xFFFF FFFF -> 64-bit, it's alright, higher bytes will be eliminated
1531  // (consider this is operation with 32-bit regs in 64-bit environment).
1532  esilprintf(op, "%s,%s,&,0xffffffff,&,%s,=,$z,zf,:=,$p,pf,:=,%d,$s,sf,:=,0,cf,:=,0,of,:=",
1533  src, dst_reg64, dst_reg64, bitsize - 1);
1534  } else {
1535  esilprintf(op, "%s,%s,$z,zf,:=,$p,pf,:=,%d,$s,sf,:=,0,cf,:=,0,of,:=", src, dst, bitsize - 1);
1536  }
1537  } break;
1538  case X86_INS_IDIV: {
1539  arg0 = getarg(&gop, 0, 0, NULL, ARG0_AR, NULL);
1540  arg1 = getarg(&gop, 1, 0, NULL, ARG1_AR, NULL);
1541  arg2 = getarg(&gop, 2, 0, NULL, ARG2_AR, NULL);
1542  // DONE handle signedness
1543  // IDIV does not change flags
1544  op->sign = true;
1545  if (!arg2 && !arg1) {
1546  // TODO: IDIV rbx not implemented. this is just a workaround
1547  //
1548  // http://www.tptp.cc/mirrors/siyobik.info/instruction/IDIV.html
1549  // Divides (signed) the value in the AX, DX:AX, or EDX:EAX registers (dividend) by the source operand (divisor) and stores the result in the AX (AH:AL), DX:AX, or EDX:EAX registers. The source operand can be a general-purpose register or a memory location. The action of this instruction depends on the operand size (dividend/divisor), as shown in the following table:
1550  // IDIV RBX == RDX:RAX /= RBX
1551 
1552  //
1553  if (arg0) {
1554  int width = INSOP(0).size;
1555  const char *rz_quot = (width == 1) ? "al" : (width == 2) ? "ax"
1556  : (width == 4) ? "eax"
1557  : "rax";
1558  const char *rz_rema = (width == 1) ? "ah" : (width == 2) ? "dx"
1559  : (width == 4) ? "edx"
1560  : "rdx";
1561  const char *rz_nume = (width == 1) ? "ax" : rz_quot;
1562 
1563  esilprintf(op, "%d,%s,~,%d,%s,<<,%s,+,~%%,%d,%s,~,%d,%s,<<,%s,+,~/,%s,=,%s,=",
1564  width * 8, arg0, width * 8, rz_rema, rz_nume, width * 8, arg0, width * 8, rz_rema, rz_nume, rz_quot, rz_rema);
1565  } else {
1566  /* should never happen */
1567  }
1568  } else {
1569  // does this instruction even exist?
1570  int width = INSOP(0).size;
1571  esilprintf(op, "%d,%s,~,%d,%s,~,~/,%s,=", width * 8, arg2, width * 8, arg1, arg0);
1572  }
1573  } break;
1574  case X86_INS_DIV: {
1575  int width = INSOP(0).size;
1576  dst = getarg(&gop, 0, 0, NULL, DST_AR, NULL);
1577  const char *rz_quot = (width == 1) ? "al" : (width == 2) ? "ax"
1578  : (width == 4) ? "eax"
1579  : "rax";
1580  const char *rz_rema = (width == 1) ? "ah" : (width == 2) ? "dx"
1581  : (width == 4) ? "edx"
1582  : "rdx";
1583  const char *rz_nume = (width == 1) ? "ax" : rz_quot;
1584  // DIV does not change flags and is unsigned
1585 
1586  esilprintf(op, "%s,%d,%s,<<,%s,+,%%,%s,%d,%s,<<,%s,+,/,%s,=,%s,=",
1587  dst, width * 8, rz_rema, rz_nume, dst, width * 8, rz_rema, rz_nume, rz_quot, rz_rema);
1588  } break;
1589  case X86_INS_IMUL: {
1590  arg0 = getarg(&gop, 0, 0, NULL, ARG0_AR, NULL);
1591  arg1 = getarg(&gop, 1, 0, NULL, ARG1_AR, NULL);
1592  arg2 = getarg(&gop, 2, 0, NULL, ARG2_AR, NULL);
1593  op->sign = true;
1594  int width = INSOP(0).size;
1595  if (arg2) {
1596  // flags and sign have been handled
1597  esilprintf(op, "%d,%s,~,%d,%s,~,*,DUP,%s,=,%s,-,?{,1,1,}{,0,0,},cf,:=,of,:=", width * 8, arg2, width * 8, arg1, arg0, arg0);
1598  } else {
1599  if (arg1) {
1600  esilprintf(op, "%d,%s,~,%d,%s,~,*,DUP,%s,=,%s,-,?{,1,1,}{,0,0,},cf,:=,of,:=", width * 8, arg0, width * 8, arg1, arg0, arg0);
1601  } else {
1602  if (arg0) {
1603  const char *rz_quot = (width == 1) ? "al" : (width == 2) ? "ax"
1604  : (width == 4) ? "eax"
1605  : "rax";
1606  const char *rz_rema = (width == 1) ? "ah" : (width == 2) ? "dx"
1607  : (width == 4) ? "edx"
1608  : "rdx";
1609  const char *rz_nume = (width == 1) ? "ax" : rz_quot;
1610 
1611  if (width == 1) {
1612  esilprintf(op, "0xffffff00,eflags,&=,%s,%s,%%,eflags,|=,%s,%s,*,%s,=,0xff,eflags,&,%s,=,0xffffff00,eflags,&=,2,eflags,|=",
1613  arg0, rz_nume, arg0, rz_nume, rz_quot, rz_rema);
1614  } else {
1615  // this got a little bit crazy,
1616  esilprintf(op, "%d,%d,%s,~,%d,%s,~,*,>>,%s,=,%s,%s,*=,%d,%d,%s,~,>>,%s,-,?{,1,1,}{,0,0,},cf,:=,of,:=",
1617  width * 8, width * 8, arg0, width * 8, rz_nume, rz_rema, arg0, rz_nume, width * 8, width * 8, rz_nume, rz_rema);
1618  }
1619  } else {
1620  /* should never happen */
1621  }
1622  }
1623  }
1624  } break;
1625  case X86_INS_MUL: {
1626  src = getarg(&gop, 0, 0, NULL, SRC_AR, NULL);
1627  if (src) {
1628  int width = INSOP(0).size;
1629  const char *rz_quot = (width == 1) ? "al" : (width == 2) ? "ax"
1630  : (width == 4) ? "eax"
1631  : "rax";
1632  const char *rz_rema = (width == 1) ? "ah" : (width == 2) ? "dx"
1633  : (width == 4) ? "edx"
1634  : "rdx";
1635  const char *rz_nume = (width == 1) ? "ax" : rz_quot;
1636 
1637  if (width == 1) {
1638  esilprintf(op, "0xffffff00,eflags,&=,%s,%s,%%,eflags,|=,%s,%s,*,%s,=,0xff,eflags,&,%s,=,0xffffff00,eflags,&=,2,eflags,|=",
1639  src, rz_nume, src, rz_nume, rz_quot, rz_rema);
1640  } else {
1641  esilprintf(op, "%d,%s,%s,*,>>,%s,=,%s,%s,*=,%s,?{,1,1,}{,0,0,},cf,:=,of,:=",
1642  width * 8, src, rz_nume, rz_rema, src, rz_nume, rz_rema);
1643  }
1644  } else {
1645  /* should never happen */
1646  }
1647  } break;
1648  case X86_INS_MULX:
1649  case X86_INS_MULPD:
1650  case X86_INS_MULPS:
1651  case X86_INS_MULSD:
1652  case X86_INS_MULSS: {
1653  src = getarg(&gop, 1, 0, NULL, SRC_AR, NULL);
1654  dst = getarg(&gop, 0, 1, "*", DST_AR, NULL);
1655  if (!src && dst) {
1656  switch (dst[0]) {
1657  case 'r':
1658  src = "rax";
1659  break;
1660  case 'e':
1661  src = "eax";
1662  break;
1663  default:
1664  src = "al";
1665  break;
1666  }
1667  }
1668  esilprintf(op, "%s,%s", src, dst);
1669  } break;
1670  case X86_INS_NEG: {
1671  ut32 bitsize;
1672  src = getarg(&gop, 0, 0, NULL, SRC_AR, NULL);
1673  dst = getarg(&gop, 0, 1, NULL, DST_AR, &bitsize);
1674  ut64 xor = 0;
1675  switch (bitsize) {
1676  case 8:
1677  xor = 0xff;
1678  break;
1679  case 16:
1680  xor = 0xffff;
1681  break;
1682  case 32:
1683  xor = 0xffffffff;
1684  break;
1685  case 64:
1686  xor = 0xffffffffffffffff;
1687  break;
1688  default:
1689  RZ_LOG_ERROR("x86: unhandled neg bitsize %d\n", bitsize);
1690  break;
1691  }
1692  esilprintf(op, "%s,!,!,cf,:=,%s,0x%" PFMT64x ",^,1,+,%s,$z,zf,:=,0,of,:=,%d,$s,sf,:=,%d,$o,pf,:=",
1693  src, src, xor, dst, bitsize - 1, bitsize - 1);
1694  } break;
1695  case X86_INS_NOT: {
1696  dst = getarg(&gop, 0, 1, "^", DST_AR, NULL);
1697  esilprintf(op, "-1,%s", dst);
1698  } break;
1699  case X86_INS_PACKSSDW:
1700  case X86_INS_PACKSSWB:
1701  case X86_INS_PACKUSWB:
1702  break;
1703  case X86_INS_PADDB:
1704  case X86_INS_PADDD:
1705  case X86_INS_PADDW:
1706  case X86_INS_PADDSB:
1707  case X86_INS_PADDSW:
1708  case X86_INS_PADDUSB:
1709  case X86_INS_PADDUSW:
1710  break;
1711  case X86_INS_XCHG: {
1712  dst = getarg(&gop, 0, 0, NULL, DST_AR, NULL);
1713  src = getarg(&gop, 1, 0, NULL, SRC_AR, NULL);
1714  if (INSOP(0).type == X86_OP_MEM) {
1715  dst2 = getarg(&gop, 0, 1, NULL, DST2_AR, NULL);
1716  esilprintf(op,
1717  "%s,%s,^,%s,=,"
1718  "%s,%s,^,%s,"
1719  "%s,%s,^,%s,=",
1720  dst, src, src, // x = x ^ y
1721  src, dst, dst2, // y = y ^ x
1722  dst, src, src); // x = x ^ y
1723  } else {
1724  esilprintf(op,
1725  "%s,%s,^,%s,=,"
1726  "%s,%s,^,%s,=,"
1727  "%s,%s,^,%s,=",
1728  dst, src, src, // x = x ^ y
1729  src, dst, dst, // y = y ^ x
1730  dst, src, src); // x = x ^ y
1731  // esilprintf (op, "%s,%s,%s,=,%s", src, dst, src, dst);
1732  }
1733  } break;
1734  case X86_INS_XADD: /* xchg + add */
1735  {
1736  src = getarg(&gop, 1, 0, NULL, SRC_AR, NULL);
1737  dst = getarg(&gop, 0, 0, NULL, DST_AR, NULL);
1738  dstAdd = getarg(&gop, 0, 1, "+", DSTADD_AR, NULL);
1739  if (INSOP(0).type == X86_OP_MEM) {
1740  dst2 = getarg(&gop, 0, 1, NULL, DST2_AR, NULL);
1741  esilprintf(op,
1742  "%s,%s,^,%s,=,"
1743  "%s,%s,^,%s,"
1744  "%s,%s,^,%s,=,"
1745  "%s,%s",
1746  dst, src, src, // x = x ^ y
1747  src, dst, dst2, // y = y ^ x
1748  dst, src, src, // x = x ^ y
1749  src, dstAdd);
1750  } else {
1751  esilprintf(op,
1752  "%s,%s,^,%s,=,"
1753  "%s,%s,^,%s,=,"
1754  "%s,%s,^,%s,=,"
1755  "%s,%s",
1756  dst, src, src, // x = x ^ y
1757  src, dst, dst, // y = y ^ x
1758  dst, src, src, // x = x ^ y
1759  src, dstAdd);
1760  // esilprintf (op, "%s,%s,%s,=,%s", src, dst, src, dst);
1761  }
1762  } break;
1763  case X86_INS_FADD:
1764 #if CS_API_MAJOR > 4
1765  case X86_INS_PFADD:
1766 #else
1767  case X86_INS_FADDP:
1768 #endif
1769  break;
1770  case X86_INS_ADDPS:
1771  case X86_INS_ADDSD:
1772  case X86_INS_ADDSS:
1773  case X86_INS_ADDSUBPD:
1774  case X86_INS_ADDSUBPS:
1775  case X86_INS_ADDPD:
1776  // The OF, SF, ZF, AF, CF, and PF flags are set according to the
1777  // result.
1778  if (INSOP(0).type == X86_OP_MEM) {
1779  src = getarg(&gop, 1, 0, NULL, SRC_AR, NULL);
1780  src2 = getarg(&gop, 0, 0, NULL, SRC2_AR, NULL);
1781  dst = getarg(&gop, 0, 1, NULL, DST_AR, NULL);
1782  esilprintf(op, "%s,%s,+,%s", src, src2, dst);
1783  } else {
1784  src = getarg(&gop, 1, 0, NULL, SRC_AR, NULL);
1785  dst = getarg(&gop, 0, 1, "+", DST_AR, NULL);
1786  esilprintf(op, "%s,%s", src, dst);
1787  }
1788  break;
1789  case X86_INS_ADD:
1790  // The OF, SF, ZF, AF, CF, and PF flags are set according to the
1791  // result.
1792  {
1793  ut32 bitsize;
1794  src = getarg(&gop, 1, 0, NULL, SRC_AR, NULL);
1795  dst = getarg(&gop, 0, 1, "+", DST_AR, &bitsize);
1796  esilprintf(op, "%s,%s,%d,$o,of,:=,%d,$s,sf,:=,$z,zf,:=,%d,$c,cf,:=,$p,pf,:=,3,$c,af,:=",
1797  src, dst, bitsize - 1, bitsize - 1, bitsize - 1);
1798  }
1799  break;
1800  case X86_INS_ADC: {
1801  ut32 bitsize;
1802  src = getarg(&gop, 1, 0, NULL, SRC_AR, NULL);
1803  dst = getarg(&gop, 0, 1, "+", DST_AR, &bitsize);
1804  // dst = dst + src + cf
1805  // NOTE: We would like to add the carry first before adding the
1806  // source to ensure that the flag computation from $c belongs
1807  // to the operation of adding dst += src rather than the one
1808  // that adds carry (as esil only keeps track of the last
1809  // addition to set the flags).
1810  esilprintf(op, "cf,%s,+,%s,%d,$o,of,:=,%d,$s,sf,:=,$z,zf,:=,%d,$c,cf,:=,$p,pf,:=,3,$c,af,:=",
1811  src, dst, bitsize - 1, bitsize - 1, bitsize - 1);
1812  } break;
1813  /* Direction flag */
1814  case X86_INS_CLD:
1815  esilprintf(op, "0,df,:=");
1816  break;
1817  case X86_INS_STD:
1818  esilprintf(op, "1,df,:=");
1819  break;
1820  case X86_INS_SUBSD: // cvtss2sd
1821  case X86_INS_CVTSS2SD: // cvtss2sd
1822  break;
1823  case X86_INS_BT:
1824  case X86_INS_BTC:
1825  case X86_INS_BTR:
1826  case X86_INS_BTS:
1827  if (INSOP(0).type == X86_OP_MEM && INSOP(1).type == X86_OP_REG) {
1828  int width = INSOP(0).size;
1829  src = getarg(&gop, 1, 0, NULL, SRC_AR, NULL);
1830  dst_r = getarg(&gop, 0, 2 /* use the address without loading */, NULL, DST_R_AR, NULL);
1831  esilprintf(op, "0,cf,:=,%d,%s,%%,1,<<,%d,%s,/,%s,+,[%d],&,?{,1,cf,:=,}",
1832  width * 8, src, width * 8, src, dst_r, width);
1833  switch (insn->id) {
1834  case X86_INS_BTS:
1835  case X86_INS_BTC:
1836  rz_strbuf_appendf(&op->esil, ",%d,%s,%%,1,<<,%d,%s,/,%s,+,%c=[%d]",
1837  width * 8, src, width * 8, src, dst_r,
1838  (insn->id == X86_INS_BTS) ? '|' : '^', width);
1839  break;
1840  case X86_INS_BTR:
1841  getarg(&gop, 0, 1, "&", DST_R_AR, NULL);
1842  rz_strbuf_appendf(&op->esil, ",%d,%s,%%,1,<<,-1,^,%d,%s,/,%s,+,&=[%d]",
1843  width * 8, src, width * 8, src, dst_r, width);
1844  break;
1845  }
1846  } else {
1847  int width = INSOP(0).size;
1848  src = getarg(&gop, 1, 0, NULL, SRC_AR, NULL);
1849  dst_r = getarg(&gop, 0, 0, NULL, DST_R_AR, NULL);
1850  esilprintf(op, "0,cf,:=,%d,%s,%%,1,<<,%s,&,?{,1,cf,:=,}",
1851  width * 8, src, dst_r);
1852  switch (insn->id) {
1853  case X86_INS_BTS:
1854  case X86_INS_BTC:
1855  dst_w = getarg(&gop, 0, 1, (insn->id == X86_INS_BTS) ? "|" : "^", DST_R_AR, NULL);
1856  rz_strbuf_appendf(&op->esil, ",%d,%s,%%,1,<<,%s", width * 8, src, dst_w);
1857  break;
1858  case X86_INS_BTR:
1859  dst_w = getarg(&gop, 0, 1, "&", DST_R_AR, NULL);
1860  rz_strbuf_appendf(&op->esil, ",%d,%s,%%,1,<<,-1,^,%s", width * 8, src, dst_w);
1861  break;
1862  }
1863  }
1864  break;
1865  }
1866 
1867  if (op->prefix & RZ_ANALYSIS_OP_PREFIX_REP) {
1868  rz_strbuf_appendf(&op->esil, ",%s,--=,%s,?{,5,GOTO,}", counter, counter);
1869  }
1870 }
1871 
1872 static RzRegItem *cs_reg2reg(RzReg *reg, csh *h, int id) {
1873  if (id == X86_REG_INVALID) {
1874  return NULL;
1875  }
1876  return rz_reg_get(reg, (char *)cs_reg_name(*h, id), -1);
1877 }
1878 
1879 static void set_access_info(RzReg *reg, RzAnalysisOp *op, csh *handle, cs_insn *insn, int mode) {
1880  int i;
1882  int regsz;
1883  x86_reg sp, ip;
1884  switch (mode) {
1885  case CS_MODE_64:
1886  regsz = 8;
1887  sp = X86_REG_RSP;
1888  ip = X86_REG_RIP;
1889  break;
1890  default:
1891  regsz = 4;
1892  sp = X86_REG_ESP;
1893  ip = X86_REG_EIP;
1894  break;
1895  }
1897  if (!ret) {
1898  return;
1899  }
1900 
1901  // PC register
1903  val->type = RZ_ANALYSIS_VAL_REG;
1904  val->access = RZ_ANALYSIS_ACC_W;
1905  val->reg = cs_reg2reg(reg, handle, ip);
1906  rz_list_append(ret, val);
1907 
1908 #if CS_API_MAJOR >= 4
1909  // Register access info
1910  cs_regs regs_read, regs_write;
1911  ut8 read_count, write_count;
1912  if (cs_regs_access(*handle, insn, regs_read, &read_count, regs_write, &write_count) == 0) {
1913  if (read_count > 0) {
1914  for (i = 0; i < read_count; i++) {
1916  val->type = RZ_ANALYSIS_VAL_REG;
1917  val->access = RZ_ANALYSIS_ACC_R;
1918  val->reg = cs_reg2reg(reg, handle, regs_read[i]);
1919  rz_list_append(ret, val);
1920  }
1921  }
1922  if (write_count > 0) {
1923  for (i = 0; i < write_count; i++) {
1925  val->type = RZ_ANALYSIS_VAL_REG;
1926  val->access = RZ_ANALYSIS_ACC_W;
1927  val->reg = cs_reg2reg(reg, handle, regs_write[i]);
1928  rz_list_append(ret, val);
1929  }
1930  }
1931  }
1932 #endif
1933 
1934  switch (insn->id) {
1935  case X86_INS_PUSH:
1937  val->type = RZ_ANALYSIS_VAL_MEM;
1938  val->access = RZ_ANALYSIS_ACC_W;
1939  val->reg = cs_reg2reg(reg, handle, sp);
1940  val->delta = -INSOP(0).size;
1941  val->memref = INSOP(0).size;
1942  rz_list_append(ret, val);
1943  break;
1944  case X86_INS_PUSHAW:
1945  // AX, CX, DX, BX, SP, BP, SI, DI
1947  val->type = RZ_ANALYSIS_VAL_MEM;
1948  val->access = RZ_ANALYSIS_ACC_W;
1949  val->reg = cs_reg2reg(reg, handle, sp);
1950  val->delta = -16;
1951  val->memref = 16;
1952  rz_list_append(ret, val);
1953  break;
1954  case X86_INS_PUSHAL:
1955  // EAX, ECX, EDX, EBX, EBP, ESP, EBP, ESI, EDI
1957  val->type = RZ_ANALYSIS_VAL_MEM;
1958  val->access = RZ_ANALYSIS_ACC_W;
1959  val->reg = cs_reg2reg(reg, handle, sp);
1960  val->delta = -32;
1961  val->memref = 32;
1962  rz_list_append(ret, val);
1963  break;
1964  case X86_INS_PUSHF:
1966  val->type = RZ_ANALYSIS_VAL_MEM;
1967  val->access = RZ_ANALYSIS_ACC_W;
1968  val->reg = cs_reg2reg(reg, handle, sp);
1969  val->delta = -2;
1970  val->memref = 2;
1971  rz_list_append(ret, val);
1972  break;
1973  case X86_INS_PUSHFD:
1975  val->type = RZ_ANALYSIS_VAL_MEM;
1976  val->access = RZ_ANALYSIS_ACC_W;
1977  val->reg = cs_reg2reg(reg, handle, sp);
1978  val->delta = -4;
1979  val->memref = 4;
1980  rz_list_append(ret, val);
1981  break;
1982  case X86_INS_PUSHFQ:
1984  val->type = RZ_ANALYSIS_VAL_MEM;
1985  val->access = RZ_ANALYSIS_ACC_W;
1986  val->reg = cs_reg2reg(reg, handle, sp);
1987  val->delta = -8;
1988  val->memref = 8;
1989  rz_list_append(ret, val);
1990  break;
1991  case X86_INS_CALL:
1992  case X86_INS_LCALL:
1994  val->type = RZ_ANALYSIS_VAL_MEM;
1995  val->access = RZ_ANALYSIS_ACC_W;
1996  val->reg = cs_reg2reg(reg, handle, sp);
1997  val->delta = -regsz;
1998  val->memref = regsz;
1999  rz_list_append(ret, val);
2000  break;
2001  default:
2002  break;
2003  }
2004 
2005  // Memory access info based on operands
2006  for (i = 0; i < INSOPS; i++) {
2007  if (INSOP(i).type == X86_OP_MEM) {
2009  val->type = RZ_ANALYSIS_VAL_MEM;
2010 #if CS_API_MAJOR >= 4
2011  switch (INSOP(i).access) {
2012  case CS_AC_READ:
2013  val->access = RZ_ANALYSIS_ACC_R;
2014  break;
2015  case CS_AC_WRITE:
2016  val->access = RZ_ANALYSIS_ACC_W;
2017  break;
2018  case CS_AC_INVALID:
2019  val->access = RZ_ANALYSIS_ACC_UNKNOWN;
2020  break;
2021  }
2022 #else
2023  val->access = RZ_ANALYSIS_ACC_UNKNOWN;
2024 #endif
2025  val->mul = INSOP(i).mem.scale;
2026  val->delta = INSOP(i).mem.disp;
2027  if (INSOP(0).mem.base == X86_REG_RIP ||
2028  INSOP(0).mem.base == X86_REG_EIP) {
2029  val->delta += insn->size;
2030  }
2031  val->memref = INSOP(i).size;
2032  val->seg = cs_reg2reg(reg, handle, INSOP(i).mem.segment);
2033  val->reg = cs_reg2reg(reg, handle, INSOP(i).mem.base);
2034  val->regdelta = cs_reg2reg(reg, handle, INSOP(i).mem.index);
2035  rz_list_append(ret, val);
2036  }
2037  }
2038 
2039  op->access = ret;
2040 }
2041 
2042 #define CREATE_SRC_DST(op) \
2043  (op)->src[0] = rz_analysis_value_new(); \
2044  (op)->src[1] = rz_analysis_value_new(); \
2045  (op)->src[2] = rz_analysis_value_new(); \
2046  (op)->dst = rz_analysis_value_new();
2047 
2048 static void set_src_dst(RzReg *reg, RzAnalysisValue *val, csh *handle, cs_insn *insn, int x) {
2049  switch (INSOP(x).type) {
2050  case X86_OP_MEM:
2051  val->type = RZ_ANALYSIS_VAL_MEM;
2052  val->mul = INSOP(x).mem.scale;
2053  val->delta = INSOP(x).mem.disp;
2054  val->memref = INSOP(x).size;
2055  val->seg = cs_reg2reg(reg, handle, INSOP(x).mem.segment);
2056  val->reg = cs_reg2reg(reg, handle, INSOP(x).mem.base);
2057  val->regdelta = cs_reg2reg(reg, handle, INSOP(x).mem.index);
2058  break;
2059  case X86_OP_REG:
2060  val->type = RZ_ANALYSIS_VAL_REG;
2061  val->reg = cs_reg2reg(reg, handle, INSOP(x).reg);
2062  break;
2063  case X86_OP_IMM:
2064  val->type = RZ_ANALYSIS_VAL_IMM;
2065  val->imm = INSOP(x).imm;
2066  break;
2067  default:
2068  break;
2069  }
2070 }
2071 
2072 static void op_fillval(RzAnalysis *a, RzAnalysisOp *op, csh *handle, cs_insn *insn, int mode) {
2073  set_access_info(a->reg, op, handle, insn, mode);
2074  switch (op->type & RZ_ANALYSIS_OP_TYPE_MASK) {
2094  CREATE_SRC_DST(op);
2095  set_src_dst(a->reg, op->dst, handle, insn, 0);
2096  set_src_dst(a->reg, op->src[0], handle, insn, 1);
2097  set_src_dst(a->reg, op->src[1], handle, insn, 2);
2098  set_src_dst(a->reg, op->src[2], handle, insn, 3);
2099  break;
2101  if ((op->type & RZ_ANALYSIS_OP_TYPE_REG)) {
2102  CREATE_SRC_DST(op);
2103  set_src_dst(a->reg, op->src[0], handle, insn, 0);
2104  }
2105  break;
2106  default:
2107  break;
2108  }
2109 }
2110 
2111 static void op0_memimmhandle(RzAnalysisOp *op, cs_insn *insn, ut64 addr, int regsz) {
2112  op->ptr = UT64_MAX;
2113  switch (INSOP(0).type) {
2114  case X86_OP_MEM:
2115  op->cycles = CYCLE_MEM;
2116  op->disp = INSOP(0).mem.disp;
2117  if (!op->disp) {
2118  op->disp = UT64_MAX;
2119  }
2120  op->refptr = INSOP(0).size;
2121  if (INSOP(0).mem.base == X86_REG_RIP) {
2122  op->ptr = addr + insn->size + op->disp;
2123  } else if (INSOP(0).mem.base == X86_REG_RBP || INSOP(0).mem.base == X86_REG_EBP) {
2124  op->type |= RZ_ANALYSIS_OP_TYPE_REG;
2125  op->stackop = RZ_ANALYSIS_STACK_SET;
2126  op->stackptr = regsz;
2127  } else if (INSOP(0).mem.segment == X86_REG_INVALID && INSOP(0).mem.base == X86_REG_INVALID && INSOP(0).mem.index == X86_REG_INVALID && INSOP(0).mem.scale == 1) { // [<addr>]
2128  op->ptr = op->disp;
2129  if (op->ptr < 0x1000) {
2130  op->ptr = UT64_MAX;
2131  }
2132  }
2133  if (INSOP(1).type == X86_OP_IMM) {
2134  op->val = INSOP(1).imm;
2135  }
2136  break;
2137  case X86_OP_REG:
2138  if (INSOP(1).type == X86_OP_IMM) {
2139  // (INSOP(0).reg != X86_REG_RSP) && (INSOP(0).reg != X86_REG_ESP)) {
2140  op->val = INSOP(1).imm;
2141  }
2142  break;
2143  default:
2144  break;
2145  }
2146 }
2147 
2148 static void op1_memimmhandle(RzAnalysisOp *op, cs_insn *insn, ut64 addr, int regsz) {
2149  if (op->refptr < 1 || op->ptr == UT64_MAX) {
2150  switch (INSOP(1).type) {
2151  case X86_OP_MEM:
2152  op->disp = INSOP(1).mem.disp;
2153  op->refptr = INSOP(1).size;
2154  if (INSOP(1).mem.base == X86_REG_RIP) {
2155  op->ptr = addr + insn->size + op->disp;
2156  } else if (INSOP(1).mem.base == X86_REG_RBP || INSOP(1).mem.base == X86_REG_EBP) {
2157  op->stackop = RZ_ANALYSIS_STACK_GET;
2158  op->stackptr = regsz;
2159  } else if (INSOP(1).mem.segment == X86_REG_INVALID && INSOP(1).mem.base == X86_REG_INVALID && INSOP(1).mem.index == X86_REG_INVALID && INSOP(1).mem.scale == 1) { // [<addr>]
2160  op->ptr = op->disp;
2161  }
2162  break;
2163  case X86_OP_IMM:
2164  if ((INSOP(1).imm > 10) &&
2165  (INSOP(0).reg != X86_REG_RSP) && (INSOP(0).reg != X86_REG_ESP)) {
2166  op->ptr = INSOP(1).imm;
2167  }
2168  break;
2169  default:
2170  break;
2171  }
2172  }
2173 }
2174 
2175 static void op_stackidx(RzAnalysisOp *op, cs_insn *insn, bool minus) {
2176  if (INSOP(0).type == X86_OP_REG && INSOP(1).type == X86_OP_IMM) {
2177  if (INSOP(0).reg == X86_REG_RSP || INSOP(0).reg == X86_REG_ESP) {
2178  op->stackop = RZ_ANALYSIS_STACK_INC;
2179  if (minus) {
2180  op->stackptr = -INSOP(1).imm;
2181  } else {
2182  op->stackptr = INSOP(1).imm;
2183  }
2184  }
2185  }
2186 }
2187 
2188 static void set_opdir(RzAnalysisOp *op, cs_insn *insn) {
2189  switch (op->type & RZ_ANALYSIS_OP_TYPE_MASK) {
2191  switch (INSOP(0).type) {
2192  case X86_OP_MEM:
2193  op->direction = RZ_ANALYSIS_OP_DIR_WRITE;
2194  break;
2195  case X86_OP_REG:
2196  if (INSOP(1).type == X86_OP_MEM) {
2197  op->direction = RZ_ANALYSIS_OP_DIR_READ;
2198  }
2199  break;
2200  default:
2201  break;
2202  }
2203  break;
2205  op->direction = RZ_ANALYSIS_OP_DIR_REF;
2206  break;
2211  op->direction = RZ_ANALYSIS_OP_DIR_EXEC;
2212  break;
2213  default:
2214  break;
2215  }
2216 }
2217 
2218 static void anop(RzAnalysis *a, RzAnalysisOp *op, ut64 addr, const ut8 *buf, int len, csh *handle, cs_insn *insn) {
2219  struct Getarg gop = {
2220  .handle = *handle,
2221  .insn = insn,
2222  .bits = a->bits
2223  };
2224  int regsz = 4;
2225  switch (a->bits) {
2226  case 64: regsz = 8; break;
2227  case 16: regsz = 2; break;
2228  default: regsz = 4; break; // 32
2229  }
2230  switch (insn->id) {
2231  case X86_INS_FNOP:
2232  op->family = RZ_ANALYSIS_OP_FAMILY_FPU;
2233  /* fallthru */
2234  case X86_INS_NOP:
2235  case X86_INS_PAUSE:
2236  op->type = RZ_ANALYSIS_OP_TYPE_NOP;
2237  break;
2238  case X86_INS_HLT:
2239  op->type = RZ_ANALYSIS_OP_TYPE_TRAP;
2240  break;
2241  case X86_INS_FBLD:
2242  case X86_INS_FBSTP:
2243  case X86_INS_FCOMPP:
2244  case X86_INS_FDECSTP:
2245  case X86_INS_FEMMS:
2246  case X86_INS_FFREE:
2247  case X86_INS_FICOM:
2248  case X86_INS_FICOMP:
2249  case X86_INS_FINCSTP:
2250  case X86_INS_FNCLEX:
2251  case X86_INS_FNINIT:
2252  case X86_INS_FNSTCW:
2253  case X86_INS_FNSTSW:
2254  case X86_INS_FPATAN:
2255  case X86_INS_FPREM:
2256  case X86_INS_FPREM1:
2257  case X86_INS_FPTAN:
2258 #if CS_API_MAJOR >= 4
2259  case X86_INS_FFREEP:
2260 #endif
2261  case X86_INS_FRNDINT:
2262  case X86_INS_FRSTOR:
2263  case X86_INS_FNSAVE:
2264  case X86_INS_FSCALE:
2265  case X86_INS_FSETPM:
2266  case X86_INS_FSINCOS:
2267  case X86_INS_FNSTENV:
2268  case X86_INS_FXAM:
2269  case X86_INS_FXSAVE:
2270  case X86_INS_FXSAVE64:
2271  case X86_INS_FXTRACT:
2272  case X86_INS_FYL2X:
2273  case X86_INS_FYL2XP1:
2274  case X86_INS_FISTTP:
2275  case X86_INS_FSQRT:
2276  case X86_INS_FXCH:
2277  op->family = RZ_ANALYSIS_OP_FAMILY_FPU;
2278  op->type = RZ_ANALYSIS_OP_TYPE_STORE;
2279  break;
2280  case X86_INS_FTST:
2281  case X86_INS_FUCOMI:
2282  case X86_INS_FUCOMPP:
2283  case X86_INS_FUCOMP:
2284  case X86_INS_FUCOM:
2285  op->family = RZ_ANALYSIS_OP_FAMILY_FPU;
2286  op->type = RZ_ANALYSIS_OP_TYPE_CMP;
2287  break;
2288  case X86_INS_BT:
2289  case X86_INS_BTC:
2290  case X86_INS_BTR:
2291  case X86_INS_BTS:
2292  op->type = RZ_ANALYSIS_OP_TYPE_CMP;
2293  break;
2294  case X86_INS_FABS:
2295  op->type = RZ_ANALYSIS_OP_TYPE_ABS;
2296  op->family = RZ_ANALYSIS_OP_FAMILY_FPU;
2297  break;
2298  case X86_INS_FLDCW:
2299  case X86_INS_FLDENV:
2300  case X86_INS_FLDL2E:
2301  case X86_INS_FLDL2T:
2302  case X86_INS_FLDLG2:
2303  case X86_INS_FLDLN2:
2304  case X86_INS_FLDPI:
2305  case X86_INS_FLDZ:
2306  case X86_INS_FLD1:
2307  case X86_INS_FLD:
2308  op->type = RZ_ANALYSIS_OP_TYPE_LOAD;
2309  op->family = RZ_ANALYSIS_OP_FAMILY_FPU;
2310  break;
2311  case X86_INS_FIST:
2312  case X86_INS_FISTP:
2313  case X86_INS_FST:
2314  case X86_INS_FSTP:
2315  case X86_INS_FSTPNCE:
2316  case X86_INS_FXRSTOR:
2317  case X86_INS_FXRSTOR64:
2318  op->type = RZ_ANALYSIS_OP_TYPE_STORE;
2319  op->family = RZ_ANALYSIS_OP_FAMILY_FPU;
2320  break;
2321  case X86_INS_FDIV:
2322  case X86_INS_FIDIV:
2323  case X86_INS_FDIVP:
2324  case X86_INS_FDIVR:
2325  case X86_INS_FIDIVR:
2326  case X86_INS_FDIVRP:
2327  op->type = RZ_ANALYSIS_OP_TYPE_DIV;
2328  op->family = RZ_ANALYSIS_OP_FAMILY_FPU;
2329  break;
2330  case X86_INS_FSUBR:
2331  case X86_INS_FISUBR:
2332  case X86_INS_FSUBRP:
2333  case X86_INS_FSUB:
2334  case X86_INS_FISUB:
2335  case X86_INS_FSUBP:
2336  op->type = RZ_ANALYSIS_OP_TYPE_SUB;
2337  op->family = RZ_ANALYSIS_OP_FAMILY_FPU;
2338  break;
2339  case X86_INS_FMUL:
2340  case X86_INS_FIMUL:
2341  case X86_INS_FMULP:
2342  op->type = RZ_ANALYSIS_OP_TYPE_MUL;
2343  op->family = RZ_ANALYSIS_OP_FAMILY_FPU;
2344  break;
2345  case X86_INS_CLI:
2346  case X86_INS_STI:
2347  op->type = RZ_ANALYSIS_OP_TYPE_MOV;
2348  op->family = RZ_ANALYSIS_OP_FAMILY_PRIV;
2349  break;
2350  case X86_INS_CLC:
2351  case X86_INS_STC:
2352  case X86_INS_CLAC:
2353  case X86_INS_CLGI:
2354  case X86_INS_CLTS:
2355 #if CS_API_MAJOR >= 4
2356  case X86_INS_CLWB:
2357 #endif
2358  case X86_INS_STAC:
2359  case X86_INS_STGI:
2360  op->type = RZ_ANALYSIS_OP_TYPE_MOV;
2361  break;
2362  // cmov
2363  case X86_INS_SETNE:
2364  case X86_INS_SETNO:
2365  case X86_INS_SETNP:
2366  case X86_INS_SETNS:
2367  case X86_INS_SETO:
2368  case X86_INS_SETP:
2369  case X86_INS_SETS:
2370  case X86_INS_SETL:
2371  case X86_INS_SETLE:
2372  case X86_INS_SETB:
2373  case X86_INS_SETG:
2374  case X86_INS_SETAE:
2375  case X86_INS_SETA:
2376  case X86_INS_SETBE:
2377  case X86_INS_SETE:
2378  case X86_INS_SETGE:
2379  op->type = RZ_ANALYSIS_OP_TYPE_CMOV;
2380  op->family = 0;
2381  break;
2382  // cmov
2383  case X86_INS_FCMOVBE:
2384  case X86_INS_FCMOVB:
2385  case X86_INS_FCMOVNBE:
2386  case X86_INS_FCMOVNB:
2387  case X86_INS_FCMOVE:
2388  case X86_INS_FCMOVNE:
2389  case X86_INS_FCMOVNU:
2390  case X86_INS_FCMOVU:
2391  op->family = RZ_ANALYSIS_OP_FAMILY_FPU;
2392  op->type = RZ_ANALYSIS_OP_TYPE_CMOV;
2393  break;
2394  case X86_INS_CMOVA:
2395  case X86_INS_CMOVAE:
2396  case X86_INS_CMOVB:
2397  case X86_INS_CMOVBE:
2398  case X86_INS_CMOVE:
2399  case X86_INS_CMOVG:
2400  case X86_INS_CMOVGE:
2401  case X86_INS_CMOVL:
2402  case X86_INS_CMOVLE:
2403  case X86_INS_CMOVNE:
2404  case X86_INS_CMOVNO:
2405  case X86_INS_CMOVNP:
2406  case X86_INS_CMOVNS:
2407  case X86_INS_CMOVO:
2408  case X86_INS_CMOVP:
2409  case X86_INS_CMOVS:
2410  op->type = RZ_ANALYSIS_OP_TYPE_CMOV;
2411  break;
2412  case X86_INS_STOSB:
2413  case X86_INS_STOSD:
2414  case X86_INS_STOSQ:
2415  case X86_INS_STOSW:
2416  op->type = RZ_ANALYSIS_OP_TYPE_STORE;
2417  break;
2418  case X86_INS_LODSB:
2419  case X86_INS_LODSD:
2420  case X86_INS_LODSQ:
2421  case X86_INS_LODSW:
2422  op->type = RZ_ANALYSIS_OP_TYPE_LOAD;
2423  break;
2424  case X86_INS_PALIGNR:
2425  case X86_INS_VALIGND:
2426  case X86_INS_VALIGNQ:
2427  case X86_INS_VPALIGNR:
2428  op->type = RZ_ANALYSIS_OP_TYPE_AND;
2429  op->family = RZ_ANALYSIS_OP_FAMILY_CPU;
2430  break;
2431  case X86_INS_CPUID:
2432  op->type = RZ_ANALYSIS_OP_TYPE_MOV;
2433  op->family = RZ_ANALYSIS_OP_FAMILY_CPU;
2434  break;
2435  case X86_INS_SFENCE:
2436  case X86_INS_LFENCE:
2437  case X86_INS_MFENCE:
2438  op->type = RZ_ANALYSIS_OP_TYPE_NOP;
2439  op->family = RZ_ANALYSIS_OP_FAMILY_THREAD;
2440  break;
2441  // mov
2442  case X86_INS_MOVNTQ:
2443  case X86_INS_MOVNTDQA:
2444  case X86_INS_MOVNTDQ:
2445  case X86_INS_MOVNTI:
2446  case X86_INS_MOVNTPD:
2447  case X86_INS_MOVNTPS:
2448  case X86_INS_MOVNTSD:
2449  case X86_INS_MOVNTSS:
2450  case X86_INS_VMOVNTDQA:
2451  case X86_INS_VMOVNTDQ:
2452  case X86_INS_VMOVNTPD:
2453  case X86_INS_VMOVNTPS:
2454  op->type = RZ_ANALYSIS_OP_TYPE_MOV;
2455  op->family = RZ_ANALYSIS_OP_FAMILY_SSE;
2456  break;
2457  case X86_INS_PCMPEQB:
2458  case X86_INS_PCMPEQD:
2459  case X86_INS_PCMPEQW:
2460  case X86_INS_PCMPGTB:
2461  case X86_INS_PCMPGTD:
2462  case X86_INS_PCMPGTW:
2463  case X86_INS_PCMPEQQ:
2464  case X86_INS_PCMPESTRI:
2465  case X86_INS_PCMPESTRM:
2466  case X86_INS_PCMPGTQ:
2467  case X86_INS_PCMPISTRI:
2468  case X86_INS_PCMPISTRM:
2469 #if CS_API_MAJOR >= 4
2470  case X86_INS_VPCMPB:
2471 #endif
2472  case X86_INS_VPCMPD:
2473  case X86_INS_VPCMPEQB:
2474  case X86_INS_VPCMPEQD:
2475  case X86_INS_VPCMPEQQ:
2476  case X86_INS_VPCMPEQW:
2477  case X86_INS_VPCMPESTRI:
2478  case X86_INS_VPCMPESTRM:
2479  case X86_INS_VPCMPGTB:
2480  case X86_INS_VPCMPGTD:
2481  case X86_INS_VPCMPGTQ:
2482  case X86_INS_VPCMPGTW:
2483  case X86_INS_VPCMPISTRI:
2484  case X86_INS_VPCMPISTRM:
2485  case X86_INS_VPCMPQ:
2486 #if CS_API_MAJOR >= 4
2487  case X86_INS_VPCMPUB:
2488 #endif
2489  case X86_INS_VPCMPUD:
2490  case X86_INS_VPCMPUQ:
2491 #if CS_API_MAJOR >= 4
2492  case X86_INS_VPCMPUW:
2493  case X86_INS_VPCMPW:
2494 #endif
2495  op->type = RZ_ANALYSIS_OP_TYPE_CMP;
2496  op->family = RZ_ANALYSIS_OP_FAMILY_SSE;
2497  break;
2498  case X86_INS_MOVSS:
2499  case X86_INS_MOV:
2500  case X86_INS_MOVAPS:
2501  case X86_INS_MOVAPD:
2502  case X86_INS_MOVZX:
2503  case X86_INS_MOVUPS:
2504  case X86_INS_MOVABS:
2505  case X86_INS_MOVHPD:
2506  case X86_INS_MOVHPS:
2507  case X86_INS_MOVLPD:
2508  case X86_INS_MOVLPS:
2509  case X86_INS_MOVBE:
2510  case X86_INS_MOVSB:
2511  case X86_INS_MOVSD:
2512  case X86_INS_MOVSQ:
2513  case X86_INS_MOVSX:
2514  case X86_INS_MOVSXD:
2515  case X86_INS_MOVSW:
2516  case X86_INS_MOVD:
2517  case X86_INS_MOVQ:
2518  case X86_INS_MOVDQ2Q: {
2519  op->type = RZ_ANALYSIS_OP_TYPE_MOV;
2520  op0_memimmhandle(op, insn, addr, regsz);
2521  op1_memimmhandle(op, insn, addr, regsz);
2522  } break;
2523  case X86_INS_ROL:
2524  case X86_INS_RCL:
2525  // TODO: RCL Still does not work as intended
2526  // - Set flags
2527  op->type = RZ_ANALYSIS_OP_TYPE_ROL;
2528  break;
2529  case X86_INS_ROR:
2530  case X86_INS_RCR:
2531  // TODO: RCR Still does not work as intended
2532  // - Set flags
2533  op->type = RZ_ANALYSIS_OP_TYPE_ROR;
2534  break;
2535  case X86_INS_SHL:
2536  case X86_INS_SHLD:
2537  case X86_INS_SHLX:
2538  // TODO: Set CF: Carry flag is the last bit shifted out due to
2539  // this operation. It is undefined for SHL and SHR where the
2540  // number of bits shifted is greater than the size of the
2541  // destination.
2542  op->type = RZ_ANALYSIS_OP_TYPE_SHL;
2543  break;
2544  case X86_INS_SAR:
2545  case X86_INS_SARX:
2546  // TODO: Set CF. See case X86_INS_SHL for more details.
2547  op->type = RZ_ANALYSIS_OP_TYPE_SAR;
2548  break;
2549  case X86_INS_SAL:
2550  // TODO: Set CF: See case X86_INS_SAL for more details.
2551  op->type = RZ_ANALYSIS_OP_TYPE_SAL;
2552  break;
2553  case X86_INS_SALC:
2554  op->type = RZ_ANALYSIS_OP_TYPE_SAL;
2555  break;
2556  case X86_INS_SHR:
2557  case X86_INS_SHRD:
2558  case X86_INS_SHRX:
2559  // TODO: Set CF: See case X86_INS_SAL for more details.
2560  op->type = RZ_ANALYSIS_OP_TYPE_SHR;
2561  op->val = INSOP(1).imm;
2562  // XXX this should be op->imm
2563  // op->src[0] = rz_analysis_value_new ();
2564  // op->src[0]->imm = INSOP(1).imm;
2565  break;
2566  case X86_INS_CMP:
2567  case X86_INS_CMPPD:
2568  case X86_INS_CMPPS:
2569  case X86_INS_CMPSW:
2570  case X86_INS_CMPSD:
2571  case X86_INS_CMPSQ:
2572  case X86_INS_CMPSB:
2573  case X86_INS_CMPSS:
2574  case X86_INS_TEST:
2575  if (insn->id == X86_INS_TEST) {
2576  op->type = RZ_ANALYSIS_OP_TYPE_ACMP; // compare via and
2577  } else {
2578  op->type = RZ_ANALYSIS_OP_TYPE_CMP;
2579  }
2580  switch (INSOP(0).type) {
2581  case X86_OP_MEM:
2582  op->disp = INSOP(0).mem.disp;
2583  op->refptr = INSOP(0).size;
2584  if (INSOP(0).mem.base == X86_REG_RIP) {
2585  op->ptr = addr + insn->size + op->disp;
2586  } else if (INSOP(0).mem.base == X86_REG_RBP || INSOP(0).mem.base == X86_REG_EBP) {
2587  op->stackop = RZ_ANALYSIS_STACK_SET;
2588  op->stackptr = regsz;
2589  op->type |= RZ_ANALYSIS_OP_TYPE_REG;
2590  } else if (INSOP(0).mem.segment == X86_REG_INVALID && INSOP(0).mem.base == X86_REG_INVALID && INSOP(0).mem.index == X86_REG_INVALID && INSOP(0).mem.scale == 1) { // [<addr>]
2591  op->ptr = op->disp;
2592  }
2593  if (INSOP(1).type == X86_OP_IMM) {
2594  op->val = INSOP(1).imm;
2595  }
2596  break;
2597  default:
2598  switch (INSOP(1).type) {
2599  case X86_OP_MEM:
2600  op->disp = INSOP(1).mem.disp;
2601  op->refptr = INSOP(1).size;
2602  if (INSOP(1).mem.base == X86_REG_RIP) {
2603  op->ptr = addr + insn->size + op->disp;
2604  ;
2605  } else if (INSOP(1).mem.base == X86_REG_RBP || INSOP(1).mem.base == X86_REG_EBP) {
2606  op->type |= RZ_ANALYSIS_OP_TYPE_REG;
2607  op->stackop = RZ_ANALYSIS_STACK_SET;
2608  op->stackptr = regsz;
2609  } else if (INSOP(1).mem.segment == X86_REG_INVALID && INSOP(1).mem.base == X86_REG_INVALID && INSOP(1).mem.index == X86_REG_INVALID && INSOP(1).mem.scale == 1) { // [<addr>]
2610  op->ptr = op->disp;
2611  }
2612  if (INSOP(0).type == X86_OP_IMM) {
2613  op->val = INSOP(0).imm;
2614  }
2615  break;
2616  case X86_OP_IMM:
2617  op->val = op->ptr = INSOP(1).imm;
2618  break;
2619  default:
2620  break;
2621  }
2622  break;
2623  }
2624  break;
2625  case X86_INS_LEA:
2626  op->type = RZ_ANALYSIS_OP_TYPE_LEA;
2627  switch (INSOP(1).type) {
2628  case X86_OP_MEM:
2629  // op->type = RZ_ANALYSIS_OP_TYPE_ULEA;
2630  op->disp = INSOP(1).mem.disp;
2631  op->refptr = INSOP(1).size;
2632  switch (INSOP(1).mem.base) {
2633  case X86_REG_RIP:
2634  op->ptr = addr + op->size + op->disp;
2635  break;
2636  case X86_REG_RBP:
2637  case X86_REG_EBP:
2638  op->stackop = RZ_ANALYSIS_STACK_GET;
2639  op->stackptr = regsz;
2640  break;
2641  default:
2642  /* unhandled */
2643  break;
2644  }
2645  break;
2646  case X86_OP_IMM:
2647  if (INSOP(1).imm > 10) {
2648  op->ptr = INSOP(1).imm;
2649  }
2650  break;
2651  default:
2652  break;
2653  }
2654  break;
2655  case X86_INS_PUSHAW:
2656  // pushal, popal - push/pop EAX,EBX,ECX,EDX,ESP,EBP,ESI,EDI
2657  case X86_INS_PUSHAL:
2658  op->ptr = UT64_MAX;
2659  op->type = RZ_ANALYSIS_OP_TYPE_UPUSH;
2660  op->stackop = RZ_ANALYSIS_STACK_INC;
2661  op->stackptr = regsz * 8;
2662  break;
2663  case X86_INS_ENTER:
2664  case X86_INS_PUSH:
2665  case X86_INS_PUSHF:
2666  case X86_INS_PUSHFD:
2667  case X86_INS_PUSHFQ:
2668  switch (INSOP(0).type) {
2669  case X86_OP_MEM:
2670  if (INSOP(0).mem.disp && !INSOP(0).mem.base && !INSOP(0).mem.index) {
2671  op->val = op->ptr = INSOP(0).mem.disp;
2672  op->type = RZ_ANALYSIS_OP_TYPE_PUSH;
2673  } else {
2674  op->type = RZ_ANALYSIS_OP_TYPE_UPUSH;
2675  }
2676  op->cycles = CYCLE_REG + CYCLE_MEM;
2677  break;
2678  case X86_OP_IMM:
2679  op->val = op->ptr = INSOP(0).imm;
2680  op->type = RZ_ANALYSIS_OP_TYPE_PUSH;
2681  op->cycles = CYCLE_REG + CYCLE_MEM;
2682  break;
2683  case X86_OP_REG:
2684  op->type = RZ_ANALYSIS_OP_TYPE_RPUSH;
2685  op->cycles = CYCLE_REG + CYCLE_MEM;
2686  break;
2687  default:
2688  op->type = RZ_ANALYSIS_OP_TYPE_UPUSH;
2689  op->cycles = CYCLE_MEM + CYCLE_MEM;
2690  break;
2691  }
2692  op->stackop = RZ_ANALYSIS_STACK_INC;
2693  op->stackptr = regsz;
2694  break;
2695  case X86_INS_LEAVE:
2696  op->type = RZ_ANALYSIS_OP_TYPE_POP;
2697  op->stackop = RZ_ANALYSIS_STACK_INC;
2698  op->stackptr = -regsz;
2699  break;
2700  case X86_INS_POP:
2701  case X86_INS_POPF:
2702  case X86_INS_POPFD:
2703  case X86_INS_POPFQ:
2704  op->type = RZ_ANALYSIS_OP_TYPE_POP;
2705  op->stackop = RZ_ANALYSIS_STACK_INC;
2706  op->stackptr = -regsz;
2707  break;
2708  case X86_INS_POPAW:
2709  case X86_INS_POPAL:
2710  op->type = RZ_ANALYSIS_OP_TYPE_POP;
2711  op->stackop = RZ_ANALYSIS_STACK_INC;
2712  op->stackptr = -regsz * 8;
2713  break;
2714  case X86_INS_IRET:
2715  case X86_INS_IRETD:
2716  case X86_INS_IRETQ:
2717  case X86_INS_SYSRET:
2718  op->family = RZ_ANALYSIS_OP_FAMILY_PRIV;
2719  /* fallthrough */
2720  case X86_INS_RET:
2721  case X86_INS_RETF:
2722  case X86_INS_RETFQ:
2723  op->type = RZ_ANALYSIS_OP_TYPE_RET;
2724  op->stackop = RZ_ANALYSIS_STACK_INC;
2725  op->stackptr = -regsz;
2726  op->cycles = CYCLE_MEM + CYCLE_JMP;
2727  break;
2728 #if CS_API_MAJOR >= 4
2729  case X86_INS_UD0:
2730 #endif
2731  case X86_INS_UD2:
2732 #if CS_API_MAJOR == 4
2733  case X86_INS_UD2B:
2734 #endif
2735  case X86_INS_INT3:
2736  op->type = RZ_ANALYSIS_OP_TYPE_TRAP; // TRAP
2737  break;
2738  case X86_INS_INT1:
2739  op->type = RZ_ANALYSIS_OP_TYPE_SWI;
2740  op->val = 1;
2741  break;
2742  case X86_INS_INT:
2743  op->type = RZ_ANALYSIS_OP_TYPE_SWI;
2744  op->val = (int)INSOP(0).imm;
2745  break;
2746  case X86_INS_SYSCALL:
2747  case X86_INS_SYSENTER:
2748  op->type = RZ_ANALYSIS_OP_TYPE_SWI;
2749  op->cycles = CYCLE_JMP;
2750  break;
2751  case X86_INS_SYSEXIT:
2752  op->type = RZ_ANALYSIS_OP_TYPE_SWI;
2753  op->family = RZ_ANALYSIS_OP_FAMILY_PRIV;
2754  break;
2755  case X86_INS_INTO:
2756  op->type = RZ_ANALYSIS_OP_TYPE_SWI;
2757  // int4 if overflow bit is set , so this is an optional swi
2758  op->type |= RZ_ANALYSIS_OP_TYPE_COND;
2759  break;
2760  case X86_INS_VMCALL:
2761  case X86_INS_VMMCALL:
2762  op->type = RZ_ANALYSIS_OP_TYPE_TRAP;
2763  break;
2764  case X86_INS_JL:
2765  case X86_INS_JLE:
2766  case X86_INS_JA:
2767  case X86_INS_JAE:
2768  case X86_INS_JB:
2769  case X86_INS_JBE:
2770  case X86_INS_JCXZ:
2771  case X86_INS_JECXZ:
2772  case X86_INS_JRCXZ:
2773  case X86_INS_JO:
2774  case X86_INS_JNO:
2775  case X86_INS_JS:
2776  case X86_INS_JNS:
2777  case X86_INS_JP:
2778  case X86_INS_JNP:
2779  case X86_INS_JE:
2780  case X86_INS_JNE:
2781  case X86_INS_JG:
2782  case X86_INS_JGE:
2783  case X86_INS_LOOP:
2784  case X86_INS_LOOPE:
2785  case X86_INS_LOOPNE:
2786  op->type = RZ_ANALYSIS_OP_TYPE_CJMP;
2787  op->jump = INSOP(0).imm;
2788  op->fail = addr + op->size;
2789  op->cycles = CYCLE_JMP;
2790  switch (insn->id) {
2791  case X86_INS_JL:
2792  case X86_INS_JLE:
2793  case X86_INS_JS:
2794  case X86_INS_JG:
2795  case X86_INS_JGE:
2796  op->sign = true;
2797  break;
2798  }
2799  break;
2800  case X86_INS_CALL:
2801  case X86_INS_LCALL:
2802  op->cycles = CYCLE_JMP + CYCLE_MEM;
2803  switch (INSOP(0).type) {
2804  case X86_OP_IMM:
2805  op->type = RZ_ANALYSIS_OP_TYPE_CALL;
2806  // TODO: what if UCALL?
2807  if (INSOP(1).type == X86_OP_IMM) {
2808  ut64 seg = INSOP(0).imm;
2809  ut64 off = INSOP(1).imm;
2810  op->ptr = INSOP(0).mem.disp;
2811  op->jump = (seg << a->seggrn) + off;
2812  } else {
2813  op->jump = INSOP(0).imm;
2814  }
2815  op->fail = addr + op->size;
2816  break;
2817  case X86_OP_MEM:
2818  op->type = RZ_ANALYSIS_OP_TYPE_UCALL;
2819  op->jump = UT64_MAX;
2820  op->ptr = INSOP(0).mem.disp;
2821  op->disp = INSOP(0).mem.disp;
2822  op->reg = NULL;
2823  op->ireg = NULL;
2824  op->cycles += CYCLE_MEM;
2825  if (INSOP(0).mem.index == X86_REG_INVALID) {
2826  if (INSOP(0).mem.base != X86_REG_INVALID) {
2827  op->reg = cs_reg_name(*handle, INSOP(0).mem.base);
2829  }
2830  } else {
2831  op->ireg = cs_reg_name(*handle, INSOP(0).mem.index);
2832  op->scale = INSOP(0).mem.scale;
2833  }
2834  if (INSOP(0).mem.base == X86_REG_RIP) {
2835  op->ptr += addr + insn->size;
2836  op->refptr = 8;
2837  }
2838  break;
2839  case X86_OP_REG:
2840  op->reg = cs_reg_name(*handle, INSOP(0).reg);
2841  op->type = RZ_ANALYSIS_OP_TYPE_RCALL;
2842  op->ptr = UT64_MAX;
2843  op->cycles += CYCLE_REG;
2844  break;
2845  default:
2846  op->type = RZ_ANALYSIS_OP_TYPE_UCALL;
2847  op->jump = UT64_MAX;
2848  break;
2849  }
2850  break;
2851  case X86_INS_JMP:
2852  case X86_INS_LJMP:
2853  // TODO: what if UJMP?
2854  switch (INSOP(0).type) {
2855  case X86_OP_IMM:
2856  if (INSOP(1).type == X86_OP_IMM) {
2857  ut64 seg = INSOP(0).imm;
2858  ut64 off = INSOP(1).imm;
2859  op->ptr = INSOP(0).mem.disp;
2860  op->jump = (seg << a->seggrn) + off;
2861  } else {
2862  op->jump = INSOP(0).imm;
2863  }
2864  op->type = RZ_ANALYSIS_OP_TYPE_JMP;
2865  op->cycles = CYCLE_JMP;
2866  break;
2867  case X86_OP_MEM:
2868  // op->type = RZ_ANALYSIS_OP_TYPE_UJMP;
2869  op->type = RZ_ANALYSIS_OP_TYPE_MJMP;
2870  op->ptr = INSOP(0).mem.disp;
2871  op->disp = INSOP(0).mem.disp;
2872  op->reg = NULL;
2873  op->ireg = NULL;
2874  op->cycles = CYCLE_JMP + CYCLE_MEM;
2875  if (INSOP(0).mem.base != X86_REG_INVALID) {
2876  if (INSOP(0).mem.base != X86_REG_INVALID) {
2877  op->reg = cs_reg_name(*handle, INSOP(0).mem.base);
2878  op->type = RZ_ANALYSIS_OP_TYPE_IRJMP;
2879  }
2880  }
2881  if (INSOP(0).mem.index == X86_REG_INVALID) {
2882  op->ireg = NULL;
2883  } else {
2884  op->type = RZ_ANALYSIS_OP_TYPE_UJMP;
2885  op->ireg = cs_reg_name(*handle, INSOP(0).mem.index);
2886  op->scale = INSOP(0).mem.scale;
2887  }
2888  if (INSOP(0).mem.base == X86_REG_RIP) {
2889  op->ptr += addr + insn->size;
2890  op->refptr = 8;
2891  }
2892  break;
2893  case X86_OP_REG: {
2894  op->cycles = CYCLE_JMP + CYCLE_REG;
2895  op->reg = cs_reg_name(gop.handle, INSOP(0).reg);
2896  op->type = RZ_ANALYSIS_OP_TYPE_RJMP;
2897  op->ptr = UT64_MAX;
2898  } break;
2899  // case X86_OP_FP:
2900  default: // other?
2901  op->type = RZ_ANALYSIS_OP_TYPE_UJMP;
2902  op->ptr = UT64_MAX;
2903  break;
2904  }
2905  break;
2906  case X86_INS_IN:
2907  case X86_INS_INSW:
2908  case X86_INS_INSD:
2909  case X86_INS_INSB:
2910  op->type = RZ_ANALYSIS_OP_TYPE_IO;
2911  op->type2 = 0;
2912  break;
2913  case X86_INS_OUT:
2914  case X86_INS_OUTSB:
2915  case X86_INS_OUTSD:
2916  case X86_INS_OUTSW:
2917  op->type = RZ_ANALYSIS_OP_TYPE_IO;
2918  op->type2 = 1;
2919  break;
2920  case X86_INS_VXORPD:
2921  case X86_INS_VXORPS:
2922  case X86_INS_VPXORD:
2923  case X86_INS_VPXORQ:
2924  case X86_INS_VPXOR:
2925  case X86_INS_XORPS:
2926  case X86_INS_KXORW:
2927  case X86_INS_PXOR:
2928  op->type = RZ_ANALYSIS_OP_TYPE_XOR;
2929  break;
2930  case X86_INS_XOR:
2931  op->type = RZ_ANALYSIS_OP_TYPE_XOR;
2932  // TODO: Add stack indexing handling chang
2933  op0_memimmhandle(op, insn, addr, regsz);
2934  op1_memimmhandle(op, insn, addr, regsz);
2935  break;
2936  case X86_INS_OR:
2937  // The OF and CF flags are cleared; the SF, ZF, and PF flags are
2938  // set according to the result. The state of the AF flag is
2939  // undefined.
2940  op->type = RZ_ANALYSIS_OP_TYPE_OR;
2941  // TODO: Add stack indexing handling chang
2942  op0_memimmhandle(op, insn, addr, regsz);
2943  op1_memimmhandle(op, insn, addr, regsz);
2944  break;
2945  case X86_INS_INC:
2946  // The CF flag is not affected. The OF, SF, ZF, AF, and PF flags
2947  // are set according to the result.
2948  op->type = RZ_ANALYSIS_OP_TYPE_ADD;
2949  op->val = 1;
2950  break;
2951  case X86_INS_DEC:
2952  // The CF flag is not affected. The OF, SF, ZF, AF, and PF flags
2953  // are set according to the result.
2954  op->type = RZ_ANALYSIS_OP_TYPE_SUB;
2955  op->val = 1;
2956  break;
2957  case X86_INS_NEG:
2958  op->type = RZ_ANALYSIS_OP_TYPE_SUB;
2959  op->family = RZ_ANALYSIS_OP_FAMILY_CPU;
2960  break;
2961  case X86_INS_NOT:
2962  op->type = RZ_ANALYSIS_OP_TYPE_NOT;
2963  op->family = RZ_ANALYSIS_OP_FAMILY_CPU;
2964  break;
2965  case X86_INS_PSUBB:
2966  case X86_INS_PSUBW:
2967  case X86_INS_PSUBD:
2968  case X86_INS_PSUBQ:
2969  case X86_INS_PSUBSB:
2970  case X86_INS_PSUBSW:
2971  case X86_INS_PSUBUSB:
2972  case X86_INS_PSUBUSW:
2973  op->type = RZ_ANALYSIS_OP_TYPE_SUB;
2974  break;
2975  case X86_INS_SUB:
2976  op->type = RZ_ANALYSIS_OP_TYPE_SUB;
2977  op_stackidx(op, insn, false);
2978  op0_memimmhandle(op, insn, addr, regsz);
2979  op1_memimmhandle(op, insn, addr, regsz);
2980  break;
2981  case X86_INS_SBB:
2982  // dst = dst - (src + cf)
2983  op->type = RZ_ANALYSIS_OP_TYPE_SUB;
2984  break;
2985  case X86_INS_LIDT:
2986  op->type = RZ_ANALYSIS_OP_TYPE_LOAD;
2987  op->family = RZ_ANALYSIS_OP_FAMILY_PRIV;
2988  break;
2989  case X86_INS_SIDT:
2990  op->type = RZ_ANALYSIS_OP_TYPE_STORE;
2991  op->family = RZ_ANALYSIS_OP_FAMILY_PRIV;
2992  break;
2993  case X86_INS_RDRAND:
2994  case X86_INS_RDSEED:
2995  case X86_INS_RDMSR:
2996  case X86_INS_RDPMC:
2997  case X86_INS_RDTSC:
2998  case X86_INS_RDTSCP:
2999  case X86_INS_CRC32:
3000  case X86_INS_SHA1MSG1:
3001  case X86_INS_SHA1MSG2:
3002  case X86_INS_SHA1NEXTE:
3003  case X86_INS_SHA1RNDS4:
3004  case X86_INS_SHA256MSG1:
3005  case X86_INS_SHA256MSG2:
3006  case X86_INS_SHA256RNDS2:
3007  case X86_INS_AESDECLAST:
3008  case X86_INS_AESDEC:
3009  case X86_INS_AESENCLAST:
3010  case X86_INS_AESENC:
3011  case X86_INS_AESIMC:
3013  // AES instructions
3014  op->family = RZ_ANALYSIS_OP_FAMILY_CRYPTO;
3015  op->type = RZ_ANALYSIS_OP_TYPE_MOV; // XXX
3016  break;
3017  case X86_INS_ANDN:
3018  case X86_INS_ANDPD:
3019  case X86_INS_ANDPS:
3020  case X86_INS_ANDNPD:
3021  case X86_INS_ANDNPS:
3022  op->type = RZ_ANALYSIS_OP_TYPE_AND;
3023  break;
3024  case X86_INS_AND:
3025  op->type = RZ_ANALYSIS_OP_TYPE_AND;
3026  // TODO: Add stack register change operation
3027  op0_memimmhandle(op, insn, addr, regsz);
3028  op1_memimmhandle(op, insn, addr, regsz);
3029  break;
3030  case X86_INS_IDIV:
3031  op->type = RZ_ANALYSIS_OP_TYPE_DIV;
3032  break;
3033  case X86_INS_DIV:
3034  op->type = RZ_ANALYSIS_OP_TYPE_DIV;
3035  break;
3036  case X86_INS_IMUL:
3037  op->type = RZ_ANALYSIS_OP_TYPE_MUL;
3038  op->sign = true;
3039  break;
3040  case X86_INS_AAM:
3041  case X86_INS_MUL:
3042  case X86_INS_MULX:
3043  case X86_INS_MULPD:
3044  case X86_INS_MULPS:
3045  case X86_INS_MULSD:
3046  case X86_INS_MULSS:
3047  op->type = RZ_ANALYSIS_OP_TYPE_MUL;
3048  break;
3049  case X86_INS_PACKSSDW:
3050  case X86_INS_PACKSSWB:
3051  case X86_INS_PACKUSWB:
3052  op->type = RZ_ANALYSIS_OP_TYPE_MOV;
3053  op->family = RZ_ANALYSIS_OP_FAMILY_MMX;
3054  break;
3055  case X86_INS_PADDB:
3056  case X86_INS_PADDD:
3057  case X86_INS_PADDW:
3058  case X86_INS_PADDSB:
3059  case X86_INS_PADDSW:
3060  case X86_INS_PADDUSB:
3061  case X86_INS_PADDUSW:
3062  op->type = RZ_ANALYSIS_OP_TYPE_ADD;
3063  op->family = RZ_ANALYSIS_OP_FAMILY_MMX;
3064  break;
3065  case X86_INS_XCHG:
3066  op->type = RZ_ANALYSIS_OP_TYPE_MOV;
3067  op->family = RZ_ANALYSIS_OP_FAMILY_CPU;
3068  break;
3069  case X86_INS_XADD: /* xchg + add */
3070  op->type = RZ_ANALYSIS_OP_TYPE_ADD;
3071  op->family = RZ_ANALYSIS_OP_FAMILY_CPU;
3072  break;
3073  case X86_INS_FADD:
3074 #if CS_API_MAJOR == 4
3075  case X86_INS_FADDP:
3076 #endif
3077  op->family = RZ_ANALYSIS_OP_FAMILY_FPU;
3078  op->type = RZ_ANALYSIS_OP_TYPE_ADD;
3079  break;
3080  case X86_INS_ADDPS:
3081  case X86_INS_ADDSD:
3082  case X86_INS_ADDSS:
3083  case X86_INS_ADDSUBPD:
3084  case X86_INS_ADDSUBPS:
3085  case X86_INS_ADDPD:
3086  // The OF, SF, ZF, AF, CF, and PF flags are set according to the
3087  // result.
3088  op->type = RZ_ANALYSIS_OP_TYPE_ADD;
3089  op_stackidx(op, insn, true);
3090  op->val = INSOP(1).imm;
3091  break;
3092  case X86_INS_ADD:
3093  // The OF, SF, ZF, AF, CF, and PF flags are set according to the
3094  // result.
3095  op->type = RZ_ANALYSIS_OP_TYPE_ADD;
3096  op_stackidx(op, insn, true);
3097  op0_memimmhandle(op, insn, addr, regsz);
3098  op1_memimmhandle(op, insn, addr, regsz);
3099  break;
3100  case X86_INS_ADC:
3101  op->type = RZ_ANALYSIS_OP_TYPE_ADD;
3102  break;
3103  /* Direction flag */
3104  case X86_INS_CLD:
3105  op->type = RZ_ANALYSIS_OP_TYPE_MOV;
3106  break;
3107  case X86_INS_STD:
3108  op->type = RZ_ANALYSIS_OP_TYPE_MOV;
3109  break;
3110  case X86_INS_SUBSD: // cvtss2sd
3111  case X86_INS_CVTSS2SD: // cvtss2sd
3112  break;
3113  }
3115  op->family = RZ_ANALYSIS_OP_FAMILY_MMX;
3116  }
3117  // TODO: add SSE* families?
3119  op->family = RZ_ANALYSIS_OP_FAMILY_SSE;
3120  }
3122  op->family = RZ_ANALYSIS_OP_FAMILY_SSE;
3123  }
3125  op->family = RZ_ANALYSIS_OP_FAMILY_SSE;
3126  }
3127 }
3128 
3129 static int cs_len_prefix_opcode(uint8_t *item) {
3130  int i, len = 0;
3131  for (i = 0; i < 4; i++) {
3132  len += (item[i] != 0) ? 1 : 0;
3133  }
3134  return len;
3135 }
3136 
3137 static inline int select_mode(RzAnalysis *a) {
3138  switch (a->bits) {
3139  case 64:
3140  return CS_MODE_64;
3141  case 32:
3142  return CS_MODE_32;
3143  case 16:
3144  return CS_MODE_16;
3145  default:
3146  return 0;
3147  }
3148 }
3149 
3151  X86CSContext *ctx = (X86CSContext *)a->plugin_data;
3152 
3153  int mode = select_mode(a);
3154  int n, ret;
3155 
3156  if (ctx->handle && mode != ctx->omode) {
3157  if (ctx->handle != 0) {
3158  cs_close(&ctx->handle);
3159  ctx->handle = 0;
3160  }
3161  }
3162  ctx->omode = mode;
3163  if (ctx->handle == 0) {
3164  ret = cs_open(CS_ARCH_X86, mode, &ctx->handle);
3165  if (ret != CS_ERR_OK) {
3166  ctx->handle = 0;
3167  return 0;
3168  }
3169  }
3170  op->cycles = 1; // aprox
3171  cs_option(ctx->handle, CS_OPT_DETAIL, CS_OPT_ON);
3172  // capstone-next
3173  n = cs_disasm(ctx->handle, (const ut8 *)buf, len, addr, 1, &ctx->insn);
3174  if (n < 1) {
3175  op->type = RZ_ANALYSIS_OP_TYPE_ILL;
3177  op->mnemonic = strdup("invalid");
3178  }
3179  } else {
3181  op->mnemonic = rz_str_newf("%s%s%s",
3182  ctx->insn->mnemonic,
3183  ctx->insn->op_str[0] ? " " : "",
3184  ctx->insn->op_str);
3185  }
3186 
3187  op->nopcode = cs_len_prefix_opcode(ctx->insn->detail->x86.prefix) + cs_len_prefix_opcode(ctx->insn->detail->x86.opcode);
3188  op->size = ctx->insn->size;
3189  op->id = ctx->insn->id;
3190  op->family = RZ_ANALYSIS_OP_FAMILY_CPU; // almost everything is CPU
3191  op->prefix = 0;
3192  op->cond = cond_x862r2(ctx->insn->id);
3193  switch (ctx->insn->detail->x86.prefix[0]) {
3194  case X86_PREFIX_REPNE:
3195  op->prefix |= RZ_ANALYSIS_OP_PREFIX_REPNE;
3196  break;
3197  case X86_PREFIX_REP:
3198  op->prefix |= RZ_ANALYSIS_OP_PREFIX_REP;
3199  break;
3200  case X86_PREFIX_LOCK:
3201  op->prefix |= RZ_ANALYSIS_OP_PREFIX_LOCK;
3202  op->family = RZ_ANALYSIS_OP_FAMILY_THREAD; // XXX ?
3203  break;
3204  }
3205  anop(a, op, addr, buf, len, &ctx->handle, ctx->insn);
3206  set_opdir(op, ctx->insn);
3208  anop_esil(a, op, addr, buf, len, &ctx->handle, ctx->insn);
3209  }
3211  opex(&op->opex, ctx, mode);
3212  }
3213  if (mask & RZ_ANALYSIS_OP_MASK_VAL) {
3214  op_fillval(a, op, &ctx->handle, ctx->insn, mode);
3215  }
3216  }
3217  //#if X86_GRP_PRIVILEGE>0
3218  if (ctx->insn) {
3219 #if HAVE_CSGRP_PRIVILEGE
3220  if (cs_insn_group(ctx->handle, ctx->insn, X86_GRP_PRIVILEGE)) {
3221  op->family = RZ_ANALYSIS_OP_FAMILY_PRIV;
3222  }
3223 #endif
3224  cs_free(ctx->insn, n);
3225  }
3226  // cs_close (&ctx->handle);
3227  return op->size;
3228 }
3229 
3231  if (!esil) {
3232  return false;
3233  }
3234  // XXX. this depends on kernel
3235  // rz_analysis_esil_set_interrupt (esil, 0x80, x86_int_0x80);
3236  /* disable by default */
3237  // rz_analysis_esil_set_interrupt (esil, 0x80, NULL); // this is stupid, don't do this
3238  return true;
3239 }
3240 
3241 static bool x86_init(void **user) {
3243  if (!ctx) {
3244  return false;
3245  }
3246  *user = ctx;
3247  return true;
3248 }
3249 
3250 static bool x86_fini(void *user) {
3251  rz_return_val_if_fail(user, false);
3252  X86CSContext *ctx = (X86CSContext *)user;
3253  cs_close(&ctx->handle);
3254  free(ctx);
3255  return true;
3256 }
3257 
3259  return true;
3260 }
3261 
3262 static char *get_reg_profile(RzAnalysis *analysis) {
3263  const char *p = NULL;
3264  switch (analysis->bits) {
3265  case 16: p =
3266  "=PC ip\n"
3267  "=SP sp\n"
3268  "=BP bp\n"
3269  "=A0 ax\n"
3270  "=A1 bx\n"
3271  "=A2 cx\n"
3272  "=A3 dx\n"
3273  "=A4 si\n"
3274  "=A5 di\n"
3275  "=SN ah\n"
3276  "gpr ip .16 48 0\n"
3277  "gpr ax .16 24 0\n"
3278  "gpr ah .8 25 0\n"
3279  "gpr al .8 24 0\n"
3280  "gpr bx .16 0 0\n"
3281  "gpr bh .8 1 0\n"
3282  "gpr bl .8 0 0\n"
3283  "gpr cx .16 4 0\n"
3284  "gpr ch .8 5 0\n"
3285  "gpr cl .8 4 0\n"
3286  "gpr dx .16 8 0\n"
3287  "gpr dh .8 9 0\n"
3288  "gpr dl .8 8 0\n"
3289  "gpr sp .16 60 0\n"
3290  "gpr bp .16 20 0\n"
3291  "gpr si .16 12 0\n"
3292  "gpr di .16 16 0\n"
3293  "seg cs .16 52 0\n"
3294  "seg ss .16 54 0\n"
3295  "seg ds .16 56 0\n"
3296  "seg es .16 58 0\n"
3297  "gpr flags .16 56 0\n"
3298  "flg cf .1 .448 0\n"
3299  "flg pf .1 .449 0\n"
3300  "flg af .1 .450 0\n"
3301  "flg zf .1 .451 0\n"
3302  "flg sf .1 .452 0\n"
3303  "flg tf .1 .453 0\n"
3304  "flg if .1 .454 0\n"
3305  "flg df .1 .455 0\n"
3306  "flg of .1 .456 0\n"
3307  "flg rf .1 .457 0\n";
3308 #if 0
3309  "drx dr0 .32 0 0\n"
3310  "drx dr1 .32 4 0\n"
3311  "drx dr2 .32 8 0\n"
3312  "drx dr3 .32 12 0\n"
3313  //"drx dr4 .32 16 0\n"
3314  //"drx dr5 .32 20 0\n"
3315  "drx dr6 .32 24 0\n"
3316  "drx dr7 .32 28 0\n"
3317 #endif
3318  break;
3319  case 32:
3320  p =
3321  "=PC eip\n"
3322  "=SP esp\n"
3323  "=BP ebp\n"
3324  "=A0 eax\n"
3325  "=A1 ebx\n"
3326  "=A2 ecx\n"
3327  "=A3 edx\n"
3328  "=A4 esi\n"
3329  "=A5 edi\n"
3330  "=SN eax\n"
3331  "gpr oeax .32 44 0\n"
3332  "gpr eax .32 24 0\n"
3333  "gpr ax .16 24 0\n"
3334  "gpr ah .8 25 0\n"
3335  "gpr al .8 24 0\n"
3336  "gpr ebx .32 0 0\n"
3337  "gpr bx .16 0 0\n"
3338  "gpr bh .8 1 0\n"
3339  "gpr bl .8 0 0\n"
3340  "gpr ecx .32 4 0\n"
3341  "gpr cx .16 4 0\n"
3342  "gpr ch .8 5 0\n"
3343  "gpr cl .8 4 0\n"
3344  "gpr edx .32 8 0\n"
3345  "gpr dx .16 8 0\n"
3346  "gpr dh .8 9 0\n"
3347  "gpr dl .8 8 0\n"
3348  "gpr esi .32 12 0\n"
3349  "gpr si .16 12 0\n"
3350  "gpr edi .32 16 0\n"
3351  "gpr di .16 16 0\n"
3352  "gpr esp .32 60 0\n"
3353  "gpr sp .16 60 0\n"
3354  "gpr ebp .32 20 0\n"
3355  "gpr bp .16 20 0\n"
3356  "gpr eip .32 48 0\n"
3357  "gpr ip .16 48 0\n"
3358  "seg xfs .32 36 0\n"
3359  "seg xgs .32 40 0\n"
3360  "seg xcs .32 52 0\n"
3361  "seg cs .16 52 0\n"
3362  "seg xss .32 52 0\n"
3363  "flg eflags .32 .448 0 c1p.a.zstido.n.rv\n"
3364  "flg flags .16 .448 0\n"
3365  "flg cf .1 .448 0\n"
3366  "flg pf .1 .450 0\n"
3367  "flg af .1 .452 0\n"
3368  "flg zf .1 .454 0\n"
3369  "flg sf .1 .455 0\n"
3370  "flg tf .1 .456 0\n"
3371  "flg if .1 .457 0\n"
3372  "flg df .1 .458 0\n"
3373  "flg of .1 .459 0\n"
3374  "flg nt .1 .462 0\n"
3375  "flg rf .1 .464 0\n"
3376  "flg vm .1 .465 0\n"
3377  "drx dr0 .32 0 0\n"
3378  "drx dr1 .32 4 0\n"
3379  "drx dr2 .32 8 0\n"
3380  "drx dr3 .32 12 0\n"
3381  //"drx dr4 .32 16 0\n"
3382  //"drx dr5 .32 20 0\n"
3383  "drx dr6 .32 24 0\n"
3384  "drx dr7 .32 28 0\n"
3385  "xmm@fpu xmm0 .128 160 4\n"
3386  "fpu xmm0l .64 160 0\n"
3387  "fpu xmm0h .64 168 0\n"
3388 
3389  "xmm@fpu xmm1 .128 176 4\n"
3390  "fpu xmm1l .64 176 0\n"
3391  "fpu xmm1h .64 184 0\n"
3392 
3393  "xmm@fpu xmm2 .128 192 4\n"
3394  "fpu xmm2l .64 192 0\n"
3395  "fpu xmm2h .64 200 0\n"
3396 
3397  "xmm@fpu xmm3 .128 208 4\n"
3398  "fpu xmm3l .64 208 0\n"
3399  "fpu xmm3h .64 216 0\n"
3400 
3401  "xmm@fpu xmm4 .128 224 4\n"
3402  "fpu xmm4l .64 224 0\n"
3403  "fpu xmm4h .64 232 0\n"
3404 
3405  "xmm@fpu xmm5 .128 240 4\n"
3406  "fpu xmm5l .64 240 0\n"
3407  "fpu xmm5h .64 248 0\n"
3408 
3409  "xmm@fpu xmm6 .128 256 4\n"
3410  "fpu xmm6l .64 256 0\n"
3411  "fpu xmm6h .64 264 0\n"
3412 
3413  "xmm@fpu xmm7 .128 272 4\n"
3414  "fpu xmm7l .64 272 0\n"
3415  "fpu xmm7h .64 280 0\n";
3416 
3417  break;
3418  case 64: {
3419  const char *cc = rz_analysis_cc_default(analysis);
3420  const char *args_prof = cc && !strcmp(cc, "ms")
3421  ? // Microsoft x64 CC
3422  "# RAX return value\n"
3423  "# RCX argument 1\n"
3424  "# RDX argument 2\n"
3425  "# R8 argument 3\n"
3426  "# R9 argument 4\n"
3427  "# R10-R11 syscall/sysret\n"
3428  "# R12-R15 GP preserved\n"
3429  "# RSI preserved source\n"
3430  "# RDI preserved destination\n"
3431  "# RSP stack pointer\n"
3432  "=PC rip\n"
3433  "=SP rsp\n"
3434  "=BP rbp\n"
3435  "=A0 rcx\n"
3436  "=A1 rdx\n"
3437  "=A2 r8\n"
3438  "=A3 r9\n"
3439  "=SN rax\n"
3440  : // System V AMD64 ABI
3441  "=PC rip\n"
3442  "=SP rsp\n"
3443  "=BP rbp\n"
3444  "=A0 rdi\n"
3445  "=A1 rsi\n"
3446  "=A2 rdx\n"
3447  "=A3 rcx\n"
3448  "=A4 r8\n"
3449  "=A5 r9\n"
3450  "=A6 r10\n"
3451  "=A7 r11\n"
3452  "=SN rax\n";
3453  char *prof = rz_str_newf("%s%s", args_prof,
3454  "gpr rax .64 80 0\n"
3455  "gpr eax .32 80 0\n"
3456  "gpr ax .16 80 0\n"
3457  "gpr al .8 80 0\n"
3458  "gpr ah .8 81 0\n"
3459  "gpr rbx .64 40 0\n"
3460  "gpr ebx .32 40 0\n"
3461  "gpr bx .16 40 0\n"
3462  "gpr bl .8 40 0\n"
3463  "gpr bh .8 41 0\n"
3464  "gpr rcx .64 88 0\n"
3465  "gpr ecx .32 88 0\n"
3466  "gpr cx .16 88 0\n"
3467  "gpr cl .8 88 0\n"
3468  "gpr ch .8 89 0\n"
3469  "gpr rdx .64 96 0\n"
3470  "gpr edx .32 96 0\n"
3471  "gpr dx .16 96 0\n"
3472  "gpr dl .8 96 0\n"
3473  "gpr dh .8 97 0\n"
3474  "gpr rsi .64 104 0\n"
3475  "gpr esi .32 104 0\n"
3476  "gpr si .16 104 0\n"
3477  "gpr sil .8 104 0\n"
3478  "gpr rdi .64 112 0\n"
3479  "gpr edi .32 112 0\n"
3480  "gpr di .16 112 0\n"
3481  "gpr dil .8 112 0\n"
3482  "gpr r8 .64 72 0\n"
3483  "gpr r8d .32 72 0\n"
3484  "gpr r8w .16 72 0\n"
3485  "gpr r8b .8 72 0\n"
3486  "gpr r9 .64 64 0\n"
3487  "gpr r9d .32 64 0\n"
3488  "gpr r9w .16 64 0\n"
3489  "gpr r9b .8 64 0\n"
3490  "gpr r10 .64 56 0\n"
3491  "gpr r10d .32 56 0\n"
3492  "gpr r10w .16 56 0\n"
3493  "gpr r10b .8 56 0\n"
3494  "gpr r11 .64 48 0\n"
3495  "gpr r11d .32 48 0\n"
3496  "gpr r11w .16 48 0\n"
3497  "gpr r11b .8 48 0\n"
3498  "gpr r12 .64 24 0\n"
3499  "gpr r12d .32 24 0\n"
3500  "gpr r12w .16 24 0\n"
3501  "gpr r12b .8 24 0\n"
3502  "gpr r13 .64 16 0\n"
3503  "gpr r13d .32 16 0\n"
3504  "gpr r13w .16 16 0\n"
3505  "gpr r13b .8 16 0\n"
3506  "gpr r14 .64 8 0\n"
3507  "gpr r14d .32 8 0\n"
3508  "gpr r14w .16 8 0\n"
3509  "gpr r14b .8 8 0\n"
3510  "gpr r15 .64 0 0\n"
3511  "gpr r15d .32 0 0\n"
3512  "gpr r15w .16 0 0\n"
3513  "gpr r15b .8 0 0\n"
3514  "gpr rip .64 128 0\n"
3515  "gpr rbp .64 32 0\n"
3516  "gpr ebp .32 32 0\n"
3517  "gpr bp .16 32 0\n"
3518  "gpr bpl .8 32 0\n"
3519  "seg cs .64 136 0\n"
3520  "flg rflags .64 144 0 c1p.a.zstido.n.rv\n"
3521  "flg eflags .32 144 0 c1p.a.zstido.n.rv\n"
3522  "flg cf .1 144.0 0 carry\n"
3523  "flg pf .1 144.2 0 parity\n"
3524  //"gpr cf .1 .1152 0 carry\n"
3525  //"gpr pf .1 .1154 0 parity\n"
3526  "flg af .1 144.4 0 adjust\n"
3527  "flg zf .1 144.6 0 zero\n"
3528  "flg sf .1 144.7 0 sign\n"
3529  "flg tf .1 .1160 0 trap\n"
3530  "flg if .1 .1161 0 interrupt\n"
3531  "flg df .1 .1162 0 direction\n"
3532  "flg of .1 .1163 0 overflow\n"
3533 
3534  "gpr rsp .64 152 0\n"
3535  "gpr esp .32 152 0\n"
3536  "gpr sp .16 152 0\n"
3537  "gpr spl .8 152 0\n"
3538  "seg ss .64 160 0\n"
3539  "seg fs_base .64 168 0\n"
3540  "seg gs_base .64 176 0\n"
3541  "seg ds .64 184 0\n"
3542  "seg es .64 192 0\n"
3543  "seg fs .64 200 0\n"
3544  "seg gs .64 208 0\n"
3545  "drx dr0 .64 0 0\n"
3546  "drx dr1 .64 8 0\n"
3547  "drx dr2 .64 16 0\n"
3548  "drx dr3 .64 24 0\n"
3549  // dr4 32
3550  // dr5 40
3551  "drx dr6 .64 48 0\n"
3552  "drx dr7 .64 56 0\n"
3553 
3554  /*0030 struct user_fpregs_struct
3555  0031 {
3556  0032 __uint16_t cwd;
3557  0033 __uint16_t swd;
3558  0034 __uint16_t ftw;
3559  0035 __uint16_t fop;
3560  0036 __uint64_t rip;
3561  0037 __uint64_t rdp;
3562  0038 __uint32_t mxcsr;
3563  0039 __uint32_t mxcr_mask;
3564  0040 __uint32_t st_space[32]; // 8*16 bytes for each FP-reg = 128 bytes
3565  0041 __uint32_t xmm_space[64]; // 16*16 bytes for each XMM-reg = 256 bytes
3566  0042 __uint32_t padding[24];
3567  0043 };
3568  */
3569  "fpu cwd .16 0 0\n"
3570  "fpu swd .16 2 0\n"
3571  "fpu ftw .16 4 0\n"
3572  "fpu fop .16 6 0\n"
3573  "fpu frip .64 8 0\n"
3574  "fpu frdp .64 16 0\n"
3575  "fpu mxcsr .32 24 0\n"
3576  "fpu mxcr_mask .32 28 0\n"
3577 
3578  "fpu st0 .64 32 0\n"
3579  "fpu st1 .64 48 0\n"
3580  "fpu st2 .64 64 0\n"
3581  "fpu st3 .64 80 0\n"
3582  "fpu st4 .64 96 0\n"
3583  "fpu st5 .64 112 0\n"
3584  "fpu st6 .64 128 0\n"
3585  "fpu st7 .64 144 0\n"
3586 
3587  "xmm@fpu xmm0 .128 160 4\n"
3588  "fpu xmm0l .64 160 0\n"
3589  "fpu xmm0h .64 168 0\n"
3590 
3591  "xmm@fpu xmm1 .128 176 4\n"
3592  "fpu xmm1l .64 176 0\n"
3593  "fpu xmm1h .64 184 0\n"
3594 
3595  "xmm@fpu xmm2 .128 192 4\n"
3596  "fpu xmm2l .64 192 0\n"
3597  "fpu xmm2h .64 200 0\n"
3598 
3599  "xmm@fpu xmm3 .128 208 4\n"
3600  "fpu xmm3l .64 208 0\n"
3601  "fpu xmm3h .64 216 0\n"
3602 
3603  "xmm@fpu xmm4 .128 224 4\n"
3604  "fpu xmm4l .64 224 0\n"
3605  "fpu xmm4h .64 232 0\n"
3606 
3607  "xmm@fpu xmm5 .128 240 4\n"
3608  "fpu xmm5l .64 240 0\n"
3609  "fpu xmm5h .64 248 0\n"
3610 
3611  "xmm@fpu xmm6 .128 256 4\n"
3612  "fpu xmm6l .64 256 0\n"
3613  "fpu xmm6h .64 264 0\n"
3614 
3615  "xmm@fpu xmm7 .128 272 4\n"
3616  "fpu xmm7l .64 272 0\n"
3617  "fpu xmm7h .64 280 0\n"
3618  "fpu x64 .64 288 0\n");
3619  return prof;
3620  }
3621 #if 0
3622  default: p= /* XXX */
3623  "=PC rip\n"
3624  "=SP rsp\n"
3625  "=BP rbp\n"
3626  "=A0 rax\n"
3627  "=A1 rbx\n"
3628  "=A2 rcx\n"
3629  "=A3 rdx\n"
3630  "# no profile defined for x86-64\n"
3631  "gpr r15 .64 0 0\n"
3632  "gpr r14 .64 8 0\n"
3633  "gpr r13 .64 16 0\n"
3634  "gpr r12 .64 24 0\n"
3635  "gpr rbp .64 32 0\n"
3636  "gpr ebp .32 32 0\n"
3637  "gpr rbx .64 40 0\n"
3638  "gpr ebx .32 40 0\n"
3639  "gpr bx .16 40 0\n"
3640  "gpr bh .8 41 0\n"
3641  "gpr bl .8 40 0\n"
3642  "gpr r11 .64 48 0\n"
3643  "gpr r10 .64 56 0\n"
3644  "gpr r9 .64 64 0\n"
3645  "gpr r8 .64 72 0\n"
3646  "gpr rax .64 80 0\n"
3647  "gpr eax .32 80 0\n"
3648  "gpr rcx .64 88 0\n"
3649  "gpr ecx .32 88 0\n"
3650  "gpr rdx .64 96 0\n"
3651  "gpr edx .32 96 0\n"
3652  "gpr rsi .64 104 0\n"
3653  "gpr esi .32 104 0\n"
3654  "gpr rdi .64 112 0\n"
3655  "gpr edi .32 112 0\n"
3656  "gpr oeax .64 120 0\n"
3657  "gpr rip .64 128 0\n"
3658  "seg cs .64 136 0\n"
3659  //"flg eflags .64 144 0\n"
3660  "gpr eflags .32 144 0 c1p.a.zstido.n.rv\n"
3661  "flg cf .1 .1152 0\n"
3662  "flg pf .1 .1153 0\n"
3663  "flg af .1 .1154 0\n"
3664  "flg zf .1 .1155 0\n"
3665  "flg sf .1 .1156 0\n"
3666  "flg tf .1 .1157 0\n"
3667  "flg if .1 .1158 0\n"
3668  "flg df .1 .1159 0\n"
3669  "flg of .1 .1160 0\n"
3670  "flg rf .1 .1161 0\n"
3671  "gpr rsp .64 152 0\n"
3672  "seg ss .64 160 0\n"
3673  "seg fs_base .64 168 0\n"
3674  "seg gs_base .64 176 0\n"
3675  "seg ds .64 184 0\n"
3676  "seg es .64 192 0\n"
3677  "seg fs .64 200 0\n"
3678  "seg gs .64 208 0\n"
3679  "drx dr0 .32 0 0\n"
3680  "drx dr1 .32 4 0\n"
3681  "drx dr2 .32 8 0\n"
3682  "drx dr3 .32 12 0\n"
3683  "drx dr6 .32 24 0\n"
3684  "drx dr7 .32 28 0\n";
3685  break;
3686 #endif
3687  }
3688  return (p && *p) ? strdup(p) : NULL;
3689 }
3690 
3691 static int archinfo(RzAnalysis *analysis, int q) {
3692  switch (q) {
3694  return 0;
3696  return 16;
3698  return 1;
3699  }
3700  return 0;
3701 }
3702 
3704 #define KW(d, ds, m, ms) rz_list_append(l, rz_search_keyword_new((const ut8 *)d, ds, (const ut8 *)m, ms, NULL))
3706  switch (analysis->bits) {
3707  case 32:
3708  KW("\x8b\xff\x55\x8b\xec", 5, NULL, 0);
3709  KW("\x55\x89\xe5", 3, NULL, 0);
3710  KW("\x55\x8b\xec", 3, NULL, 0);
3711  KW("\xf3\x0f\x1e\xfb", 4, NULL, 0); // endbr32
3712  break;
3713  case 64:
3714  KW("\x55\x48\x89\xe5", 4, NULL, 0);
3715  KW("\x55\x48\x8b\xec", 4, NULL, 0);
3716  KW("\xf3\x0f\x1e\xfa", 4, NULL, 0); // endbr64
3717  break;
3718  default:
3719  rz_list_free(l);
3720  l = NULL;
3721  break;
3722  }
3723  return l;
3724 }
3725 
3727  .name = "x86",
3728  .desc = "Capstone X86 analysis",
3729  .esil = true,
3730  .license = "BSD",
3731  .arch = "x86",
3732  .bits = 16 | 32 | 64,
3733  .op = &analop,
3734  .preludes = analysis_preludes,
3735  .archinfo = archinfo,
3736  .get_reg_profile = &get_reg_profile,
3737  .init = x86_init,
3738  .fini = x86_fini,
3739  .esil_init = esil_x86_cs_init,
3740  .esil_fini = esil_x86_cs_fini,
3741  // .esil_intr = esil_x86_cs_intr,
3742 };
3743 
3744 #ifndef RZ_PLUGIN_INCORE
3747  .data = &rz_analysis_plugin_x86_cs,
3748  .version = RZ_VERSION
3749 };
3750 #endif
size_t len
Definition: 6502dis.c:15
ut8 op
Definition: 6502dis.c:13
si
RZ_API void rz_analysis_value_free(RzAnalysisValue *value)
Definition: value.c:29
RZ_API RzAnalysisValue * rz_analysis_value_new(void)
Definition: value.c:6
#define rs()
#define mask()
#define imm
#define DST_W_AR
static int esil_x86_cs_init(RzAnalysisEsil *esil)
static void opex(RzStrBuf *buf, X86CSContext *ctx, int mode)
static bool x86_fini(void *user)
static void set_access_info(RzReg *reg, RzAnalysisOp *op, csh *handle, cs_insn *insn, int mode)
static void hidden_op(cs_insn *insn, cs_x86 *x, int mode)
static void anop_esil(RzAnalysis *a, RzAnalysisOp *op, ut64 addr, const ut8 *buf, int len, csh *handle, cs_insn *insn)
#define CREATE_SRC_DST(op)
static char * get_reg_profile(RzAnalysis *analysis)
static void set_opdir(RzAnalysisOp *op, cs_insn *insn)
#define CYCLE_REG
RzAnalysisPlugin rz_analysis_plugin_x86_cs
static int select_mode(RzAnalysis *a)
static char * getarg(struct Getarg *gop, int n, int set, char *setop, int sel, ut32 *bitsize)
static void op1_memimmhandle(RzAnalysisOp *op, cs_insn *insn, ut64 addr, int regsz)
static void op_fillval(RzAnalysis *a, RzAnalysisOp *op, csh *handle, cs_insn *insn, int mode)
static void op0_memimmhandle(RzAnalysisOp *op, cs_insn *insn, ut64 addr, int regsz)
static const char * reg32_to_name(ut8 reg)
#define BUF_SZ
#define INSOPS
#define DST_R_AR
#define INSOP(n)
static bool x86_init(void **user)
#define KW(d, ds, m, ms)
#define ARG0_AR
static bool is_xmm_reg(cs_x86_op op)
static int analop(RzAnalysis *a, RzAnalysisOp *op, ut64 addr, const ut8 *buf, int len, RzAnalysisOpMask mask)
#define DST_AR
#define CYCLE_JMP
#define ISIMM(x)
RZ_API RzLibStruct rizin_plugin
#define ARG1_AR
struct x86_cs_context_t X86CSContext
static void op_stackidx(RzAnalysisOp *op, cs_insn *insn, bool minus)
static RzRegItem * cs_reg2reg(RzReg *reg, csh *h, int id)
#define DST2_AR
#define SRC2_AR
#define CYCLE_MEM
static void set_src_dst(RzReg *reg, RzAnalysisValue *val, csh *handle, cs_insn *insn, int x)
static int esil_x86_cs_fini(RzAnalysisEsil *esil)
static int cond_x862r2(int id)
static int archinfo(RzAnalysis *analysis, int q)
static void anop(RzAnalysis *a, RzAnalysisOp *op, ut64 addr, const ut8 *buf, int len, csh *handle, cs_insn *insn)
static RzList * analysis_preludes(RzAnalysis *analysis)
#define DSTADD_AR
#define ARG2_AR
#define AR_DIM
static int cs_len_prefix_opcode(uint8_t *item)
#define SRC_AR
lzma_index ** i
Definition: index.h:629
lzma_index * src
Definition: index.h:567
#define setarg(i, v, pos, size)
Definition: arch_53.h:173
static RzILOpEffect * sel(cs_insn *insn, bool is_thumb)
Definition: arm_il32.c:1869
ut16 val
Definition: armass64_const.h:6
static mcore_handle handle
Definition: asm_mcore.c:8
int jump(int a, int b)
Definition: bcj_test.c:35
int call(int a, int b)
Definition: bcj_test.c:25
int bits(struct state *s, int need)
Definition: blast.c:72
const lzma_allocator const uint8_t * in
Definition: block.h:527
const lzma_allocator const uint8_t size_t uint8_t * out
Definition: block.h:528
@ 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_DETAIL
Break down instruction structure into details.
Definition: capstone.h:171
size_t csh
Definition: capstone.h:71
@ CS_OPT_ON
Turn ON an option (CS_OPT_DETAIL, CS_OPT_SKIPDATA).
Definition: capstone.h:183
@ CS_AC_INVALID
Uninitialized/invalid access type.
Definition: capstone.h:203
@ CS_AC_READ
Operand read from memory or register.
Definition: capstone.h:204
@ CS_AC_WRITE
Operand write to memory or register.
Definition: capstone.h:205
@ X86_PREFIX_LOCK
lock (cs_x86.prefix[0]
Definition: x86.h:248
@ X86_PREFIX_REPNE
repne/repnz (cs_x86.prefix[0]
Definition: x86.h:251
@ X86_PREFIX_REP
rep (cs_x86.prefix[0]
Definition: x86.h:249
@ X86_INS_VMOVNTDQ
Definition: x86.h:1328
@ X86_INS_FISUB
Definition: x86.h:1078
@ X86_INS_FXRSTOR
Definition: x86.h:576
@ X86_INS_FIST
Definition: x86.h:621
@ X86_INS_VALIGND
Definition: x86.h:1113
@ X86_INS_FNINIT
Definition: x86.h:559
@ X86_INS_PAUSE
Definition: x86.h:887
@ X86_INS_LODSQ
Definition: x86.h:723
@ X86_INS_FXTRACT
Definition: x86.h:580
@ X86_INS_VPCMPEQQ
Definition: x86.h:1395
@ X86_INS_FIDIV
Definition: x86.h:529
@ X86_INS_MOVNTSS
Definition: x86.h:855
@ X86_INS_RDMSR
Definition: x86.h:986
@ X86_INS_ROL
Definition: x86.h:992
@ X86_INS_PCMPGTB
Definition: x86.h:780
@ X86_INS_JGE
Definition: x86.h:646
@ X86_INS_AESDEC
Definition: x86.h:406
@ X86_INS_SETO
Definition: x86.h:1025
@ X86_INS_POPAW
Definition: x86.h:953
@ X86_INS_FLD1
Definition: x86.h:706
@ X86_INS_LODSD
Definition: x86.h:722
@ X86_INS_SETBE
Definition: x86.h:1014
@ X86_INS_VXORPS
Definition: x86.h:1261
@ X86_INS_MOV
Definition: x86.h:835
@ X86_INS_FDECSTP
Definition: x86.h:545
@ X86_INS_VPCMPESTRI
Definition: x86.h:1397
@ X86_INS_ANDNPS
Definition: x86.h:414
@ X86_INS_INT
Definition: x86.h:607
@ X86_INS_FSUBRP
Definition: x86.h:1074
@ X86_INS_MULX
Definition: x86.h:874
@ X86_INS_FPATAN
Definition: x86.h:563
@ X86_INS_RDPMC
Definition: x86.h:987
@ X86_INS_JAE
Definition: x86.h:639
@ X86_INS_LCALL
Definition: x86.h:540
@ X86_INS_FCMOVNU
Definition: x86.h:475
@ X86_INS_MOVHPS
Definition: x86.h:843
@ X86_INS_FADD
Definition: x86.h:401
@ X86_INS_ANDNPD
Definition: x86.h:413
@ X86_INS_JNE
Definition: x86.h:651
@ X86_INS_FUCOMP
Definition: x86.h:1094
@ X86_INS_MULPS
Definition: x86.h:871
@ X86_INS_SETAE
Definition: x86.h:1012
@ X86_INS_MOVLPS
Definition: x86.h:846
@ X86_INS_AESKEYGENASSIST
Definition: x86.h:410
@ X86_INS_CLGI
Definition: x86.h:452
@ X86_INS_SYSENTER
Definition: x86.h:1082
@ X86_INS_SHA1RNDS4
Definition: x86.h:1033
@ X86_INS_FNCLEX
Definition: x86.h:558
@ X86_INS_SETNP
Definition: x86.h:1023
@ X86_INS_CLTS
Definition: x86.h:454
@ X86_INS_FLDL2E
Definition: x86.h:553
@ X86_INS_PACKSSDW
Definition: x86.h:761
@ X86_INS_RET
Definition: x86.h:533
@ X86_INS_VMOVNTDQA
Definition: x86.h:1327
@ X86_INS_VMMCALL
Definition: x86.h:1307
@ X86_INS_AESDECLAST
Definition: x86.h:405
@ X86_INS_STOSQ
Definition: x86.h:1063
@ X86_INS_FLDLN2
Definition: x86.h:556
@ X86_INS_PSUBB
Definition: x86.h:818
@ X86_INS_LOOP
Definition: x86.h:725
@ X86_INS_MOVNTPD
Definition: x86.h:852
@ X86_INS_VMOVNTPD
Definition: x86.h:1329
@ X86_INS_ADDSUBPD
Definition: x86.h:399
@ X86_INS_RETFQ
Definition: x86.h:729
@ X86_INS_JL
Definition: x86.h:649
@ X86_INS_FDIV
Definition: x86.h:528
@ X86_INS_AND
Definition: x86.h:411
@ X86_INS_AESENCLAST
Definition: x86.h:407
@ X86_INS_FNSTCW
Definition: x86.h:561
@ X86_INS_NOP
Definition: x86.h:880
@ X86_INS_SHR
Definition: x86.h:1040
@ X86_INS_SHA1MSG1
Definition: x86.h:1030
@ X86_INS_VPCMPGTQ
Definition: x86.h:1401
@ X86_INS_SHRD
Definition: x86.h:1041
@ X86_INS_AESENC
Definition: x86.h:408
@ X86_INS_SETG
Definition: x86.h:1018
@ X86_INS_FUCOMI
Definition: x86.h:1092
@ X86_INS_PUSHAW
Definition: x86.h:975
@ X86_INS_SETL
Definition: x86.h:1020
@ X86_INS_XORPS
Definition: x86.h:590
@ X86_INS_VPCMPEQB
Definition: x86.h:1393
@ X86_INS_INTO
Definition: x86.h:610
@ X86_INS_RCR
Definition: x86.h:983
@ X86_INS_OUTSW
Definition: x86.h:885
@ X86_INS_LOOPE
Definition: x86.h:726
@ X86_INS_PCMPISTRI
Definition: x86.h:896
@ X86_INS_FYL2X
Definition: x86.h:581
@ X86_INS_MOVDQ2Q
Definition: x86.h:754
@ X86_INS_SETLE
Definition: x86.h:1019
@ X86_INS_UD0
Definition: x86.h:1894
@ X86_INS_PCMPEQD
Definition: x86.h:778
@ X86_INS_FRSTOR
Definition: x86.h:569
@ X86_INS_VPCMPQ
Definition: x86.h:1405
@ X86_INS_CRC32
Definition: x86.h:497
@ X86_INS_CMPSW
Definition: x86.h:484
@ X86_INS_XADD
Definition: x86.h:733
@ X86_INS_PSUBQ
Definition: x86.h:820
@ X86_INS_SYSRET
Definition: x86.h:1084
@ X86_INS_BTR
Definition: x86.h:439
@ X86_INS_FSQRT
Definition: x86.h:1054
@ X86_INS_PADDW
Definition: x86.h:771
@ X86_INS_IMUL
Definition: x86.h:599
@ X86_INS_FICOMP
Definition: x86.h:549
@ X86_INS_VPCMPUQ
Definition: x86.h:1408
@ X86_INS_BSWAP
Definition: x86.h:436
@ X86_INS_CDQE
Definition: x86.h:445
@ X86_INS_ADC
Definition: x86.h:392
@ X86_INS_XOR
Definition: x86.h:720
@ X86_INS_CMOVA
Definition: x86.h:457
@ X86_INS_VPCMPISTRI
Definition: x86.h:1403
@ X86_INS_RDRAND
Definition: x86.h:988
@ X86_INS_FST
Definition: x86.h:1066
@ X86_INS_FICOM
Definition: x86.h:548
@ X86_INS_POP
Definition: x86.h:952
@ X86_INS_OUT
Definition: x86.h:882
@ X86_INS_ENTER
Definition: x86.h:536
@ X86_INS_STI
Definition: x86.h:1059
@ X86_INS_PACKUSWB
Definition: x86.h:763
@ X86_INS_CMOVAE
Definition: x86.h:458
@ X86_INS_MOVSS
Definition: x86.h:861
@ X86_INS_MOVNTSD
Definition: x86.h:854
@ X86_INS_CMPPD
Definition: x86.h:1748
@ X86_INS_STD
Definition: x86.h:1057
@ X86_INS_CMOVO
Definition: x86.h:477
@ X86_INS_VPCMPEQW
Definition: x86.h:1396
@ X86_INS_ADDPS
Definition: x86.h:396
@ X86_INS_VPCMPB
Definition: x86.h:1391
@ X86_INS_AAM
Definition: x86.h:389
@ X86_INS_CMOVNS
Definition: x86.h:476
@ X86_INS_SYSEXIT
Definition: x86.h:1083
@ X86_INS_JBE
Definition: x86.h:641
@ X86_INS_VPCMPISTRM
Definition: x86.h:1404
@ X86_INS_PCMPISTRM
Definition: x86.h:897
@ X86_INS_SBB
Definition: x86.h:1007
@ X86_INS_MOVSW
Definition: x86.h:862
@ X86_INS_MULSD
Definition: x86.h:872
@ X86_INS_FLD
Definition: x86.h:707
@ X86_INS_SUBSD
Definition: x86.h:1075
@ X86_INS_AAA
Definition: x86.h:387
@ X86_INS_BTC
Definition: x86.h:438
@ X86_INS_CMOVBE
Definition: x86.h:460
@ X86_INS_PFADD
Definition: x86.h:907
@ X86_INS_FCMOVNE
Definition: x86.h:472
@ X86_INS_FNSTENV
Definition: x86.h:574
@ X86_INS_CMP
Definition: x86.h:481
@ X86_INS_PSUBD
Definition: x86.h:819
@ X86_INS_PADDD
Definition: x86.h:765
@ X86_INS_VPCMPUW
Definition: x86.h:1409
@ X86_INS_FPREM1
Definition: x86.h:565
@ X86_INS_FDIVR
Definition: x86.h:523
@ X86_INS_FNSTSW
Definition: x86.h:562
@ X86_INS_VPCMPGTW
Definition: x86.h:1402
@ X86_INS_FINCSTP
Definition: x86.h:550
@ X86_INS_FBLD
Definition: x86.h:542
@ X86_INS_BSF
Definition: x86.h:434
@ X86_INS_PCMPEQQ
Definition: x86.h:892
@ X86_INS_FDIVRP
Definition: x86.h:525
@ X86_INS_FLDLG2
Definition: x86.h:555
@ X86_INS_JB
Definition: x86.h:642
@ X86_INS_VPXOR
Definition: x86.h:1619
@ X86_INS_FCMOVU
Definition: x86.h:479
@ X86_INS_JECXZ
Definition: x86.h:644
@ X86_INS_ADD
Definition: x86.h:394
@ X86_INS_PUSHFQ
Definition: x86.h:979
@ X86_INS_NOT
Definition: x86.h:881
@ X86_INS_CMPSB
Definition: x86.h:482
@ X86_INS_PSUBSB
Definition: x86.h:821
@ X86_INS_MOVSD
Definition: x86.h:857
@ X86_INS_PSUBUSW
Definition: x86.h:824
@ X86_INS_FCMOVNB
Definition: x86.h:470
@ X86_INS_MOVHPD
Definition: x86.h:842
@ X86_INS_FLDL2T
Definition: x86.h:554
@ X86_INS_SETP
Definition: x86.h:1026
@ X86_INS_MOVAPD
Definition: x86.h:583
@ X86_INS_MOVNTQ
Definition: x86.h:755
@ X86_INS_VPCMPUD
Definition: x86.h:1407
@ X86_INS_JNO
Definition: x86.h:652
@ X86_INS_XCHG
Definition: x86.h:1687
@ X86_INS_SIDT
Definition: x86.h:1045
@ X86_INS_OUTSB
Definition: x86.h:883
@ X86_INS_INSB
Definition: x86.h:602
@ X86_INS_MOVSB
Definition: x86.h:856
@ X86_INS_PUSHF
Definition: x86.h:977
@ X86_INS_FIMUL
Definition: x86.h:876
@ X86_INS_CLC
Definition: x86.h:448
@ X86_INS_SHA256RNDS2
Definition: x86.h:1036
@ X86_INS_MOVBE
Definition: x86.h:837
@ X86_INS_MULPD
Definition: x86.h:870
@ X86_INS_FTST
Definition: x86.h:1088
@ X86_INS_VPALIGNR
Definition: x86.h:1367
@ X86_INS_VPXORQ
Definition: x86.h:1618
@ X86_INS_SETNO
Definition: x86.h:1022
@ X86_INS_MOVAPS
Definition: x86.h:584
@ X86_INS_CVTSS2SD
Definition: x86.h:508
@ X86_INS_AAD
Definition: x86.h:388
@ X86_INS_SAL
Definition: x86.h:1003
@ X86_INS_CMOVB
Definition: x86.h:459
@ X86_INS_JLE
Definition: x86.h:648
@ X86_INS_STAC
Definition: x86.h:1055
@ X86_INS_SETB
Definition: x86.h:1015
@ X86_INS_OUTSD
Definition: x86.h:884
@ X86_INS_ANDPD
Definition: x86.h:415
@ X86_INS_FSCALE
Definition: x86.h:571
@ X86_INS_FLDENV
Definition: x86.h:552
@ X86_INS_FYL2XP1
Definition: x86.h:582
@ X86_INS_CALL
Definition: x86.h:442
@ X86_INS_VPCMPUB
Definition: x86.h:1406
@ X86_INS_LFENCE
Definition: x86.h:711
@ X86_INS_MOVSQ
Definition: x86.h:860
@ X86_INS_SHL
Definition: x86.h:1037
@ X86_INS_FADDP
Definition: x86.h:403
@ X86_INS_PSUBW
Definition: x86.h:825
@ X86_INS_PEXTRB
Definition: x86.h:901
@ X86_INS_CMPPS
Definition: x86.h:1738
@ X86_INS_VPCMPW
Definition: x86.h:1410
@ X86_INS_FEMMS
Definition: x86.h:546
@ X86_INS_MOVDQA
Definition: x86.h:839
@ X86_INS_FLDZ
Definition: x86.h:705
@ X86_INS_MULSS
Definition: x86.h:873
@ X86_INS_MOVABS
Definition: x86.h:836
@ X86_INS_BTS
Definition: x86.h:440
@ X86_INS_CLAC
Definition: x86.h:447
@ X86_INS_POPFD
Definition: x86.h:957
@ X86_INS_SUB
Definition: x86.h:719
@ X86_INS_PCMPGTD
Definition: x86.h:781
@ X86_INS_RDTSC
Definition: x86.h:990
@ X86_INS_FABS
Definition: x86.h:391
@ X86_INS_SARX
Definition: x86.h:1006
@ X86_INS_PADDB
Definition: x86.h:764
@ X86_INS_INC
Definition: x86.h:601
@ X86_INS_ADDSS
Definition: x86.h:398
@ X86_INS_FXSAVE64
Definition: x86.h:579
@ X86_INS_FUCOMPP
Definition: x86.h:1093
@ X86_INS_FXAM
Definition: x86.h:575
@ X86_INS_PUSHAL
Definition: x86.h:976
@ X86_INS_STOSW
Definition: x86.h:1064
@ X86_INS_POPFQ
Definition: x86.h:958
@ X86_INS_PCMPEQB
Definition: x86.h:777
@ X86_INS_ADDSUBPS
Definition: x86.h:400
@ X86_INS_KXORW
Definition: x86.h:699
@ X86_INS_VPCMPGTD
Definition: x86.h:1400
@ X86_INS_JS
Definition: x86.h:658
@ X86_INS_FNSAVE
Definition: x86.h:570
@ X86_INS_INSW
Definition: x86.h:606
@ X86_INS_SETGE
Definition: x86.h:1017
@ X86_INS_STOSD
Definition: x86.h:1062
@ X86_INS_FNOP
Definition: x86.h:560
@ X86_INS_MOVD
Definition: x86.h:753
@ X86_INS_CMOVGE
Definition: x86.h:466
@ X86_INS_PXOR
Definition: x86.h:832
@ X86_INS_FCOMPP
Definition: x86.h:544
@ X86_INS_PCMPESTRM
Definition: x86.h:894
@ X86_INS_SETNE
Definition: x86.h:1021
@ X86_INS_IRET
Definition: x86.h:617
@ X86_INS_IRETQ
Definition: x86.h:619
@ X86_INS_SHA1NEXTE
Definition: x86.h:1032
@ X86_INS_SETE
Definition: x86.h:1016
@ X86_INS_PADDUSW
Definition: x86.h:770
@ X86_INS_FDIVP
Definition: x86.h:530
@ X86_INS_JMP
Definition: x86.h:650
@ X86_INS_CMOVNE
Definition: x86.h:471
@ X86_INS_SHLD
Definition: x86.h:1038
@ X86_INS_PADDSB
Definition: x86.h:767
@ X86_INS_PSUBSW
Definition: x86.h:822
@ X86_INS_SAR
Definition: x86.h:1005
@ X86_INS_PCMPESTRI
Definition: x86.h:893
@ X86_INS_FXSAVE
Definition: x86.h:578
@ X86_INS_VPCMPD
Definition: x86.h:1392
@ X86_INS_VMOVNTPS
Definition: x86.h:1330
@ X86_INS_JRCXZ
Definition: x86.h:657
@ X86_INS_ANDPS
Definition: x86.h:416
@ X86_INS_VPCMPGTB
Definition: x86.h:1399
@ X86_INS_FSUBP
Definition: x86.h:1079
@ X86_INS_VPCMPEQD
Definition: x86.h:1394
@ X86_INS_OR
Definition: x86.h:718
@ X86_INS_SHA256MSG2
Definition: x86.h:1035
@ X86_INS_UD2B
Definition: x86.h:1096
@ X86_INS_RCL
Definition: x86.h:980
@ X86_INS_SHA1MSG2
Definition: x86.h:1031
@ X86_INS_IN
Definition: x86.h:600
@ X86_INS_MOVUPS
Definition: x86.h:866
@ X86_INS_LEAVE
Definition: x86.h:709
@ X86_INS_VPCMPESTRM
Definition: x86.h:1398
@ X86_INS_MOVZX
Definition: x86.h:867
@ X86_INS_CLD
Definition: x86.h:449
@ X86_INS_FSETPM
Definition: x86.h:572
@ X86_INS_STOSB
Definition: x86.h:1061
@ X86_INS_CMC
Definition: x86.h:456
@ X86_INS_FFREE
Definition: x86.h:547
@ X86_INS_BT
Definition: x86.h:437
@ X86_INS_FSTP
Definition: x86.h:1067
@ X86_INS_MOVQ
Definition: x86.h:757
@ X86_INS_FBSTP
Definition: x86.h:543
@ X86_INS_MOVNTDQA
Definition: x86.h:849
@ X86_INS_LOOPNE
Definition: x86.h:727
@ X86_INS_PCMPGTW
Definition: x86.h:782
@ X86_INS_BSR
Definition: x86.h:435
@ X86_INS_MOVLPD
Definition: x86.h:845
@ X86_INS_FSTPNCE
Definition: x86.h:1068
@ X86_INS_CLWB
Definition: x86.h:455
@ X86_INS_IDIV
Definition: x86.h:597
@ X86_INS_FXCH
Definition: x86.h:1069
@ X86_INS_MOVSX
Definition: x86.h:863
@ X86_INS_CMOVNO
Definition: x86.h:473
@ X86_INS_FMUL
Definition: x86.h:875
@ X86_INS_CMPSS
Definition: x86.h:1718
@ X86_INS_STC
Definition: x86.h:1056
@ X86_INS_SFENCE
Definition: x86.h:1028
@ X86_INS_FPTAN
Definition: x86.h:566
@ X86_INS_INT3
Definition: x86.h:609
@ X86_INS_JCXZ
Definition: x86.h:643
@ X86_INS_HLT
Definition: x86.h:594
@ X86_INS_FIDIVR
Definition: x86.h:524
@ X86_INS_JA
Definition: x86.h:640
@ X86_INS_POPAL
Definition: x86.h:954
@ X86_INS_FUCOM
Definition: x86.h:1095
@ X86_INS_DEC
Definition: x86.h:519
@ X86_INS_FXRSTOR64
Definition: x86.h:577
@ X86_INS_RDSEED
Definition: x86.h:989
@ X86_INS_RETF
Definition: x86.h:728
@ X86_INS_TEST
Definition: x86.h:1086
@ X86_INS_PUSH
Definition: x86.h:974
@ X86_INS_FSUBR
Definition: x86.h:1072
@ X86_INS_FLDPI
Definition: x86.h:557
@ X86_INS_VMCALL
Definition: x86.h:1298
@ X86_INS_JO
Definition: x86.h:655
@ X86_INS_CMOVL
Definition: x86.h:467
@ X86_INS_PACKSSWB
Definition: x86.h:762
@ X86_INS_FFREEP
Definition: x86.h:567
@ X86_INS_FSUB
Definition: x86.h:1077
@ X86_INS_FLDCW
Definition: x86.h:551
@ X86_INS_FCMOVE
Definition: x86.h:464
@ X86_INS_FSINCOS
Definition: x86.h:573
@ X86_INS_ADDSD
Definition: x86.h:397
@ X86_INS_INT1
Definition: x86.h:608
@ X86_INS_CDQ
Definition: x86.h:444
@ X86_INS_CPUID
Definition: x86.h:495
@ X86_INS_STGI
Definition: x86.h:1058
@ X86_INS_INSD
Definition: x86.h:605
@ X86_INS_FISTP
Definition: x86.h:622
@ X86_INS_PCMPEQW
Definition: x86.h:779
@ X86_INS_IRETD
Definition: x86.h:618
@ X86_INS_CWDE
Definition: x86.h:515
@ X86_INS_CMOVLE
Definition: x86.h:468
@ X86_INS_PUSHFD
Definition: x86.h:978
@ X86_INS_PADDUSB
Definition: x86.h:769
@ X86_INS_CMOVG
Definition: x86.h:465
@ X86_INS_JE
Definition: x86.h:645
@ X86_INS_VXORPD
Definition: x86.h:1260
@ X86_INS_LODSW
Definition: x86.h:724
@ X86_INS_PCMPGTQ
Definition: x86.h:895
@ X86_INS_DIV
Definition: x86.h:520
@ X86_INS_FMULP
Definition: x86.h:877
@ X86_INS_CMOVE
Definition: x86.h:463
@ X86_INS_POPF
Definition: x86.h:956
@ X86_INS_SETA
Definition: x86.h:1013
@ X86_INS_PALIGNR
Definition: x86.h:772
@ X86_INS_SETS
Definition: x86.h:1027
@ X86_INS_MFENCE
Definition: x86.h:740
@ X86_INS_UD2
Definition: x86.h:1087
@ X86_INS_PSUBUSB
Definition: x86.h:823
@ X86_INS_SALC
Definition: x86.h:1004
@ X86_INS_JNS
Definition: x86.h:654
@ X86_INS_MOVNTI
Definition: x86.h:851
@ X86_INS_FPREM
Definition: x86.h:564
@ X86_INS_MOVNTPS
Definition: x86.h:853
@ X86_INS_MOVNTDQ
Definition: x86.h:850
@ X86_INS_FCMOVBE
Definition: x86.h:461
@ X86_INS_JG
Definition: x86.h:647
@ X86_INS_CMPSD
Definition: x86.h:1728
@ X86_INS_VPXORD
Definition: x86.h:1617
@ X86_INS_FISTTP
Definition: x86.h:620
@ X86_INS_SHA256MSG1
Definition: x86.h:1034
@ X86_INS_VALIGNQ
Definition: x86.h:1114
@ X86_INS_ROR
Definition: x86.h:993
@ X86_INS_JP
Definition: x86.h:656
@ X86_INS_LIDT
Definition: x86.h:715
@ X86_INS_LJMP
Definition: x86.h:541
@ X86_INS_MOVSXD
Definition: x86.h:864
@ X86_INS_CMOVNP
Definition: x86.h:474
@ X86_INS_FCMOVNBE
Definition: x86.h:469
@ X86_INS_CMOVS
Definition: x86.h:480
@ X86_INS_PADDSW
Definition: x86.h:768
@ X86_INS_CLI
Definition: x86.h:453
@ X86_INS_ADDPD
Definition: x86.h:395
@ X86_INS_FISUBR
Definition: x86.h:1073
@ X86_INS_MUL
Definition: x86.h:869
@ X86_INS_NEG
Definition: x86.h:879
@ X86_INS_LEA
Definition: x86.h:708
@ X86_INS_FCMOVB
Definition: x86.h:462
@ X86_INS_ANDN
Definition: x86.h:412
@ X86_INS_CMOVP
Definition: x86.h:478
@ X86_INS_JNP
Definition: x86.h:653
@ X86_INS_FRNDINT
Definition: x86.h:568
@ X86_INS_MOVDQU
Definition: x86.h:840
@ X86_INS_RDTSCP
Definition: x86.h:991
@ X86_INS_SHRX
Definition: x86.h:1042
@ X86_INS_LODSB
Definition: x86.h:721
@ X86_INS_SYSCALL
Definition: x86.h:1081
@ X86_INS_CMPSQ
Definition: x86.h:483
@ X86_INS_SHLX
Definition: x86.h:1039
@ X86_INS_CBW
Definition: x86.h:443
@ X86_INS_AESIMC
Definition: x86.h:409
@ X86_INS_SETNS
Definition: x86.h:1024
@ X86_OP_IMM
= CS_OP_IMM (Immediate operand).
Definition: x86.h:161
@ X86_OP_INVALID
= CS_OP_INVALID (Uninitialized).
Definition: x86.h:159
@ X86_OP_REG
= CS_OP_REG (Register operand).
Definition: x86.h:160
@ X86_OP_MEM
= CS_OP_MEM (Memory operand).
Definition: x86.h:162
x86_reg
X86 registers.
Definition: x86.h:19
@ X86_REG_ES
Definition: x86.h:26
@ X86_REG_ESP
Definition: x86.h:26
@ X86_REG_XMM14
Definition: x86.h:48
@ X86_REG_XMM16
Definition: x86.h:49
@ X86_REG_EFLAGS
Definition: x86.h:25
@ X86_REG_XMM31
Definition: x86.h:52
@ X86_REG_XMM3
Definition: x86.h:46
@ X86_REG_XMM5
Definition: x86.h:47
@ X86_REG_XMM10
Definition: x86.h:48
@ X86_REG_XMM21
Definition: x86.h:50
@ X86_REG_XMM23
Definition: x86.h:50
@ X86_REG_XMM7
Definition: x86.h:47
@ X86_REG_XMM2
Definition: x86.h:46
@ X86_REG_RIP
Definition: x86.h:29
@ X86_REG_XMM24
Definition: x86.h:50
@ X86_REG_XMM25
Definition: x86.h:51
@ X86_REG_XMM11
Definition: x86.h:48
@ X86_REG_INVALID
Definition: x86.h:20
@ X86_REG_XMM0
Definition: x86.h:46
@ X86_REG_XMM6
Definition: x86.h:47
@ X86_REG_XMM4
Definition: x86.h:46
@ X86_REG_DS
Definition: x86.h:24
@ X86_REG_XMM8
Definition: x86.h:47
@ X86_REG_XMM20
Definition: x86.h:50
@ X86_REG_RSP
Definition: x86.h:29
@ X86_REG_FS
Definition: x86.h:27
@ X86_REG_XMM15
Definition: x86.h:49
@ X86_REG_XMM13
Definition: x86.h:48
@ X86_REG_XMM17
Definition: x86.h:49
@ X86_REG_XMM22
Definition: x86.h:50
@ X86_REG_SS
Definition: x86.h:30
@ X86_REG_XMM28
Definition: x86.h:51
@ X86_REG_XMM9
Definition: x86.h:47
@ X86_REG_XMM30
Definition: x86.h:52
@ X86_REG_EBP
Definition: x86.h:24
@ X86_REG_XMM18
Definition: x86.h:49
@ X86_REG_XMM1
Definition: x86.h:46
@ X86_REG_XMM12
Definition: x86.h:48
@ X86_REG_EIP
Definition: x86.h:26
@ X86_REG_RBP
Definition: x86.h:28
@ X86_REG_XMM27
Definition: x86.h:51
@ X86_REG_XMM26
Definition: x86.h:51
@ X86_REG_GS
Definition: x86.h:27
@ X86_REG_XMM29
Definition: x86.h:51
@ X86_REG_CS
Definition: x86.h:23
@ X86_REG_XMM19
Definition: x86.h:49
@ X86_GRP_SSE1
Definition: x86.h:1942
@ X86_GRP_SSE3
Definition: x86.h:1944
@ X86_GRP_MMX
Definition: x86.h:1937
@ X86_GRP_PRIVILEGE
= CS_GRP_PRIVILEGE
Definition: x86.h:1917
@ X86_GRP_SSE2
Definition: x86.h:1943
RZ_API const char * rz_analysis_cc_default(RzAnalysis *analysis)
Definition: cc.c:200
#define RZ_API
#define NULL
Definition: cris-opc.c:27
CAPSTONE_EXPORT cs_err CAPSTONE_API cs_regs_access(csh ud, const cs_insn *insn, cs_regs regs_read, uint8_t *regs_read_count, cs_regs regs_write, uint8_t *regs_write_count)
Definition: cs.c:1504
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 cs_err CAPSTONE_API cs_open(cs_arch arch, cs_mode mode, csh *handle)
Definition: cs.c:453
CAPSTONE_EXPORT bool CAPSTONE_API cs_insn_group(csh ud, const cs_insn *insn, unsigned int group_id)
Definition: cs.c:1190
CAPSTONE_EXPORT void CAPSTONE_API cs_free(cs_insn *insn, size_t count)
Definition: cs.c:1017
CAPSTONE_EXPORT const char *CAPSTONE_API cs_reg_name(csh ud, unsigned int reg)
Definition: cs.c:1154
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
uint32_t ut32
void cleanup(void)
Definition: enough.c:244
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
voidpf void uLong size
Definition: ioapi.h:138
const char int mode
Definition: ioapi.h:137
voidpf void * buf
Definition: ioapi.h:138
snprintf
Definition: kernel.h:364
RZ_API void rz_search_keyword_free(RzSearchKeyword *kw)
Definition: keyword.c:49
#define reg(n)
uint8_t ut8
Definition: lh5801.h:11
void * p
Definition: libc.cpp:67
void * mem
Definition: libc.cpp:91
RZ_API RZ_OWN RzList * rz_list_newf(RzListFree f)
Returns a new initialized RzList pointer and sets the free method.
Definition: list.c:248
RZ_API RZ_BORROW RzListIter * rz_list_append(RZ_NONNULL RzList *list, void *data)
Appends at the end of the list a new element.
Definition: list.c:288
RZ_API void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
Definition: list.c:137
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
static static fork const void static count static fd const char static mode const char static pathname const char static path const char static dev const char static group static getpid static getuid void void static data static pause access
Definition: sflib.h:64
char * dst
Definition: lz4.h:724
#define ip
@ RZ_ABS
int x
Definition: mipsasm.c:20
int n
Definition: mipsasm.c:19
int type
Definition: mipsasm.c:17
int CS_ERR_OK
Definition: __init__.py:235
int off
Definition: pal.c:13
RZ_API RzRegItem * rz_reg_get(RzReg *reg, const char *name, int type)
Definition: reg.c:344
RZ_API const char * rz_reg_32_to_64(RzReg *reg, const char *rreg32)
Definition: reg.c:17
#define RZ_ANALYSIS_ARCHINFO_ALIGN
Definition: rz_analysis.h:100
#define esilprintf(op, fmt,...)
Definition: rz_analysis.h:29
@ RZ_ANALYSIS_STACK_SET
Definition: rz_analysis.h:459
@ RZ_ANALYSIS_STACK_GET
Definition: rz_analysis.h:458
@ RZ_ANALYSIS_STACK_INC
Definition: rz_analysis.h:457
@ RZ_ANALYSIS_VAL_IMM
Definition: rz_analysis.h:770
@ RZ_ANALYSIS_VAL_REG
Definition: rz_analysis.h:768
@ RZ_ANALYSIS_VAL_MEM
Definition: rz_analysis.h:769
@ RZ_ANALYSIS_OP_FAMILY_FPU
Definition: rz_analysis.h:313
@ RZ_ANALYSIS_OP_FAMILY_THREAD
Definition: rz_analysis.h:318
@ RZ_ANALYSIS_OP_FAMILY_CRYPTO
Definition: rz_analysis.h:317
@ RZ_ANALYSIS_OP_FAMILY_SSE
Definition: rz_analysis.h:315
@ RZ_ANALYSIS_OP_FAMILY_PRIV
Definition: rz_analysis.h:316
@ RZ_ANALYSIS_OP_FAMILY_CPU
Definition: rz_analysis.h:312
@ RZ_ANALYSIS_OP_FAMILY_MMX
Definition: rz_analysis.h:314
#define RZ_ANALYSIS_ARCHINFO_MAX_OP_SIZE
Definition: rz_analysis.h:99
@ RZ_ANALYSIS_OP_PREFIX_REP
Definition: rz_analysis.h:348
@ RZ_ANALYSIS_OP_PREFIX_LOCK
Definition: rz_analysis.h:350
@ RZ_ANALYSIS_OP_PREFIX_REPNE
Definition: rz_analysis.h:349
@ RZ_ANALYSIS_OP_DIR_READ
Definition: rz_analysis.h:790
@ RZ_ANALYSIS_OP_DIR_EXEC
Definition: rz_analysis.h:792
@ RZ_ANALYSIS_OP_DIR_WRITE
Definition: rz_analysis.h:791
@ RZ_ANALYSIS_OP_DIR_REF
Definition: rz_analysis.h:793
RzAnalysisOpMask
Definition: rz_analysis.h:439
@ RZ_ANALYSIS_OP_MASK_DISASM
Definition: rz_analysis.h:445
@ RZ_ANALYSIS_OP_MASK_VAL
Definition: rz_analysis.h:442
@ RZ_ANALYSIS_OP_MASK_OPEX
Definition: rz_analysis.h:444
@ RZ_ANALYSIS_OP_MASK_ESIL
Definition: rz_analysis.h:441
#define RZ_ANALYSIS_OP_TYPE_MASK
Definition: rz_analysis.h:358
@ RZ_ANALYSIS_ACC_R
Definition: rz_analysis.h:762
@ RZ_ANALYSIS_ACC_UNKNOWN
Definition: rz_analysis.h:761
@ RZ_ANALYSIS_ACC_W
Definition: rz_analysis.h:763
#define RZ_ANALYSIS_ARCHINFO_MIN_OP_SIZE
Definition: rz_analysis.h:98
@ RZ_ANALYSIS_OP_TYPE_CMP
Definition: rz_analysis.h:399
@ RZ_ANALYSIS_OP_TYPE_SUB
Definition: rz_analysis.h:402
@ RZ_ANALYSIS_OP_TYPE_LOAD
Definition: rz_analysis.h:416
@ RZ_ANALYSIS_OP_TYPE_MUL
Definition: rz_analysis.h:404
@ RZ_ANALYSIS_OP_TYPE_ROL
Definition: rz_analysis.h:420
@ RZ_ANALYSIS_OP_TYPE_JMP
Definition: rz_analysis.h:368
@ RZ_ANALYSIS_OP_TYPE_AND
Definition: rz_analysis.h:411
@ RZ_ANALYSIS_OP_TYPE_SAL
Definition: rz_analysis.h:408
@ RZ_ANALYSIS_OP_TYPE_UPUSH
Definition: rz_analysis.h:395
@ RZ_ANALYSIS_OP_TYPE_RPUSH
Definition: rz_analysis.h:396
@ RZ_ANALYSIS_OP_TYPE_UJMP
Definition: rz_analysis.h:369
@ RZ_ANALYSIS_OP_TYPE_IO
Definition: rz_analysis.h:403
@ RZ_ANALYSIS_OP_TYPE_MJMP
Definition: rz_analysis.h:375
@ RZ_ANALYSIS_OP_TYPE_ROR
Definition: rz_analysis.h:419
@ RZ_ANALYSIS_OP_TYPE_SWI
Definition: rz_analysis.h:393
@ RZ_ANALYSIS_OP_TYPE_SAR
Definition: rz_analysis.h:409
@ RZ_ANALYSIS_OP_TYPE_ABS
Definition: rz_analysis.h:428
@ RZ_ANALYSIS_OP_TYPE_CMOV
Definition: rz_analysis.h:391
@ RZ_ANALYSIS_OP_TYPE_TRAP
Definition: rz_analysis.h:392
@ RZ_ANALYSIS_OP_TYPE_XCHG
Definition: rz_analysis.h:421
@ RZ_ANALYSIS_OP_TYPE_CALL
Definition: rz_analysis.h:378
@ RZ_ANALYSIS_OP_TYPE_ADD
Definition: rz_analysis.h:401
@ RZ_ANALYSIS_OP_TYPE_OR
Definition: rz_analysis.h:410
@ RZ_ANALYSIS_OP_TYPE_STORE
Definition: rz_analysis.h:415
@ RZ_ANALYSIS_OP_TYPE_REG
Definition: rz_analysis.h:365
@ RZ_ANALYSIS_OP_TYPE_PUSH
Definition: rz_analysis.h:397
@ RZ_ANALYSIS_OP_TYPE_SHR
Definition: rz_analysis.h:406
@ RZ_ANALYSIS_OP_TYPE_IRJMP
Definition: rz_analysis.h:372
@ RZ_ANALYSIS_OP_TYPE_POP
Definition: rz_analysis.h:398
@ RZ_ANALYSIS_OP_TYPE_RJMP
Definition: rz_analysis.h:370
@ RZ_ANALYSIS_OP_TYPE_CJMP
Definition: rz_analysis.h:373
@ RZ_ANALYSIS_OP_TYPE_DIV
Definition: rz_analysis.h:405
@ RZ_ANALYSIS_OP_TYPE_COND
Definition: rz_analysis.h:361
@ RZ_ANALYSIS_OP_TYPE_MOV
Definition: rz_analysis.h:390
@ RZ_ANALYSIS_OP_TYPE_SHL
Definition: rz_analysis.h:407
@ RZ_ANALYSIS_OP_TYPE_ILL
Definition: rz_analysis.h:387
@ RZ_ANALYSIS_OP_TYPE_UCALL
Definition: rz_analysis.h:379
@ RZ_ANALYSIS_OP_TYPE_NOT
Definition: rz_analysis.h:414
@ RZ_ANALYSIS_OP_TYPE_RET
Definition: rz_analysis.h:385
@ RZ_ANALYSIS_OP_TYPE_NOP
Definition: rz_analysis.h:389
@ RZ_ANALYSIS_OP_TYPE_ACMP
Definition: rz_analysis.h:400
@ RZ_ANALYSIS_OP_TYPE_LEA
Definition: rz_analysis.h:417
@ RZ_ANALYSIS_OP_TYPE_RCALL
Definition: rz_analysis.h:380
@ RZ_ANALYSIS_OP_TYPE_XOR
Definition: rz_analysis.h:412
@ RZ_ANALYSIS_OP_TYPE_IRCALL
Definition: rz_analysis.h:382
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
@ RZ_LIB_TYPE_ANALYSIS
Definition: rz_lib.h:73
void(* RzListFree)(void *ptr)
Definition: rz_list.h:11
#define RZ_LOG_ERROR(fmtstr,...)
Definition: rz_log.h:58
RZ_API PJ * pj_ka(PJ *j, const char *k)
Definition: pj.c:163
RZ_API PJ * pj_new(void)
Definition: pj.c:25
RZ_API PJ * pj_kb(PJ *j, const char *k, bool v)
Definition: pj.c:177
RZ_API PJ * pj_ki(PJ *j, const char *k, int d)
Definition: pj.c:149
RZ_API PJ * pj_end(PJ *j)
Definition: pj.c:87
RZ_API const char * pj_string(PJ *pj)
Definition: pj.c:57
RZ_API void pj_free(PJ *j)
Definition: pj.c:34
RZ_API PJ * pj_o(PJ *j)
Definition: pj.c:75
RZ_API PJ * pj_ks(PJ *j, const char *k, const char *v)
Definition: pj.c:170
RZ_API PJ * pj_kN(PJ *j, const char *k, st64 n)
Definition: pj.c:128
@ RZ_REG_TYPE_GPR
Definition: rz_reg.h:21
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
RZ_API bool rz_strbuf_append(RzStrBuf *sb, const char *s)
Definition: strbuf.c:222
RZ_API bool rz_strbuf_appendf(RzStrBuf *sb, const char *fmt,...) RZ_PRINTF_CHECK(2
RZ_API void rz_strbuf_init(RzStrBuf *sb)
Definition: strbuf.c:33
@ RZ_TYPE_COND_LE
Less or equal.
Definition: rz_type.h:188
@ RZ_TYPE_COND_GE
Greater or equal.
Definition: rz_type.h:186
@ RZ_TYPE_COND_EQ
Equal.
Definition: rz_type.h:184
@ RZ_TYPE_COND_NE
Not equal.
Definition: rz_type.h:185
@ RZ_TYPE_COND_GT
Greater than.
Definition: rz_type.h:187
@ RZ_TYPE_COND_LT
Less than.
Definition: rz_type.h:189
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define PFMT64u
Definition: rz_types.h:395
#define RZ_ARRAY_SIZE(x)
Definition: rz_types.h:300
#define PFMT64x
Definition: rz_types.h:393
#define st64
Definition: rz_types_base.h:10
#define UT64_MAX
Definition: rz_types_base.h:86
#define RZ_VERSION
Definition: rz_version.h:8
static int
Definition: sfsocketcall.h:114
unsigned char uint8_t
Definition: sftypes.h:31
#define a(i)
Definition: sha256.c:41
#define h(i)
Definition: sha256.c:48
cs_insn * insn
Instruction operand.
Definition: x86.h:275
Instruction structure.
Definition: x86.h:312
Definition: names.h:123
Definition: rz_pj.h:12
const char * version
Definition: rz_analysis.h:1239
int64_t counter
Definition: main.c:4
int width
Definition: main.c:10
Definition: dis.c:32
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
static int sp
Definition: z80asm.c:91
static int addr
Definition: z80asm.c:58