/* Print out the sib byte of the parsed instruction in the given decoder state
 * to the given file.
 */
static void SibPrint(const NCDecoderInst* dinst, struct Gio* fp) {
  uint8_t sib = NCInstBytesByte(&dinst->inst_bytes, NCSibOffset(dinst));

  if (!dinst->inst.hassibbyte) {
    /* This should not happen. */
    gprintf(fp, "?");
  } else if (sib_ss(sib) == 0) {
    if (sib_base(sib) == 5) {
      /* This code is JUST WRONG!. However, I am not fixing since
       * the decoder printer is broken in so many other ways!. See tables
       * 2-1 and 2-2 of "Intel 64 and IA-32 Architectures Software Developer's
       * Manual" for details of what should be done (there are
       * 3 cases, depending on the value of the mod field of the modrm
       * byte).
       * Note: While the changes here are not correct, they at least make
       * sure that we process bytes that are actually in the instruction.
       * That is, the code doesn't accidentally walk off the end of the
       * parsed instruction.
       */
      gprintf(fp, "[0x%x]", DispValue32(dinst));
    } else {
      /* Has a base register */
      if (sib_index(sib) == 4) {
        /* No index */
        gprintf(fp, "[%s]", gp_regs[sib_base(sib)]);
      } else {
        gprintf(fp, "[%s + %s]",
                gp_regs[sib_base(sib)],
                gp_regs[sib_index(sib)]);
      }
    }
  } else {
    if (sib_index(sib) == 4) {
      /* No index */
      gprintf(fp, "[%s]", gp_regs[sib_base(sib)]);
    } else {
      gprintf(fp, "[%s + %d * %s]",
              gp_regs[sib_base(sib)],
              1 << sib_ss(sib),
              gp_regs[sib_index(sib)]);
    }
  }
}
Пример #2
0
/*
 * Read address at location and return updated location.
 */
db_addr_t
db_read_address(db_addr_t loc, int short_addr, int regmodrm, int rex,
    struct i_addr *addrp)
{
	int		mod, rm, sib, index, disp, size;

	size = (short_addr ? LONG : QUAD);
	mod = f_mod(regmodrm);
	rm  = f_rm(regmodrm, rex);

	if (mod == 3) {
		addrp->is_reg = TRUE;
		addrp->disp = rm;
		return (loc);
	}
	addrp->is_reg = FALSE;
	addrp->index = 0;

	if (rm == 4 || rm == 12) {
		get_value_inc(sib, loc, 1, FALSE);
		rm = sib_base(sib, rex);
		index = sib_index(sib, rex);
		if (index != 4)
			addrp->index = db_reg[size][index];
		addrp->ss = sib_ss(sib);
	}

	switch (mod) {
	case 0:
		if (rm == 5) {
		get_value_inc(addrp->disp, loc, 4, FALSE);
			addrp->base = 0;
		} else {
			addrp->disp = 0;
			addrp->base = db_reg[size][rm];
		}
		break;
	case 1:
		get_value_inc(disp, loc, 1, TRUE);
		addrp->disp = disp;
		addrp->base = db_reg[size][rm];
		break;
	case 2:
		get_value_inc(disp, loc, 4, FALSE);
		addrp->disp = disp;
		addrp->base = db_reg[size][rm];
		break;
	}
	return (loc);
}
Пример #3
0
/*
 * Read address at location and return updated location.
 */
db_addr_t
db_read_address(db_addr_t loc, int short_addr, int regmodrm,
    struct i_addr *addrp)
{
	int		mod, rm, sib, index, disp;

	mod = f_mod(regmodrm);
	rm  = f_rm(regmodrm);

	if (mod == 3) {
		addrp->is_reg = TRUE;
		addrp->disp = rm;
		return (loc);
	}
	addrp->is_reg = FALSE;
	addrp->index = 0;

	if (short_addr) {
		addrp->index = 0;
		addrp->ss = 0;
		switch (mod) {
		    case 0:
			if (rm == 6) {
				get_value_inc(disp, loc, 2, FALSE);
				addrp->disp = disp;
				addrp->base = 0;
			} else {
				addrp->disp = 0;
				addrp->base = db_index_reg_16[rm];
			}
			break;
		    case 1:
			get_value_inc(disp, loc, 1, TRUE);
			disp &= 0xffff;
			addrp->disp = disp;
			addrp->base = db_index_reg_16[rm];
			break;
		    case 2:
			get_value_inc(disp, loc, 2, FALSE);
			addrp->disp = disp;
			addrp->base = db_index_reg_16[rm];
			break;
		}
	} else {
		if (rm == 4) {
			get_value_inc(sib, loc, 1, FALSE);
			rm = sib_base(sib);
			index = sib_index(sib);
			if (index != 4)
				addrp->index = db_reg[LONG][index];
			addrp->ss = sib_ss(sib);
		}

		switch (mod) {
		    case 0:
			if (rm == 5) {
				get_value_inc(addrp->disp, loc, 4, FALSE);
				addrp->base = 0;
			} else {
				addrp->disp = 0;
				addrp->base = db_reg[LONG][rm];
			}
			break;
		    case 1:
			get_value_inc(disp, loc, 1, TRUE);
			addrp->disp = disp;
			addrp->base = db_reg[LONG][rm];
			break;
		    case 2:
			get_value_inc(disp, loc, 4, FALSE);
			addrp->disp = disp;
			addrp->base = db_reg[LONG][rm];
			break;
		}
	}
	return (loc);
}
Пример #4
0
/*
 * Read address at location and return updated location.
 */
static db_addr_t
db_read_address(db_addr_t loc, int short_addr, int rex, int regmodrm,
    struct i_addr *addrp)
{
	int		mod, rm, sib, index, disp, size, have_sib;

	mod = f_mod(rex, regmodrm);
	rm  = f_rm(rex, regmodrm);

	if (mod == 3) {
	    addrp->is_reg = TRUE;
	    addrp->disp = rm;
	    return (loc);
	}
	addrp->is_reg = FALSE;
	addrp->index = NULL;

	if (short_addr)
	    size = LONG;
	else
	    size = QUAD;

	if ((rm & 0x7) == 4) {
	    get_value_inc(sib, loc, 1, FALSE);
	    rm = sib_base(rex, sib);
	    index = sib_index(rex, sib);
	    if (index != 4)
		addrp->index = db_reg[1][size][index];
	    addrp->ss = sib_ss(rex, sib);
	    have_sib = 1;
	} else
	    have_sib = 0;

	switch (mod) {
	    case 0:
		if (rm == 5) {
		    get_value_inc(addrp->disp, loc, 4, FALSE);
		    if (have_sib)
			addrp->base = NULL;
		    else if (short_addr)
			addrp->base = "%eip";
		    else
			addrp->base = "%rip";
		} else {
		    addrp->disp = 0;
		    addrp->base = db_reg[1][size][rm];
		}
		break;

	    case 1:
		get_value_inc(disp, loc, 1, TRUE);
		addrp->disp = disp;
		addrp->base = db_reg[1][size][rm];
		break;

	    case 2:
		get_value_inc(disp, loc, 4, FALSE);
		addrp->disp = disp;
		addrp->base = db_reg[1][size][rm];
		break;
	}
	return (loc);
}