Rizin
unix-like reverse engineering framework and cli tools
cstool_x86.c
Go to the documentation of this file.
1 /* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013> */
2 
3 #include <stdio.h>
4 #include <stdlib.h>
5 
6 #include <capstone/capstone.h>
7 
8 void print_string_hex(const char *comment, unsigned char *str, size_t len);
9 
10 static const char *get_eflag_name(uint64_t flag)
11 {
12  switch(flag) {
13  default:
14  return NULL;
16  return "UNDEF_OF";
18  return "UNDEF_SF";
20  return "UNDEF_ZF";
22  return "MOD_AF";
24  return "UNDEF_PF";
26  return "MOD_CF";
28  return "MOD_SF";
30  return "MOD_ZF";
32  return "UNDEF_AF";
34  return "MOD_PF";
36  return "UNDEF_CF";
38  return "MOD_OF";
40  return "RESET_OF";
42  return "RESET_CF";
44  return "RESET_DF";
46  return "RESET_IF";
48  return "RESET_ZF";
49  case X86_EFLAGS_TEST_OF:
50  return "TEST_OF";
51  case X86_EFLAGS_TEST_SF:
52  return "TEST_SF";
53  case X86_EFLAGS_TEST_ZF:
54  return "TEST_ZF";
55  case X86_EFLAGS_TEST_PF:
56  return "TEST_PF";
57  case X86_EFLAGS_TEST_CF:
58  return "TEST_CF";
60  return "RESET_SF";
62  return "RESET_AF";
64  return "RESET_TF";
66  return "RESET_NT";
68  return "PRIOR_OF";
70  return "PRIOR_SF";
72  return "PRIOR_ZF";
74  return "PRIOR_AF";
76  return "PRIOR_PF";
78  return "PRIOR_CF";
80  return "PRIOR_TF";
82  return "PRIOR_IF";
84  return "PRIOR_DF";
85  case X86_EFLAGS_TEST_NT:
86  return "TEST_NT";
87  case X86_EFLAGS_TEST_DF:
88  return "TEST_DF";
90  return "RESET_PF";
92  return "PRIOR_NT";
94  return "MOD_TF";
96  return "MOD_IF";
98  return "MOD_DF";
100  return "MOD_NT";
102  return "MOD_RF";
103  case X86_EFLAGS_SET_CF:
104  return "SET_CF";
105  case X86_EFLAGS_SET_DF:
106  return "SET_DF";
107  case X86_EFLAGS_SET_IF:
108  return "SET_IF";
109  case X86_EFLAGS_SET_OF:
110  return "SET_OF";
111  case X86_EFLAGS_SET_SF:
112  return "SET_SF";
113  case X86_EFLAGS_SET_ZF:
114  return "SET_ZF";
115  case X86_EFLAGS_SET_AF:
116  return "SET_AF";
117  case X86_EFLAGS_SET_PF:
118  return "SET_PF";
119  case X86_EFLAGS_TEST_AF:
120  return "TEST_AF";
121  case X86_EFLAGS_TEST_TF:
122  return "TEST_TF";
123  case X86_EFLAGS_TEST_RF:
124  return "TEST_RF";
125  case X86_EFLAGS_RESET_0F:
126  return "RESET_0F";
127  case X86_EFLAGS_RESET_AC:
128  return "RESET_AC";
129  }
130 }
131 
132 static const char *get_fpu_flag_name(uint64_t flag)
133 {
134  switch (flag) {
135  default:
136  return NULL;
138  return "MOD_C0";
140  return "MOD_C1";
142  return "MOD_C2";
144  return "MOD_C3";
146  return "RESET_C0";
148  return "RESET_C1";
150  return "RESET_C2";
152  return "RESET_C3";
154  return "SET_C0";
156  return "SET_C1";
158  return "SET_C2";
160  return "SET_C3";
162  return "UNDEF_C0";
164  return "UNDEF_C1";
166  return "UNDEF_C2";
168  return "UNDEF_C3";
170  return "TEST_C0";
172  return "TEST_C1";
174  return "TEST_C2";
176  return "TEST_C3";
177  }
178 }
179 
180 void print_insn_detail_x86(csh ud, cs_mode mode, cs_insn *ins)
181 {
182  int count, i;
183  cs_x86 *x86;
184  cs_regs regs_read, regs_write;
185  uint8_t regs_read_count, regs_write_count;
186 
187  // detail can be NULL on "data" instruction if SKIPDATA option is turned ON
188  if (ins->detail == NULL)
189  return;
190 
191  x86 = &(ins->detail->x86);
192 
193  print_string_hex("\tPrefix:", x86->prefix, 4);
194  print_string_hex("\tOpcode:", x86->opcode, 4);
195  printf("\trex: 0x%x\n", x86->rex);
196  printf("\taddr_size: %u\n", x86->addr_size);
197  printf("\tmodrm: 0x%x\n", x86->modrm);
198  printf("\tdisp: 0x%" PRIx64 "\n", x86->disp);
199 
200  // SIB is not available in 16-bit mode
201  if ((mode & CS_MODE_16) == 0) {
202  printf("\tsib: 0x%x\n", x86->sib);
203  if (x86->sib_base != X86_REG_INVALID)
204  printf("\t\tsib_base: %s\n", cs_reg_name(ud, x86->sib_base));
205  if (x86->sib_index != X86_REG_INVALID)
206  printf("\t\tsib_index: %s\n", cs_reg_name(ud, x86->sib_index));
207  if (x86->sib_scale != 0)
208  printf("\t\tsib_scale: %d\n", x86->sib_scale);
209  }
210 
211  // XOP code condition
212  if (x86->xop_cc != X86_XOP_CC_INVALID) {
213  printf("\txop_cc: %u\n", x86->xop_cc);
214  }
215 
216  // SSE code condition
217  if (x86->sse_cc != X86_SSE_CC_INVALID) {
218  printf("\tsse_cc: %u\n", x86->sse_cc);
219  }
220 
221  // AVX code condition
222  if (x86->avx_cc != X86_AVX_CC_INVALID) {
223  printf("\tavx_cc: %u\n", x86->avx_cc);
224  }
225 
226  // AVX Suppress All Exception
227  if (x86->avx_sae) {
228  printf("\tavx_sae: %u\n", x86->avx_sae);
229  }
230 
231  // AVX Rounding Mode
232  if (x86->avx_rm != X86_AVX_RM_INVALID) {
233  printf("\tavx_rm: %u\n", x86->avx_rm);
234  }
235 
236  // Print out all immediate operands
237  count = cs_op_count(ud, ins, X86_OP_IMM);
238  if (count > 0) {
239  printf("\timm_count: %u\n", count);
240  for (i = 1; i < count + 1; i++) {
241  int index = cs_op_index(ud, ins, X86_OP_IMM, i);
242  printf("\t\timms[%u]: 0x%" PRIx64 "\n", i, x86->operands[index].imm);
243  }
244  }
245 
246  if (x86->op_count)
247  printf("\top_count: %u\n", x86->op_count);
248 
249  // Print out all operands
250  for (i = 0; i < x86->op_count; i++) {
251  cs_x86_op *op = &(x86->operands[i]);
252 
253  switch((int)op->type) {
254  case X86_OP_REG:
255  printf("\t\toperands[%u].type: REG = %s\n", i, cs_reg_name(ud, op->reg));
256  break;
257  case X86_OP_IMM:
258  printf("\t\toperands[%u].type: IMM = 0x%" PRIx64 "\n", i, op->imm);
259  break;
260  case X86_OP_MEM:
261  printf("\t\toperands[%u].type: MEM\n", i);
262  if (op->mem.segment != X86_REG_INVALID)
263  printf("\t\t\toperands[%u].mem.segment: REG = %s\n", i, cs_reg_name(ud, op->mem.segment));
264  if (op->mem.base != X86_REG_INVALID)
265  printf("\t\t\toperands[%u].mem.base: REG = %s\n", i, cs_reg_name(ud, op->mem.base));
266  if (op->mem.index != X86_REG_INVALID)
267  printf("\t\t\toperands[%u].mem.index: REG = %s\n", i, cs_reg_name(ud, op->mem.index));
268  if (op->mem.scale != 1)
269  printf("\t\t\toperands[%u].mem.scale: %u\n", i, op->mem.scale);
270  if (op->mem.disp != 0)
271  printf("\t\t\toperands[%u].mem.disp: 0x%" PRIx64 "\n", i, op->mem.disp);
272  break;
273  default:
274  break;
275  }
276 
277  // AVX broadcast type
278  if (op->avx_bcast != X86_AVX_BCAST_INVALID)
279  printf("\t\toperands[%u].avx_bcast: %u\n", i, op->avx_bcast);
280 
281  // AVX zero opmask {z}
282  if (op->avx_zero_opmask != false)
283  printf("\t\toperands[%u].avx_zero_opmask: TRUE\n", i);
284 
285  printf("\t\toperands[%u].size: %u\n", i, op->size);
286 
287  switch(op->access) {
288  default:
289  break;
290  case CS_AC_READ:
291  printf("\t\toperands[%u].access: READ\n", i);
292  break;
293  case CS_AC_WRITE:
294  printf("\t\toperands[%u].access: WRITE\n", i);
295  break;
296  case CS_AC_READ | CS_AC_WRITE:
297  printf("\t\toperands[%u].access: READ | WRITE\n", i);
298  break;
299  }
300  }
301 
302  // Print out all registers accessed by this instruction (either implicit or explicit)
303  if (!cs_regs_access(ud, ins,
304  regs_read, &regs_read_count,
305  regs_write, &regs_write_count)) {
306  if (regs_read_count) {
307  printf("\tRegisters read:");
308  for(i = 0; i < regs_read_count; i++) {
309  printf(" %s", cs_reg_name(ud, regs_read[i]));
310  }
311  printf("\n");
312  }
313 
314  if (regs_write_count) {
315  printf("\tRegisters modified:");
316  for(i = 0; i < regs_write_count; i++) {
317  printf(" %s", cs_reg_name(ud, regs_write[i]));
318  }
319  printf("\n");
320  }
321  }
322 
323  if (x86->eflags || x86->fpu_flags) {
324  for(i = 0; i < ins->detail->groups_count; i++) {
325  if (ins->detail->groups[i] == X86_GRP_FPU) {
326  printf("\tFPU_FLAGS:");
327  for(i = 0; i <= 63; i++)
328  if (x86->fpu_flags & ((uint64_t)1 << i)) {
329  printf(" %s", get_fpu_flag_name((uint64_t)1 << i));
330  }
331  printf("\n");
332  break;
333  }
334  }
335 
336  if (i == ins->detail->groups_count) {
337  printf("\tEFLAGS:");
338  for(i = 0; i <= 63; i++)
339  if (x86->eflags & ((uint64_t)1 << i)) {
340  printf(" %s", get_eflag_name((uint64_t)1 << i));
341  }
342  printf("\n");
343  }
344  }
345 }
size_t len
Definition: 6502dis.c:15
lzma_index ** i
Definition: index.h:629
cs_mode
Mode type.
Definition: capstone.h:102
@ CS_MODE_16
16-bit mode (X86)
Definition: capstone.h:105
size_t csh
Definition: capstone.h:71
@ 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
#define X86_EFLAGS_SET_IF
Definition: x86.h:107
@ X86_AVX_BCAST_INVALID
Uninitialized.
Definition: x86.h:180
#define X86_EFLAGS_RESET_AF
Definition: x86.h:101
#define X86_EFLAGS_PRIOR_DF
Definition: x86.h:94
#define X86_FPU_FLAGS_RESET_C0
Definition: x86.h:139
#define X86_FPU_FLAGS_SET_C3
Definition: x86.h:146
#define X86_EFLAGS_PRIOR_NT
Definition: x86.h:95
#define X86_FPU_FLAGS_UNDEFINED_C0
Definition: x86.h:147
#define X86_FPU_FLAGS_UNDEFINED_C1
Definition: x86.h:148
#define X86_EFLAGS_TEST_NT
Definition: x86.h:113
@ X86_AVX_RM_INVALID
Uninitialized.
Definition: x86.h:239
#define X86_EFLAGS_RESET_TF
Definition: x86.h:102
#define X86_EFLAGS_RESET_DF
Definition: x86.h:98
#define X86_EFLAGS_RESET_CF
Definition: x86.h:97
#define X86_EFLAGS_SET_SF
Definition: x86.h:128
#define X86_FPU_FLAGS_UNDEFINED_C3
Definition: x86.h:150
#define X86_FPU_FLAGS_MODIFY_C0
Definition: x86.h:135
#define X86_FPU_FLAGS_TEST_C0
Definition: x86.h:151
#define X86_EFLAGS_SET_ZF
Definition: x86.h:129
#define X86_EFLAGS_UNDEFINED_AF
Definition: x86.h:119
#define X86_EFLAGS_MODIFY_CF
Definition: x86.h:76
#define X86_EFLAGS_TEST_OF
Definition: x86.h:108
#define X86_FPU_FLAGS_SET_C0
Definition: x86.h:143
#define X86_EFLAGS_MODIFY_IF
Definition: x86.h:82
#define X86_EFLAGS_MODIFY_DF
Definition: x86.h:83
#define X86_FPU_FLAGS_MODIFY_C3
Definition: x86.h:138
#define X86_EFLAGS_PRIOR_IF
Definition: x86.h:93
#define X86_EFLAGS_SET_CF
Definition: x86.h:105
#define X86_EFLAGS_TEST_TF
Definition: x86.h:124
#define X86_EFLAGS_MODIFY_OF
Definition: x86.h:80
#define X86_EFLAGS_RESET_SF
Definition: x86.h:100
#define X86_EFLAGS_TEST_PF
Definition: x86.h:111
#define X86_FPU_FLAGS_TEST_C1
Definition: x86.h:152
@ X86_OP_IMM
= CS_OP_IMM (Immediate operand).
Definition: x86.h:161
@ X86_OP_REG
= CS_OP_REG (Register operand).
Definition: x86.h:160
@ X86_OP_MEM
= CS_OP_MEM (Memory operand).
Definition: x86.h:162
#define X86_EFLAGS_SET_DF
Definition: x86.h:106
#define X86_EFLAGS_MODIFY_PF
Definition: x86.h:79
#define X86_EFLAGS_RESET_OF
Definition: x86.h:96
#define X86_EFLAGS_UNDEFINED_ZF
Definition: x86.h:117
#define X86_EFLAGS_MODIFY_TF
Definition: x86.h:81
#define X86_EFLAGS_MODIFY_NT
Definition: x86.h:84
#define X86_FPU_FLAGS_RESET_C2
Definition: x86.h:141
#define X86_EFLAGS_PRIOR_OF
Definition: x86.h:86
#define X86_EFLAGS_TEST_RF
Definition: x86.h:122
#define X86_EFLAGS_SET_AF
Definition: x86.h:130
#define X86_FPU_FLAGS_TEST_C3
Definition: x86.h:154
#define X86_EFLAGS_RESET_PF
Definition: x86.h:104
#define X86_EFLAGS_MODIFY_ZF
Definition: x86.h:78
#define X86_EFLAGS_PRIOR_PF
Definition: x86.h:90
#define X86_EFLAGS_MODIFY_AF
Definition: x86.h:75
@ X86_REG_INVALID
Definition: x86.h:20
#define X86_FPU_FLAGS_MODIFY_C2
Definition: x86.h:137
#define X86_FPU_FLAGS_SET_C1
Definition: x86.h:144
@ X86_XOP_CC_INVALID
Uninitialized.
Definition: x86.h:167
@ X86_GRP_FPU
Definition: x86.h:1963
#define X86_EFLAGS_UNDEFINED_PF
Definition: x86.h:118
#define X86_EFLAGS_TEST_ZF
Definition: x86.h:110
#define X86_EFLAGS_TEST_AF
Definition: x86.h:125
#define X86_FPU_FLAGS_UNDEFINED_C2
Definition: x86.h:149
#define X86_EFLAGS_UNDEFINED_SF
Definition: x86.h:116
#define X86_EFLAGS_RESET_ZF
Definition: x86.h:126
#define X86_FPU_FLAGS_RESET_C3
Definition: x86.h:142
#define X86_EFLAGS_TEST_SF
Definition: x86.h:109
#define X86_FPU_FLAGS_RESET_C1
Definition: x86.h:140
#define X86_EFLAGS_SET_PF
Definition: x86.h:131
#define X86_FPU_FLAGS_SET_C2
Definition: x86.h:145
#define X86_EFLAGS_PRIOR_ZF
Definition: x86.h:88
#define X86_EFLAGS_RESET_NT
Definition: x86.h:103
#define X86_EFLAGS_UNDEFINED_OF
Definition: x86.h:115
#define X86_EFLAGS_PRIOR_AF
Definition: x86.h:89
#define X86_EFLAGS_PRIOR_SF
Definition: x86.h:87
#define X86_EFLAGS_PRIOR_TF
Definition: x86.h:92
#define X86_EFLAGS_MODIFY_SF
Definition: x86.h:77
@ X86_AVX_CC_INVALID
Uninitialized.
Definition: x86.h:202
@ X86_SSE_CC_INVALID
Uninitialized.
Definition: x86.h:189
#define X86_EFLAGS_RESET_IF
Definition: x86.h:99
#define X86_EFLAGS_RESET_AC
Definition: x86.h:133
#define X86_EFLAGS_TEST_DF
Definition: x86.h:114
#define X86_EFLAGS_RESET_0F
Definition: x86.h:132
#define X86_FPU_FLAGS_MODIFY_C1
Definition: x86.h:136
#define X86_EFLAGS_TEST_CF
Definition: x86.h:112
#define X86_EFLAGS_PRIOR_CF
Definition: x86.h:91
#define X86_FPU_FLAGS_TEST_C2
Definition: x86.h:153
#define X86_EFLAGS_UNDEFINED_CF
Definition: x86.h:120
#define X86_EFLAGS_SET_OF
Definition: x86.h:127
#define X86_EFLAGS_MODIFY_RF
Definition: x86.h:85
#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 int CAPSTONE_API cs_op_count(csh ud, const cs_insn *insn, unsigned int op_type)
Definition: cs.c:1271
CAPSTONE_EXPORT const char *CAPSTONE_API cs_reg_name(csh ud, unsigned int reg)
Definition: cs.c:1154
CAPSTONE_EXPORT int CAPSTONE_API cs_op_index(csh ud, const cs_insn *insn, unsigned int op_type, unsigned int post)
Definition: cs.c:1369
_Use_decl_annotations_ int __cdecl printf(const char *const _Format,...)
Definition: cs_driver.c:93
void print_string_hex(const char *comment, unsigned char *str, size_t len)
Definition: cstool.c:91
void print_insn_detail_x86(csh ud, cs_mode mode, cs_insn *ins)
Definition: cstool_x86.c:180
static const char * get_fpu_flag_name(uint64_t flag)
Definition: cstool_x86.c:132
static const char * get_eflag_name(uint64_t flag)
Definition: cstool_x86.c:10
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void count
Definition: sflib.h:98
const char int mode
Definition: ioapi.h:137
unsigned long uint64_t
Definition: sftypes.h:28
unsigned char uint8_t
Definition: sftypes.h:31
Instruction operand.
Definition: x86.h:275
Instruction structure.
Definition: x86.h:312
#define PRIx64
Definition: sysdefs.h:94
Definition: dis.c:32