24 #include <mnemonics.h>
48 unsigned char *inst_buf,
unsigned int buf_len,
49 struct array_list **idata_list_saveptr,
int noabort) {
53 unsigned int di_count = 0;
57 if (!idata_list_saveptr) {
62 tmplist = array_list_create(0);
64 ci.code = (
unsigned char *)inst_buf;
67 ci.features = DF_NONE;
73 while (ci.codeOffset < buf_len) {
74 memset(&di,0,
sizeof(di));
75 if (distorm_decompose64(&ci,&di,1,&di_count) == DECRES_INPUTERR) {
76 vwarn(
"decoding error at offset %"PRIu64
"\n",ci.codeOffset);
82 if (di.flags == FLAG_NOT_DECODABLE) {
83 vwarn(
"bad instruction at offset %"PRIu64
"\n",ci.codeOffset);
95 idata->
type = di.opcode;
96 idata->
size = di.size;
100 array_list_add(tmplist,idata);
102 memset(&inst,0,
sizeof(inst));
103 distorm_format(&ci,&di,&inst);
105 inst.mnemonic.p,inst.operands.p,ci.codeOffset);
108 ci.codeOffset += di.size;
112 if (ci.codeOffset != buf_len) {
113 vwarn(
"decoding stopped %"PRIi64
" bytes short\n",
114 (uint64_t)buf_len - ci.codeOffset);
119 if (idata_list_saveptr)
120 *idata_list_saveptr = tmplist;
124 array_list_deep_free(tmplist);
132 unsigned char *inst_buf,
unsigned int buf_len,
138 unsigned int di_count = 0;
147 tmplist = array_list_create(0);
149 ci.code = (
unsigned char *)inst_buf;
150 ci.codeLen = buf_len;
152 ci.features = DF_NONE;
154 ci.dt = Decode32Bits;
156 ci.dt = Decode64Bits;
158 while (ci.codeOffset < buf_len) {
159 memset(&di,0,
sizeof(di));
160 if (distorm_decompose64(&ci,&di,1,&di_count) == DECRES_INPUTERR) {
162 "decoding error at offset %"PRIu64
"\n",ci.codeOffset);
168 if (di.flags == FLAG_NOT_DECODABLE) {
170 "bad instruction at offset %"PRIu64
"\n",ci.codeOffset);
183 memset(&inst,0,
sizeof(inst));
185 && (di.opcode == I_RET || di.opcode == I_RETF)) {
186 idata =
calloc(1,
sizeof(*idata));
187 memset(idata,0,
sizeof(*idata));
190 array_list_add(tmplist,idata);
194 else if ((!flags || flags &
INST_CF_IRET) && di.opcode == I_IRET) {
195 idata =
calloc(1,
sizeof(*idata));
196 memset(idata,0,
sizeof(*idata));
199 array_list_add(tmplist,idata);
203 else if ((!flags || flags &
INST_CF_INT) && di.opcode == I_INT) {
204 idata =
calloc(1,
sizeof(*idata));
205 memset(idata,0,
sizeof(*idata));
209 array_list_add(tmplist,idata);
213 else if ((!flags || flags &
INST_CF_INT3) && di.opcode == I_INT_3) {
214 idata =
calloc(1,
sizeof(*idata));
215 memset(idata,0,
sizeof(*idata));
219 array_list_add(tmplist,idata);
223 else if ((!flags || flags &
INST_CF_INTO) && di.opcode == I_INTO) {
224 idata =
calloc(1,
sizeof(*idata));
225 memset(idata,0,
sizeof(*idata));
229 array_list_add(tmplist,idata);
233 else if (((!flags || flags &
INST_CF_SYSCALL) && di.opcode == I_SYSCALL)
237 idata =
calloc(1,
sizeof(*idata));
238 memset(idata,0,
sizeof(*idata));
256 array_list_add(tmplist,idata);
260 else if ((!flags || flags &
INST_CF_JCC) && META_GET_FC(di.meta) == FC_CND_BRANCH) {
261 idata =
calloc(1,
sizeof(*idata));
262 memset(idata,0,
sizeof(*idata));
267 array_list_add(tmplist,idata);
272 && (di.opcode == I_CALL || di.opcode == I_CALL_FAR))
274 && META_GET_FC(di.meta) == FC_UNC_BRANCH)) {
275 idata =
calloc(1,
sizeof(*idata));
276 memset(idata,0,
sizeof(*idata));
278 if (META_GET_FC(di.meta) == FC_UNC_BRANCH)
287 if (di.ops[0].type == O_PC) {
291 else if (di.ops[0].type == O_IMM && (di.opcode == I_CALL
292 || di.opcode == I_JMP)) {
297 else if (di.ops[0].type == O_IMM && (di.opcode == I_CALL_FAR
298 || di.opcode == I_JMP_FAR)) {
299 idata->
cf.
addr = di.imm.qword;
301 else if (di.ops[0].type == O_PTR && (di.opcode == I_CALL_FAR
302 || di.opcode == I_JMP_FAR)) {
303 idata->
cf.
addr = di.imm.ptr.off;
305 else if (di.ops[0].type == O_REG) {
312 else if (di.ops[0].type == O_SMEM) {
319 else if (di.ops[0].type == O_MEM) {
325 else if (di.ops[0].type == O_DISP) {
328 idata->
cf.
mem = di.disp;
331 distorm_format(&ci,&di,&inst);
332 vwarn(
"decoded unknown call inst %s %s at %"PRIu64
333 " (type=%hhu,index=%hhu,size=%hu) -- returning to user"
335 inst.mnemonic.p,inst.operands.p,ci.codeOffset,
336 di.ops[0].type,di.ops[0].index,di.ops[0].size);
340 array_list_add(tmplist,idata);
345 distorm_format(&ci,&di,&inst);
347 inst.mnemonic.p,inst.operands.p,ci.codeOffset);
352 idata->
size = di.size;
353 idata->
offset = ci.codeOffset;
357 if (toff >= 0 && toff < buf_len)
364 if (idata->
cf.
addr >= base && idata->
cf.
addr < (base + buf_len))
373 distorm_format(&ci,&di,&inst);
375 inst.mnemonic.p,inst.operands.p,ci.codeOffset);
379 ci.codeOffset += di.size;
383 if (ci.codeOffset != buf_len) {
385 "decoding stopped %"PRIi64
" bytes short\n",
386 (uint64_t)buf_len - ci.codeOffset);
392 *offset_list = tmplist;
396 array_list_deep_free(tmplist);
410 unsigned char *inst_buf,
unsigned int buf_len,
415 unsigned int di_count = 0;
424 ci.code = (
unsigned char *)inst_buf;
425 ci.codeLen = buf_len;
431 ci.features = DF_STOP_ON_FLOW_CONTROL;
433 ci.dt = Decode32Bits;
435 ci.dt = Decode64Bits;
437 while (ci.codeOffset < buf_len) {
438 memset(&di,0,
sizeof(di));
439 if (distorm_decompose64(&ci,&di,1,&di_count) == DECRES_INPUTERR) {
440 vwarn(
"decoding error at offset %"PRIu64
"\n",ci.codeOffset);
446 if (di.flags == FLAG_NOT_DECODABLE) {
447 vwarn(
"bad instruction at offset %"PRIu64
"\n",ci.codeOffset);
451 distorm_format(&ci,&di,&inst);
470 if (di.ops[0].type != O_IMM1 || di.ops[1].type != O_IMM2) {
471 vwarn(
"ENTER did not have two imm operands; error!\n");
475 int size = di.imm.ex.i1;
476 int nestinglevel = di.imm.ex.i2 % 32;
482 for (i = 1; i < nestinglevel; ++
i) {
510 if (di.ops[0].type == O_REG && di.usedRegistersMask & RM_SP) {
511 if (di.ops[1].type == O_IMM)
512 retval += di.imm.sword;
514 vwarn(
"unsupported SP offset op: ADD!\n");
520 if (di.ops[0].type == O_REG && di.usedRegistersMask & RM_SP) {
521 if (di.ops[1].type == O_IMM)
522 retval -= di.imm.sword;
524 vwarn(
"unsupported SP offset op: SUB!\n");
535 if (di.ops[0].type == O_REG && di.ops[0].index & RM_SP) {
536 if (di.ops[1].type != O_IMM) {
537 vwarn(
"unsupported SP offset op: SAL/SAR/SHL!\n");
541 if (di.imm.byte == 0)
543 if (di.opcode == I_SAR)
544 retval -= 1 << di.imm.byte;
546 retval += 1 << di.imm.byte;
551 if (di.ops[0].type == O_REG && di.ops[0].index & RM_SP) {
552 vwarn(
"unsupported SP offset op: SHR!\n");
557 if (di.ops[0].type == O_REG && di.ops[0].index & RM_SP) {
558 vwarn(
"unsupported SP offset op: MOV!\n");
582 if (di.ops[1].type != O_NONE
583 && di.ops[0].type == O_REG && di.ops[0].index & RM_SP) {
584 vwarn(
"unsupported SP offset op: IMUL!\n");
589 if (di.ops[0].type == O_REG && di.ops[0].index & RM_SP) {
590 vwarn(
"unsupported SP offset op: XOR!\n");
595 if (di.ops[0].type == O_REG && di.ops[0].index & RM_SP) {
596 vwarn(
"unsupported SP offset op: AND!\n");
601 if (di.ops[0].type == O_REG && di.ops[0].index & RM_SP) {
602 vwarn(
"unsupported SP offset op: OR!\n");
608 if (di.ops[0].type == O_REG && di.ops[0].index & RM_SP) {
609 vwarn(
"unsupported SP offset op: NOT!\n");
614 if (di.ops[0].type == O_REG && di.ops[0].index & RM_SP) {
615 vwarn(
"unsupported SP offset op: NEG!\n");
624 ci.codeOffset += di.size;
628 if (ci.codeOffset != buf_len) {
629 vwarn(
"decoding stopped %"PRIu64
" bytes short; bad prologue?\n",
630 buf_len - ci.codeOffset - 1);
#define vwarnopt(level, area, flags, format,...)
int disasm_generic(struct target *target, unsigned char *inst_buf, unsigned int buf_len, struct array_list **idata_list_saveptr, int noabort)
static uint64_t unsigned int i
char *const inst_type_names[]
#define vwarn(format,...)
int disasm_get_control_flow_offsets(struct target *target, inst_cf_flags_t flags, unsigned char *inst_buf, unsigned int buf_len, struct array_list **offset_list, ADDR base, int noabort)
#define vdebug(devel, areas, flags, format,...)
const char * disasm_get_inst_name(inst_type_t type)
struct cf_inst_data::@12 cf
void * calloc(size_t nmemb, size_t size)
int disasm_get_prologue_stack_size(struct target *target, unsigned char *inst_buf, unsigned int buf_len, int *sp)