static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) { static struct disassemble_info disasm_obj; if (len < 2) { return -1; } buf_global = &op->buf_asm; Offset = a->pc; memcpy (bytes, buf, 2); /* prepare disassembler */ memset (&disasm_obj,'\0', sizeof (struct disassemble_info)); disasm_obj.buffer = bytes; disasm_obj.read_memory_func = &sh_buffer_read_memory; disasm_obj.symbol_at_address_func = &symbol_at_address; disasm_obj.memory_error_func = &memory_error_func; disasm_obj.print_address_func = &generic_print_address_func; disasm_obj.endian = !a->big_endian; disasm_obj.fprintf_func = &generic_fprintf_func; disasm_obj.stream = stdout; if (disasm_obj.endian == BFD_ENDIAN_BIG) { op->size = print_insn_shb ((bfd_vma)Offset, &disasm_obj); } else { op->size = print_insn_shl ((bfd_vma)Offset, &disasm_obj); } if (op->size == -1) { r_asm_op_set_asm (op, "(data)"); } return op->size; }
static int disassemble(RAsm *a, RAsmOp *aop, const ut8 *buf, int len) { m68k_word bof[8] = {0}; int iaddr = (int)a->pc; char opcode[256], operands[256]; const unsigned char *buf2; int ilen ; static struct DisasmPara_68k dp; char *buf_asm; /* initialize DisasmPara */ *operands = *opcode = 0; memcpy (bof, buf, R_MIN(len, sizeof(bof))); dp.opcode = opcode; dp.operands = operands; dp.iaddr = (m68k_word *) (size_t)iaddr; dp.instr = bof; buf2 = (const ut8*)M68k_Disassemble (&dp); if (!buf2) { // invalid instruction return aop->size = 2; } ilen = (buf2-(const ut8*)bof); if (*operands) buf_asm = sdb_fmt ("%s %s", opcode, operands); else buf_asm = sdb_fmt ("%s", opcode); r_str_rmch (buf_asm, '#'); r_asm_op_set_asm (aop, buf_asm); aop->size = ilen; return aop->size; }
static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) { ebc_command_t cmd = { {0}, {0} }; int ret = ebc_decode_command (buf, &cmd); const char *buf_asm = (cmd.operands[0]) ? sdb_fmt ("%s %s", cmd.instr, cmd.operands): cmd.instr; r_asm_op_set_asm (op, buf_asm); return op->size = ret; }
static int tms320c64x_disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) { cs_insn* insn; int n = -1, ret = -1; int mode = 0; if (op) { memset (op, 0, sizeof (RAsmOp)); op->size = 4; } if (cd != 0) { cs_close (&cd); } ret = cs_open (CS_ARCH_TMS320C64X, mode, &cd); if (ret) { goto fin; } cs_option (cd, CS_OPT_DETAIL, CS_OPT_OFF); if (!op) { return 0; } n = cs_disasm (cd, buf, len, a->pc, 1, &insn); if (n < 1) { r_asm_op_set_asm (op, "invalid"); op->size = 4; ret = -1; goto beach; } else { ret = 4; } if (insn->size < 1) { goto beach; } op->size = insn->size; char *buf_asm = sdb_fmt ("%s%s%s", insn->mnemonic, insn->op_str[0]? " ": "", insn->op_str); r_str_replace_char (buf_asm, '%', 0); r_str_case (buf_asm, false); r_asm_op_set_asm (op, buf_asm); cs_free (insn, n); beach: // cs_close (&cd); fin: return ret; }
static int tms320_disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) { if (a->cpu && r_str_casecmp (a->cpu, "c54x") == 0) { tms320_f_set_cpu (&engine, TMS320_F_CPU_C54X); } else if (a->cpu && r_str_casecmp(a->cpu, "c55x+") == 0) { tms320_f_set_cpu (&engine, TMS320_F_CPU_C55X_PLUS); } else if (a->cpu && r_str_casecmp(a->cpu, "c55x") == 0) { tms320_f_set_cpu (&engine, TMS320_F_CPU_C55X); } else { #if CAPSTONE_HAS_TMS320C64X if (a->cpu && !r_str_casecmp (a->cpu, "c64x")) { return tms320c64x_disassemble (a, op, buf, len); } #endif r_asm_op_set_asm (op, "unknown asm.cpu"); return op->size = -1; } op->size = tms320_dasm (&engine, buf, len); r_asm_op_set_asm (op, engine.syntax); return op->size; }
static int asm_pic_disassemble(RAsm *a, RAsmOp *op, const ut8 *b, int l) { int res = -1; char opbuf[128]; const char *opstr = opbuf; strcpy (opbuf, "invalid"); if (a->cpu && strcasecmp (a->cpu, "baseline") == 0) { res = pic_baseline_disassemble (op, opbuf, b, l); } else if (a->cpu && strcasecmp (a->cpu, "midrange") == 0) { res = pic_midrange_disassemble (op, opbuf, b, l); } else if (a->cpu && strcasecmp (a->cpu, "pic18") == 0) { res = pic_pic18_disassemble (op, opbuf, b, l); } r_asm_op_set_asm (op, opstr); return op->size = res; }
static int disassemble(RAsm *a, RAsmOp *aop, const ut8 *buf, int len) { static DISASM disasm_obj; memset (&disasm_obj, '\0', sizeof (DISASM)); disasm_obj.EIP = (long long)buf; disasm_obj.VirtualAddr = a->pc; disasm_obj.Archi = ((a->bits == 64) ? 64 : 0); disasm_obj.SecurityBlock = len; if (a->syntax == R_ASM_SYNTAX_ATT) disasm_obj.Options = 0x400; else disasm_obj.Options = 0; aop->size = Disasm (&disasm_obj); r_asm_op_set_asm (aop, disasm_obj.CompleteInstr); return aop->size; }
static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) { static int omode = 0; int mode, ret; ut64 off = a->pc; mode = (a->bits == 64)? CS_MODE_64: (a->bits == 32)? CS_MODE_32: (a->bits == 16)? CS_MODE_16: 0; if (cd && mode != omode) { cs_close (&cd); cd = 0; } if (op) { op->size = 0; } omode = mode; if (cd == 0) { ret = cs_open (CS_ARCH_X86, mode, &cd); if (ret) { return 0; } } if (a->features && *a->features) { cs_option (cd, CS_OPT_DETAIL, CS_OPT_ON); } else { cs_option (cd, CS_OPT_DETAIL, CS_OPT_OFF); } // always unsigned immediates (kernel addresses) // maybe r2 should have an option for this too? #if CS_API_MAJOR >= 4 cs_option (cd, CS_OPT_UNSIGNED, CS_OPT_ON); #endif if (a->syntax == R_ASM_SYNTAX_MASM) { #if CS_API_MAJOR >= 4 cs_option (cd, CS_OPT_SYNTAX, CS_OPT_SYNTAX_MASM); #endif } else if (a->syntax == R_ASM_SYNTAX_ATT) { cs_option (cd, CS_OPT_SYNTAX, CS_OPT_SYNTAX_ATT); } else { cs_option (cd, CS_OPT_SYNTAX, CS_OPT_SYNTAX_INTEL); } if (!op) { return true; } op->size = 1; cs_insn *insn = NULL; #if USE_ITER_API { size_t size = len; if (!insn || cd < 1) { insn = cs_malloc (cd); } if (!insn) { cs_free (insn, n); return 0; } memset (insn, 0, insn->size); insn->size = 1; n = cs_disasm_iter (cd, (const uint8_t**)&buf, &size, (uint64_t*)&off, insn); } #else n = cs_disasm (cd, (const ut8*)buf, len, off, 1, &insn); #endif if (op) { op->size = 0; } if (a->features && *a->features) { if (!check_features (a, insn)) { op->size = insn->size; r_asm_op_set_asm (op, "illegal"); } } if (op->size == 0 && n > 0 && insn->size > 0) { char *ptrstr; op->size = insn->size; char *buf_asm = sdb_fmt ("%s%s%s", insn->mnemonic, insn->op_str[0]?" ":"", insn->op_str); ptrstr = strstr (buf_asm, "ptr "); if (ptrstr) { memmove (ptrstr, ptrstr + 4, strlen (ptrstr + 4) + 1); } r_asm_op_set_asm (op, buf_asm); } else { decompile_vm (a, op, buf, len); } if (a->syntax == R_ASM_SYNTAX_JZ) { char *buf_asm = r_strbuf_get (&op->buf_asm); if (!strncmp (buf_asm, "je ", 3)) { memcpy (buf_asm, "jz", 2); } else if (!strncmp (buf_asm, "jne ", 4)) { memcpy (buf_asm, "jnz", 3); } } #if 0 // [eax + ebx*4] => [eax + ebx * 4] char *ast = strchr (op->buf_asm, '*'); if (ast && ast > op->buf_asm) { ast--; if (ast[0] != ' ') { char *tmp = strdup (ast + 1); if (tmp) { ast[0] = ' '; if (tmp[0] && tmp[1] && tmp[1] != ' ') { strcpy (ast, " * "); strcpy (ast + 3, tmp + 1); } else { strcpy (ast + 1, tmp); } free (tmp); } } } #endif #if USE_ITER_API /* do nothing because it should be allocated once and freed in the_end */ #else if (insn) { cs_free (insn, n); } #endif return op->size; }
void decompile_vm(RAsm *a, RAsmOp *op, const ut8 *buf, int len) { const char *buf_asm = "invalid"; if (len > 3 && buf[0] == 0x0F && buf[1] == 0x3F && (VPCEXT2 (buf, 0x01) || VPCEXT2 (buf, 0x05) || VPCEXT2 (buf, 0x07) || VPCEXT2 (buf, 0x0D) || VPCEXT2 (buf, 0x10))) { if (a->syntax == R_ASM_SYNTAX_ATT) { buf_asm = sdb_fmt ("vpcext $0x%x, $0x%x", buf[3], buf[2]); } else { buf_asm = sdb_fmt ("vpcext %xh, %xh", buf[2], buf[3]); } op->size = 4; } else if (len > 4 && buf[0] == 0x0F && buf[1] == 0xC6 && buf[2] == 0x28 && buf[3] == 0x00 && buf[4] == 0x00) { /* 0F C6 28 00 00 vmgetinfo */ buf_asm ="vmgetinfo"; op->size = 5; } else if (len > 4 && buf[0] == 0x0F && buf[1] == 0xC6 && buf[2] == 0x28 && buf[3] == 0x00 && buf[4] == 0x01) { /* 0F C6 28 00 01 vmsetinfo */ buf_asm ="vmsetinfo"; op->size = 5; } else if (len > 4 && buf[0] == 0x0F && buf[1] == 0xC6 && buf[2] == 0x28 && buf[3] == 0x00 && buf[4] == 0x02) { /* 0F C6 28 00 02 vmdxdsbl */ buf_asm ="vmdxdsbl"; op->size = 5; } else if (len > 4 && buf[0] == 0x0F && buf[1] == 0xC6 && buf[2] == 0x28 && buf[3] == 0x00 && buf[4] == 0x03) { /* 0F C6 28 00 03 vmdxenbl */ buf_asm ="vmdxenbl"; op->size = 5; } else if (len > 4 && buf[0] == 0x0F && buf[1] == 0xC6 && buf[2] == 0x28 && buf[3] == 0x01 && buf[4] == 0x00) { /* 0F C6 28 01 00 vmcpuid */ buf_asm ="vmcpuid"; op->size = 5; } else if (len > 4 && buf[0] == 0x0F && buf[1] == 0xC6 && buf[2] == 0x28 && buf[3] == 0x01 && buf[4] == 0x01) { /* 0F C6 28 01 01 vmhlt */ buf_asm ="vmhlt"; op->size = 5; } else if (len > 4 && buf[0] == 0x0F && buf[1] == 0xC6 && buf[2] == 0x28 && buf[3] == 0x01 && buf[4] == 0x02) { /* 0F C6 28 01 02 vmsplaf */ buf_asm ="vmsplaf"; op->size = 5; } else if (len > 4 && buf[0] == 0x0F && buf[1] == 0xC6 && buf[2] == 0x28 && buf[3] == 0x02 && buf[4] == 0x00) { /* 0F C6 28 02 00 vmpushfd */ buf_asm ="vmpushfd"; op->size = 5; } else if (len > 4 && buf[0] == 0x0F && buf[1] == 0xC6 && buf[2] == 0x28 && buf[3] == 0x02 && buf[4] == 0x01) { /* 0F C6 28 02 01 vmpopfd */ buf_asm ="vmpopfd"; op->size = 5; } else if (len > 4 && buf[0] == 0x0F && buf[1] == 0xC6 && buf[2] == 0x28 && buf[3] == 0x02 && buf[4] == 0x02) { /* 0F C6 28 02 02 vmcli */ buf_asm ="vmcli"; op->size = 5; } else if (len > 4 && buf[0] == 0x0F && buf[1] == 0xC6 && buf[2] == 0x28 && buf[3] == 0x02 && buf[4] == 0x03) { /* 0F C6 28 02 03 vmsti */ buf_asm ="vmsti"; op->size = 5; } else if (len > 4 && buf[0] == 0x0F && buf[1] == 0xC6 && buf[2] == 0x28 && buf[3] == 0x02 && buf[4] == 0x04) { /* 0F C6 28 02 04 vmiretd */ buf_asm ="vmiretd"; op->size = 5; } else if (len > 4 && buf[0] == 0x0F && buf[1] == 0xC6 && buf[2] == 0x28 && buf[3] == 0x03 && buf[4] == 0x00) { /* 0F C6 28 03 00 vmsgdt */ buf_asm ="vmsgdt"; op->size = 5; } else if (len > 4 && buf[0] == 0x0F && buf[1] == 0xC6 && buf[2] == 0x28 && buf[3] == 0x03 && buf[4] == 0x01) { /* 0F C6 28 03 01 vmsidt */ buf_asm ="vmsidt"; op->size = 5; } else if (len > 4 && buf[0] == 0x0F && buf[1] == 0xC6 && buf[2] == 0x28 && buf[3] == 0x03 && buf[4] == 0x02) { /* 0F C6 28 03 02 vmsldt */ buf_asm ="vmsldt"; op->size = 5; } else if (len > 4 && buf[0] == 0x0F && buf[1] == 0xC6 && buf[2] == 0x28 && buf[3] == 0x03 && buf[4] == 0x03) { /* 0F C6 28 03 03 vmstr */ buf_asm ="vmstr"; op->size = 5; } else if (len > 4 && buf[0] == 0x0F && buf[1] == 0xC6 && buf[2] == 0x28 && buf[3] == 0x04 && buf[4] == 0x00) { /* 0F C6 28 04 00 vmsdte */ buf_asm ="vmsdte"; op->size = 5; } r_asm_op_set_asm (op, buf_asm); }