2 * Hacker Disassembler Engine 32 C
3 * Copyright (c) 2008-2009, Vyacheslav Patkov.
8 /* #include <stdint.h> */
14 unsigned int hde32_disasm(const void *code, hde32s *hs)
16 uint8_t x, c, *p = (uint8_t *)code, cflags, opcode, pref = 0;
17 uint8_t *ht = hde32_table, m_mod, m_reg, m_rm, disp_size = 0;
19 memset(hs,0,sizeof(hde32s));
35 case 0x26: case 0x2e: case 0x36:
36 case 0x3e: case 0x64: case 0x65:
53 hs->flags = (uint32_t)pref << 23;
58 if ((hs->opcode = c) == 0x0f) {
59 hs->opcode2 = c = *p++;
61 } else if (c >= 0xa0 && c <= 0xa3) {
69 cflags = ht[ht[opcode / 4] + (opcode % 4)];
71 if (cflags == C_ERROR) {
72 hs->flags |= F_ERROR | F_ERROR_OPCODE;
74 if ((opcode & -3) == 0x24)
79 if (cflags & C_GROUP) {
81 t = *(uint16_t *)(ht + (cflags & 0x7f));
83 x = (uint8_t)(t >> 8);
87 ht = hde32_table + DELTA_PREFIXES;
88 if (ht[ht[opcode / 4] + (opcode % 4)] & pref)
89 hs->flags |= F_ERROR | F_ERROR_OPCODE;
92 if (cflags & C_MODRM) {
95 hs->modrm_mod = m_mod = c >> 6;
96 hs->modrm_rm = m_rm = c & 7;
97 hs->modrm_reg = m_reg = (c & 0x3f) >> 3;
99 if (x && ((x << m_reg) & 0x80))
100 hs->flags |= F_ERROR | F_ERROR_OPCODE;
102 if (!hs->opcode2 && opcode >= 0xd9 && opcode <= 0xdf) {
103 uint8_t t = opcode - 0xd9;
105 ht = hde32_table + DELTA_FPU_MODRM + t*8;
106 t = ht[m_reg] << m_rm;
108 ht = hde32_table + DELTA_FPU_REG;
112 hs->flags |= F_ERROR | F_ERROR_OPCODE;
115 if (pref & PRE_LOCK) {
117 hs->flags |= F_ERROR | F_ERROR_LOCK;
119 uint8_t *table_end, op = opcode;
121 ht = hde32_table + DELTA_OP2_LOCK_OK;
122 table_end = ht + DELTA_OP_ONLY_MEM - DELTA_OP2_LOCK_OK;
124 ht = hde32_table + DELTA_OP_LOCK_OK;
125 table_end = ht + DELTA_OP2_LOCK_OK - DELTA_OP_LOCK_OK;
128 for (; ht != table_end; ht++)
130 if (!((*ht << m_reg) & 0x80))
135 hs->flags |= F_ERROR | F_ERROR_LOCK;
143 case 0x20: case 0x22:
145 if (m_reg > 4 || m_reg == 1)
148 goto no_error_operand;
149 case 0x21: case 0x23:
151 if (m_reg == 4 || m_reg == 5)
154 goto no_error_operand;
162 goto no_error_operand;
164 if (m_reg == 1 || m_reg > 5)
167 goto no_error_operand;
174 ht = hde32_table + DELTA_OP2_ONLY_MEM;
175 table_end = ht + sizeof(hde32_table) - DELTA_OP2_ONLY_MEM;
177 ht = hde32_table + DELTA_OP_ONLY_MEM;
178 table_end = ht + DELTA_OP2_ONLY_MEM - DELTA_OP_ONLY_MEM;
180 for (; ht != table_end; ht += 2)
181 if (*ht++ == opcode) {
182 if (*ht++ & pref && !((*ht << m_reg) & 0x80))
187 goto no_error_operand;
188 } else if (hs->opcode2) {
190 case 0x50: case 0xd7: case 0xf7:
191 if (pref & (PRE_NONE | PRE_66))
195 if (pref & (PRE_F2 | PRE_F3))
201 goto no_error_operand;
203 goto no_error_operand;
206 hs->flags |= F_ERROR | F_ERROR_OPERAND;
213 else if (opcode == 0xf7)
231 if (!(pref & PRE_67))
235 if (m_mod != 3 && m_rm == 4 && !(pref & PRE_67)) {
239 hs->sib_scale = c >> 6;
240 hs->sib_index = (c & 0x3f) >> 3;
241 if ((hs->sib_base = c & 7) == 5 && !(m_mod & 1))
248 hs->flags |= F_DISP8;
252 hs->flags |= F_DISP16;
253 hs->disp.disp16 = *(uint16_t *)p;
256 hs->flags |= F_DISP32;
257 hs->disp.disp32 = *(uint32_t *)p;
260 } else if (pref & PRE_LOCK)
261 hs->flags |= F_ERROR | F_ERROR_LOCK;
263 if (cflags & C_IMM_P66) {
264 if (cflags & C_REL32) {
266 hs->flags |= F_IMM16 | F_RELATIVE;
267 hs->imm.imm16 = *(uint16_t *)p;
274 hs->flags |= F_IMM16;
275 hs->imm.imm16 = *(uint16_t *)p;
278 hs->flags |= F_IMM32;
279 hs->imm.imm32 = *(uint32_t *)p;
284 if (cflags & C_IMM16) {
285 if (hs->flags & F_IMM32) {
286 hs->flags |= F_IMM16;
287 hs->disp.disp16 = *(uint16_t *)p;
288 } else if (hs->flags & F_IMM16) {
289 hs->flags |= F_2IMM16;
290 hs->disp.disp16 = *(uint16_t *)p;
292 hs->flags |= F_IMM16;
293 hs->imm.imm16 = *(uint16_t *)p;
297 if (cflags & C_IMM8) {
302 if (cflags & C_REL32) {
304 hs->flags |= F_IMM32 | F_RELATIVE;
305 hs->imm.imm32 = *(uint32_t *)p;
307 } else if (cflags & C_REL8) {
308 hs->flags |= F_IMM8 | F_RELATIVE;
314 if ((hs->len = (uint8_t)(p-(uint8_t *)code)) > 15) {
315 hs->flags |= F_ERROR | F_ERROR_LENGTH;
319 return (unsigned int)hs->len;