Beispiel #1
0
/* -----------------------------------------------------------------------------
 * inp_peek() - Peek into the next byte in source. 
 * -----------------------------------------------------------------------------
 */
extern uint8_t
inp_peek(struct ud* u) 
{
  uint8_t r = inp_next(u);
  if ( !u->error ) inp_back(u); /* Don't backup if there was an error */
  return r;
}
Beispiel #2
0
/* 
 * decode_prefixes
 *
 *  Extracts instruction prefixes.
 */
static int 
decode_prefixes(struct ud *u)
{
    unsigned int have_pfx = 1;
    unsigned int i;
    uint8_t curr;

    /* if in error state, bail out */
    if ( u->error ) 
        return -1; 

    /* keep going as long as there are prefixes available */
    for ( i = 0; have_pfx ; ++i ) {

        /* Get next byte. */
        inp_next(u); 
        if ( u->error ) 
            return -1;
        curr = inp_curr( u );

        /* rex prefixes in 64bit mode */
        if ( u->dis_mode == 64 && ( curr & 0xF0 ) == 0x40 ) {
            u->pfx_rex = curr;  
        } else {
            switch ( curr )  
            {
            case 0x2E : 
                u->pfx_seg = UD_R_CS; 
                u->pfx_rex = 0;
                break;
            case 0x36 :     
                u->pfx_seg = UD_R_SS; 
                u->pfx_rex = 0;
                break;
            case 0x3E : 
                u->pfx_seg = UD_R_DS; 
                u->pfx_rex = 0;
                break;
            case 0x26 : 
                u->pfx_seg = UD_R_ES; 
                u->pfx_rex = 0;
                break;
            case 0x64 : 
                u->pfx_seg = UD_R_FS; 
                u->pfx_rex = 0;
                break;
            case 0x65 : 
                u->pfx_seg = UD_R_GS; 
                u->pfx_rex = 0;
                break;
            case 0x67 : /* adress-size override prefix */ 
                u->pfx_adr = 0x67;
                u->pfx_rex = 0;
                break;
            case 0xF0 : 
                u->pfx_lock = 0xF0;
                u->pfx_rex  = 0;
                break;
            case 0x66: 
                /* the 0x66 sse prefix is only effective if no other sse prefix
                 * has already been specified.
                 */
                if ( !u->pfx_insn ) u->pfx_insn = 0x66;
                u->pfx_opr = 0x66;           
                u->pfx_rex = 0;
                break;
            case 0xF2:
                u->pfx_insn  = 0xF2;
                u->pfx_repne = 0xF2; 
                u->pfx_rex   = 0;
                break;
            case 0xF3:
                u->pfx_insn = 0xF3;
                u->pfx_rep  = 0xF3; 
                u->pfx_repe = 0xF3; 
                u->pfx_rex  = 0;
                break;
            default : 
                /* No more prefixes */
                have_pfx = 0;
                break;
            }
        }

        /* check if we reached max instruction length */
        if ( i + 1 == MAX_INSN_LENGTH ) {
            u->error = 1;
            break;
        }
    }

    /* return status */
    if ( u->error ) 
        return -1; 

    /* rewind back one byte in stream, since the above loop 
     * stops with a non-prefix byte. 
     */
    inp_back(u);
    return 0;
}
Beispiel #3
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;
}
Beispiel #4
0
/* Extracts instruction prefixes.
 */
