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

📄 disasm-x86.c

📁 It s a Linux disassemble, can set break point, disassemble ELF file.
💻 C
📖 第 1 页 / 共 2 页
字号:
      else if (*(codeptr + 1) == '\0')      {        /*         * We failed to match a byte against 'data' however this         * is the very last byte of the opcode, so it may have         * been modified by adding an integer between 0-7 in the         * case of +rb/+rw/+rd/+i opcodes - check if this is the         * case.         */        if ((*OpPtr)->digit == REGCODE)        {          /*           * If the 'digit' field of OpPtr is REGCODE *and* this           * is the last byte of the opcode, it is possible that           * the byte stored in 'data' is up to 7 numbers larger           * than the opcode stored in OpPtr. This means that           * the difference between the 'data' byte and the 'OpPtr'           * byte is a special value corresponding to a specific           * register. These registers are listed in Table 3.1 of           * the Intel Instruction Set Reference. If we indeed find           * the difference to be a number between 0 and 7, store           * it into 'tmpreg' for future reference.           */          regcode = (unsigned char) *(data + bytesMatched) -                    (unsigned char) *codeptr;          if ((regcode >= 0) && (regcode <= 7))          {            /*             * We have just found a good match on the last byte             * of the opcode - therefore the data string matches             * the stored opcode byte for byte - it is an exact             * match             */            ++bytesMatched;            exactMatch = 1;          }          else          {            /*             * regcode is larger than 8, so this opcode does not             * satisfy the +rb/+rw/+rd nomenclature - reset             * regcode and BytesMatched.             */            regcode = (-1);            bytesMatched = 0;            break;          }        } /* if ((*OpPtr)->digit == REGCODE) */        else if ((*OpPtr)->digit == FPUCODE)        {          /*           * Since this is the last byte of the opcode, and since           * 'digit' is FPUCODE, this last byte of the opcode may           * have been altered by adding a number from 0-7, in           * order to reflect an fpu stack register. Figure out           * what the difference is, and assign it to tmpfpu for           * later use.           */          fpucode = (unsigned char) *(data + bytesMatched) -                    (unsigned char) *codeptr;          if ((fpucode >= 0) && (fpucode <= 7))          {            ++bytesMatched;            exactMatch = 1;          }          else          {            /*             * fpucode is larger than 8, and so it cannot represent             * a fpu stack register - reset fpucode and bytesMatched.             */            fpucode = (-1);            bytesMatched = 0;            break;          }        } /* if ((*OpPtr)->digit == FPUCODE) */      } /* if (*(codeptr + 1) == '\0') */      else      {        /*         * We failed to match an opcode byte against 'data' and it         * is not the last byte of the opcode, so this is not a         * good match         */        bytesMatched = 0;        break;      }    } /* while (*++codeptr) */    if (bytesMatched < (*OpPtr)->oplen)    {      /*       * We did not match all of the necessary bytes - bad match       */      continue;    }    /*     * If the opcode is expecting a register code     * and we do not have one, it is a bad match. The only     * case I can think of in which this will happen is with     * NOP and XCHG and we get a "66 90" to indicate     * a 32 bit version of NOP. Since there is technically no     * 32 bit version of NOP, we would normally move onto     * XCHG (where there is a 32 bit version) and use it, but     * we do not want to do that since 0x90 is specifically     * NOP.     */    if ((regcode == (-1)) && ((*OpPtr)->digit == REGCODE))      continue;    if ((fpucode == (-1)) && ((*OpPtr)->digit == FPUCODE))      continue;    /*     * If the current prospective match expects a ModR/M (and SIB)     * byte, make sure that the corresponding byte(s) in our actual     * data string matches up with the correct columns in     * the ModR/M (and SIB) tables given in tables 2-1, 2-2, and 2-3     * of the Intel Architecture Software Developers Manual, Vol 2.     */    if ((((*OpPtr)->digit >= 0) && ((*OpPtr)->digit <= 7)) ||        ((*OpPtr)->digit == REGRM))    {      int ret;      ret = x86processModSib(ws,                             data + bytesMatched,                             *OpPtr,                             &msinfo);      if (ret < 0)        continue;  /* bad match */      assert(msinfo.modptr != 0);      bytesMatched += ret;    }    /*     * Our opcode passed all of the tests, add it to our array     * of possible matches - there may be more than one instruction     * which matches the opcode, so we will store all matches and     * sort it out later. One example is NOP and XCHG ax,ax both     * of which have an opcode of 0x90. They both do the same thing,     * but from our viewpoint, we would rather pick NOP as the final     * instruction instead of XCHG ax,ax.     */    matches[midx].bytesMatched = bytesMatched;    matches[midx].opPtr = *OpPtr;    matches[midx].regcode = regcode;    matches[midx].fpucode = fpucode;    matches[midx].prefixPriority = 0;    matches[midx].msinfo = msinfo;    ++midx;    if (midx >= MAXBUF)    {      sprintf(outbuf,              "x86findOpCode: error: too many matches (>= %d)",              MAXBUF);      return (0);    }  } /* for (OpPtr = candidates; *OpPtr; ++OpPtr) */#if 0  printf("x86findOpCode: number of matches: %d\n", midx);#endif  /*   * We now have a prospective list of matches, contained in the   * array 'matches'. Each of these matches shares their opcode   * with the opcode we are trying to disassemble, and also passed   * a few sanity tests. There are two tests left to perform:   *   * 1. Prefix overrides: if there is an operand override then we   *    may have stored both the 16 and 32 bit versions of the   *    same instruction in our array 'matches'. In this case   *    we need to pick out the right one depending upon what   *    mode we are in (16 or 32 bit mode). This test could be   *    done in the main loop above, but it would be extremely   *    messy since we may hit the 16 bit version before the 32   *    bit version and there would be some ugliness to figure out   *    to throw one of them away. In the interests of elegance,   *    I put this test after the main loop.   * 2. If we are in 16 bit mode, and our potential match is marked   *    as expecting 32 bits with no operands (example: INSD, IRETD).   *    In this case, reject the potential match.   */  foundBestMatch = 0;  for (ii = 0; ii < midx; ++ii)  {    pret = x86testPrefix(ws, matches[ii].opPtr);    if (pret == 0)      continue;    if (foundBestMatch)    {      /*       * If we have already found a match, we need       * to check if this match is better than       * the previous match.       */      betterMatch = 0;      /*       * Check if the prefix is a better match for this       * instruction       */      if (pret > bestmatch->prefixPriority)        betterMatch = 1;      /*       * This test is for the case of FADD. If we have two       * matches, where one uses a ModR/M byte and the other       * is defined with +rb/+rw/+rd/+i, then the latter is       * chosen over the former. With FADD, there are two       * separate opcodes (D8 /0 and D8 C0 +i). C0 is in column       * 0, so it is possible to match D8 C0 against the wrong       * opcode with the ModR/M.       */      if (x86UsesRegFPU(matches[ii].opPtr) &&          x86UsesModRM(bestmatch->opPtr))      {        betterMatch = 1;      }      else if (x86UsesRegFPU(bestmatch->opPtr) &&               x86UsesModRM(matches[ii].opPtr))      {        betterMatch = 0;        continue;      }      else if (!x86UsesModRM(matches[ii].opPtr) &&               x86UsesModRM(bestmatch->opPtr))      {        /*         * If the previous match uses a ModR/M byte and the         * current match does not, then the current match is         * a better match. An example of this is FTST and         * FLDENV. FTST is D9 E4, and FLDENV is D9 /4. E4 is         * in column 4, so we must make sure we choose FTST         * over FLDENV.         */        betterMatch = 1;      }      if (betterMatch)      {        matches[ii].prefixPriority = pret;        *bestmatch = matches[ii];      }    } /* if (foundBestMatch) */    else    {      /*       * We have not yet found a match, and this one passed       * the prefix requirements so record it.       */      matches[ii].prefixPriority = pret;      *bestmatch = matches[ii];      foundBestMatch = 1;    }  }  if (foundBestMatch)    return (bestmatch->bytesMatched + (long) prefBytes);  else    return (0);} /* x86findOpCode() */

⌨️ 快捷键说明

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