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

📄 prefix-x86.c

📁 It s a Linux disassemble, can set break point, disassemble ELF file.
💻 C
字号:
/* * 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: prefix-x86.c,v 1.1.1.1 2004/04/26 00:40:09 pa33 Exp $ */#include <stdio.h>#include <assert.h>#include "regs-x86.h"#include "prefix-x86.h"#include "operands-x86.h"/* * Top-level includes */#include "libDASM.h"/* * If any of these bytes follow a REP (0xF3) prefix, use * REPE instead of REP */int prefixREPE[] = {  0xA6,  0xA7,  0xAE,  0xAF,  (-1)};/*x86processPrefix()  Called from x86findOpCode() to determine if there is a prefixin front of the opcode being disassembled. If so, toggle thecorrect flags in ws->prefixFlags.Inputs: ws   - disasm workspace        data - buffer containing opcodeReturn: number of bytes in prefix*/unsigned charx86processPrefix(struct disasmWorkspace *ws, unsigned char *data){  unsigned char numBytes;  int done;  unsigned char byte;  assert(ws && data);  numBytes = 0;  done = 0;  while (!done)  {    byte = *data++;    switch (byte)    {      /*       * Indicates operand size override. If in 16 bit mode,       * instructions with 32 bit operands will be chosen over       * those with 16 bit operands. If in 32 bit mode, instructions       * with 16 bit operands will be chosen over those with 32       * bit operands.       */      case 0x66:      {        ws->prefixFlags |= PX_OPOVER;        ++numBytes;        break;      } /* case 0x66 */      /*       * Addressing size override. If in 16 bit mode, 32 bit addressing       * will be used and vice versa.       */      case 0x67:      {        ws->prefixFlags |= PX_ADDROVER;        ++numBytes;        break;      } /* case 0x67 */      /*       * lock prefix       */      case 0xF0:      {        ws->prefixFlags |= PX_LOCK;        ++numBytes;        break;      } /* case 0xF0 */      /*       * Indicates a REPNE (repeat while not equal) prefix       */      case 0xF2:      {        /*         * If we have an "F2 0F ..." situation, the F2 is         * not a prefix but part of the opcode of an SSE         * instruction.         */        if (*data == 0x0F)        {          done = 1;          break;        }        ws->prefixFlags |= PX_REPNE;        ++numBytes;        break;      } /* case 0xF2 */      /*       * Indicates a REP or REPE prefix       */      case 0xF3:      {        int *tmp;        unsigned int flag;        /*         * If we have an "F3 0F ..." situation, the F3 is         * not a prefix but part of the opcode of an SSE         * instruction.         */        if (*data == 0x0F)        {          done = 1;          break;        }        flag = PX_REP;        for (tmp = prefixREPE; *tmp != (-1); ++tmp)        {          if ((unsigned int) *data == (unsigned int) *tmp)            flag = PX_REPE;        }        ws->prefixFlags |= flag;        ++numBytes;        break;      } /* case 0xF3 */      /*       * Segment overrides       */      case 0x2E:        /* cs */      {        ws->prefixFlags |= PX_SEGOVER;        ws->segmentOverride = R_CS;        ++numBytes;        break;      } /* case 0x2E */      case 0x36:        /* ss */      {        ws->prefixFlags |= PX_SEGOVER;        ws->segmentOverride = R_SS;        ++numBytes;        break;      } /* case 0x36 */      case 0x3E:        /* ds */      {        ws->prefixFlags |= PX_SEGOVER;        ws->segmentOverride = R_DS;        ++numBytes;        break;      } /* case 0x3E */      case 0x26:        /* es */      {        ws->prefixFlags |= PX_SEGOVER;        ws->segmentOverride = R_ES;        ++numBytes;        break;      } /* case 0x26 */      case 0x64:        /* fs */      {        ws->prefixFlags |= PX_SEGOVER;        ws->segmentOverride = R_FS;        ++numBytes;        break;      } /* case 0x64 */      case 0x65:        /* gs */      {        ws->prefixFlags |= PX_SEGOVER;        ws->segmentOverride = R_GS;        ++numBytes;        break;      } /* case 0x65 */      default:      {        done = 1;        break;      }    } /* switch (byte) */  } /* while (!done) */  return (numBytes);} /* x86processPrefix() *//*x86testPrefix()  Called from x86findOpCode() to determine if a potential match passesprefix requirements, such as operand override.Inputs: ws  - disasm workspace        ptr - potential opcode matchReturn: 0 if ptr does not pass prefix test        1 if ptr passes prefix test but there is a possibility of          a better match        2 if ptr passes all prefix tests with no possibility of a          better match*/intx86testPrefix(struct disasmWorkspace *ws, struct x86OpCode *ptr){  unsigned int flags;  assert(ptr != 0);  /*   * Our goal here is to determine what bit mode this   * instruction wants to be in. For example, we may   * be disassembling the file in 16 bit mode, but if   * this instruction has an operand override prefix,   * we need to disassemble it in 32 bit mode. The   * operand override prefix is a toggle between 16   * and 32 bit mode. The requirements here are as   * follows:   *   * 1. If we are in 16 bit mode, an operand override prioritizes   *    the 32 bit version of the same instruction, if there is one.   *    If there is not, the 16 bit version is still acceptable. An   *    example of this is the NOP instruction. There is only one   *    NOP (0x90) so an opcode of the form (0x66 0x90) should also   *    be a NOP since there is no "32 bit" version of NOP.   * 2. If we are in 32 bit mode, an operand override tells us to   *    use the 16 bit version of the instruction.   */  flags = 0;  if (ws->flags & DA_16BITMODE)  {    if (ws->prefixFlags & PX_OPOVER)      flags = DA_32BITMODE;    else      flags = DA_16BITMODE;  }  else if (ws->flags & DA_32BITMODE)  {    if (ws->prefixFlags & PX_OPOVER)      flags = DA_16BITMODE;    else      flags = DA_32BITMODE;  }  else  {    fprintf(stderr,            "x86testPrefix: error: we are neither in 16 nor 32 bit mode\n");    return (0);  }  if (flags & DA_16BITMODE)  {    /*     * The instruction wants to be disassembled in 16     * bit mode: if any of the prospective match's operands     * is 32 bits, declare it to be a weak match.     */    if ((ptr->operands[0] & BITS32) ||        (ptr->operands[1] & BITS32) ||        (ptr->operands[2] & BITS32))      return (1);  }  else if (flags & DA_32BITMODE)  {    /*     * The instruction wants to be disassembled in 32     * bit mode. If this prospective match has no 32     * bit operands, declare it to be a weak match:     * there may be another prospective down the line     * with a 32 bit operand, but if there is not, this     * prospective could still be used.     */    if (!(ptr->operands[0] & BITS32) &&        !(ptr->operands[1] & BITS32) &&        !(ptr->operands[2] & BITS32))      return (1);  }  else  {    fprintf(stderr,            "x86testPrefix: error: flags variable is empty\n");    return (0);  }  return (2);} /* x86testPrefix() *//*x86addrSizeAttribute()  Determine the address size attribute of the currentinstruction we are disassembling.Inputs: ws - disasm workspaceReturn: DA_16BITMODE or DA_32BITMODE depending on the size attributes        of the instruction*/unsigned intx86addrSizeAttribute(struct disasmWorkspace *ws){  if (ws->flags & DA_16BITMODE)  {    if (ws->prefixFlags & PX_ADDROVER)      return (DA_32BITMODE);    else      return (DA_16BITMODE);  }  else if (ws->flags & DA_32BITMODE)  {    if (ws->prefixFlags & PX_ADDROVER)      return (DA_16BITMODE);    else      return (DA_32BITMODE);  }  /*   * We should never get here: default to 32 bit mode   */  fprintf(stderr,          "x86addrSizeAttribute: error: we are neither in 16 nor 32 bit mode\n");  return (DA_32BITMODE);} /* x86addrSizeAttribute() */

⌨️ 快捷键说明

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