capstone

Форк
0
/
cstool_x86.c 
346 строк · 8.8 Кб
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
#include "cstool.h"
8

9
void print_string_hex(const char *comment, unsigned char *str, size_t len);
10

11
static const char *get_eflag_name(uint64_t flag)
12
{
13
	switch(flag) {
14
		default:
15
			return NULL;
16
		case X86_EFLAGS_UNDEFINED_OF:
17
			return "UNDEF_OF";
18
		case X86_EFLAGS_UNDEFINED_SF:
19
			return "UNDEF_SF";
20
		case X86_EFLAGS_UNDEFINED_ZF:
21
			return "UNDEF_ZF";
22
		case X86_EFLAGS_MODIFY_AF:
23
			return "MOD_AF";
24
		case X86_EFLAGS_UNDEFINED_PF:
25
			return "UNDEF_PF";
26
		case X86_EFLAGS_MODIFY_CF:
27
			return "MOD_CF";
28
		case X86_EFLAGS_MODIFY_SF:
29
			return "MOD_SF";
30
		case X86_EFLAGS_MODIFY_ZF:
31
			return "MOD_ZF";
32
		case X86_EFLAGS_UNDEFINED_AF:
33
			return "UNDEF_AF";
34
		case X86_EFLAGS_MODIFY_PF:
35
			return "MOD_PF";
36
		case X86_EFLAGS_UNDEFINED_CF:
37
			return "UNDEF_CF";
38
		case X86_EFLAGS_MODIFY_OF:
39
			return "MOD_OF";
40
		case X86_EFLAGS_RESET_OF:
41
			return "RESET_OF";
42
		case X86_EFLAGS_RESET_CF:
43
			return "RESET_CF";
44
		case X86_EFLAGS_RESET_DF:
45
			return "RESET_DF";
46
		case X86_EFLAGS_RESET_IF:
47
			return "RESET_IF";
48
		case X86_EFLAGS_RESET_ZF:
49
			return "RESET_ZF";
50
		case X86_EFLAGS_TEST_OF:
51
			return "TEST_OF";
52
		case X86_EFLAGS_TEST_SF:
53
			return "TEST_SF";
54
		case X86_EFLAGS_TEST_ZF:
55
			return "TEST_ZF";
56
		case X86_EFLAGS_TEST_PF:
57
			return "TEST_PF";
58
		case X86_EFLAGS_TEST_CF:
59
			return "TEST_CF";
60
		case X86_EFLAGS_RESET_SF:
61
			return "RESET_SF";
62
		case X86_EFLAGS_RESET_AF:
63
			return "RESET_AF";
64
		case X86_EFLAGS_RESET_TF:
65
			return "RESET_TF";
66
		case X86_EFLAGS_RESET_NT:
67
			return "RESET_NT";
68
		case X86_EFLAGS_PRIOR_OF:
69
			return "PRIOR_OF";
70
		case X86_EFLAGS_PRIOR_SF:
71
			return "PRIOR_SF";
72
		case X86_EFLAGS_PRIOR_ZF:
73
			return "PRIOR_ZF";
74
		case X86_EFLAGS_PRIOR_AF:
75
			return "PRIOR_AF";
76
		case X86_EFLAGS_PRIOR_PF:
77
			return "PRIOR_PF";
78
		case X86_EFLAGS_PRIOR_CF:
79
			return "PRIOR_CF";
80
		case X86_EFLAGS_PRIOR_TF:
81
			return "PRIOR_TF";
82
		case X86_EFLAGS_PRIOR_IF:
83
			return "PRIOR_IF";
84
		case X86_EFLAGS_PRIOR_DF:
85
			return "PRIOR_DF";
86
		case X86_EFLAGS_TEST_NT:
87
			return "TEST_NT";
88
		case X86_EFLAGS_TEST_DF:
89
			return "TEST_DF";
90
		case X86_EFLAGS_RESET_PF:
91
			return "RESET_PF";
92
		case X86_EFLAGS_PRIOR_NT:
93
			return "PRIOR_NT";
94
		case X86_EFLAGS_MODIFY_TF:
95
			return "MOD_TF";
96
		case X86_EFLAGS_MODIFY_IF:
97
			return "MOD_IF";
98
		case X86_EFLAGS_MODIFY_DF:
99
			return "MOD_DF";
100
		case X86_EFLAGS_MODIFY_NT:
101
			return "MOD_NT";
102
		case X86_EFLAGS_MODIFY_RF:
103
			return "MOD_RF";
104
		case X86_EFLAGS_SET_CF:
105
			return "SET_CF";
106
		case X86_EFLAGS_SET_DF:
107
			return "SET_DF";
108
		case X86_EFLAGS_SET_IF:
109
			return "SET_IF";
110
		case X86_EFLAGS_SET_OF:
111
			return "SET_OF";
112
		case X86_EFLAGS_SET_SF:
113
			return "SET_SF";
114
		case X86_EFLAGS_SET_ZF:
115
			return "SET_ZF";
116
		case X86_EFLAGS_SET_AF:
117
			return "SET_AF";
118
		case X86_EFLAGS_SET_PF:
119
			return "SET_PF";
120
		case X86_EFLAGS_TEST_AF:
121
			return "TEST_AF";
122
		case X86_EFLAGS_TEST_TF:
123
			return "TEST_TF";
124
		case X86_EFLAGS_TEST_RF:
125
			return "TEST_RF";
126
		case X86_EFLAGS_RESET_0F:
127
			return "RESET_0F";
128
		case X86_EFLAGS_RESET_AC:
129
			return "RESET_AC";
130
	}
131
}
132