static int get_prefixes( struct ud* u )
{
    unsigned int have_pfx = 1;
    unsigned int i;
    uint8_t curr;

    /* if in error state, bail out */
    if ( u->error ) 
        return -1; 

    /* keep going as long as there are prefixes available */
    for ( i = 0; have_pfx ; ++i ) {

        /* Get next byte. */
        inp_next(u); 
        if ( u->error ) 
            return -1;
        curr = inp_curr( u );

        /* rex prefixes in 64bit mode */
        if ( u->dis_mode == 64 && ( curr & 0xF0 ) == 0x40 ) {
            u->pfx_rex = curr;  
        } else {
            switch ( curr )  
            {
            case 0x2E : 
                u->pfx_seg = UD_R_CS; 
                u->pfx_rex = 0;
                break;
            case 0x36 :     
                u->pfx_seg = UD_R_SS; 
                u->pfx_rex = 0;
                break;
            case 0x3E : 
                u->pfx_seg = UD_R_DS; 
                u->pfx_rex = 0;
                break;
            case 0x26 : 
                u->pfx_seg = UD_R_ES; 
                u->pfx_rex = 0;
                break;
            case 0x64 : 
                u->pfx_seg = UD_R_FS; 
                u->pfx_rex = 0;
                break;
            case 0x65 : 
                u->pfx_seg = UD_R_GS; 
                u->pfx_rex = 0;
                break;
            case 0x67 : /* adress-size override prefix */ 
                u->pfx_adr = 0x67;
                u->pfx_rex = 0;
                break;
            case 0xF0 : 
                u->pfx_lock = 0xF0;
                u->pfx_rex  = 0;
                break;
            case 0x66: 
                /* the 0x66 sse prefix is only effective if no other sse prefix
                 * has already been specified.
                 */
                if ( !u->pfx_insn ) u->pfx_insn = 0x66;
                u->pfx_opr = 0x66;           
                u->pfx_rex = 0;
                break;
            case 0xF2:
                u->pfx_insn  = 0xF2;
                u->pfx_repne = 0xF2; 
                u->pfx_rex   = 0;
                break;
            case 0xF3:
                u->pfx_insn = 0xF3;
                u->pfx_rep  = 0xF3; 
                u->pfx_repe = 0xF3; 
                u->pfx_rex  = 0;
                break;
            default : 
                /* No more prefixes */
                have_pfx = 0;
                break;
            }
        }

        /* check if we reached max instruction length */
        if ( i + 1 == MAX_INSN_LENGTH ) {
            u->error = 1;
            break;
        }
    }

    /* return status */
    if ( u->error ) 
        return -1; 

    /* rewind back one byte in stream, since the above loop 
     * stops with a non-prefix byte. 
     */
    inp_back(u);

    /* speculatively determine the effective operand mode,
     * based on the prefixes and the current disassembly
     * mode. This may be inaccurate, but useful for mode
     * dependent decoding.
     */
    if ( u->dis_mode == 64 ) {
        u->opr_mode = REX_W( u->pfx_rex ) ? 64 : ( ( u->pfx_opr ) ? 16 : 32 ) ;
        u->adr_mode = ( u->pfx_adr ) ? 32 : 64;
    } else if ( u->dis_mode == 32 ) {
        u->opr_mode = ( u->pfx_opr ) ? 16 : 32;
        u->adr_mode = ( u->pfx_adr ) ? 16 : 32;
    } else if ( u->dis_mode == 16 ) {
        u->opr_mode = ( u->pfx_opr ) ? 32 : 16;
        u->adr_mode = ( u->pfx_adr ) ? 32 : 16;
    }

    return 0;
}
Beispiel #5
0
static int do_prefixes( struct ud* u )
{
  int have_pfx = 1;
  int i;
  uint8_t last_pfx = -1;
  if ( u->error ) return -1; /* if in error state, bail out */

  for ( i = 0; have_pfx ; ++i ) {

	uint8_t curr;
	/* Get next byte. */
  	inp_next(u); if ( u->error ) return -1;
	curr = inp_curr( u );
	/* Rex prefixes in 64bit mode */
	if ( u->dis_mode == 64 && ( curr & 0xF0 ) == 0x40 ) {
		u->pfx_rex = curr;	
	} else {
		switch ( curr )  
		{
		/* TBD: Need to find out the behavior in the case of multiple
		 * segment prefixes.
		 */
		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 : { /* operand-size override, and SSE modifier */
			/* if there was already an F2, F3 prefix, 66 becomes
			 * in effective.
			 */
			if ( u->pfx_insn != 0xF2 &&  u->pfx_insn != 0xF3 ) {
				u->pfx_insn = 0x66;
			} 
			/* operand size prefix */
			u->pfx_opr = 0x66;			 
			break;
			}
		/* 0xF2 is an SSE instruction modifier */
		case 0xF2 : {
			u->pfx_insn = 0xF2;
			u->pfx_repne= 0xF2; 
			break;
			}
		/* 0xF3 is an SSE instruction modifier */
		case 0xF3 : {
			u->pfx_insn = 0xF3;
			u->pfx_rep  = 0xF3; 
			break;
			}
		default : {
			/* No more prefixes */
			have_pfx = 0;
			}
		}
	}

	/* check if we reached max instruction length */
	if ( i == 14 ) {
		u->error = 1;
		break;
	}
	/* we keep the last prefix for checking 0x66 insn modifier. */	
	last_pfx = curr;
  }

  /* return status */
  if ( u->error ) return -1; 

  /* rewind back one byte in stream, since the above loop stopped 
   * with a non-prefix byte. 
   */
  inp_back(u);

  return 0;
}