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

📄 args-x86.c

📁 It s a Linux disassemble, can set break point, disassemble ELF file.
💻 C
📖 第 1 页 / 共 2 页
字号:
  return (1);} /* x86constructArguments() *//*x86operandRegister()  Handle a register operand (r8/r16/r32/mm/xmm)Inputs: ptr     - opcode pointer        opnum   - number of current operand (first, second, etc)        errstr  - where to store errorsReturn: pointer to string containing matching register upon success        NULL upon errorSide effects: Upon failure, an error message goes in errstr*/static char *x86operandRegister(struct x86matchInfo *ptr, int opnum, char *errstr){  struct x86OpCode *opPtr;  unsigned int operand;  int regindex;  opPtr = ptr->opPtr;  operand = opPtr->operands[opnum];  /*   * First check if it is a specific register (R_AL etc). This   * occurs in instructions like ADC where a specific register   * is encoded into the instruction.   */  if ((operand & REGISTER) && (opPtr->opinfo[opnum] != NOOPARG))  {    if (opPtr->opinfo[opnum] < 0)    {      sprintf(errstr,              "x86operandRegister: bad operand info\n");      return (0);    }    if (opPtr->opinfo[opnum] == MODFIELD_RM)      return (x86getModRegister(ptr->msinfo.rm, operand));    else      return (x86RegistersDASM[opPtr->opinfo[opnum]].name);  }  if (opPtr->digit == REGRM)  {    /*     * This instruction is defined with a /r as well as a     * register operand. The register for this operand     * is determined by the REG field of the ModR/M byte.     */    assert(ptr->msinfo.modptr != 0);    return (x86getModRegister(ptr->msinfo.reg, operand));  } /* if (opPtr->digit == REGRM) */  else if ((opPtr->digit >= 0) && (opPtr->digit <= 7))  {    if ((operand & REG_MMX) || (operand & REG_XMM))    {      /*       * We got a mm or xmm operand       */      return (x86getModRegister(ptr->msinfo.rm, operand));    }    else    {      /*       * We got an r8/r16/r32 operand. We should never get here: /digit       * opcodes always have rm8/rm16/rm32/mm/xmm operands, never r8/r16/r32       * operands.       */      sprintf(errstr,              "x86operandRegister: error: we got a /digit with a register operand");      return (0);    }  }  else if (opPtr->digit == REGCODE)  {    /*     * This instruction is defined with a +rb/+rw/+rd code     * indicating something was added to the last byte of     * the opcode which specifies a register. This added     * value is stored in ptr->regcode (from x86findOpCode)     */    assert(ptr->regcode >= 0);    assert(ptr->regcode <= 7);    regindex = (-1);    if (operand & BITS8)      regindex = x86RegisterCodes8[ptr->regcode];    else if (operand & BITS16)      regindex = x86RegisterCodes16[ptr->regcode];    else if (operand & BITS32)      regindex = x86RegisterCodes32[ptr->regcode];    if (regindex < 0)    {      sprintf(errstr,              "x86operandRegister: invalid register operand for instruction %s (%ld)",              x86InstructionNames[opPtr->name],              opPtr->operands[opnum]);      return (0);    }    return (x86RegistersDASM[regindex].name);  } /* if (opPtr->digit == REGCODE) */  return (0);} /* x86operandRegister() *//*x86operandEffectiveAddress()  This routine handles the following operands (which all requireeffective address computations from ModR/M bytes):rm8rm16rm32m8m16m32m64m128xmm?/m*Inputs: ws      - disasm workspace        ptr     - opcode pointer        operand - operand flags        str     - where to store register or addressReturn: -1 upon failure: error message goes in 'str'        1 upon success*/static intx86operandEffectiveAddress(struct disasmWorkspace *ws,                           struct x86matchInfo *ptr,                           unsigned int operand,                           char *str){  char *origstr;  char *tmpstr;  assert(ptr->msinfo.modptr);  origstr = str;  if (ptr->msinfo.mod == 3)  {    /*     * Special case: ModR/M bytes C0 -> FF are ambiguous. That is,     * their effective addresses can be one of five registers -     * we can determine the correct register by looking at the     * operand's size attribute. Also, we don't have to worry about     * SIB bytes since any ModR/M bytes with a "mod" of 3 have     * no SIBs.     */    tmpstr = x86getModRegister(ptr->msinfo.rm, operand);    if (!tmpstr)    {      sprintf(origstr,              "x86operandEffectiveAddress: x86getModRegister failed");      return (-1);    }    str += sprintf(str, "%s", tmpstr);    return (1);  }  /*   * The r/m operand specifies a memory location, not a register:   * we need to calculate the effective address.   */  if (operand & BITS8)    str += sprintf(str, "byte ");  else if (operand & BITS16)    str += sprintf(str, "word ");  else if (operand & BITS32)    str += sprintf(str, "dword ");  else if (operand & BITS64)    str += sprintf(str, "qword ");  else if (operand & BITS80)    str += sprintf(str, "tword "); /* FPU */  /*   * It is a memory location: use []'s :)   */  *str++ = '[';  if (ws->prefixFlags & PX_SEGOVER)  {    assert(ws->segmentOverride != (-1));    str += sprintf(str, "%s:", x86RegistersDASM[ws->segmentOverride].name);  }  if (ptr->msinfo.modptr->flags & MF_SIB)  {    /*     * Write the base register to str: there is one case     * where there is no base register (base = 5, mod = 0) -     * see table 2-3 of IAS.     */    if (!((ptr->msinfo.base == 5) && (ptr->msinfo.mod == 0)))    {      tmpstr = x86getSibBaseRegister(ptr->msinfo.base);      str += sprintf(str, "%s", tmpstr);      if (ptr->msinfo.sibptr->index != M_NONE)        *str++ = '+';    }    /*     * Get the index address     */    if (ptr->msinfo.sibptr->index != M_NONE)    {      tmpstr = x86getModAddrStr(ptr->msinfo.sibptr->index);      if (!tmpstr)      {        sprintf(origstr,                "x86operandEffectiveAddress: x86getModAddrStr failed");        return (-1);      }      str += sprintf(str, "%s", tmpstr);      if (ptr->msinfo.scale > 0)        str += sprintf(str, "*%d", 1 << ptr->msinfo.scale);    }  } /* if (ptr->msinfo.modptr->flags & MF_SIB) */  else  {    tmpstr = x86getModAddrStr(ptr->msinfo.modptr->index);    if (!tmpstr)    {      sprintf(origstr,              "x86operandEffectiveAddress: x86getModAddrStr failed");      return (-1);    }    str += sprintf(str, "%s", tmpstr);  }  /*   * Add any displacements   */  if (ptr->msinfo.disp)    str += sprintf(str, "+0x%x", ptr->msinfo.disp);  *str++ = ']';  *str = '\0';  return (1);} /* x86operandEffectiveAddress() *//*x86operandSegOff()  This routine handles the operands ptr16:16 or ptr16:32,which are of the form segment:offset, where segment is the number of bitson the left of the colon, and offset is the number of bits on the right.Inputs: data    - opcode data stream        operand - flags for this operand        str     - argument string (or error string)Return: 1 upon success (argument goes in str)        0 upon failure (error goes in str)*/static intx86operandSegOff(unsigned char **data, unsigned int operand, char *str){  int err;  unsigned long segment,                offset;  err = 0;  if (operand & OFF16)    offset = x86getImmediate(data, BITS16, &err);  else if (operand & OFF32)    offset = x86getImmediate(data, BITS32, &err);  else  {    sprintf(str,            "x86operandSegOff: offset operand is neither 16 nor 32 bits");    return (0);  }  if (err)  {    sprintf(str,            "x86operandSegOff: x86getImmediate failed");    return (0);  }  segment = x86getImmediate(data, BITS16, &err);  if (err)  {    sprintf(str,            "x86operandSegOff: x86getImmediate failed");    return (0);  }  sprintf(str, "0x%lx:0x%lx", segment, offset);  return (1);} /* x86operandSegOff() *//*x86operandMemoryOffset()  This routine is called when we have a moffs8/16/32 operand.The 8/16/32 refer to the size of the data at the offset. The offsetis a 16 or 32 bit value (depending on the size attributes of theinstruction) which follows the opcode.Inputs: ws     - disasm workspace        data   - opcode data stream        str    - where to store resultReturn: 1 upon success        0 upon failure*/static intx86operandMemoryOffset(struct disasmWorkspace *ws, unsigned char **data,                       char *str){  unsigned long value;  int err;  unsigned int sizeattr;  err = 0;  sizeattr = x86addrSizeAttribute(ws);  if (sizeattr & DA_16BITMODE)    value = x86getImmediate(data, BITS16, &err);  else    value = x86getImmediate(data, BITS32, &err);  if (err)  {    sprintf(str,            "x86operandMemoryOffset: x86getImmediate failed");    return (0);  }  if (ws->prefixFlags & PX_SEGOVER)  {    assert(ws->segmentOverride != (-1));    str += sprintf(str, "%s:", x86RegistersDASM[ws->segmentOverride].name);  }  sprintf(str, "[+0x%lx]", value);  return (1);} /* x86operandMemoryOffset() *//*x86getImmediate()  Called when an operand has the IMMEDIATE bit set - obtain theimmediate byte value from 'data'Inputs: data  - actual opcode data stream where immediate byte(s) are stored        flags - bitmask variable containing size of immediate                value        err   - set to 1 if error occursReturn: value of the immediate byte(s)*/static unsigned longx86getImmediate(unsigned char **data, unsigned int flags, int *err){  unsigned long ret;  int length;  ret = 0;  length = 0;  /*   * Thank god for little endian :-)   */  if (flags & BITS8)  {    ret = (unsigned char) (*data)[length++];    ++(*data);  }  else if (flags & BITS16)  {    ret = (unsigned char) (*data)[length++];    ret += (unsigned char) (*data)[length++] * 256;    (*data) += 2;  }  else if (flags & BITS32)  {    ret = (unsigned char) (*data)[length++];    ret += (unsigned char) (*data)[length++] * 256;    ret += (unsigned char) (*data)[length++] * 65536;    ret += (unsigned char) (*data)[length++] * 16777216;    (*data) += 4;  }  else    *err = 1;  return (ret);} /* x86getImmediate() */

⌨️ 快捷键说明

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