133
static const char *get_fpu_flag_name(uint64_t flag)
134
{
135
	switch (flag) {
136
		default:
137
			return NULL;
138
		case X86_FPU_FLAGS_MODIFY_C0:
139
			return "MOD_C0";
140
		case X86_FPU_FLAGS_MODIFY_C1:
141
			return "MOD_C1";
142
		case X86_FPU_FLAGS_MODIFY_C2:
143
			return "MOD_C2";
144
		case X86_FPU_FLAGS_MODIFY_C3:
145
			return "MOD_C3";
146
		case X86_FPU_FLAGS_RESET_C0:
147
			return "RESET_C0";
148
		case X86_FPU_FLAGS_RESET_C1:
149
			return "RESET_C1";
150
		case X86_FPU_FLAGS_RESET_C2:
151
			return "RESET_C2";
152
		case X86_FPU_FLAGS_RESET_C3:
153
			return "RESET_C3";
154
		case X86_FPU_FLAGS_SET_C0:
155
			return "SET_C0";
156
		case X86_FPU_FLAGS_SET_C1:
157
			return "SET_C1";
158
		case X86_FPU_FLAGS_SET_C2:
159
			return "SET_C2";
160
		case X86_FPU_FLAGS_SET_C3:
161
			return "SET_C3";
162
		case X86_FPU_FLAGS_UNDEFINED_C0:
163
			return "UNDEF_C0";
164
		case X86_FPU_FLAGS_UNDEFINED_C1:
165
			return "UNDEF_C1";
166
		case X86_FPU_FLAGS_UNDEFINED_C2:
167
			return "UNDEF_C2";
168
		case X86_FPU_FLAGS_UNDEFINED_C3:
169
			return "UNDEF_C3";
170
		case X86_FPU_FLAGS_TEST_C0:
171
			return "TEST_C0";
172
		case X86_FPU_FLAGS_TEST_C1:
173
			return "TEST_C1";
174
		case X86_FPU_FLAGS_TEST_C2:
175
			return "TEST_C2";
176
		case X86_FPU_FLAGS_TEST_C3:
177
			return "TEST_C3";
178
	}
179
}
180

