static int decode_ssepfx(struct ud *u) { uint8_t idx = ((u->pfx_insn & 0xf) + 1) / 2; if (u->le->table[idx] == 0) { idx = 0; } if (idx && u->le->table[idx] != 0) { /* * "Consume" the prefix as a part of the opcode, so it is no * longer exported as an instruction prefix. */ switch (u->pfx_insn) { case 0xf2: u->pfx_repne = 0; break; case 0xf3: u->pfx_rep = 0; u->pfx_repe = 0; break; case 0x66: u->pfx_opr = 0; break; } } return decode_ext(u, u->le->table[idx]); }
static int decode_ssepfx(struct ud *u) { uint8_t idx; uint8_t pfx; /* * String prefixes (f2, f3) take precedence over operand * size prefix (66). */ pfx = u->pfx_str; if (pfx == 0) { pfx = u->pfx_opr; } idx = ((pfx & 0xf) + 1) / 2; if (u->le->table[idx] == 0) { idx = 0; } if (idx && u->le->table[idx] != 0) { /* * "Consume" the prefix as a part of the opcode, so it is no * longer exported as an instruction prefix. */ u->pfx_str = 0; if (pfx == 0x66) { /* * consume "66" only if it was used for decoding, leaving * it to be used as an operands size override for some * simd instructions. */ u->pfx_opr = 0; } } return decode_ext(u, u->le->table[idx]); }
/* * decode_ext() * * Decode opcode extensions (if any) */ static int decode_ext(struct ud *u, uint16_t ptr) { uint8_t idx = 0; if ((ptr & 0x8000) == 0) { return decode_insn(u, ptr); } u->le = &ud_lookup_table_list[(~0x8000 & ptr)]; if (u->le->type == UD_TAB__OPC_3DNOW) { return decode_3dnow(u); } switch (u->le->type) { case UD_TAB__OPC_MOD: /* !11 = 0, 11 = 1 */ idx = (MODRM_MOD(modrm(u)) + 1) / 4; break; /* disassembly mode/operand size/address size based tables. * 16 = 0,, 32 = 1, 64 = 2 */ case UD_TAB__OPC_MODE: idx = u->dis_mode / 32; break; case UD_TAB__OPC_OSIZE: idx = eff_opr_mode(u->dis_mode, REX_W(u->pfx_rex), u->pfx_opr) / 32; break; case UD_TAB__OPC_ASIZE: idx = eff_adr_mode(u->dis_mode, u->pfx_adr) / 32; break; case UD_TAB__OPC_X87: idx = modrm(u) - 0xC0; break; case UD_TAB__OPC_VENDOR: if (u->vendor == UD_VENDOR_ANY) { /* choose a valid entry */ idx = (u->le->table[idx] != 0) ? 0 : 1; } else if (u->vendor == UD_VENDOR_AMD) { idx = 0; } else { idx = 1; } break; case UD_TAB__OPC_RM: idx = MODRM_RM(modrm(u)); break; case UD_TAB__OPC_REG: idx = MODRM_REG(modrm(u)); break; case UD_TAB__OPC_SSE: return decode_ssepfx(u); default: assert(!"not reached"); break; } return decode_ext(u, u->le->table[idx]); }
int _tmain(int argc, _TCHAR* argv[]) { std::vector<int> msg_old = { 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1 }; std::vector<int> msg = { 0, 2, 5, 0, 13, 4, 10, 15, 4 }; std::vector<int> bmsg = convertMessageToBinary(msg); std::vector<int> msg_decode(bmsg.begin() + 4, bmsg.end()); decode_ext(msg_decode, msg_old); return 0; }
static int decode_opcode(struct ud *u) { uint16_t ptr; UD_ASSERT(u->le->type == UD_TAB__OPC_TABLE); UD_RETURN_ON_ERROR(u); u->primary_opcode = inp_curr(u); ptr = u->le->table[inp_curr(u)]; if (ptr & 0x8000) { u->le = &ud_lookup_table_list[ptr & ~0x8000]; if (u->le->type == UD_TAB__OPC_TABLE) { inp_next(u); return decode_opcode(u); } } return decode_ext(u, ptr); }
static __inline int decode_opcode(struct ud *u) { uint16_t ptr; assert(u->le->type == UD_TAB__OPC_TABLE); inp_next(u); if (u->error) { return -1; } ptr = u->le->table[inp_curr(u)]; if (ptr & 0x8000) { u->le = &ud_lookup_table_list[ptr & ~0x8000]; if (u->le->type == UD_TAB__OPC_TABLE) { return decode_opcode(u); } } return decode_ext(u, ptr); }