/* Chrysalide - Outil d'analyse de fichiers binaires * instruction.h - prototypes pour la gestion des instructions de l'architecture x86 * * Copyright (C) 2008-2017 Cyrille Bagard * * This file is part of Chrysalide. * * Chrysalide is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * Chrysalide is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Foobar. If not, see . */ #ifndef _ARCH_X86_INSTRUCTION_H #define _ARCH_X86_INSTRUCTION_H #include "../instruction.h" /* Types de préfixes pour x86 */ typedef enum _X86Prefix X86Prefix; /* Enumération de tous les opcodes */ typedef enum _X86Opcodes { /* Instructions avec opcode sur un octet */ XOP_ADD_RM8_R8, /* add (0x00) */ XOP_ADD_RM1632_R1632, /* add ([0x66] 0x01) */ XOP_ADD_R8_RM8, /* add (0x02) */ XOP_ADD_R1632_RM1632, /* add ([0x66] 0x03) */ XOP_ADD_AL_IMM8, /* add (0x04) */ XOP_ADD_E_AX_IMM1632, /* sub ([0x66] 0x05) */ XOP_OR_RM8_R8, /* or (0x08) */ XOP_OR_RM1632_R1632, /* or ([0x66] 0x09) */ XOP_OR_R8_RM8, /* or (0x0a) */ XOP_OR_R1632_RM1632, /* or ([0x66] 0x0b) */ XOP_OR_AL_IMM8, /* or (0x0c) */ XOP_ADC_RM8_R8, /* adc (0x10) */ XOP_SBB_RM1632_R1632, /* and ([0x66] 0x19) */ XOP_AND_RM8_R8, /* and (0x20) */ XOP_AND_RM1632_R1632, /* and ([0x66] 0x21) */ XOP_AND_AL_IMM8, /* and (0x24) */ XOP_AND_E_AX_IMM1632, /* and ([0x66] 0x25) */ XOP_SUB_RM1632_R1632, /* sub ([0x66] 0x29) */ XOP_SUB_R8_RM8, /* sub (0x2a) */ XOP_SUB_R1632_RM1632, /* sub ([0x66] 0x2b) */ XOP_SUB_AL_IMM8, /* sub (0x2c) */ XOP_SUB_E_AX_IMM1632, /* sub ([0x66] 0x2d) */ XOP_XOR_RM8_R8, /* xor (0x30) */ XOP_XOR_RM1632_R1632, /* xor ([0x66] 0x31) */ XOP_XOR_R8_RM8, /* xor (0x32) */ XOP_XOR_R1632_RM1632, /* xor ([0x66] 0x33) */ XOP_XOR_AL_IMM8, /* xor (0x34) */ XOP_XOR_E_AX_IMM1632, /* xor ([0x66] 0x35) */ XOP_CMP_RM8_R8, /* cmp (0x38) */ XOP_CMP_RM1632_R1632, /* cmp ([0x66] 0x39) */ XOP_CMP_R8_RM8, /* cmp (0x3a) */ XOP_CMP_R1632_RM1632, /* cmp ([0x66] 0x3b) */ XOP_CMP_AL_IMM8, /* cmp (0x3c) */ XOP_CMP_E_AX_IMM1632, /* cmp ([0x66] 0x3d) */ XOP_INC_E_AX, /* inc ([0x66] 0x40) */ XOP_INC_E_CX, /* inc ([0x66] 0x41) */ XOP_INC_E_DX, /* inc ([0x66] 0x42) */ XOP_INC_E_BX, /* inc ([0x66] 0x43) */ XOP_INC_E_SP, /* inc ([0x66] 0x44) */ XOP_INC_E_BP, /* inc ([0x66] 0x45) */ XOP_INC_E_SI, /* inc ([0x66] 0x46) */ XOP_INC_E_DI, /* inc ([0x66] 0x47) */ XOP_DEC_E_AX, /* dec ([0x66] 0x48) */ XOP_DEC_E_CX, /* dec ([0x66] 0x49) */ XOP_DEC_E_DX, /* dec ([0x66] 0x4a) */ XOP_DEC_E_BX, /* dec ([0x66] 0x4b) */ XOP_DEC_E_SP, /* dec ([0x66] 0x4c) */ XOP_DEC_E_BP, /* dec ([0x66] 0x4d) */ XOP_DEC_E_SI, /* dec ([0x66] 0x4e) */ XOP_DEC_E_DI, /* dec ([0x66] 0x4f) */ XOP_PUSH_E_AX, /* push ([0x66] 0x50) */ XOP_PUSH_E_CX, /* push ([0x66] 0x51) */ XOP_PUSH_E_DX, /* push ([0x66] 0x52) */ XOP_PUSH_E_BX, /* push ([0x66] 0x53) */ XOP_PUSH_E_SP, /* push ([0x66] 0x54) */ XOP_PUSH_E_BP, /* push ([0x66] 0x55) */ XOP_PUSH_E_SI, /* push ([0x66] 0x56) */ XOP_PUSH_E_DI, /* push ([0x66] 0x57) */ XOP_POP_E_AX, /* pop ([0x66] 0x58) */ XOP_POP_E_CX, /* pop ([0x66] 0x59) */ XOP_POP_E_DX, /* pop ([0x66] 0x5a) */ XOP_POP_E_BX, /* pop ([0x66] 0x5b) */ XOP_POP_E_SP, /* pop ([0x66] 0x5c) */ XOP_POP_E_BP, /* pop ([0x66] 0x5d) */ XOP_POP_E_SI, /* pop ([0x66] 0x5e) */ XOP_POP_E_DI, /* pop ([0x66] 0x5f) */ XOP_POPA, /* popa (0x61) */ XOP_ARPL_RM16_R16, /* arpl (0x63) */ XOP_PUSH_IMM1632, /* push ([0x66] 0x68) */ XOP_IMUL_R1632_RM1632_IMM1632, /* imul ([0x66] 0x69) */ XOP_IMUL_RM1632_IMM8, /* imul ([0x66] 0x6b) */ XOP_JO_REL8, /* jo (0x70) */ XOP_JNO_REL8, /* jno (0x71) */ XOP_JB_REL8, /* jb (0x72) */ XOP_JNB_REL8, /* jnb (0x73) */ XOP_JE_REL8, /* je (0x74) */ XOP_JNE_REL8, /* jne (0x75) */ XOP_JNA_REL8, /* jna (0x76) */ XOP_JA_REL8, /* ja (0x77) */ XOP_JS_REL8, /* js (0x78) */ XOP_JNS_REL8, /* jns (0x79) */ XOP_JP_REL8, /* jp (0x7a) */ XOP_JNP_REL8, /* jnp (0x7b) */ XOP_JL_REL8, /* jl (0x7c) */ XOP_JNL_REL8, /* jnl (0x7d) */ XOP_JNG_REL8, /* jng (0x7e) */ XOP_JG_REL8, /* jg (0x7f) */ XOP_ADD_RM8_IMM8, /* add (0x80 0) */ XOP_OR_RM8_IMM8, /* or (0x80 1) */ XOP_ADC_RM8_IMM8, /* adc (0x80 2) */ XOP_SBB_RM8_IMM8, /* sbb (0x80 3) */ XOP_AND_RM8_IMM8, /* and (0x80 4) */ XOP_SUB_RM8_IMM8, /* sub (0x80 5) */ XOP_XOR_RM8_IMM8, /* xor (0x80 6) */ XOP_CMP_RM8_IMM8, /* cmp (0x80 7) */ XOP_ADD_RM1632_IMM1632, /* add ([0x66] 0x81 0) */ XOP_OR_RM1632_IMM1632, /* or ([0x66] 0x81 1) */ XOP_ADC_RM1632_IMM1632, /* adc ([0x66] 0x81 2) */ XOP_SBB_RM1632_IMM1632, /* sbb ([0x66] 0x81 3) */ XOP_AND_RM1632_IMM1632, /* and ([0x66] 0x81 4) */ XOP_SUB_RM1632_IMM1632, /* sub ([0x66] 0x81 5) */ XOP_XOR_RM1632_IMM1632, /* xor ([0x66] 0x81 6) */ XOP_CMP_RM1632_IMM1632, /* xor ([0x66] 0x81 7) */ XOP_ADD_RM1632_IMM8, /* add ([0x66] 0x83 0) */ XOP_OR_RM1632_IMM8, /* or ([0x66] 0x83 1) */ XOP_ADC_RM1632_IMM8, /* adc ([0x66] 0x83 2) */ XOP_SBB_RM1632_IMM8, /* sbb ([0x66] 0x83 3) */ XOP_AND_RM1632_IMM8, /* and ([0x66] 0x83 4) */ XOP_SUB_RM1632_IMM8, /* sub ([0x66] 0x83 5) */ XOP_XOR_RM1632_IMM8, /* xor ([0x66] 0x83 6) */ XOP_CMP_RM1632_IMM8, /* cmp ([0x66] 0x83 7) */ XOP_TEST_RM8_R8, /* test (0x84) */ XOP_TEST_RM1632_R1632, /* test ([0x66] 0x85) */ XOP_MOV_RM8_R8, /* mov (0x88) */ XOP_MOV_RM1632_R1632, /* mov ([0x66] 0x89) */ XOP_MOV_R1632_RM1632, /* mov ([0x66] 0x8b) */ XOP_LEA_R1632_M, /* lea ([0x66] 0x8d) */ XOP_NOP, /* nop (0x90) */ XOP_XCHG_R1632_E_AX, /* xchg ([0x66] 0x90) */ XOP_XCHG_R1632_E_CX, /* xchg ([0x66] 0x91) */ XOP_XCHG_R1632_E_DX, /* xchg ([0x66] 0x92) */ XOP_XCHG_R1632_E_BX, /* xchg ([0x66] 0x93) */ XOP_XCHG_R1632_E_SP, /* xchg ([0x66] 0x94) */ XOP_XCHG_R1632_E_BP, /* xchg ([0x66] 0x95) */ XOP_XCHG_R1632_E_SI, /* xchg ([0x66] 0x96) */ XOP_XCHG_R1632_E_DI, /* xchg ([0x66] 0x97) */ XOP_MOV_AL_MOFFS8, /* mov (0xa0) */ XOP_MOV_E_AX_MOFFS1632, /* mov ([0x66] 0xa1) */ XOP_MOV_MOFFS8_AL, /* mov (0xa2) */ XOP_MOV_MOFFS1632_E_AX, /* mov ([0x66] 0xa3) */ XOP_MOVS_M1632_M1632, /* movs ([0x66] 0xa5) */ XOP_CMPS_M8_M8, /* cmps (0xa6) */ XOP_TEST_AL_IMM8, /* test (0xa8) */ XOP_TEST_E_AX_IMM1632, /* test ([0x66] 0xa9) */ XOP_STOS_M1632_E_AX, /* stos ([0x66] 0xab) */ XOP_SCAS_AL_M8, /* scas (0xae) */ XOP_MOV_AL_IMM8, /* mov (0xb0) */ XOP_MOV_CL_IMM8, /* mov (0xb1) */ XOP_MOV_DL_IMM8, /* mov (0xb2) */ XOP_MOV_BL_IMM8, /* mov (0xb3) */ XOP_MOV_AH_IMM8, /* mov (0xb4) */ XOP_MOV_CH_IMM8, /* mov (0xb5) */ XOP_MOV_DH_IMM8, /* mov (0xb6) */ XOP_MOV_BH_IMM8, /* mov (0xb7) */ XOP_MOV_E_AX_IMM1632, /* mov ([0x66] 0xb8) */ XOP_MOV_E_CX_IMM1632, /* mov ([0x66] 0xb9) */ XOP_MOV_E_DX_IMM1632, /* mov ([0x66] 0xba) */ XOP_MOV_E_BX_IMM1632, /* mov ([0x66] 0xbb) */ XOP_MOV_E_SP_IMM1632, /* mov ([0x66] 0xbc) */ XOP_MOV_E_BP_IMM1632, /* mov ([0x66] 0xbd) */ XOP_MOV_E_SI_IMM1632, /* mov ([0x66] 0xbe) */ XOP_MOV_E_DI_IMM1632, /* mov ([0x66] 0xbf) */ XOP_ROL_RM8_IMM8, /* rol (0xc0 0) */ XOP_ROR_RM8_IMM8, /* ror (0xc0 1) */ XOP_RCL_RM8_IMM8, /* rcl (0xc0 2) */ XOP_RCR_RM8_IMM8, /* rcr (0xc0 3) */ XOP_SHL_RM8_IMM8, /* shl (0xc0 4) */ XOP_SHR_RM8_IMM8, /* shr (0xc0 5) */ XOP_SAL_RM8_IMM8, /* sal (0xc0 6) */ XOP_SAR_RM8_IMM8, /* sar (0xc0 7) */ XOP_ROL_RM1632_IMM8, /* rol ([0x66] 0xc1 0) */ XOP_ROR_RM1632_IMM8, /* ror ([0x66] 0xc1 1) */ XOP_RCL_RM1632_IMM8, /* rcl ([0x66] 0xc1 2) */ XOP_RCR_RM1632_IMM8, /* rcr ([0x66] 0xc1 3) */ XOP_SHL_RM1632_IMM8, /* shl ([0x66] 0xc1 4) */ XOP_SHR_RM1632_IMM8, /* shr ([0x66] 0xc1 5) */ XOP_SAL_RM1632_IMM8, /* sal ([0x66] 0xc1 6) */ XOP_SAR_RM1632_IMM8, /* sar ([0x66] 0xc1 7) */ XOP_RETN_IMM16, /* retn (0xc2) */ XOP_RETN, /* ret (0xc3) */ XOP_MOV_RM8_IMM8, /* mov (0xc6 0) */ XOP_MOV_RM1632_IMM1632, /* mov ([0x66] 0xc7 0) */ XOP_LEAVE, /* leave (0xc9) */ XOP_RETF_IMM16, /* retn (0xca) */ XOP_RETF, /* ret (0xcb) */ XOP_INT_3, /* int 3 (0xcc) */ XOP_INT, /* int (0xcd) */ XOP_ROL_RM8_1, /* rol (0xd0 0) */ XOP_ROR_RM8_1, /* ror (0xd0 1) */ XOP_RCL_RM8_1, /* rcl (0xd0 2) */ XOP_RCR_RM8_1, /* rcr (0xd0 3) */ XOP_SHL_RM8_1, /* shl (0xd0 4) */ XOP_SHR_RM8_1, /* shr (0xd0 5) */ XOP_SAL_RM8_1, /* sal (0xd0 6) */ XOP_SAR_RM8_1, /* sar (0xd0 7) */ XOP_ROL_RM1632_1, /* rol ([0x66] 0xd1 0) */ XOP_ROR_RM1632_1, /* ror ([0x66] 0xd1 1) */ XOP_RCL_RM1632_1, /* rcl ([0x66] 0xd1 2) */ XOP_RCR_RM1632_1, /* rcr ([0x66] 0xd1 3) */ XOP_SHL_RM1632_1, /* shl ([0x66] 0xd1 4) */ XOP_SHR_RM1632_1, /* shr ([0x66] 0xd1 5) */ XOP_SAL_RM1632_1, /* sal ([0x66] 0xd1 6) */ XOP_SAR_RM1632_1, /* sar ([0x66] 0xd1 7) */ XOP_ROL_RM8_CL, /* rol (0xd2 0) */ XOP_ROR_RM8_CL, /* ror (0xd2 1) */ XOP_RCL_RM8_CL, /* rcl (0xd2 2) */ XOP_RCR_RM8_CL, /* rcr (0xd2 3) */ XOP_SHL_RM8_CL, /* shl (0xd2 4) */ XOP_SHR_RM8_CL, /* shr (0xd2 5) */ XOP_SAL_RM8_CL, /* sal (0xd2 6) */ XOP_SAR_RM8_CL, /* sar (0xd2 7) */ XOP_ROL_RM1632_CL, /* rol ([0x66] 0xd3 0) */ XOP_ROR_RM1632_CL, /* ror ([0x66] 0xd3 1) */ XOP_RCL_RM1632_CL, /* rcl ([0x66] 0xd3 2) */ XOP_RCR_RM1632_CL, /* rcr ([0x66] 0xd3 3) */ XOP_SHL_RM1632_CL, /* shl ([0x66] 0xd3 4) */ XOP_SHR_RM1632_CL, /* shr ([0x66] 0xd3 5) */ XOP_SAL_RM1632_CL, /* sal ([0x66] 0xd3 6) */ XOP_SAR_RM1632_CL, /* sar ([0x66] 0xd3 7) */ XOP_CALL_REL1632, /* call ([0x66] 0xe8) */ XOP_JMP_REL1632, /* jmp ([0x66] 0xe9) */ XOP_JMP_REL8, /* jmp (0xeb) */ XOP_HLT, /* hlt (0xf4) */ XOP_TEST_RM8_IMM8, /* test (0xf6 0) */ XOP_TEST_RM8_IMM8_BIS, /* test (0xf6 1) */ XOP_NOT_RM8, /* not (0xf6 2) */ XOP_TEST_RM1632_IMM1632, /* test ([0x66] 0xf7 0) */ XOP_TEST_RM1632_IMM1632_BIS, /* test ([0x66] 0xf7 1) */ XOP_NOT_RM1632, /* not ([0x66] 0xf7 2) */ XOP_IMUL_RM1632, /* imul ([0x66] 0xf7 5) */ XOP_CLD, /* cld (0xfc) */ XOP_INC_RM8, /* inc (0xfe 0) */ XOP_DEC_RM8, /* dec (0xfe 1) */ XOP_INC_RM1632, /* inc ([0x66] 0xff 0) */ XOP_DEC_RM1632, /* dec ([0x66] 0xff 1) */ XOP_CALL_RM1632, /* call ([0x66] 0xff 2) */ XOP_JMP_RM1632, /* jmp ([0x66] 0xff 4) */ XOP_PUSH_RM1632, /* push ([0x66] 0xff 6) */ /* Instructions avec opcode sur deux octets */ XOP_JO_REL1632, /* jo (0x0f 0x80) */ XOP_JNO_REL1632, /* jno (0x0f 0x81) */ XOP_JB_REL1632, /* jb (0x0f 0x82) */ XOP_JNB_REL1632, /* jnb (0x0f 0x83) */ XOP_JE_REL1632, /* je (0x0f 0x84) */ XOP_JNE_REL1632, /* jne (0x0f 0x85) */ XOP_JNA_REL1632, /* jna (0x0f 0x86) */ XOP_JA_REL1632, /* ja (0x0f 0x87) */ XOP_JS_REL1632, /* js (0x0f 0x88) */ XOP_JNS_REL1632, /* jns (0x0f 0x89) */ XOP_JP_REL1632, /* jp (0x0f 0x8a) */ XOP_JNP_REL1632, /* jnp (0x0f 0x8b) */ XOP_JL_REL1632, /* jl (0x0f 0x8c) */ XOP_JNL_REL1632, /* jnl (0x0f 0x8d) */ XOP_JNG_REL1632, /* jng (0x0f 0x8e) */ XOP_JG_REL1632, /* jg (0x0f 0x8f) */ XOP_SETO_RM8, /* seto (0x0f 0x90) */ XOP_SETNO_RM8, /* setno (0x0f 0x91) */ XOP_SETB_RM8, /* setb (0x0f 0x92) */ XOP_SETNB_RM8, /* setnb (0x0f 0x93) */ XOP_SETE_RM8, /* sete (0x0f 0x94) */ XOP_SETNE_RM8, /* setne (0x0f 0x95) */ XOP_SETNA_RM8, /* setna (0x0f 0x96) */ XOP_SETA_RM8, /* seta (0x0f 0x97) */ XOP_SETS_RM8, /* sets (0x0f 0x98) */ XOP_SETNS_RM8, /* setns (0x0f 0x99) */ XOP_SETP_RM8, /* setp (0x0f 0x9a) */ XOP_SETNP_RM8, /* setnp (0x0f 0x9b) */ XOP_SETL_RM8, /* setl (0x0f 0x9c) */ XOP_SETNL_RM8, /* setnl (0x0f 0x9d) */ XOP_SETNG_RM8, /* setng (0x0f 0x9e) */ XOP_SETG_RM8, /* setg (0x0f 0x9f) */ XOP_MOVZX_R1632_RM8, /* movzx ([0x66] 0x0f 0xb6) */ XOP_MOVZX_R1632_RM16, /* movzx ([0x66] 0x0f 0xb7) */ XOP_MOVSX_R1632_RM8, /* movsx ([0x66] 0x0f 0xbe) */ XOP_MOVSX_R1632_RM1632, /* movsx ([0x66] 0x0f 0xbf) */ XOP_COUNT } X86Opcodes; #define G_TYPE_X86_INSTRUCTION g_x86_instruction_get_type() #define G_X86_INSTRUCTION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_x86_instruction_get_type(), GX86Instruction)) #define G_IS_X86_INSTRUCTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_x86_instruction_get_type())) #define G_X86_INSTRUCTION_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_x86_instruction_get_type(), GX86InstructionIface)) /* Définition générique d'une instruction d'architecture x86 (instance) */ typedef struct _GX86Instruction GX86Instruction; /* Définition générique d'une instruction d'architecture x86 (classe) */ typedef struct _GX86InstructionClass GX86InstructionClass; /* Indique le type défini pour une instruction d'architecture x86. */ GType g_x86_instruction_get_type(void); /* Crée une instruction pour l'architecture x86. */ GArchInstruction *g_x86_instruction_new(X86Opcodes); /* Fournit l'identifiant de l'opcode représenté. */ X86Opcodes g_x86_instruction_get_opcode(const GX86Instruction *); /* Attache à une instructions ses préfixes associés. */ void g_x86_instruction_set_prefixes(GX86Instruction *, X86Prefix); /* --------------------- AIDE A LA MISE EN PLACE D'INSTRUCTIONS --------------------- */ /* Types de préfixes pour x86 */ enum _X86Prefix { XPX_NONE = (0 << 0), /* Code d'instruction pur */ XPX_OPERAND_SIZE_OVERRIDE = (1 << 0), /* Taille des opérandes */ XPX_REPEAT_STR_OPERATION_F2 = (1 << 1), /* Boucle pour les chaînes #1 */ XPX_REPEAT_STR_OPERATION_F3 = (1 << 2), /* Boucle pour les chaînes #2 */ XPX_TWO_BYTES = (1 << 3) /* Instruction sur deux octets */ }; /* Recherche l'identifiant de la prochaine instruction. */ X86Opcodes x86_guess_next_instruction(const bin_t *, off_t, off_t, X86Prefix *, bool *); #endif /* _ARCH_X86_INSTRUCTION_H */