Пример #1
0
extern uint16_t 
ud_inp_uint16(struct ud* u)
{
  uint16_t r, ret;

  ret = ud_inp_next(u);
  r = ud_inp_next(u);
  return ret | (r << 8);
}
Пример #2
0
extern uint32_t 
ud_inp_uint32(struct ud* u)
{
  uint32_t r, ret;

  ret = ud_inp_next(u);
  r = ud_inp_next(u);
  ret = ret | (r << 8);
  r = ud_inp_next(u);
  ret = ret | (r << 16);
  r = ud_inp_next(u);
  return ret | (r << 24);
}
Пример #3
0
/* -----------------------------------------------------------------------------
 * ud_inp_peek() - Peek into the next byte in source. 
 * -----------------------------------------------------------------------------
 */
extern uint8_t
ud_inp_peek(struct ud* u) 
{
  uint8_t r = ud_inp_next(u);
  if ( !u->error ) ud_inp_back(u); /* Don't backup if there was an error */
  return r;
}
Пример #4
0
static inline unsigned int modrm( struct ud * u )
{
    if ( !u->have_modrm ) {
        u->modrm = ud_inp_next( u );
        u->have_modrm = 1;
    }
    return u->modrm;
}
Пример #5
0
/*
 * decode_3dnow()
 *
 *    Decoding 3dnow is a little tricky because of its strange opcode
 *    structure. The final opcode disambiguation depends on the last
 *    byte that comes after the operands have been decoded. Fortunately,
 *    all 3dnow instructions have the same set of operand types. So we
 *    go ahead and decode the instruction by picking an arbitrarily chosen
 *    valid entry in the table, decode the operands, and read the final
 *    byte to resolve the menmonic.
 */
static inline int
decode_3dnow(struct ud* u)
{
  uint16_t ptr;
  UD_ASSERT(u->le->type == UD_TAB__OPC_3DNOW);
  UD_ASSERT(u->le->table[0xc] != 0);
  decode_insn(u, u->le->table[0xc]);
  ud_inp_next(u); 
  if (u->error) {
    return -1;
  }
  ptr = u->le->table[inp_curr(u)]; 
  UD_ASSERT((ptr & 0x8000) == 0);
  u->mnemonic = ud_itab[ptr].mnemonic;
  return 0;
}
Пример #6
0
extern uint64_t 
ud_inp_uint64(struct ud* u)
{
  uint64_t r, ret;

  ret = ud_inp_next(u);
  r = ud_inp_next(u);
  ret = ret | (r << 8);
  r = ud_inp_next(u);
  ret = ret | (r << 16);
  r = ud_inp_next(u);
  ret = ret | (r << 24);
  r = ud_inp_next(u);
  ret = ret | (r << 32);
  r = ud_inp_next(u);
  ret = ret | (r << 40);
  r = ud_inp_next(u);
  ret = ret | (r << 48);
  r = ud_inp_next(u);
  return ret | (r << 56);
}
Пример #7
0
static int
decode_opcode(struct ud *u)
{
  uint16_t ptr;
  UD_ASSERT(u->le->type == UD_TAB__OPC_TABLE);
  ud_inp_next(u); 
  if (u->error) {
    return -1;
  }
  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) {
      return decode_opcode(u);
    }
  }
  return decode_ext(u, ptr);
}
Пример #8
0
/*------------------------------------------------------------------------------
 *  ud_inp_uintN() - return uintN from source.
 *------------------------------------------------------------------------------
 */
extern uint8_t 
ud_inp_uint8(struct ud* u)
{
  return ud_inp_next(u);
}
Пример #9
0
/* -----------------------------------------------------------------------------
 * ud_inp_move() - Move ahead n input bytes.
 * -----------------------------------------------------------------------------
 */
extern void
ud_inp_move(struct ud* u, size_t n) 
{
  while (n--)
	ud_inp_next(u);
}
Пример #10
0
/*
 * inp_uint8
 * int_uint16
 * int_uint32
 * int_uint64
 *    Load little-endian values from input
 */
static uint8_t 
inp_uint8(struct ud* u)
{
  return ud_inp_next(u);
}
Пример #11
0
/*
 * decode_modrm_rm
 *
 *    Decodes rm field of mod/rm byte
 * 
 */
static void 
decode_modrm_rm(struct ud         *u, 
                struct ud_operand *op,
                unsigned char      type,    /* register type */
                unsigned int       size)    /* operand size */

