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

📄 decode.c

📁 Ksplice is practical technology for updating the Linux kernel without rebooting. It enables you to a
💻 C
📖 第 1 页 / 共 3 页
字号:
            decode_o(u, mop2s, &(iop[1]));        break;    /* rAX[r8]..rDI[r15], I/rAX..rDI/O */    case OP_rAXr8 : case OP_rCXr9 : case OP_rDXr10 : case OP_rBXr11 :    case OP_rSPr12: case OP_rBPr13: case OP_rSIr14 : case OP_rDIr15 :    case OP_rAX : case OP_rCX : case OP_rDX : case OP_rBX :    case OP_rSP : case OP_rBP : case OP_rSI : case OP_rDI :        iop[0].type = UD_OP_REG;        iop[0].base = resolve_gpr64(u, mop1t);        if (mop2t == OP_I)            decode_imm(u, mop2s, &(iop[1]));        else if (mop2t >= OP_rAX && mop2t <= OP_rDI) {            iop[1].type = UD_OP_REG;            iop[1].base = resolve_gpr64(u, mop2t);        }        else if (mop2t == OP_O) {            decode_o(u, mop2s, &(iop[1]));              iop[0].size = resolve_operand_size(u, mop2s);        }        break;    /* AL[r8b]..BH[r15b], I */    case OP_ALr8b : case OP_CLr9b : case OP_DLr10b : case OP_BLr11b :    case OP_AHr12b: case OP_CHr13b: case OP_DHr14b : case OP_BHr15b :    {        ud_type_t gpr = (mop1t - OP_ALr8b) + UD_R_AL +                         (REX_B(u->pfx_rex) << 3);        if (UD_R_AH <= gpr && u->pfx_rex)            gpr = gpr + 4;        iop[0].type = UD_OP_REG;        iop[0].base = gpr;        if (mop2t == OP_I)            decode_imm(u, mop2s, &(iop[1]));        break;    }    /* eAX..eDX, DX/I */    case OP_eAX : case OP_eCX : case OP_eDX : case OP_eBX :    case OP_eSP : case OP_eBP : case OP_eSI : case OP_eDI :        iop[0].type = UD_OP_REG;        iop[0].base = resolve_gpr32(u, mop1t);        if (mop2t == OP_DX) {            iop[1].type = UD_OP_REG;            iop[1].base = UD_R_DX;            iop[1].size = 16;        } else if (mop2t == OP_I)            decode_imm(u, mop2s, &(iop[1]));        break;    /* ES..GS */    case OP_ES : case OP_CS : case OP_DS :    case OP_SS : case OP_FS : case OP_GS :        /* in 64bits mode, only fs and gs are allowed */        if (u->dis_mode == 64)            if (mop1t != OP_FS && mop1t != OP_GS)                u->error= 1;        iop[0].type = UD_OP_REG;        iop[0].base = (mop1t - OP_ES) + UD_R_ES;        iop[0].size = 16;        break;    /* J */    case OP_J :        decode_imm(u, mop1s, &(iop[0]));                iop[0].type = UD_OP_JIMM;        break ;    /* PR, I */    case OP_PR:        if (MODRM_MOD(inp_peek(u)) != 3)            u->error = 1;        decode_modrm(u, &(iop[0]), mop1s, T_MMX, NULL, 0, T_NONE);        if (mop2t == OP_I)            decode_imm(u, mop2s, &(iop[1]));        break;     /* VR, I */    case OP_VR:        if (MODRM_MOD(inp_peek(u)) != 3)            u->error = 1;        decode_modrm(u, &(iop[0]), mop1s, T_XMM, NULL, 0, T_NONE);        if (mop2t == OP_I)            decode_imm(u, mop2s, &(iop[1]));        break;     /* P, Q[,I]/W/E[,I],VR */    case OP_P :        if (mop2t == OP_Q) {            decode_modrm(u, &(iop[1]), mop2s, T_MMX, &(iop[0]), mop1s, T_MMX);            if (mop3t == OP_I)                decode_imm(u, mop3s, &(iop[2]));        } else if (mop2t == OP_W) {            decode_modrm(u, &(iop[1]), mop2s, T_XMM, &(iop[0]), mop1s, T_MMX);        } else if (mop2t == OP_VR) {            if (MODRM_MOD(inp_peek(u)) != 3)                u->error = 1;            decode_modrm(u, &(iop[1]), mop2s, T_XMM, &(iop[0]), mop1s, T_MMX);        } else if (mop2t == OP_E) {            decode_modrm(u, &(iop[1]), mop2s, T_GPR, &(iop[0]), mop1s, T_MMX);            if (mop3t == OP_I)                decode_imm(u, mop3s, &(iop[2]));        }        break;    /* R, C/D */    case OP_R :        if (mop2t == OP_C)            decode_modrm(u, &(iop[0]), mop1s, T_GPR, &(iop[1]), mop2s, T_CRG);        else if (mop2t == OP_D)            decode_modrm(u, &(iop[0]), mop1s, T_GPR, &(iop[1]), mop2s, T_DBG);        break;    /* C, R */    case OP_C :        decode_modrm(u, &(iop[1]), mop2s, T_GPR, &(iop[0]), mop1s, T_CRG);        break;    /* D, R */    case OP_D :        decode_modrm(u, &(iop[1]), mop2s, T_GPR, &(iop[0]), mop1s, T_DBG);        break;    /* Q, P */    case OP_Q :        decode_modrm(u, &(iop[0]), mop1s, T_MMX, &(iop[1]), mop2s, T_MMX);        break;    /* S, E */    case OP_S :        decode_modrm(u, &(iop[1]), mop2s, T_GPR, &(iop[0]), mop1s, T_SEG);        break;    /* W, V */    case OP_W :        decode_modrm(u, &(iop[0]), mop1s, T_XMM, &(iop[1]), mop2s, T_XMM);        break;    /* V, W[,I]/Q/M/E */    case OP_V :        if (mop2t == OP_W) {            /* special cases for movlps and movhps */            if (MODRM_MOD(inp_peek(u)) == 3) {                if (u->mnemonic == UD_Imovlps)                    u->mnemonic = UD_Imovhlps;                else                if (u->mnemonic == UD_Imovhps)                    u->mnemonic = UD_Imovlhps;            }            decode_modrm(u, &(iop[1]), mop2s, T_XMM, &(iop[0]), mop1s, T_XMM);            if (mop3t == OP_I)                decode_imm(u, mop3s, &(iop[2]));        } else if (mop2t == OP_Q)            decode_modrm(u, &(iop[1]), mop2s, T_MMX, &(iop[0]), mop1s, T_XMM);        else if (mop2t == OP_M) {            if (MODRM_MOD(inp_peek(u)) == 3)                u->error= 1;            decode_modrm(u, &(iop[1]), mop2s, T_GPR, &(iop[0]), mop1s, T_XMM);        } else if (mop2t == OP_E) {            decode_modrm(u, &(iop[1]), mop2s, T_GPR, &(iop[0]), mop1s, T_XMM);        } else if (mop2t == OP_PR) {            decode_modrm(u, &(iop[1]), mop2s, T_MMX, &(iop[0]), mop1s, T_XMM);        }        break;    /* DX, eAX/AL */    case OP_DX :        iop[0].type = UD_OP_REG;        iop[0].base = UD_R_DX;        iop[0].size = 16;        if (mop2t == OP_eAX) {            iop[1].type = UD_OP_REG;                iop[1].base = resolve_gpr32(u, mop2t);        } else if (mop2t == OP_AL) {            iop[1].type = UD_OP_REG;            iop[1].base = UD_R_AL;            iop[1].size = 8;        }        break;    /* I, I/AL/eAX */    case OP_I :        decode_imm(u, mop1s, &(iop[0]));        if (mop2t == OP_I)            decode_imm(u, mop2s, &(iop[1]));        else if (mop2t == OP_AL) {            iop[1].type = UD_OP_REG;            iop[1].base = UD_R_AL;            iop[1].size = 16;        } else if (mop2t == OP_eAX) {            iop[1].type = UD_OP_REG;                iop[1].base = resolve_gpr32(u, mop2t);        }        break;    /* O, AL/eAX */    case OP_O :        decode_o(u, mop1s, &(iop[0]));        iop[1].type = UD_OP_REG;        iop[1].size = resolve_operand_size(u, mop1s);        if (mop2t == OP_AL)            iop[1].base = UD_R_AL;        else if (mop2t == OP_eAX)            iop[1].base = resolve_gpr32(u, mop2t);        else if (mop2t == OP_rAX)            iop[1].base = resolve_gpr64(u, mop2t);              break;    /* 3 */    case OP_I3 :        iop[0].type = UD_OP_CONST;        iop[0].lval.sbyte = 3;        break;    /* ST(n), ST(n) */    case OP_ST0 : case OP_ST1 : case OP_ST2 : case OP_ST3 :    case OP_ST4 : case OP_ST5 : case OP_ST6 : case OP_ST7 :        iop[0].type = UD_OP_REG;        iop[0].base = (mop1t-OP_ST0) + UD_R_ST0;        iop[0].size = 0;        if (mop2t >= OP_ST0 && mop2t <= OP_ST7) {            iop[1].type = UD_OP_REG;            iop[1].base = (mop2t-OP_ST0) + UD_R_ST0;            iop[1].size = 0;        }        break;    /* AX */    case OP_AX:        iop[0].type = UD_OP_REG;        iop[0].base = UD_R_AX;        iop[0].size = 16;        break;    /* none */    default :        iop[0].type = iop[1].type = iop[2].type = UD_NONE;  }  return 0;}/* ----------------------------------------------------------------------------- * clear_insn() - clear instruction pointer  * ----------------------------------------------------------------------------- */static int clear_insn(register struct ud* u){  u->error     = 0;  u->pfx_seg   = 0;  u->pfx_opr   = 0;  u->pfx_adr   = 0;  u->pfx_lock  = 0;  u->pfx_repne = 0;  u->pfx_rep   = 0;  u->pfx_repe  = 0;  u->pfx_seg   = 0;  u->pfx_rex   = 0;  u->pfx_insn  = 0;  u->mnemonic  = UD_Inone;  u->itab_entry = NULL;  memset( &u->operand[ 0 ], 0, sizeof( struct ud_operand ) );  memset( &u->operand[ 1 ], 0, sizeof( struct ud_operand ) );  memset( &u->operand[ 2 ], 0, sizeof( struct ud_operand ) );   return 0;}static int do_mode( struct ud* u ){  /* if in error state, bail out */  if ( u->error ) return -1;   /* propagate perfix effects */  if ( u->dis_mode == 64 ) {  /* set 64bit-mode flags */    /* Check validity of  instruction m64 */    if ( P_INV64( u->itab_entry->prefix ) ) {        u->error = 1;        return -1;    }    /* effective rex prefix is the  effective mask for the      * instruction hard-coded in the opcode map.     */    u->pfx_rex = ( u->pfx_rex & 0x40 ) |                  ( u->pfx_rex & REX_PFX_MASK( u->itab_entry->prefix ) );     /* whether this instruction has a default operand size of      * 64bit, also hardcoded into the opcode map.     */    u->default64 = P_DEF64( u->itab_entry->prefix );     /* calculate effective operand size */    if ( REX_W( u->pfx_rex ) ) {        u->opr_mode = 64;    } else if ( u->pfx_opr ) {        u->opr_mode = 16;    } else {        /* unless the default opr size of instruction is 64,         * the effective operand size in the absence of rex.w         * prefix is 32.         */        u->opr_mode = ( u->default64 ) ? 64 : 32;    }    /* calculate effective address size */    u->adr_mode = (u->pfx_adr) ? 32 : 64;  } else if ( u->dis_mode == 32 ) { /* set 32bit-mode flags */    u->opr_mode = ( u->pfx_opr ) ? 16 : 32;    u->adr_mode = ( u->pfx_adr ) ? 16 : 32;  } else if ( u->dis_mode == 16 ) { /* set 16bit-mode flags */    u->opr_mode = ( u->pfx_opr ) ? 32 : 16;    u->adr_mode = ( u->pfx_adr ) ? 32 : 16;  }  /* These flags determine which operand to apply the operand size   * cast to.   */  u->c1 = ( P_C1( u->itab_entry->prefix ) ) ? 1 : 0;  u->c2 = ( P_C2( u->itab_entry->prefix ) ) ? 1 : 0;  u->c3 = ( P_C3( u->itab_entry->prefix ) ) ? 1 : 0;  /* set flags for implicit addressing */  u->implicit_addr = P_IMPADDR( u->itab_entry->prefix );  return 0;}static int gen_hex( struct ud *u ){  unsigned int i;  unsigned char *src_ptr = inp_sess( u );  char* src_hex;  /* bail out if in error stat. */  if ( u->error ) return -1;   /* output buffer pointe */  src_hex = ( char* ) u->insn_hexcode;  /* for each byte used to decode instruction */  for ( i = 0; i < u->inp_ctr; ++i, ++src_ptr) {    sprintf( src_hex, "%02x", *src_ptr & 0xFF );    src_hex += 2;  }  return 0;}/* ============================================================================= * ud_decode() - Instruction decoder. Returns the number of bytes decoded. * ============================================================================= */unsigned int ud_decode( struct ud* u ){  inp_start(u);  if ( clear_insn( u ) ) {    ; /* error */  } else if ( get_prefixes( u ) != 0 ) {    ; /* error */  } else if ( search_itab( u ) != 0 ) {    ; /* error */  } else if ( do_mode( u ) != 0 ) {    ; /* error */  } else if ( disasm_operands( u ) != 0 ) {    ; /* error */  } else if ( resolve_mnemonic( u ) != 0 ) {    ; /* error */  }  /* Handle decode error. */  if ( u->error ) {    /* clear out the decode data. */    clear_insn( u );    /* mark the sequence of bytes as invalid. */    u->itab_entry = & ie_invalid;    u->mnemonic = u->itab_entry->mnemonic;  }   u->insn_offset = u->pc; /* set offset of instruction */  u->insn_fill = 0;   /* set translation buffer index to 0 */  u->pc += u->inp_ctr;    /* move program counter by bytes decoded */  gen_hex( u );       /* generate hex code */  /* return number of bytes disassembled. */  return u->inp_ctr;}/* vim:cindent * vim:ts=4 * vim:sw=4 * vim:expandtab */

⌨️ 快捷键说明

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