⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 modsib-x86.c

📁 It s a Linux disassemble, can set break point, disassemble ELF file.
💻 C
📖 第 1 页 / 共 2 页
字号:
        msinfo - where to store ModR/M and SIB informationPrerequisites: ws->prefixFlags must reflect whether we are in 16 or 32 bit               mode before calling this routineReturn: Upon success, total number of bytes in the ModR/M (and SIB) portion        of opcode. This includes the ModR/M byte, the SIB byte (if any) and        any displacement bytes, if any.        Upon failure, -1.Side effects: On success, 'msinfo' is modified to point to the correct              ModR/M information.*/intx86processModSib(struct disasmWorkspace *ws, unsigned char *data,                 struct x86OpCode *opPtr, struct x86ModSibInfo *msinfo){  unsigned char modrm;      /* ModR/M byte */  unsigned char mod,        /* MOD portion of ModR/M byte */                reg,        /* REG portion of ModR/M byte */                rm;         /* R/M portion of ModR/M byte */  unsigned char sib;        /* SIB byte */  unsigned char scale,      /* scale portion of SIB byte */                index,      /* index portion of SIB byte */                base;       /* base portion of SIB byte */  int bytes;                /* number of bytes in ModR/M, SIB portion of opcode */  int hasEffectiveOperand;  /* does instruction need to compute effective address? */  struct x86ModAddrInfo *modptr;  struct x86ModAddrInfo *sibptr;  bytes = 1;  /*   * Get the ModR/M byte   */  modrm = *data;  /*   * Strip off the MOD, REG, and R/M fields   */  mod = modrm >> 6;  reg = (modrm >> 3) & 0x07;  rm = modrm & 0x07;  if ((opPtr->digit != REGRM) && (opPtr->digit != reg))  {    /*     * Opcodes defined with /digit must have the REG portion     * of their ModR/M byte equal to "digit". This prospective     * match does not so it is a bad match.     */    return (-1);  }  modptr = x86getModAddress(ws, mod, reg, rm);  if (!modptr)    return (-1); /* error */  msinfo->disp = 0;  sib = 0;  scale = 0;  index = 0;  base = 0;  sibptr = 0;  hasEffectiveOperand = x86hasEffectiveOperand(opPtr);  if (hasEffectiveOperand)  {    /*     * Only compute SIB bytes and displacements if this opcode     * has an operand which requires an effective address. Otherwise     * we will end up returning an incorrect byte count. An example     * instruction which has a ModR/M byte but no rm/mem operand is     * psllw.     */    if (modptr->flags & MF_SIB)    {      /*       * The instruction we are disassembling contains a SIB byte       */      sib = *(data + 1);      ++bytes;      scale = sib >> 6;      index = (sib >> 3) & 0x07;      base = sib & 0x07;      sibptr = &x86SibTable[0][index];      if ((base == 5) && (mod == 0))      {        /*         * This is the special case labelled by [*] in         * table 2-3 of IAS. If base is 5 and mod is 0,         * a 32 bit displacement follows the SIB byte.         */        msinfo->disp = x86getModSibDisplacement(data + bytes, 4);        bytes += 4;      }    }    if (modptr->flags & MF_DISP8)    {      msinfo->disp = x86getModSibDisplacement(data + bytes, 1);      bytes += 1;    }    else if (modptr->flags & MF_DISP16)    {      msinfo->disp = x86getModSibDisplacement(data + bytes, 2);      bytes += 2;    }    else if (modptr->flags & MF_DISP32)    {      msinfo->disp = x86getModSibDisplacement(data + bytes, 4);      bytes += 4;    }  } /* if (hasEffectiveOperand) */  msinfo->modptr = modptr;  msinfo->modrm = modrm;  msinfo->mod = mod;  msinfo->reg = reg;  msinfo->rm = rm;  msinfo->sibptr = sibptr;  msinfo->sib = sib;  msinfo->scale = scale;  msinfo->index = index;  msinfo->base = base;  return (bytes);} /* x86processModSib() *//*x86getModAddrStr()  Look up a ModR/M address offset in our string tableInputs: index - index into x86ModAddrOffsets[] (M_xxx)Return: address string corresponding to mptr*/char *x86getModAddrStr(int index){  assert((index >= 0) && (index <= M_NONE));  return (x86ModAddrOffsets[index]);} /* x86getModAddrStr() *//*x86getModRegister()  This routine is called when we are looking for a register specifiedby a ModR/M byte. This can happen two ways:1. We get an r8/r16/r32 operand, in which case the register is specified   by the REG field of the ModR/M byte.2. We get an rm8/rm16/rm32/mm/m64 operand with a MOD field of 3, in which case   the register is specified by the RM field of the ModR/M byte.Inputs: index - either REG (for case 1) or RM (for case 2)        flags - bitmask containing operand size information (BITSXX)Return: pointer to string containing corresponding register*/char *x86getModRegister(unsigned char index, unsigned int flags){  int idx;  assert(index <= 7);  if (flags & BITS8)    idx = x86ModRegisters8[index];  else if (flags & BITS16)    idx = x86ModRegisters16[index];  else if (flags & BITS32)    idx = x86ModRegisters32[index];  else if (flags & BITS64)    idx = M_MM0 + index;  else if (flags & REG_MMX)    idx = M_MM0 + index;  else if (flags & REG_XMM)    idx = M_XMM0 + index;  else  {    fprintf(stderr, "x86getModRegister: warning: defaulting to 16 bits\n");    idx = x86ModRegisters16[index];  }  return (x86ModAddrOffsets[idx]);} /* x86getModRegister() *//*x86getSibBaseRegister()  Lookup a SIB base registerInputs: base - base portion of SIB byteReturn: register string*/char *x86getSibBaseRegister(unsigned char base){  assert(base <= 7);  return (x86SibBaseRegisters[base]);} /* x86getSibBaseRegister() *//********************************************************* *                  INTERNAL ROUTINES                    * *********************************************************//*x86getModAddress()  This routine searches x86ModTableXX[] to find the address offsetfor a given ModR/M byte.Inputs: ws  - disasm workspace        mod - mod portion of ModR/M byte        reg - reg portion of ModR/M byte        rm  - r/m portion of ModR/M byteReturn: pointer to correct entry in x86ModTableXX[] upon success        NULL upon failure*/static struct x86ModAddrInfo *x86getModAddress(struct disasmWorkspace *ws, unsigned char mod,                 unsigned char reg, unsigned char rm){  struct x86ModAddrInfo *mptr;  assert((mod <= 3) && (reg <= 7) && (rm <= 7));  mptr = 0;  if (ws->flags & DA_16BITMODE)  {    if (ws->prefixFlags & PX_ADDROVER)      mptr = &x86ModTable32[mod][rm];    else      mptr = &x86ModTable16[mod][rm];  }  else if (ws->flags & DA_32BITMODE)  {    if (ws->prefixFlags & PX_ADDROVER)      mptr = &x86ModTable16[mod][rm];    else      mptr = &x86ModTable32[mod][rm];  }  else  {    fprintf(stderr,            "x86getModAddress: error: we are neither in 16 nor 32 bit mode\n");    return (0);  }  return (mptr);} /* x86getModAddress() *//*x86getModSibDisplacement()  Called when our ModR/M or SIB byte requires a displacement. Thedisplacement can be 8, 16, or 32 bits. This routine reads offthe displacement and returns it.Inputs: data     - string containing displacement        numBytes - number of bytes in displacementReturn: displacement*/static unsigned intx86getModSibDisplacement(unsigned char *data, int numBytes){  unsigned int disp;  int len;  unsigned long factor;  assert(numBytes <= 4);  disp = 0;  len = 0;  /*   * XXX - this loop is little-endian specific   */  while (numBytes--)  {    /*     * factor = 256^len     */    factor = 1 << (8 * len);    disp += (unsigned char) data[len++] * factor;  }  return (disp);} /* x86getModSibDisplacement() *//*x86hasEffectiveOperand()  Some MMX instructions (psllw) are defined with a /digit butdo not have rm or mem operands and thus do not need to computeeffective addresses. Our routine x86processModSib() determinesany SIB bytes and displacements before operand processing, soif we get a psllw with a ModR/M which specifies a displacement,we don't want x86processModSib() to compute the displacement sinceno operand needs it and thus it is ignored.  This routine determines if any operands of opPtr requirethe calculation of an effective address.Inputs: opPtr - opcode matchReturn: 1 if opPtr has an effective address operand        0 if not*/static intx86hasEffectiveOperand(struct x86OpCode *opPtr){  int ii;  for (ii = 0; ii < opPtr->OperandCount; ++ii)  {    if (opPtr->operands[ii] & (REGMEM | MEMORY))      return (1);  }  return (0);} /* x86hasEffectiveOperand() */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -