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

📄 disasm-x86.c

📁 It s a Linux disassemble, can set break point, disassemble ELF file.
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * libDASM * * Copyright (C) 2000-2003 Patrick Alken * This library comes with absolutely NO WARRANTY * * Should you choose to use and/or modify this source code, please * do so under the terms of the GNU General Public License under which * this library is distributed. * * $Id: disasm-x86.c,v 1.3 2004/09/02 00:11:59 pa33 Exp $ */#include <stdio.h>#include <assert.h>#include <string.h>#include "args-x86.h"#include "common-x86.h"#include "disasm-x86.h"#include "modsib-x86.h"#include "operands-x86.h"#include "optab-x86.h"#include "prefix-x86.h"/* Top-level includes */#include "libDASM.h"static long x86findOpCode(struct disasmWorkspace *ws, unsigned char *data,                          char *outbuf, struct x86matchInfo *bestmatch);/*x86procDisasm()  Disassemble one instructionInputs: ws      - disasm workspace        data    - data to disassemble        outbuf  - buffer to store result        address - address of this opcode in the file or memory;                  when given, relative addresses such as in a                  CALL opcode will be added to this to compute                  an exact target address.Return: number of bytes disassembled, or if an error occurs -1 and        an error message goes in outbuf*/longx86procDisasm(struct disasmWorkspace *ws, unsigned char *data,              char *outbuf, unsigned int address){  unsigned char *origdata;  long bytesMatched;           /* number of bytes matched to opcode */  struct x86matchInfo match;   /* opcode matching data */  int ret;                     /* return result */  origdata = data;  assert(data && outbuf);  memset(&match, '\0', sizeof(struct x86matchInfo));  ws->prefixFlags = 0;  ws->effectiveAddress = 0;  bytesMatched = x86findOpCode(ws, data, outbuf, &match);  if (bytesMatched < 0)  {    /* 'outbuf' will contain the error message */    return (bytesMatched);  }  else if (bytesMatched == 0)  {    /* No match found */    return (0);  }  /*   * We found a good match   */  data += bytesMatched;  ret = x86constructArguments(ws,                              (unsigned char **) &data,                              &match,                              outbuf,                              address);  if (ret)    return (data - origdata);  else    return (-1);} /* x86procDisasm() *//*x86findOpCode()  Attempt to locate best matching opcode for given string inthe x86OpCodes[] array.Inputs: ws         - disasm workspace        data       - actual opcode        outbuf     - string in which to store error messages        bestmatch  - structure in which to store best matching                     opcodeReturn: Number of bytes matched if matching opcode is found        0 if no matching opcode found        -1 if error encounteredSide effects: On a good match, 'bestmatch' is modified to point to              the matching OpCode structure.              On an error, -1 is returned and 'outbuf' is modified              to contain the error message.Developer's Note:  The optab.pl scripts sets up the array x86OpCodes[00..FF] with pointersto different opcode arrays each corresponding to one byte (00..FF). Thisbyte is the first byte of the opcode. These opcode arrays are calledOpCode_XX where XX is the first byte of the opcode. Since severaldifferent instructions could share the same first byte of their opcodes,the OpCode_XX arrays contain pointers to all instructions which haveXX as the first byte of their opcode.  This function looks at data[0] (the first byte of the opcode) andjumps to the array defined by x86OpCodes[data[0]]. This array may containmany pointers to different instructions in the array Instructions[], butwe know they all share the same first byte of their opcodes. We thenproceed along the data[] array and compare those bytes withthe opcodes in the OpCode_XX array given by x86OpCodes[data[0]].*/static longx86findOpCode(struct disasmWorkspace *ws, unsigned char *data,              char *outbuf, struct x86matchInfo *bestmatch){  struct x86OpCode **candidates;         /* opcode candidates */  unsigned char index;                   /* index into x86OpCodes[] */  struct x86OpCode **OpPtr;              /* pointer to an opcode candidate */  struct x86matchInfo matches[MAXBUF];   /* possible opcode matches */  int midx;                              /* index into matches[] */  long bytesMatched;                     /* bytes matched on some opcode */  unsigned char *codeptr;                /* pointer to opcode string */  int regcode;                           /* register for +rb/+rw/+rd opcodes */  int fpucode;                           /* register for +i opcodes */  struct x86ModSibInfo msinfo;           /* ModR/M and SIB information */  int exactMatch;                        /* set to 1 if we find exact match */  unsigned char prefBytes;               /* number of bytes in prefix */  int pret;                              /* return value from x86testPrefix() */  int ii;                                /* looping */  int foundBestMatch;                    /* did we find the best match? */  int betterMatch;                       /* do we have a better match? */  assert(ws && data && outbuf && bestmatch);  midx = 0;  prefBytes = x86processPrefix(ws, data);  data += prefBytes;  index = (unsigned char) *data;  /*   * We cannot immediately assign candidates to x86OpCodes[*data]   * since the first byte of the opcode may have been modified   * by adding an integer between 0-7 to indicate a register code   * (+rb/+rw/+rd/+i in the IAS manual).   *   * If this was the case, x86OpCodes[*data] will be NULL (unless   * intel has instructions which share the first opcode byte   * but one of them added a register code to their real first   * byte - I haven't found any of these).   */  while (!*x86OpCodes[index])  {    /*     * Keep decrementing index until we find the real first     * byte of the opcode - do this no more than 7 times.     */    --index;    if (((unsigned char) *data - index) > 7)    {      /*       * This should never happen - unless there exists       * a string of 7+ consecutive numbers which aren't used       * as the first byte of any opcode.       */      sprintf(outbuf,              "x86findOpCode: indices of x86OpCodes[] ranging from %d to %d are \               all NULL (looking for register code)",              index,              (unsigned char) *data);      return (-1);    }  } /* while (!*x86OpCodes[index]) */  /*   * Now our instruction candidates are the array x86OpCodes[index]   */  candidates = x86OpCodes[index];  for (OpPtr = candidates; *OpPtr; ++OpPtr)  {    exactMatch = 0;    regcode = (-1);    fpucode = (-1);    memset(&msinfo, '\0', sizeof(struct x86ModSibInfo));    /*     * (*OpPtr)->mcode is the opcode string for the current     * instruction we are checking     */    codeptr = (unsigned char *) (*OpPtr)->mcode;    if (*(codeptr + 1) == '\0')    {      /*       * We are dealing with a one byte opcode: this case       * warrants special attention. If the instruction is       * defined with +rb/+rw/+rd/+i we need to determine       * if something between 0-7 was added to the first       * byte.       */      if ((*OpPtr)->digit == REGCODE)        /* +rb/+rw/+rd */        regcode = (unsigned char) *data - index;      else if ((*OpPtr)->digit == FPUCODE)   /* +i */        fpucode = (unsigned char) *data - index;      else if (index != (unsigned char) *data)      {        /*         * If index and *data do not match, it means our above loop         * decremented index since OpCodes[*data] was empty. This         * implies that the instruction we are disassembling is         * defined with +rb/+rw/+rd/+i, but the current prospective         * instruction is not defined this way, so it is a bad match.         */        continue;      }    }    /*     * We have matched the first byte of 'data' to an opcode so     * set bytesMatched to 1     */    bytesMatched = 1;    /*     * If there are more bytes to the opcode, we must check them     * against 'data'.     */    while (*++codeptr)    {      if (*codeptr == *(data + bytesMatched))      {        /*         * We just matched another byte of the opcode         */        ++bytesMatched;        /*         * Check if this is the last opcode byte. If so, check         * if this opcode has a +rb/+rw/+rd/+i flag. These flags         * indicate that a value between 0-7 is added to the         * last byte of the opcode. Since this is the last byte,         * the value 0 must have been added.         */        if (*(codeptr + 1) == '\0')        {          if ((*OpPtr)->digit == REGCODE)            regcode = 0;          else if ((*OpPtr)->digit == FPUCODE)            fpucode = 0;          exactMatch = 1;        }      } /* if (*codeptr == *(data + bytesMatched)) */

⌨️ 快捷键说明

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