181
void print_insn_detail_x86(csh ud, cs_mode mode, cs_insn *ins)
182
{
183
	int count, i;
184
	cs_x86 *x86;
185
	cs_regs regs_read, regs_write;
186
	uint8_t regs_read_count, regs_write_count;
187
	
188
	// detail can be NULL on "data" instruction if SKIPDATA option is turned ON
189
	if (ins->detail == NULL)
190
		return;
191

192
	x86 = &(ins->detail->x86);
193

194
	print_string_hex("\tPrefix:", x86->prefix, 4);
195
	print_string_hex("\tOpcode:", x86->opcode, 4);
196
	printf("\trex: 0x%x\n", x86->rex);
197
	printf("\taddr_size: %u\n", x86->addr_size);
198
	printf("\tmodrm: 0x%x\n", x86->modrm);
199
	printf("\tdisp: 0x%" PRIx64 "\n", x86->disp);
200

201
	// SIB is not available in 16-bit mode
202
	if ((mode & CS_MODE_16) == 0) {
203
		printf("\tsib: 0x%x\n", x86->sib);
204
		if (x86->sib_base != X86_REG_INVALID)
205
			printf("\t\tsib_base: %s\n", cs_reg_name(ud, x86->sib_base));
206
		if (x86->sib_index != X86_REG_INVALID)
207
			printf("\t\tsib_index: %s\n", cs_reg_name(ud, x86->sib_index));
208
		if (x86->sib_scale != 0)
209
			printf("\t\tsib_scale: %d\n", x86->sib_scale);
210
	}
211

212
	// XOP code condition
213
	if (x86->xop_cc != X86_XOP_CC_INVALID) {
214
		printf("\txop_cc: %u\n", x86->xop_cc);
215
	}
216

217
	// SSE code condition
218
	if (x86->sse_cc != X86_SSE_CC_INVALID) {
219
		printf("\tsse_cc: %u\n", x86->sse_cc);
220
	}
221

222
	// AVX code condition
223
	if (x86->avx_cc != X86_AVX_CC_INVALID) {
224
		printf("\tavx_cc: %u\n", x86->avx_cc);
225
	}
226

227
	// AVX Suppress All Exception
228
	if (x86->avx_sae) {
229
		printf("\tavx_sae: %u\n", x86->avx_sae);
230
	}
231

232
	// AVX Rounding Mode
233
	if (x86->avx_rm != X86_AVX_RM_INVALID) {
234
		printf("\tavx_rm: %u\n", x86->avx_rm);
235
	}
236

237
	// Print out all immediate operands
238
	count = cs_op_count(ud, ins, X86_OP_IMM);
239
	if (count > 0) {
240
		printf("\timm_count: %u\n", count);
241
		for (i = 1; i < count + 1; i++) {
242
			int index = cs_op_index(ud, ins, X86_OP_IMM, i);
243
			printf("\t\timms[%u]: 0x%" PRIx64 "\n", i, x86->operands[index].imm);
244
		}
245
	}
246

247
	if (x86->op_count)
248
		printf("\top_count: %u\n", x86->op_count);
249

250
	// Print out all operands
251
	for (i = 0; i < x86->op_count; i++) {
252
		cs_x86_op *op = &(x86->operands[i]);
253

254
		switch((int)op->type) {
255
			case X86_OP_REG:
256
				printf("\t\toperands[%u].type: REG = %s\n", i, cs_reg_name(ud, op->reg));
257
				break;
258
			case X86_OP_IMM:
259
				printf("\t\toperands[%u].type: IMM = 0x%" PRIx64 "\n", i, op->imm);
260
				break;
261
			case X86_OP_MEM:
262
				printf("\t\toperands[%u].type: MEM\n", i);
263
				if (op->mem.segment != X86_REG_INVALID)
264
					printf("\t\t\toperands[%u].mem.segment: REG = %s\n", i, cs_reg_name(ud, op->mem.segment));
265
				if (op->mem.base != X86_REG_INVALID)
266
					printf("\t\t\toperands[%u].mem.base: REG = %s\n", i, cs_reg_name(ud, op->mem.base));
267
				if (op->mem.index != X86_REG_INVALID)
268
					printf("\t\t\toperands[%u].mem.index: REG = %s\n", i, cs_reg_name(ud, op->mem.index));
269
				if (op->mem.scale != 1)
270
					printf("\t\t\toperands[%u].mem.scale: %u\n", i, op->mem.scale);
271
				if (op->mem.disp != 0)
272
					printf("\t\t\toperands[%u].mem.disp: 0x%" PRIx64 "\n", i, op->mem.disp);
273
				break;
274
			default:
275
				break;
276
		}
277

278
		// AVX broadcast type
279
		if (op->avx_bcast != X86_AVX_BCAST_INVALID)
280
			printf("\t\toperands[%u].avx_bcast: %u\n", i, op->avx_bcast);
281

282
		// AVX zero opmask {z}
283
		if (op->avx_zero_opmask != false)
284
			printf("\t\toperands[%u].avx_zero_opmask: TRUE\n", i);
285

286
		printf("\t\toperands[%u].size: %u\n", i, op->size);
287

288
		switch(op->access) {
289
			default:
290
				break;
291
			case CS_AC_READ:
292
				printf("\t\toperands[%u].access: READ\n", i);
293
				break;
294
			case CS_AC_WRITE:
295
				printf("\t\toperands[%u].access: WRITE\n", i);
296
				break;
297
			case CS_AC_READ | CS_AC_WRITE:
298
				printf("\t\toperands[%u].access: READ | WRITE\n", i);
299
				break;
300
		}
301
	}
302

303
	// Print out all registers accessed by this instruction (either implicit or explicit)
304
	if (!cs_regs_access(ud, ins,
305
						regs_read, &regs_read_count,
306
						regs_write, &regs_write_count)) {
307
		if (regs_read_count) {
308
			printf("\tRegisters read:");
309
			for(i = 0; i < regs_read_count; i++) {
310
				printf(" %s", cs_reg_name(ud, regs_read[i]));
311
			}
312
			printf("\n");
313
		}
314

315
		if (regs_write_count) {
316
			printf("\tRegisters modified:");
317
			for(i = 0; i < regs_write_count; i++) {
318
				printf(" %s", cs_reg_name(ud, regs_write[i]));
319
			}
320
			printf("\n");
321
		}
322
	}
323

324
	if (x86->eflags || x86->fpu_flags) {
325
		for(i = 0; i < ins->detail->groups_count; i++) {
326
			if (ins->detail->groups[i] == X86_GRP_FPU) {
327
				printf("\tFPU_FLAGS:");
328
				for(i = 0; i <= 63; i++)
329
					if (x86->fpu_flags & ((uint64_t)1 << i)) {
330
						printf(" %s", get_fpu_flag_name((uint64_t)1 << i));
331
					}
332
				printf("\n");
333
				break;
334
			}
335
		}
336

337
		if (i == ins->detail->groups_count) {
338
			printf("\tEFLAGS:");
339
			for(i = 0; i <= 63; i++)
340
				if (x86->eflags & ((uint64_t)1 << i)) {
341
					printf(" %s", get_eflag_name((uint64_t)1 << i));
342
				}
343
			printf("\n");
344
		}
345
	}
346
}
347

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.