{
  size_t offset = 0;
  unsigned char mod, rm;

  /* get mod, r/m and reg fields */
  mod = MODRM_MOD(modrm(u));
  rm  = (REX_B(u->pfx_rex) << 3) | MODRM_RM(modrm(u));

  /* 
   * If mod is 11b, then the modrm.rm specifies a register.
   *
   */
  if (mod == 3) {
    decode_reg(u, op, type, rm, size);
    return;
  }

  /* 
   * !11b => Memory Address
   */  
  op->type = UD_OP_MEM;
  op->size = resolve_operand_size(u, size);

  if (u->adr_mode == 64) {
    op->base = UD_R_RAX + rm;
    if (mod == 1) {
      offset = 8;
    } else if (mod == 2) {
      offset = 32;
    } else if (mod == 0 && (rm & 7) == 5) {           
      op->base = UD_R_RIP;
      offset = 32;
    } else {
      offset = 0;
    }
    /* 
     * Scale-Index-Base (SIB) 
     */
    if ((rm & 7) == 4) {
      ud_inp_next(u);
      
      op->scale = (1 << SIB_S(inp_curr(u))) & ~1;
      op->index = UD_R_RAX + (SIB_I(inp_curr(u)) | (REX_X(u->pfx_rex) << 3));
      op->base  = UD_R_RAX + (SIB_B(inp_curr(u)) | (REX_B(u->pfx_rex) << 3));

      /* special conditions for base reference */
      if (op->index == UD_R_RSP) {
        op->index = UD_NONE;
        op->scale = UD_NONE;
      }

      if (op->base == UD_R_RBP || op->base == UD_R_R13) {
        if (mod == 0) {
          op->base = UD_NONE;
        } 
        if (mod == 1) {
          offset = 8;
        } else {
          offset = 32;
        }
      }
    }
  } else if (u->adr_mode == 32) {
    op->base = UD_R_EAX + rm;
    if (mod == 1) {
      offset = 8;
    } else if (mod == 2) {
      offset = 32;
    } else if (mod == 0 && rm == 5) {
      op->base = UD_NONE;
      offset = 32;
    } else {
      offset = 0;
    }

    /* Scale-Index-Base (SIB) */
    if ((rm & 7) == 4) {
      ud_inp_next(u);

      op->scale = (1 << SIB_S(inp_curr(u))) & ~1;
      op->index = UD_R_EAX + (SIB_I(inp_curr(u)) | (REX_X(u->pfx_rex) << 3));
      op->base  = UD_R_EAX + (SIB_B(inp_curr(u)) | (REX_B(u->pfx_rex) << 3));

      if (op->index == UD_R_ESP) {
        op->index = UD_NONE;
        op->scale = UD_NONE;
      }

      /* special condition for base reference */
      if (op->base == UD_R_EBP) {
        if (mod == 0) {
          op->base = UD_NONE;
        } 
        if (mod == 1) {
          offset = 8;
        } else {
          offset = 32;
        }
      }
    }
  } else {
    const unsigned int bases[]   = { UD_R_BX, UD_R_BX, UD_R_BP, UD_R_BP,
                                     UD_R_SI, UD_R_DI, UD_R_BP, UD_R_BX };
    const unsigned int indices[] = { UD_R_SI, UD_R_DI, UD_R_SI, UD_R_DI,
                                     UD_NONE, UD_NONE, UD_NONE, UD_NONE };
    op->base  = bases[rm & 7];
    op->index = indices[rm & 7];
    if (mod == 0 && rm == 6) {
      offset = 16;
      op->base = UD_NONE;
    } else if (mod == 1) {
      offset = 8;
    } else if (mod == 2) { 
      offset = 16;
    }
  }

  if (offset) {
    decode_mem_disp(u, (unsigned int)offset, op);
  }
}
Пример #12
0
/* 
 * decode_prefixes
 *
 *  Extracts instruction prefixes.
 */
static int 
decode_prefixes(struct ud *u)
{
  int done = 0;
  uint8_t curr;
  UD_RETURN_ON_ERROR(u);

  do {
    ud_inp_next(u); 
    UD_RETURN_ON_ERROR(u);
    if (inp_len(u) == MAX_INSN_LENGTH) {
      UD_RETURN_WITH_ERROR(u, "max instruction length");
    }
    curr = inp_curr(u);

    switch (curr)  
    {
    case 0x2E : 
      u->pfx_seg = UD_R_CS; 
      break;
    case 0x36 :     
      u->pfx_seg = UD_R_SS; 
      break;
    case 0x3E : 
      u->pfx_seg = UD_R_DS; 
      break;
    case 0x26 : 
      u->pfx_seg = UD_R_ES; 
      break;
    case 0x64 : 
      u->pfx_seg = UD_R_FS; 
      break;
    case 0x65 : 
      u->pfx_seg = UD_R_GS; 
      break;
    case 0x67 : /* adress-size override prefix */ 
      u->pfx_adr = 0x67;
      break;
    case 0xF0 : 
      u->pfx_lock = 0xF0;
      break;
    case 0x66: 
      u->pfx_opr = 0x66;
      break;
    case 0xF2:
      u->pfx_str = 0xf2;
      break;
    case 0xF3:
      u->pfx_str = 0xf3;
      break;
    default:
      done = 1;
      break;
    }
  } while (!done);

  if (u->dis_mode == 64 && (curr & 0xF0) == 0x40) {
    /* rex prefixes in 64bit mode, must be the last prefix
     */
    u->pfx_rex = curr;  
  } else {
    /* rewind back one byte in stream, since the above loop 
     * stops with a non-prefix byte. 
     */
    inp_back(u);
  }
  return 0;
}