📄 decode.c
字号:
}/****************************************************************************PARAMETERS:reg - Register to decodeRETURNS:Pointer to the appropriate registerREMARKS:Return a pointer to the register given by the R/RM field of themodrm byte, for byte operands. Also enables the decoding of instructions.****************************************************************************/u8* decode_rm_byte_register( int reg){ switch (reg) { case 0: DECODE_PRINTF("AL"); return &M.x86.R_AL; case 1: DECODE_PRINTF("CL"); return &M.x86.R_CL; case 2: DECODE_PRINTF("DL"); return &M.x86.R_DL; case 3: DECODE_PRINTF("BL"); return &M.x86.R_BL; case 4: DECODE_PRINTF("AH"); return &M.x86.R_AH; case 5: DECODE_PRINTF("CH"); return &M.x86.R_CH; case 6: DECODE_PRINTF("DH"); return &M.x86.R_DH; case 7: DECODE_PRINTF("BH"); return &M.x86.R_BH; } HALT_SYS(); return NULL; /* NOT REACHED OR REACHED ON ERROR */}/****************************************************************************PARAMETERS:reg - Register to decodeRETURNS:Pointer to the appropriate registerREMARKS:Return a pointer to the register given by the R/RM field of themodrm byte, for word operands. Also enables the decoding of instructions.****************************************************************************/u16* decode_rm_word_register( int reg){ switch (reg) { case 0: DECODE_PRINTF("AX"); return &M.x86.R_AX; case 1: DECODE_PRINTF("CX"); return &M.x86.R_CX; case 2: DECODE_PRINTF("DX"); return &M.x86.R_DX; case 3: DECODE_PRINTF("BX"); return &M.x86.R_BX; case 4: DECODE_PRINTF("SP"); return &M.x86.R_SP; case 5: DECODE_PRINTF("BP"); return &M.x86.R_BP; case 6: DECODE_PRINTF("SI"); return &M.x86.R_SI; case 7: DECODE_PRINTF("DI"); return &M.x86.R_DI; } HALT_SYS(); return NULL; /* NOTREACHED OR REACHED ON ERROR */}/****************************************************************************PARAMETERS:reg - Register to decodeRETURNS:Pointer to the appropriate registerREMARKS:Return a pointer to the register given by the R/RM field of themodrm byte, for dword operands. Also enables the decoding of instructions.****************************************************************************/u32* decode_rm_long_register( int reg){ switch (reg) { case 0: DECODE_PRINTF("EAX"); return &M.x86.R_EAX; case 1: DECODE_PRINTF("ECX"); return &M.x86.R_ECX; case 2: DECODE_PRINTF("EDX"); return &M.x86.R_EDX; case 3: DECODE_PRINTF("EBX"); return &M.x86.R_EBX; case 4: DECODE_PRINTF("ESP"); return &M.x86.R_ESP; case 5: DECODE_PRINTF("EBP"); return &M.x86.R_EBP; case 6: DECODE_PRINTF("ESI"); return &M.x86.R_ESI; case 7: DECODE_PRINTF("EDI"); return &M.x86.R_EDI; } HALT_SYS(); return NULL; /* NOTREACHED OR REACHED ON ERROR */}/****************************************************************************PARAMETERS:reg - Register to decodeRETURNS:Pointer to the appropriate registerREMARKS:Return a pointer to the register given by the R/RM field of themodrm byte, for word operands, modified from above for the weirdospecial case of segreg operands. Also enables the decoding of instructions.****************************************************************************/u16* decode_rm_seg_register( int reg){ switch (reg) { case 0: DECODE_PRINTF("ES"); return &M.x86.R_ES; case 1: DECODE_PRINTF("CS"); return &M.x86.R_CS; case 2: DECODE_PRINTF("SS"); return &M.x86.R_SS; case 3: DECODE_PRINTF("DS"); return &M.x86.R_DS; case 4: DECODE_PRINTF("FS"); return &M.x86.R_FS; case 5: DECODE_PRINTF("GS"); return &M.x86.R_GS; case 6: case 7: DECODE_PRINTF("ILLEGAL SEGREG"); break; } printf("reg %d\n", reg); //DECODE_PRINTF("CS"); //return &M.x86.R_CS; /*HALT_SYS();*/ return NULL; /* NOT REACHED OR REACHED ON ERROR */}/* * * return offset from the SIB Byte */u32 decode_sib_address(int sib, int mod){ u32 base = 0, i = 0, scale = 1; switch(sib & 0x07) { case 0: DECODE_PRINTF("[EAX]"); base = M.x86.R_EAX; break; case 1: DECODE_PRINTF("[ECX]"); base = M.x86.R_ECX; break; case 2: DECODE_PRINTF("[EDX]"); base = M.x86.R_EDX; break; case 3: DECODE_PRINTF("[EBX]"); base = M.x86.R_EBX; break; case 4: DECODE_PRINTF("[ESP]"); base = M.x86.R_ESP; M.x86.mode |= SYSMODE_SEG_DS_SS; break; case 5: if (mod == 0) { base = fetch_long_imm(); DECODE_PRINTF2("%08x", base); } else { DECODE_PRINTF("[EBP]"); base = M.x86.R_ESP; M.x86.mode |= SYSMODE_SEG_DS_SS; } break; case 6: DECODE_PRINTF("[ESI]"); base = M.x86.R_ESI; break; case 7: DECODE_PRINTF("[EDI]"); base = M.x86.R_EDI; break; } switch ((sib >> 3) & 0x07) { case 0: DECODE_PRINTF("[EAX"); i = M.x86.R_EAX; break; case 1: DECODE_PRINTF("[ECX"); i = M.x86.R_ECX; break; case 2: DECODE_PRINTF("[EDX"); i = M.x86.R_EDX; break; case 3: DECODE_PRINTF("[EBX"); i = M.x86.R_EBX; break; case 4: i = 0; break; case 5: DECODE_PRINTF("[EBP"); i = M.x86.R_EBP; break; case 6: DECODE_PRINTF("[ESI"); i = M.x86.R_ESI; break; case 7: DECODE_PRINTF("[EDI"); i = M.x86.R_EDI; break; } scale = 1 << ((sib >> 6) & 0x03); if (((sib >> 3) & 0x07) != 4) { if (scale == 1) { DECODE_PRINTF("]"); } else { DECODE_PRINTF2("*%d]", scale); } } return base + (i * scale);}/****************************************************************************PARAMETERS:rm - RM value to decodeRETURNS:Offset in memory for the address decodingREMARKS:Return the offset given by mod=00 addressing. Also enables thedecoding of instructions.NOTE: The code which specifies the corresponding segment (ds vs ss) below in the case of [BP+..]. The assumption here is that at the point that this subroutine is called, the bit corresponding to SYSMODE_SEG_DS_SS will be zero. After every instruction except the segment override instructions, this bit (as well as any bits indicating segment overrides) will be clear. So if a SS access is needed, set this bit. Otherwise, DS access occurs (unless any of the segment override bits are set).****************************************************************************/u32 decode_rm00_address( int rm){ u32 offset; int sib; if (M.x86.mode & SYSMODE_PREFIX_ADDR) { switch (rm) { case 0: DECODE_PRINTF("[EAX]"); return M.x86.R_EAX; case 1: DECODE_PRINTF("[ECX]"); return M.x86.R_ECX; case 2: DECODE_PRINTF("[EDX]"); return M.x86.R_EDX; case 3: DECODE_PRINTF("[EBX]"); return M.x86.R_EBX; case 4: sib = fetch_byte_imm(); return decode_sib_address(sib, 0); case 5: offset = fetch_long_imm(); DECODE_PRINTF2("[%08x]", offset); return offset; case 6: DECODE_PRINTF("[ESI]"); return M.x86.R_ESI; case 7: DECODE_PRINTF("[EDI]"); return M.x86.R_EDI; } HALT_SYS(); } else { switch (rm) { case 0: DECODE_PRINTF("[BX+SI]"); return M.x86.R_BX + M.x86.R_SI; case 1: DECODE_PRINTF("[BX+DI]"); return M.x86.R_BX + M.x86.R_DI; case 2: DECODE_PRINTF("[BP+SI]"); M.x86.mode |= SYSMODE_SEG_DS_SS; return M.x86.R_BP + M.x86.R_SI; case 3: DECODE_PRINTF("[BP+DI]"); M.x86.mode |= SYSMODE_SEG_DS_SS; return M.x86.R_BP + M.x86.R_DI; case 4: DECODE_PRINTF("[SI]"); return M.x86.R_SI; case 5: DECODE_PRINTF("[DI]"); return M.x86.R_DI; case 6: offset = fetch_word_imm(); DECODE_PRINTF2("[%04x]", offset); return offset; case 7: DECODE_PRINTF("[BX]"); return M.x86.R_BX; } HALT_SYS(); } return 0;}/****************************************************************************PARAMETERS:rm - RM value to decodeRETURNS:Offset in memory for the address decodingREMARKS:Return the offset given by mod=01 addressing. Also enables thedecoding of instructions.****************************************************************************/u32 decode_rm01_address( int rm){ int displacement = 0; int sib; /* Fetch disp8 if no SIB byte */ if (!((M.x86.mode & SYSMODE_PREFIX_ADDR) && (rm == 4))) displacement = (s8)fetch_byte_imm(); if (M.x86.mode & SYSMODE_PREFIX_ADDR) { switch (rm) { case 0: DECODE_PRINTF2("%d[EAX]", displacement); return M.x86.R_EAX + displacement; case 1: DECODE_PRINTF2("%d[ECX]", displacement); return M.x86.R_ECX + displacement; case 2: DECODE_PRINTF2("%d[EDX]", displacement); return M.x86.R_EDX + displacement; case 3: DECODE_PRINTF2("%d[EBX]", displacement); return M.x86.R_EBX + displacement; case 4: sib = fetch_byte_imm(); displacement = (s8)fetch_byte_imm(); DECODE_PRINTF2("%d", displacement); return decode_sib_address(sib, 1) + displacement; case 5: DECODE_PRINTF2("%d[EBP]", displacement); return M.x86.R_EBP + displacement; case 6: DECODE_PRINTF2("%d[ESI]", displacement); return M.x86.R_ESI + displacement; case 7: DECODE_PRINTF2("%d[EDI]", displacement); return M.x86.R_EDI + displacement; } HALT_SYS(); } else { switch (rm) { case 0: DECODE_PRINTF2("%d[BX+SI]", displacement); return M.x86.R_BX + M.x86.R_SI + displacement; case 1: DECODE_PRINTF2("%d[BX+DI]", displacement); return M.x86.R_BX + M.x86.R_DI + displacement; case 2: DECODE_PRINTF2("%d[BP+SI]", displacement); M.x86.mode |= SYSMODE_SEG_DS_SS; return M.x86.R_BP + M.x86.R_SI + displacement; case 3: DECODE_PRINTF2("%d[BP+DI]", displacement); M.x86.mode |= SYSMODE_SEG_DS_SS; return M.x86.R_BP + M.x86.R_DI + displacement; case 4: DECODE_PRINTF2("%d[SI]", displacement); return M.x86.R_SI + displacement; case 5: DECODE_PRINTF2("%d[DI]", displacement); return M.x86.R_DI + displacement; case 6: DECODE_PRINTF2("%d[BP]", displacement); M.x86.mode |= SYSMODE_SEG_DS_SS; return M.x86.R_BP + displacement; case 7: DECODE_PRINTF2("%d[BX]", displacement); return M.x86.R_BX + displacement; } HALT_SYS(); } return 0; /* SHOULD NOT HAPPEN */}/****************************************************************************PARAMETERS:rm - RM value to decodeRETURNS:Offset in memory for the address decodingREMARKS:Return the offset given by mod=10 addressing. Also enables thedecoding of instructions.****************************************************************************/u32 decode_rm10_address( int rm){ u32 displacement = 0; int sib; /* Fetch disp16 if 16-bit addr mode */ if (!(M.x86.mode & SYSMODE_PREFIX_ADDR)) displacement = (u16)fetch_word_imm(); else { /* Fetch disp32 if no SIB byte */ if (rm != 4) displacement = (u32)fetch_long_imm(); } if (M.x86.mode & SYSMODE_PREFIX_ADDR) { switch (rm) { case 0: DECODE_PRINTF2("%08x[EAX]", displacement); return M.x86.R_EAX + displacement; case 1: DECODE_PRINTF2("%08x[ECX]", displacement); return M.x86.R_ECX + displacement; case 2: DECODE_PRINTF2("%08x[EDX]", displacement); M.x86.mode |= SYSMODE_SEG_DS_SS; return M.x86.R_EDX + displacement; case 3: DECODE_PRINTF2("%08x[EBX]", displacement); return M.x86.R_EBX + displacement; case 4: sib = fetch_byte_imm(); displacement = (u32)fetch_long_imm(); DECODE_PRINTF2("%08x", displacement); return decode_sib_address(sib, 2) + displacement; break; case 5: DECODE_PRINTF2("%08x[EBP]", displacement); return M.x86.R_EBP + displacement; case 6: DECODE_PRINTF2("%08x[ESI]", displacement); return M.x86.R_ESI + displacement; case 7: DECODE_PRINTF2("%08x[EDI]", displacement); return M.x86.R_EDI + displacement; } HALT_SYS(); } else { switch (rm) { case 0: DECODE_PRINTF2("%04x[BX+SI]", displacement); return M.x86.R_BX + M.x86.R_SI + displacement; case 1: DECODE_PRINTF2("%04x[BX+DI]", displacement); return M.x86.R_BX + M.x86.R_DI + displacement; case 2: DECODE_PRINTF2("%04x[BP+SI]", displacement); M.x86.mode |= SYSMODE_SEG_DS_SS; return M.x86.R_BP + M.x86.R_SI + displacement; case 3: DECODE_PRINTF2("%04x[BP+DI]", displacement); M.x86.mode |= SYSMODE_SEG_DS_SS; return M.x86.R_BP + M.x86.R_DI + displacement; case 4: DECODE_PRINTF2("%04x[SI]", displacement); return M.x86.R_SI + displacement; case 5: DECODE_PRINTF2("%04x[DI]", displacement); return M.x86.R_DI + displacement; case 6: DECODE_PRINTF2("%04x[BP]", displacement); M.x86.mode |= SYSMODE_SEG_DS_SS; return M.x86.R_BP + displacement; case 7: DECODE_PRINTF2("%04x[BX]", displacement); return M.x86.R_BX + displacement; } HALT_SYS(); } return 0; /*NOTREACHED */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -