/* ----------------------------------------------------------------------------- * 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; }
/* * 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; }
/* * 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; }
/* 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; }
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; }