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

📄 args-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: args-x86.c,v 1.3 2004/09/02 00:11:59 pa33 Exp $ * * This module is used by the disassembler to construct the argument * string for a particular opcode. */#include <stdio.h>#include <string.h>#include <assert.h>#include "args-x86.h"#include "common-x86.h"#include "inames-x86.h"#include "operands-x86.h"#include "prefix-x86.h"#include "regs-x86.h"/* * Top-level includes */#include "libDASM.h"static char *x86operandRegister(struct x86matchInfo *ptr, int opnum,                                char *errstr);static int x86operandEffectiveAddress(struct disasmWorkspace *ws,                                      struct x86matchInfo *ptr,                                      unsigned int operand, char *str);static int x86operandSegOff(unsigned char **data, unsigned int operand,                            char *str);static int x86operandMemoryOffset(struct disasmWorkspace *ws,                                  unsigned char **data,                                  char *str);static unsigned long x86getImmediate(unsigned char **data,                                     unsigned int flags, int *err);/* * The following x86RegisterCodesXX[] tables correspond to table 3.1 * in the Intel Architecture Software Developer's Manual, Vol 2. They * are used to determine the register specified by a +rb/+rw/+rd * code added to the last byte of an opcode. The value added * to the last opcode byte is between 0 and 7, and indexes these * tables to get the correct register. *//* +rb - 8 bit register operand */static int x86RegisterCodes8[] = {  R_AL,  R_CL,  R_DL,  R_BL,  R_AH,  R_CH,  R_DH,  R_BH};/* +rw - 16 bit register operand */static int x86RegisterCodes16[] = {  R_AX,  R_CX,  R_DX,  R_BX,  R_SP,  R_BP,  R_SI,  R_DI};/* +rd - 32 bit register operand */static int x86RegisterCodes32[] = {  R_EAX,  R_ECX,  R_EDX,  R_EBX,  R_ESP,  R_EBP,  R_ESI,  R_EDI};static char *x86SegmentRegisters[] = {  "es",  "cs",  "ss",  "ds",  "fs",  "gs",  "?s",  "?s"};/*x86constructArguments()  Construct the correct arguments for the instruction 'ptr'.Inputs: ws      - disasm workspace        data    - data buffer containing instruction we are                  disassembling        ptr     - instruction matching 'data'        outbuf  - where to store arguments        address - address of this instruction in the file or memory                  we are currently disassembling; when given,                  relative addresses (such as in a CALL or JMP)                  will be added to this address to calculate                  an exact target address.Return: 1 upon success        0 upon failure (error message goes in outbuf)Side effects: On success, outbuf will contain instruction name and arguments              On failure, outbuf will contain error message              'data' variable may be advanced due to reading of immediate bytes,              modrm bytes, etc*/intx86constructArguments(struct disasmWorkspace *ws, unsigned char **data,                      struct x86matchInfo *ptr, char *outbuf,                      unsigned int address){  int ii;                   /* looping */  struct x86OpCode *opPtr;  /* opcode pointer */  char tmpbuf[MAXLINE];     /* temporary buffer */  char *origout;            /* original outbuf */  long bias;                /* eip relative address bias */  assert(data && *data && ptr && outbuf);  /*   * bias is initialized to the 2's compliment of the instruction's   * actual address in the buffer.  We do this to compute the   * size of the instruction by adding the new value of *data.   * The resulting equation is this:   *   * bias = NEW_data_addr - OLD_data_addr   *   * which is precisely what we want.   *   * Note the [-1] subscript of the character array reference is   * to compensate for the fact that the instruction's opcode has   * already been "fetched" by the disassembly engine.   *   * --2004aug30 saf2   *   * The purpose of this is for relative operands which are   * defined relative to the instruction after the current   * instruction. In order to compute an exact address, we   * need to know the size of the current opcode. This bias   * variable is set to that size in the section below on   * relative operands.   *   * -- Patrick Alken   */  bias = -((unsigned long)(&((*data)[-1])));  opPtr = ptr->opPtr;  origout = outbuf;  if (ws->prefixFlags & PX_LOCK)    outbuf += sprintf(outbuf, "%s", "lock ");  else if (ws->prefixFlags & PX_REP)    outbuf += sprintf(outbuf, "%s", "rep ");  else if (ws->prefixFlags & PX_REPE)    outbuf += sprintf(outbuf, "%s", "repe ");  else if (ws->prefixFlags & PX_REPNE)    outbuf += sprintf(outbuf, "%s", "repne ");  /*   * Write instruction name to outbuf   */  outbuf += sprintf(outbuf, "%s", x86InstructionNames[opPtr->name]);  /*   * Loop through operands and add them to outbuf   */  for (ii = 0; ii < opPtr->OperandCount; ++ii)  {    if (ii == 0)      *outbuf++ = ' ';    else    {      *outbuf++ = ',';      *outbuf++ = ' ';    }    if (opPtr->operands[ii] & NEAR)      outbuf += sprintf(outbuf, "near ");    else if (opPtr->operands[ii] & FAR)      outbuf += sprintf(outbuf, "far ");    else if (opPtr->operands[ii] & SHORT)      outbuf += sprintf(outbuf, "short ");    if (opPtr->operands[ii] & (REGISTER | REG_MMX | REG_XMM))    {      char *regstr;      /*       * We have a register operand - determine which register       * and print it to outbuf       */      regstr = x86operandRegister(ptr,                                  ii,                                  tmpbuf);      if (regstr)        outbuf += sprintf(outbuf, "%s", regstr);      else      {        strcpy(origout, tmpbuf);        return (0); /* error */      }    } /* if (opPtr->operands[ii] & (REGISTER | REG_MMX | REG_XMM)) */    else if (opPtr->operands[ii] & IMMEDIATE)    {      unsigned long value;      int err;      err = 0;      value = x86getImmediate(data,                              opPtr->operands[ii],                              &err);      if (err)      {        sprintf(origout,                "x86constructArguments: x86getImmediate failed for instruction: %s",                x86InstructionNames[opPtr->name]);        return (0);      }      outbuf += sprintf(outbuf, "0x%lx", value);    } /* if (opPtr->operands[ii] & IMMEDIATE) */    else if (opPtr->operands[ii] & (REGMEM | MEMORY))    {      int ret;      /*       * We have an rm8/rm16/rm32 operand       */      ret = x86operandEffectiveAddress(ws,                                       ptr,                                       opPtr->operands[ii],                                       tmpbuf);      if (ret >= 0)        outbuf += sprintf(outbuf, "%s", tmpbuf);      else      {        strcpy(origout, tmpbuf);        return (0); /* error */      }    } /* if (opPtr->operands[ii] & (REGMEM | MEMORY)) */    else if (opPtr->operands[ii] & RELATIVE)    {      unsigned long value;      int err;      /*       * Relative operands (rel8/16/32) are bytes following       * the opcode specifying a relative address       */      err = 0;      value = x86getImmediate(data,                              opPtr->operands[ii],                              &err);      if (err)      {        sprintf(origout,                "x86constructArguments: x86getImmediate failed for instruction: %s",                x86InstructionNames[opPtr->name]);        return (0);      }      /*       * Note: this code was contributed by Samuel Falvo II       * <kc5tja =at= arrl net>       */      bias += (unsigned long) (*data);      if ((unsigned char) *(opPtr->mcode) == 0x0F)      {        /* two-byte branch */        bias++;      }      outbuf += sprintf(outbuf, "+0x%lx", value);      /*       * Store the exact target address in ws->effectiveAddress       * so that the calling program can use it to look up       * symbols/functions corresponding to this relative       * address.       */      ws->effectiveAddress = address + value + bias;    } /* if (opPtr->operands[ii] & RELATIVE) */    else if (opPtr->operands[ii] & SEG16)    {      int ret;      /*       * This operand is ptr16:16 or ptr16:32.       * This means we need an expression of the form       * segment:offset, where segment is the number of bits on       * the left of the colon, and offset is the number of bits       * on the right.       */      ret = x86operandSegOff(data, opPtr->operands[ii], tmpbuf);      if (ret >= 0)        outbuf += sprintf(outbuf, "%s", tmpbuf);      else      {        strcpy(origout, tmpbuf);        return (0); /* error */      }    } /* if (opPtr->operands[ii] & SEG16) */    else if (opPtr->operands[ii] & REG_FPU)    {      /*       * Floating point stack register       */      assert(ptr->fpucode >= 0);      assert(ptr->fpucode <= 7);      outbuf += sprintf(outbuf,                        "%s",                        x86RegistersDASM[R_ST0 + ptr->fpucode].name);    } /* if (opPtr->operands[ii] & REG_FPU) */    else if (opPtr->operands[ii] & REG_SR)    {      /*       * We have an Sreg operand (segment register). The REG       * field of the ModR/M byte specifies which register to use.       * According to IAS, Vol 2, the values of the segment registers       * are as follows:       *       * ES = 0       * CS = 1       * SS = 2       * DS = 3       * FS = 4       * GS = 5       */      outbuf += sprintf(outbuf,                        "%s",                        x86SegmentRegisters[ptr->msinfo.reg]);    } /* if (opPtr->operands[ii] & REG_SR) */    else if (opPtr->operands[ii] & REG_CONTROL)    {      /*       * According to IAS, Vol 2. the REG field of the ModR/M       * byte specifies the control register       */      outbuf += sprintf(outbuf,                        "%s",                        x86RegistersDASM[R_CR0 + ptr->msinfo.reg].name);    } /* if (opPtr->operands[ii] & REG_CONTROL) */    else if (opPtr->operands[ii] & REG_DEBUG)    {      /*       * According to IAS, Vol 2. the REG field of the ModR/M       * byte specifies the debug register       */      outbuf += sprintf(outbuf,                        "%s",                        x86RegistersDASM[R_DR0 + ptr->msinfo.reg].name);    } /* if (opPtr->operands[ii] & REG_DEBUG) */    else if (opPtr->operands[ii] & MEMOFFS)    {      int ret;      /*       * We have a moffs8/16/32 operand. This is a 16 or 32 bit       * offset (depending on the size attributes of the instruction)       * which comes after the opcode. The 8/16/32 following the moffs       * specify the size of the data at the offset location.       */      ret = x86operandMemoryOffset(ws, data, tmpbuf);      if (ret >= 0)        outbuf += sprintf(outbuf, "%s", tmpbuf);      else      {        strcpy(origout, tmpbuf);        return (0); /* error */      }    } /* if (opPtr->operands[ii] & MEMOFFS) */    else if (opPtr->operands[ii] & CONSTANT)    {      /*       * The operand is a numerical constant whose value       * is stored in opinfo[ii]       */      assert(opPtr->opinfo[ii] != NOOPARG);      outbuf += sprintf(outbuf, "%d", opPtr->opinfo[ii]);    } /* if (opPtr->operands[ii] & CONSTANT) */  } /* for (ii = 0; ii < opPtr->OperandCount; ++ii) */  *outbuf = '\0';

⌨️ 快捷键说明

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