From 2ccf097c9344465944089bebbc2ffd66ac93e1fd Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sat, 20 Sep 2008 15:28:57 +0000 Subject: Centralized all the code used to decode instructions. git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@32 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a --- ChangeLog | 31 ++++ src/arch/operand.h | 2 + src/arch/x86/instruction.h | 39 +++-- src/arch/x86/op_adc.c | 36 +--- src/arch/x86/op_add.c | 64 +------ src/arch/x86/op_and.c | 36 +--- src/arch/x86/op_call.c | 39 +---- src/arch/x86/op_cmp.c | 79 +-------- src/arch/x86/op_dec.c | 21 +-- src/arch/x86/op_inc.c | 19 +-- src/arch/x86/op_int.c | 10 +- src/arch/x86/op_jump.c | 30 +--- src/arch/x86/op_lea.c | 8 +- src/arch/x86/op_mov.c | 263 +++++------------------------ src/arch/x86/op_or.c | 36 +--- src/arch/x86/op_pop.c | 19 +-- src/arch/x86/op_push.c | 62 ++----- src/arch/x86/op_sar.c | 28 +--- src/arch/x86/op_sbb.c | 36 +--- src/arch/x86/op_sub.c | 69 +------- src/arch/x86/op_test.c | 106 +----------- src/arch/x86/op_xor.c | 288 ++++++++++++++++++++++++++----- src/arch/x86/opcodes.h | 73 +++++--- src/arch/x86/operand.c | 410 ++++++++++++++++++++++++++++++++++++++++++++- src/arch/x86/operand.h | 54 +++++- src/arch/x86/processor.c | 143 +++++++++------- src/arch/x86/processor.h | 3 +- 27 files changed, 995 insertions(+), 1009 deletions(-) diff --git a/ChangeLog b/ChangeLog index 634025b..b457000 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,34 @@ +2008-09-20 Cyrille Bagard + + * src/arch/operand.h: + * src/arch/x86/instruction.h: + * src/arch/x86/op_adc.c: + * src/arch/x86/op_add.c: + * src/arch/x86/op_and.c: + * src/arch/x86/op_call.c: + * src/arch/x86/op_cmp.c: + * src/arch/x86/opcodes.h: + * src/arch/x86/op_dec.c: + * src/arch/x86/operand.c: + * src/arch/x86/operand.h: + * src/arch/x86/op_inc.c: + * src/arch/x86/op_int.c: + * src/arch/x86/op_jump.c: + * src/arch/x86/op_lea.c: + * src/arch/x86/op_mov.c: + * src/arch/x86/op_or.c: + * src/arch/x86/op_pop.c: + * src/arch/x86/op_push.c: + * src/arch/x86/op_sar.c: + * src/arch/x86/op_sbb.c: + * src/arch/x86/op_sub.c: + * src/arch/x86/op_test.c: + * src/arch/x86/op_xor.c: + * src/arch/x86/processor.c: + * src/arch/x86/processor.h: + Centralize all the code used to decode instructions. Rename enumerations + and functions according to the handled operands. + 2008-09-16 Cyrille Bagard * src/arch/x86/op_adc.c: diff --git a/src/arch/operand.h b/src/arch/operand.h index e913059..a05f819 100644 --- a/src/arch/operand.h +++ b/src/arch/operand.h @@ -34,6 +34,8 @@ /* Taille des données intégrées */ typedef enum _AsmOperandSize { + AOS_UNDEFINED, /* Taille non définie */ + AOS_8_BITS, /* Opérande sur 8 bits */ AOS_16_BITS, /* Opérande sur 16 bits */ AOS_32_BITS, /* Opérande sur 32 bits */ diff --git a/src/arch/x86/instruction.h b/src/arch/x86/instruction.h index 68a5fff..8ef603f 100644 --- a/src/arch/x86/instruction.h +++ b/src/arch/x86/instruction.h @@ -40,7 +40,12 @@ typedef enum _X86Opcodes { X86_OP_SUB_R1632_RM1632, /* sub ([0x66] 0x29) */ - X86_OP_XOR_REG1632, /* xor ([0x66] 0x31) */ + X86_OP_XOR_RM8_R8, /* xor (0x30) */ + X86_OP_XOR_RM1632_R1632, /* xor ([0x66] 0x31) */ + X86_OP_XOR_R8_RM8, /* xor (0x32) */ + X86_OP_XOR_R1632_RM1632, /* xor ([0x66] 0x33) */ + X86_OP_XOR_AL_IMM8, /* xor (0x34) */ + X86_OP_XOR_E_AX_IMM1632, /* xor ([0x66] 0x35) */ X86_OP_CMP_RM1632_R1632, /* cmp ([0x66] 0x39) */ @@ -85,25 +90,27 @@ typedef enum _X86Opcodes X86_OP_JE_8, /* je (0x74) */ X86_OP_JNE_8, /* jne (0x75) */ + X86_OP_XOR_RM8_IMM8, /* xor (0x81 6) */ X86_OP_CMP_RM8_IMM8, /* cmp (0x80 7) */ - X86_OP_ADD_IMM1632_REG1632, /* add ([0x66] 0x81 0) */ + X86_OP_ADD_RM1632_IMM1632, /* add ([0x66] 0x81 0) */ + X86_OP_XOR_RM1632_IMM1632, /* xor ([0x66] 0x81 6) */ - X86_OP_ADD8_REG1632, /* add ([0x66] 0x83 0) */ - X86_OP_OR8_REG1632, /* or ([0x66] 0x83 1) */ - X86_OP_ADC8_REG1632, /* adc ([0x66] 0x83 2) */ - X86_OP_SBB8_REG1632, /* sbb ([0x66] 0x83 3) */ - X86_OP_AND8_REG1632, /* and ([0x66] 0x83 4) */ - X86_OP_SUB8_REG1632, /* sub ([0x66] 0x83 5) */ - X86_OP_XOR8_REG1632, /* xor ([0x66] 0x83 6) */ + X86_OP_ADD_RM1632_IMM8, /* add ([0x66] 0x83 0) */ + X86_OP_OR_RM1632_IMM8, /* or ([0x66] 0x83 1) */ + X86_OP_ADC_RM1632_IMM8, /* adc ([0x66] 0x83 2) */ + X86_OP_SBB_RM1632_IMM8, /* sbb ([0x66] 0x83 3) */ + X86_OP_AND_RM1632_IMM8, /* and ([0x66] 0x83 4) */ + X86_OP_SUB_RM1632_IMM8, /* sub ([0x66] 0x83 5) */ + X86_OP_XOR_RM1632_IMM8, /* xor ([0x66] 0x83 6) */ X86_OP_CMP_RM1632_IMM8, /* cmp ([0x66] 0x08 7) */ - X86_OP_TEST_RM8, /* test ([0x66] 0x84) */ - X86_OP_TEST_RM1632, /* test ([0x66] 0x85) */ + X86_OP_TEST_RM8_R8, /* test ([0x66] 0x84) */ + X86_OP_TEST_RM1632_R1632, /* test ([0x66] 0x85) */ - X86_OP_MOV_REG1632, /* mov ([0x66] 0x89) */ + X86_OP_MOV_RM1632_R1632, /* mov ([0x66] 0x89) */ - X86_OP_MOV_FROM_CONTENT1632, /* mov ([0x66] 0x8b) */ + X86_OP_MOV_R1632_RM1632, /* mov ([0x66] 0x8b) */ X86_OP_LEA, /* lea ([0x66] 0x8d) */ /* 66 ? */ @@ -131,20 +138,20 @@ typedef enum _X86Opcodes X86_OP_RET, /* ret (0xc3) */ X86_OP_MOV_IMM8_TO_RM8, /* mov (0xc6) */ - X86_OP_MOV_TO_CONTENT1632, /* mov ([0x66] 0xc7) */ + X86_OP_MOV_IMM1632_TO_RM1632, /* mov ([0x66] 0xc7) */ X86_OP_LEAVE, /* leave (0xc9) */ X86_OP_INT, /* int (0xcd) */ - X86_OP_CALL, /* call (0xe8) */ + X86_OP_CALL_REL1632, /* call ([0x66] 0xe8) */ X86_OP_JMP_8, /* jmp (0xeb) */ X86_OP_HLT, /* hlt (0xf4) */ X86_OP_CALL_RM1632, /* call ([0x66] 0xff 2) */ - X86_OP_PUSH_CONTENT, /* push ([0x66] 0xff 6) */ /* 66 ? */ + X86_OP_PUSH_RM1632, /* push ([0x66] 0xff 6) */ X86_OP_COUNT diff --git a/src/arch/x86/op_adc.c b/src/arch/x86/op_adc.c index 9ff0f63..8927607 100644 --- a/src/arch/x86/op_adc.c +++ b/src/arch/x86/op_adc.c @@ -46,53 +46,23 @@ * * ******************************************************************************/ -asm_x86_instr *x86_read_instr_adc8_with_reg1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +asm_x86_instr *x86_read_instr_adc_imm8_to_rm1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) { asm_x86_instr *result; /* Instruction à retourner */ AsmOperandSize oprsize; /* Taille des opérandes */ - asm_x86_operand *reg; /* Registre de destination */ - asm_x86_operand *value; /* Valeur empilée */ result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); - /* Utilisation des registres 32 bits ? */ - if (data[*pos] == 0x66) - { - oprsize = switch_x86_operand_size(proc); - (*pos)++; - } - else oprsize = get_x86_current_operand_size(proc); + oprsize = switch_x86_operand_size_if_needed(proc, data, pos); ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; - /* TODO ! */ - if ((data[*pos] & 0xc0) != 0xc0) - return NULL; - - reg = x86_create_reg1632_operand_from_modrm(data[*pos], oprsize == AOS_32_BITS, false); - if (reg == NULL) - { - free(result); - return NULL; - } - - (*pos)++; - - value = create_new_x86_operand(); - if (!fill_imm_operand(ASM_OPERAND(value), AOS_8_BITS, data, pos, len)) + if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM1632, X86_OTP_IMM8, oprsize)) { - free(reg); - free(value); free(result); return NULL; } - ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(2, sizeof(asm_operand *)); - ASM_INSTRUCTION(result)->operands_count = 2; - - ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(reg); - ASM_INSTRUCTION(result)->operands[1] = ASM_OPERAND(value); - return result; } diff --git a/src/arch/x86/op_add.c b/src/arch/x86/op_add.c index 09abfff..52b998f 100644 --- a/src/arch/x86/op_add.c +++ b/src/arch/x86/op_add.c @@ -46,53 +46,23 @@ * * ******************************************************************************/ -asm_x86_instr *x86_read_instr_add8_with_reg1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +asm_x86_instr *x86_read_instr_add_imm8_to_rm1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) { asm_x86_instr *result; /* Instruction à retourner */ AsmOperandSize oprsize; /* Taille des opérandes */ - asm_x86_operand *reg; /* Registre de destination */ - asm_x86_operand *value; /* Valeur empilée */ result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); - /* Utilisation des registres 32 bits ? */ - if (data[*pos] == 0x66) - { - oprsize = switch_x86_operand_size(proc); - (*pos)++; - } - else oprsize = get_x86_current_operand_size(proc); + oprsize = switch_x86_operand_size_if_needed(proc, data, pos); ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; - /* TODO ! */ - if ((data[*pos] & 0xc0) != 0xc0) - return NULL; - - reg = x86_create_reg1632_operand_from_modrm(data[*pos], oprsize == AOS_32_BITS, false); - if (reg == NULL) + if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM1632, X86_OTP_IMM8, oprsize)) { free(result); return NULL; } - (*pos)++; - - value = create_new_x86_operand(); - if (!fill_imm_operand(ASM_OPERAND(value), AOS_8_BITS, data, pos, len)) - { - free(reg); - free(value); - free(result); - return NULL; - } - - ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(2, sizeof(asm_operand *)); - ASM_INSTRUCTION(result)->operands_count = 2; - - ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(reg); - ASM_INSTRUCTION(result)->operands[1] = ASM_OPERAND(value); - return result; } @@ -118,43 +88,19 @@ asm_x86_instr *x86_read_instr_add_imm1632_to_rm1632(const uint8_t *data, off_t * { asm_x86_instr *result; /* Instruction à retourner */ AsmOperandSize oprsize; /* Taille des opérandes */ - asm_x86_operand *reg; /* Registre de destination */ - asm_x86_operand *value; /* Valeur empilée */ result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); - /* Utilisation des registres 32 bits ? */ - if (data[*pos] == 0x66) - { - oprsize = switch_x86_operand_size(proc); - (*pos)++; - } - else oprsize = get_x86_current_operand_size(proc); + oprsize = switch_x86_operand_size_if_needed(proc, data, pos); ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; - reg = x86_create_rm1632_operand(data, pos, len, oprsize == AOS_32_BITS, true); - if (reg == NULL) - { - free(result); - return NULL; - } - - value = create_new_x86_operand(); - if (!fill_imm_operand(ASM_OPERAND(value), oprsize, data, pos, len)) + if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM1632, X86_OTP_IMM1632, oprsize)) { - free(reg); - free(value); free(result); return NULL; } - ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(2, sizeof(asm_operand *)); - ASM_INSTRUCTION(result)->operands_count = 2; - - ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(reg); - ASM_INSTRUCTION(result)->operands[1] = ASM_OPERAND(value); - return result; } diff --git a/src/arch/x86/op_and.c b/src/arch/x86/op_and.c index d4ad22a..3e3ba26 100644 --- a/src/arch/x86/op_and.c +++ b/src/arch/x86/op_and.c @@ -46,53 +46,23 @@ * * ******************************************************************************/ -asm_x86_instr *x86_read_instr_and8_with_reg1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +asm_x86_instr *x86_read_instr_and_rm1632_with_imm8(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) { asm_x86_instr *result; /* Instruction à retourner */ AsmOperandSize oprsize; /* Taille des opérandes */ - asm_x86_operand *reg; /* Registre de destination */ - asm_x86_operand *value; /* Valeur empilée */ result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); - /* Utilisation des registres 32 bits ? */ - if (data[*pos] == 0x66) - { - oprsize = switch_x86_operand_size(proc); - (*pos)++; - } - else oprsize = get_x86_current_operand_size(proc); + oprsize = switch_x86_operand_size_if_needed(proc, data, pos); ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; - /* TODO ! */ - if ((data[*pos] & 0xc0) != 0xc0) - return NULL; - - reg = x86_create_reg1632_operand_from_modrm(data[*pos], oprsize == AOS_32_BITS, false); - if (reg == NULL) - { - free(result); - return NULL; - } - - (*pos)++; - - value = create_new_x86_operand(); - if (!fill_imm_operand(ASM_OPERAND(value), AOS_8_BITS, data, pos, len)) + if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM1632, X86_OTP_IMM8, oprsize)) { - free(reg); - free(value); free(result); return NULL; } - ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(2, sizeof(asm_operand *)); - ASM_INSTRUCTION(result)->operands_count = 2; - - ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(reg); - ASM_INSTRUCTION(result)->operands[1] = ASM_OPERAND(value); - return result; } diff --git a/src/arch/x86/op_call.c b/src/arch/x86/op_call.c index 28964b2..980a5e7 100644 --- a/src/arch/x86/op_call.c +++ b/src/arch/x86/op_call.c @@ -46,38 +46,23 @@ * * ******************************************************************************/ -asm_x86_instr *x86_read_instr_call(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +asm_x86_instr *x86_read_instr_call_rel1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) { asm_x86_instr *result; /* Instruction à retourner */ AsmOperandSize oprsize; /* Taille des opérandes */ - asm_x86_operand *value; /* Valeur empilée */ result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); - /* Utilisation des registres 32 bits ? */ - if (data[*pos] == 0x66) - { - oprsize = switch_x86_operand_size(proc); - (*pos)++; - offset++; - } - else oprsize = get_x86_current_operand_size(proc); + oprsize = switch_x86_operand_size_if_needed(proc, data, pos); ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; - value = create_new_x86_operand(); - if (!fill_relimm_operand(ASM_OPERAND(value), oprsize, data, pos, len, ++offset)) + if (!x86_read_one_operand(result, data, pos, len, X86_OTP_REL1632, oprsize, offset)) { - free(value); free(result); return NULL; } - ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(1, sizeof(asm_operand *)); - ASM_INSTRUCTION(result)->operands_count = 1; - - ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(value); - return result; } @@ -103,33 +88,19 @@ asm_x86_instr *x86_read_instr_call_rm1632(const uint8_t *data, off_t *pos, off_t { asm_x86_instr *result; /* Instruction à retourner */ AsmOperandSize oprsize; /* Taille des opérandes */ - asm_x86_operand *reg; /* Elément à appeler */ result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); - /* Utilisation des registres 32 bits ? */ - if (data[*pos] == 0x66) - { - oprsize = switch_x86_operand_size(proc); - (*pos)++; - offset++; - } - else oprsize = get_x86_current_operand_size(proc); + oprsize = switch_x86_operand_size_if_needed(proc, data, pos); ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; - reg = x86_create_rm1632_operand(data, pos, len, oprsize == AOS_32_BITS, true); - if (reg == NULL) + if (!x86_read_one_operand(result, data, pos, len, X86_OTP_RM1632, oprsize)) { free(result); return NULL; } - ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(1, sizeof(asm_operand *)); - ASM_INSTRUCTION(result)->operands_count = 1; - - ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(reg); - return result; } diff --git a/src/arch/x86/op_cmp.c b/src/arch/x86/op_cmp.c index 9e5bcc5..5afd794 100644 --- a/src/arch/x86/op_cmp.c +++ b/src/arch/x86/op_cmp.c @@ -49,35 +49,17 @@ asm_x86_instr *x86_read_instr_cmp_rm8_with_imm8(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) { asm_x86_instr *result; /* Instruction à retourner */ - asm_x86_operand *reg; /* Registre de destination */ - asm_x86_operand *value; /* Valeur portée */ result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; - reg = x86_create_rm8_operand(data, pos, len, true); - if (reg == NULL) + if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM8, X86_OTP_IMM8)) { free(result); return NULL; } - value = create_new_x86_operand(); - if (!fill_imm_operand(ASM_OPERAND(value), AOS_8_BITS, data, pos, len)) - { - free(reg); - free(value); - free(result); - return NULL; - } - - ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(2, sizeof(asm_operand *)); - ASM_INSTRUCTION(result)->operands_count = 2; - - ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(reg); - ASM_INSTRUCTION(result)->operands[1] = ASM_OPERAND(value); - return result; } @@ -103,43 +85,19 @@ asm_x86_instr *x86_read_instr_cmp_rm1632_with_imm8(const uint8_t *data, off_t *p { asm_x86_instr *result; /* Instruction à retourner */ AsmOperandSize oprsize; /* Taille des opérandes */ - asm_x86_operand *reg; /* Registre de destination */ - asm_x86_operand *value; /* Valeur portée */ result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); - /* Utilisation des registres 32 bits ? */ - if (data[*pos] == 0x66) - { - oprsize = switch_x86_operand_size(proc); - (*pos)++; - } - else oprsize = get_x86_current_operand_size(proc); + oprsize = switch_x86_operand_size_if_needed(proc, data, pos); ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; - reg = x86_create_rm1632_operand(data, pos, len, oprsize == AOS_32_BITS, true); - if (reg == NULL) - { - free(result); - return NULL; - } - - value = create_new_x86_operand(); - if (!fill_imm_operand(ASM_OPERAND(value), AOS_8_BITS, data, pos, len)) + if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM1632, X86_OTP_IMM8, oprsize)) { - free(reg); - free(value); free(result); return NULL; } - ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(2, sizeof(asm_operand *)); - ASM_INSTRUCTION(result)->operands_count = 2; - - ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(reg); - ASM_INSTRUCTION(result)->operands[1] = ASM_OPERAND(value); - return result; } @@ -165,46 +123,19 @@ asm_x86_instr *x86_read_instr_cmp_rm1632_with_r1632(const uint8_t *data, off_t * { asm_x86_instr *result; /* Instruction à retourner */ AsmOperandSize oprsize; /* Taille des opérandes */ - off_t reg1_pos; /* POsition après lecture #1 */ - asm_x86_operand *reg1; /* Registre de destination */ - asm_x86_operand *reg2; /* Registre de source */ result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); - /* Utilisation des registres 32 bits ? */ - if (data[*pos] == 0x66) - { - oprsize = switch_x86_operand_size(proc); - (*pos)++; - } - else oprsize = get_x86_current_operand_size(proc); + oprsize = switch_x86_operand_size_if_needed(proc, data, pos); ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; - reg1_pos = *pos; - reg1 = x86_create_rm1632_operand(data, ®1_pos, len, oprsize == AOS_32_BITS, true); - if (reg1 == NULL) + if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM1632, X86_OTP_R1632, oprsize)) { free(result); return NULL; } - reg2 = x86_create_r1632_operand(data[*pos], oprsize == AOS_32_BITS, false); - if (reg2 == NULL) - { - free(result); - free(reg1); - return NULL; - } - - *pos = reg1_pos; - - ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(2, sizeof(asm_operand *)); - ASM_INSTRUCTION(result)->operands_count = 2; - - ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(reg1); - ASM_INSTRUCTION(result)->operands[1] = ASM_OPERAND(reg2); - return result; } diff --git a/src/arch/x86/op_dec.c b/src/arch/x86/op_dec.c index 2849524..dd3562e 100644 --- a/src/arch/x86/op_dec.c +++ b/src/arch/x86/op_dec.c @@ -38,7 +38,7 @@ * offset = adresse virtuelle de l'instruction. * * proc = architecture ciblée par le désassemblage. * * * -* Description : Décode une instruction de type 'inc' (16 ou 32 bits). * +* Description : Décode une instruction de type 'dec' (16 ou 32 bits). * * * * Retour : Instruction mise en place ou NULL. * * * @@ -46,36 +46,23 @@ * * ******************************************************************************/ -asm_x86_instr *x86_read_instr_dec_1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +asm_x86_instr *x86_read_instr_dec_r1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) { asm_x86_instr *result; /* Instruction à retourner */ AsmOperandSize oprsize; /* Taille des opérandes */ - asm_x86_operand *reg; /* Registre de destination */ result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); - /* Utilisation des registres 32 bits ? */ - if (data[*pos] == 0x66) - { - oprsize = switch_x86_operand_size(proc); - (*pos)++; - } - else oprsize = get_x86_current_operand_size(proc); + oprsize = switch_x86_operand_size_if_needed(proc, data, pos); ASM_INSTRUCTION(result)->opcode = data[*pos]; - reg = x86_create_reg1632_operand(data[(*pos)++], oprsize == AOS_32_BITS, 0x48); - if (reg == NULL) + if (!x86_read_one_operand(result, data, pos, len, X86_OTP_OP_R1632, oprsize, 0x48)) { free(result); return NULL; } - ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(1, sizeof(asm_operand *)); - ASM_INSTRUCTION(result)->operands_count = 1; - - ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(reg); - return result; } diff --git a/src/arch/x86/op_inc.c b/src/arch/x86/op_inc.c index 8b6326b..912d432 100644 --- a/src/arch/x86/op_inc.c +++ b/src/arch/x86/op_inc.c @@ -46,36 +46,23 @@ * * ******************************************************************************/ -asm_x86_instr *x86_read_instr_inc_1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +asm_x86_instr *x86_read_instr_inc_r1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) { asm_x86_instr *result; /* Instruction à retourner */ AsmOperandSize oprsize; /* Taille des opérandes */ - asm_x86_operand *reg; /* Registre de destination */ result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); - /* Utilisation des registres 32 bits ? */ - if (data[*pos] == 0x66) - { - oprsize = switch_x86_operand_size(proc); - (*pos)++; - } - else oprsize = get_x86_current_operand_size(proc); + oprsize = switch_x86_operand_size_if_needed(proc, data, pos); ASM_INSTRUCTION(result)->opcode = data[*pos]; - reg = x86_create_reg1632_operand(data[(*pos)++], oprsize == AOS_32_BITS, 0x40); - if (reg == NULL) + if (!x86_read_one_operand(result, data, pos, len, X86_OTP_OP_R1632, oprsize, 0x40)) { free(result); return NULL; } - ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(1, sizeof(asm_operand *)); - ASM_INSTRUCTION(result)->operands_count = 1; - - ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(reg); - return result; } diff --git a/src/arch/x86/op_int.c b/src/arch/x86/op_int.c index 6fb868a..7c2ae1d 100644 --- a/src/arch/x86/op_int.c +++ b/src/arch/x86/op_int.c @@ -49,25 +49,17 @@ asm_x86_instr *x86_read_instr_int(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) { asm_x86_instr *result; /* Instruction à retourner */ - asm_x86_operand *syscall; /* Indice de l'appel système */ result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; - syscall = create_new_x86_operand(); - if (!fill_imm_operand(ASM_OPERAND(syscall), AOS_8_BITS, data, pos, len)) + if (!x86_read_one_operand(result, data, pos, len, X86_OTP_IMM8)) { - free(syscall); free(result); return NULL; } - ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(1, sizeof(asm_operand *)); - ASM_INSTRUCTION(result)->operands_count = 1; - - ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(syscall); - return result; } diff --git a/src/arch/x86/op_jump.c b/src/arch/x86/op_jump.c index 39683c0..b301b10 100644 --- a/src/arch/x86/op_jump.c +++ b/src/arch/x86/op_jump.c @@ -49,25 +49,17 @@ asm_x86_instr *x86_read_instr_je_8(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) { asm_x86_instr *result; /* Instruction à retourner */ - asm_x86_operand *address; /* Adresse visée réelle */ result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; - /* TODO : 64bits */ - address = x86_create_rel8_operand_in_32b(offset + 1, data, pos, len); - if (address == NULL) + if (!x86_read_one_operand(result, data, pos, len, X86_OTP_REL8, offset)) { free(result); return NULL; } - ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(1, sizeof(asm_operand *)); - ASM_INSTRUCTION(result)->operands_count = 1; - - ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(address); - return result; } @@ -92,25 +84,17 @@ asm_x86_instr *x86_read_instr_je_8(const uint8_t *data, off_t *pos, off_t len, u asm_x86_instr *x86_read_instr_jne_8(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) { asm_x86_instr *result; /* Instruction à retourner */ - asm_x86_operand *address; /* Adresse visée réelle */ result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; - /* TODO : 64bits */ - address = x86_create_rel8_operand_in_32b(offset + 1, data, pos, len); - if (address == NULL) + if (!x86_read_one_operand(result, data, pos, len, X86_OTP_REL8, offset)) { free(result); return NULL; } - ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(1, sizeof(asm_operand *)); - ASM_INSTRUCTION(result)->operands_count = 1; - - ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(address); - return result; } @@ -135,25 +119,17 @@ asm_x86_instr *x86_read_instr_jne_8(const uint8_t *data, off_t *pos, off_t len, asm_x86_instr *x86_read_instr_jmp_8(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) { asm_x86_instr *result; /* Instruction à retourner */ - asm_x86_operand *address; /* Adresse visée réelle */ result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; - /* TODO : 64bits */ - address = x86_create_rel8_operand_in_32b(offset + 1, data, pos, len); - if (address == NULL) + if (!x86_read_one_operand(result, data, pos, len, X86_OTP_REL8, offset)) { free(result); return NULL; } - ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(1, sizeof(asm_operand *)); - ASM_INSTRUCTION(result)->operands_count = 1; - - ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(address); - return result; } diff --git a/src/arch/x86/op_lea.c b/src/arch/x86/op_lea.c index 96e4def..bf63818 100644 --- a/src/arch/x86/op_lea.c +++ b/src/arch/x86/op_lea.c @@ -55,13 +55,7 @@ asm_x86_instr *x86_read_instr_lea(const uint8_t *data, off_t *pos, off_t len, ui result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); - /* Utilisation des registres 32 bits ? */ - if (data[*pos] == 0x66) - { - oprsize = switch_x86_operand_size(proc); - (*pos)++; - } - else oprsize = get_x86_current_operand_size(proc); + oprsize = switch_x86_operand_size_if_needed(proc, data, pos); ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; diff --git a/src/arch/x86/op_mov.c b/src/arch/x86/op_mov.c index 8764526..01e04ff 100644 --- a/src/arch/x86/op_mov.c +++ b/src/arch/x86/op_mov.c @@ -49,34 +49,17 @@ asm_x86_instr *x86_read_instr_mov_al_to_moffs8(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) { asm_x86_instr *result; /* Instruction à retourner */ - asm_x86_operand *value; /* Valeur portée */ - asm_x86_operand *reg; /* Registre de source */ result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; - value = x86_create_moffs8_operand(data, pos, len); - if (value == NULL) + if (!x86_read_two_operands(result, data, pos, len, X86_OTP_MOFFS8, X86_OTP_AL)) { free(result); return NULL; } - reg = x86_create_r8_operand(0x00, true); - if (reg == NULL) - { - free(value); - free(result); - return NULL; - } - - ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(2, sizeof(asm_operand *)); - ASM_INSTRUCTION(result)->operands_count = 2; - - ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(value); - ASM_INSTRUCTION(result)->operands[1] = ASM_OPERAND(reg); - return result; } @@ -102,42 +85,19 @@ asm_x86_instr *x86_read_instr_mov_e_ax_to_moffs1632(const uint8_t *data, off_t * { asm_x86_instr *result; /* Instruction à retourner */ AsmOperandSize oprsize; /* Taille des opérandes */ - asm_x86_operand *value; /* Valeur portée */ - asm_x86_operand *reg; /* Registre de source */ result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); - /* Utilisation des registres 32 bits ? */ - if (data[*pos] == 0x66) - { - oprsize = switch_x86_operand_size(proc); - (*pos)++; - } - else oprsize = get_x86_current_operand_size(proc); + oprsize = switch_x86_operand_size_if_needed(proc, data, pos); ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; - value = x86_create_moffs1632_operand(data, pos, len, oprsize == AOS_32_BITS); - if (value == NULL) - { - free(result); - return NULL; - } - - reg = x86_create_r1632_operand(0x00, oprsize == AOS_32_BITS, true); - if (reg == NULL) + if (!x86_read_two_operands(result, data, pos, len, X86_OTP_MOFFS1632, X86_OTP_E_AX, oprsize)) { - free(value); free(result); return NULL; } - ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(2, sizeof(asm_operand *)); - ASM_INSTRUCTION(result)->operands_count = 2; - - ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(value); - ASM_INSTRUCTION(result)->operands[1] = ASM_OPERAND(reg); - return result; } @@ -162,35 +122,17 @@ asm_x86_instr *x86_read_instr_mov_e_ax_to_moffs1632(const uint8_t *data, off_t * asm_x86_instr *x86_read_instr_mov_imm8_to_rm8(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) { asm_x86_instr *result; /* Instruction à retourner */ - asm_x86_operand *reg; /* Registre de destination */ - asm_x86_operand *value; /* Valeur portée */ result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; - reg = x86_create_rm8_operand(data, pos, len, true); - if (reg == NULL) + if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM8, X86_OTP_IMM8)) { free(result); return NULL; } - value = create_new_x86_operand(); - if (!fill_imm_operand(ASM_OPERAND(value), AOS_8_BITS, data, pos, len)) - { - free(reg); - free(value); - free(result); - return NULL; - } - - ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(2, sizeof(asm_operand *)); - ASM_INSTRUCTION(result)->operands_count = 2; - - ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(reg); - ASM_INSTRUCTION(result)->operands[1] = ASM_OPERAND(value); - return result; } @@ -204,7 +146,7 @@ asm_x86_instr *x86_read_instr_mov_imm8_to_rm8(const uint8_t *data, off_t *pos, o * offset = adresse virtuelle de l'instruction. * * proc = architecture ciblée par le désassemblage. * * * -* Description : Décode une instruction de type 'mov al, ...' (8 bits). * +* Description : Décode une instruction de type 'mov' (16 ou 32 bits). * * * * Retour : Instruction mise en place ou NULL. * * * @@ -212,27 +154,44 @@ asm_x86_instr *x86_read_instr_mov_imm8_to_rm8(const uint8_t *data, off_t *pos, o * * ******************************************************************************/ -asm_x86_instr *x86_read_instr_mov_moffs8_to_al(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +asm_x86_instr *x86_read_instr_mov_imm1632_to_r1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) { asm_x86_instr *result; /* Instruction à retourner */ + AsmOperandSize oprsize; /* Taille des opérandes */ asm_x86_operand *reg; /* Registre de destination */ asm_x86_operand *value; /* Valeur portée */ result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); - ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; + oprsize = switch_x86_operand_size_if_needed(proc, data, pos); - reg = x86_create_r8_operand(0x00, true); + ASM_INSTRUCTION(result)->opcode = data[*pos]; + + + /* + if (!x86_read_one_operand(result, data, pos, len, X86_OTP_OP_R1632, oprsize, 0x40)) + { + free(result); + return NULL; + } + */ + + + + + + reg = x86_create_reg1632_operand(data[(*pos)++], oprsize == AOS_32_BITS, 0xb8); if (reg == NULL) { free(result); return NULL; } - value = x86_create_moffs8_operand(data, pos, len); - if (value == NULL) + value = create_new_x86_operand(); + if (!fill_imm_operand(ASM_OPERAND(value), oprsize, data, pos, len)) { free(reg); + free(value); free(result); return NULL; } @@ -256,7 +215,7 @@ asm_x86_instr *x86_read_instr_mov_moffs8_to_al(const uint8_t *data, off_t *pos, * offset = adresse virtuelle de l'instruction. * * proc = architecture ciblée par le désassemblage. * * * -* Description : Décode une instruction de type 'mov [e]ax, ...' (16/32 bits).* +* Description : Décode une instruction de type 'mov' (16 ou 32 bits). * * * * Retour : Instruction mise en place ou NULL. * * * @@ -264,57 +223,28 @@ asm_x86_instr *x86_read_instr_mov_moffs8_to_al(const uint8_t *data, off_t *pos, * * ******************************************************************************/ -asm_x86_instr *x86_read_instr_mov_moffs1632_to_e_ax(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +asm_x86_instr *x86_read_instr_mov_imm1632_to_rm1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) { asm_x86_instr *result; /* Instruction à retourner */ AsmOperandSize oprsize; /* Taille des opérandes */ - asm_x86_operand *reg; /* Registre de destination */ - asm_x86_operand *value; /* Valeur portée */ result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); - /* Utilisation des registres 32 bits ? */ - if (data[*pos] == 0x66) - { - oprsize = switch_x86_operand_size(proc); - (*pos)++; - } - else oprsize = get_x86_current_operand_size(proc); + oprsize = switch_x86_operand_size_if_needed(proc, data, pos); ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; - reg = x86_create_r1632_operand(0x00, oprsize == AOS_32_BITS, true); - if (reg == NULL) - { - free(result); - return NULL; - } - - value = x86_create_moffs1632_operand(data, pos, len, oprsize == AOS_32_BITS); - if (value == NULL) + if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM1632, X86_OTP_IMM1632, oprsize)) { - free(reg); free(result); return NULL; } - ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(2, sizeof(asm_operand *)); - ASM_INSTRUCTION(result)->operands_count = 2; - - ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(reg); - ASM_INSTRUCTION(result)->operands[1] = ASM_OPERAND(value); - return result; } - - - - - - /****************************************************************************** * * * Paramètres : data = flux de données à analyser. * @@ -323,7 +253,7 @@ asm_x86_instr *x86_read_instr_mov_moffs1632_to_e_ax(const uint8_t *data, off_t * * offset = adresse virtuelle de l'instruction. * * proc = architecture ciblée par le désassemblage. * * * -* Description : Décode une instruction de type 'mov' (16 ou 32 bits). * +* Description : Décode une instruction de type 'mov al, ...' (8 bits). * * * * Retour : Instruction mise en place ou NULL. * * * @@ -331,52 +261,20 @@ asm_x86_instr *x86_read_instr_mov_moffs1632_to_e_ax(const uint8_t *data, off_t * * * ******************************************************************************/ -asm_x86_instr *x86_read_instr_mov_with_reg1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +asm_x86_instr *x86_read_instr_mov_moffs8_to_al(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) { asm_x86_instr *result; /* Instruction à retourner */ - AsmOperandSize oprsize; /* Taille des opérandes */ - asm_x86_operand *reg2; /* Registre de source */ - asm_x86_operand *reg1; /* Registre de destination */ result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); - /* Utilisation des registres 32 bits ? */ - if (data[*pos] == 0x66) - { - oprsize = switch_x86_operand_size(proc); - (*pos)++; - } - else oprsize = get_x86_current_operand_size(proc); - ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; - reg2 = x86_create_reg1632_operand_from_modrm(data[*pos], oprsize == AOS_32_BITS, false); - if (reg2 == NULL) - { - free(result); - return NULL; - } - - if ((data[*pos] & 0xc0) == 0xc0) - { - reg1 = x86_create_reg1632_operand_from_modrm(data[*pos], oprsize == AOS_32_BITS, true); - (*pos)++; - } - else reg1 = x86_create_content1632_operand(data, pos, len, oprsize == AOS_32_BITS, true); - - if (reg1 == NULL) + if (!x86_read_two_operands(result, data, pos, len, X86_OTP_AL, X86_OTP_MOFFS8)) { free(result); - free(reg2); return NULL; } - ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(2, sizeof(asm_operand *)); - ASM_INSTRUCTION(result)->operands_count = 2; - - ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(reg1); - ASM_INSTRUCTION(result)->operands[1] = ASM_OPERAND(reg2); - return result; } @@ -390,7 +288,7 @@ asm_x86_instr *x86_read_instr_mov_with_reg1632(const uint8_t *data, off_t *pos, * offset = adresse virtuelle de l'instruction. * * proc = architecture ciblée par le désassemblage. * * * -* Description : Décode une instruction de type 'mov' (16 ou 32 bits). * +* Description : Décode une instruction de type 'mov [e]ax, ...' (16/32 bits).* * * * Retour : Instruction mise en place ou NULL. * * * @@ -398,47 +296,23 @@ asm_x86_instr *x86_read_instr_mov_with_reg1632(const uint8_t *data, off_t *pos, * * ******************************************************************************/ -asm_x86_instr *x86_read_instr_mov_to_1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +asm_x86_instr *x86_read_instr_mov_moffs1632_to_e_ax(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) { asm_x86_instr *result; /* Instruction à retourner */ AsmOperandSize oprsize; /* Taille des opérandes */ - asm_x86_operand *reg; /* Registre de destination */ - asm_x86_operand *value; /* Valeur portée */ result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); - /* Utilisation des registres 32 bits ? */ - if (data[*pos] == 0x66) - { - oprsize = switch_x86_operand_size(proc); - (*pos)++; - } - else oprsize = get_x86_current_operand_size(proc); + oprsize = switch_x86_operand_size_if_needed(proc, data, pos); - ASM_INSTRUCTION(result)->opcode = data[*pos]; + ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; - reg = x86_create_reg1632_operand(data[(*pos)++], oprsize == AOS_32_BITS, 0xb8); - if (reg == NULL) + if (!x86_read_two_operands(result, data, pos, len, X86_OTP_E_AX, X86_OTP_MOFFS1632, oprsize)) { free(result); return NULL; } - value = create_new_x86_operand(); - if (!fill_imm_operand(ASM_OPERAND(value), oprsize, data, pos, len)) - { - free(reg); - free(value); - free(result); - return NULL; - } - - ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(2, sizeof(asm_operand *)); - ASM_INSTRUCTION(result)->operands_count = 2; - - ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(reg); - ASM_INSTRUCTION(result)->operands[1] = ASM_OPERAND(value); - return result; } @@ -460,46 +334,23 @@ asm_x86_instr *x86_read_instr_mov_to_1632(const uint8_t *data, off_t *pos, off_t * * ******************************************************************************/ -asm_x86_instr *x86_read_instr_mov_from_content_1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +asm_x86_instr *x86_read_instr_mov_r1632_to_rm1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) { asm_x86_instr *result; /* Instruction à retourner */ AsmOperandSize oprsize; /* Taille des opérandes */ - asm_x86_operand *reg1; /* Registre de destination */ - asm_x86_operand *reg2; /* Registre de source */ result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); - /* Utilisation des registres 32 bits ? */ - if (data[*pos] == 0x66) - { - oprsize = switch_x86_operand_size(proc); - (*pos)++; - } - else oprsize = get_x86_current_operand_size(proc); + oprsize = switch_x86_operand_size_if_needed(proc, data, pos); ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; - reg1 = x86_create_reg1632_operand_from_modrm(data[*pos], oprsize == AOS_32_BITS, false); - if (reg1 == NULL) - { - free(result); - return NULL; - } - - reg2 = x86_create_content1632_operand(data, pos, len, oprsize == AOS_32_BITS, true); - if (reg2 == NULL) + if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM1632, X86_OTP_R1632, oprsize)) { free(result); - free(reg1); return NULL; } - ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(2, sizeof(asm_operand *)); - ASM_INSTRUCTION(result)->operands_count = 2; - - ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(reg1); - ASM_INSTRUCTION(result)->operands[1] = ASM_OPERAND(reg2); - return result; } @@ -521,47 +372,23 @@ asm_x86_instr *x86_read_instr_mov_from_content_1632(const uint8_t *data, off_t * * * ******************************************************************************/ -asm_x86_instr *x86_read_instr_mov_to_content_1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +asm_x86_instr *x86_read_instr_mov_rm1632_to_r1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) { asm_x86_instr *result; /* Instruction à retourner */ AsmOperandSize oprsize; /* Taille des opérandes */ - asm_x86_operand *reg; /* Registre de destination */ - asm_x86_operand *value; /* Valeur portée */ result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); - /* Utilisation des registres 32 bits ? */ - if (data[*pos] == 0x66) - { - oprsize = switch_x86_operand_size(proc); - (*pos)++; - } - else oprsize = get_x86_current_operand_size(proc); + oprsize = switch_x86_operand_size_if_needed(proc, data, pos); ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; - reg = x86_create_content1632_operand(data, pos, len, oprsize == AOS_32_BITS, true); - if (reg == NULL) - { - free(result); - return NULL; - } - - value = create_new_x86_operand(); - if (!fill_imm_operand(ASM_OPERAND(value), oprsize, data, pos, len)) + if (!x86_read_two_operands(result, data, pos, len, X86_OTP_R1632, X86_OTP_RM1632, oprsize)) { - free(reg); - free(value); free(result); return NULL; } - ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(2, sizeof(asm_operand *)); - ASM_INSTRUCTION(result)->operands_count = 2; - - ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(reg); - ASM_INSTRUCTION(result)->operands[1] = ASM_OPERAND(value); - return result; } diff --git a/src/arch/x86/op_or.c b/src/arch/x86/op_or.c index dfd02c6..0dd7cf3 100644 --- a/src/arch/x86/op_or.c +++ b/src/arch/x86/op_or.c @@ -46,53 +46,23 @@ * * ******************************************************************************/ -asm_x86_instr *x86_read_instr_or8_with_reg1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +asm_x86_instr *x86_read_instr_or_rm1632_with_imm8(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) { asm_x86_instr *result; /* Instruction à retourner */ AsmOperandSize oprsize; /* Taille des opérandes */ - asm_x86_operand *reg; /* Registre de destination */ - asm_x86_operand *value; /* Valeur empilée */ result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); - /* Utilisation des registres 32 bits ? */ - if (data[*pos] == 0x66) - { - oprsize = switch_x86_operand_size(proc); - (*pos)++; - } - else oprsize = get_x86_current_operand_size(proc); + oprsize = switch_x86_operand_size_if_needed(proc, data, pos); ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; - /* TODO ! */ - if ((data[*pos] & 0xc0) != 0xc0) - return NULL; - - reg = x86_create_reg1632_operand_from_modrm(data[*pos], oprsize == AOS_32_BITS, false); - if (reg == NULL) - { - free(result); - return NULL; - } - - (*pos)++; - - value = create_new_x86_operand(); - if (!fill_imm_operand(ASM_OPERAND(value), AOS_8_BITS, data, pos, len)) + if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM1632, X86_OTP_IMM8, oprsize)) { - free(reg); - free(value); free(result); return NULL; } - ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(2, sizeof(asm_operand *)); - ASM_INSTRUCTION(result)->operands_count = 2; - - ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(reg); - ASM_INSTRUCTION(result)->operands[1] = ASM_OPERAND(value); - return result; } diff --git a/src/arch/x86/op_pop.c b/src/arch/x86/op_pop.c index 891985c..ab0d278 100644 --- a/src/arch/x86/op_pop.c +++ b/src/arch/x86/op_pop.c @@ -46,36 +46,23 @@ * * ******************************************************************************/ -asm_x86_instr *x86_read_instr_pop_reg1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +asm_x86_instr *x86_read_instr_pop_r1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) { asm_x86_instr *result; /* Instruction à retourner */ AsmOperandSize oprsize; /* Taille des opérandes */ - asm_x86_operand *reg; /* Registre de destination */ result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); - /* Utilisation des registres 32 bits ? */ - if (data[*pos] == 0x66) - { - oprsize = switch_x86_operand_size(proc); - (*pos)++; - } - else oprsize = get_x86_current_operand_size(proc); + oprsize = switch_x86_operand_size_if_needed(proc, data, pos); ASM_INSTRUCTION(result)->opcode = data[*pos]; - reg = x86_create_reg1632_operand(data[(*pos)++], oprsize == AOS_32_BITS, 0x58); - if (reg == NULL) + if (!x86_read_one_operand(result, data, pos, len, X86_OTP_OP_R1632, oprsize, 0x58)) { free(result); return NULL; } - ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(1, sizeof(asm_operand *)); - ASM_INSTRUCTION(result)->operands_count = 1; - - ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(reg); - return result; } diff --git a/src/arch/x86/op_push.c b/src/arch/x86/op_push.c index 153c70d..ce76919 100644 --- a/src/arch/x86/op_push.c +++ b/src/arch/x86/op_push.c @@ -47,36 +47,23 @@ * * ******************************************************************************/ -asm_x86_instr *x86_read_instr_push_content(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +asm_x86_instr *x86_read_instr_push_imm1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) { asm_x86_instr *result; /* Instruction à retourner */ AsmOperandSize oprsize; /* Taille des opérandes */ - asm_x86_operand *content; /* Registre de source */ result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); - /* Utilisation des registres 32 bits ? */ - if (data[*pos] == 0x66) - { - oprsize = switch_x86_operand_size(proc); - (*pos)++; - } - else oprsize = get_x86_current_operand_size(proc); + oprsize = switch_x86_operand_size_if_needed(proc, data, pos); ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; - content = x86_create_content1632_operand(data, pos, len, oprsize == AOS_32_BITS, true); - if (content == NULL) + if (!x86_read_one_operand(result, data, pos, len, X86_OTP_IMM1632, oprsize)) { free(result); return NULL; } - ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(1, sizeof(asm_operand *)); - ASM_INSTRUCTION(result)->operands_count = 1; - - ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(content); - return result; } @@ -98,37 +85,23 @@ asm_x86_instr *x86_read_instr_push_content(const uint8_t *data, off_t *pos, off_ * * ******************************************************************************/ -asm_x86_instr *x86_read_instr_push_imm1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +asm_x86_instr *x86_read_instr_push_r1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) { asm_x86_instr *result; /* Instruction à retourner */ AsmOperandSize oprsize; /* Taille des opérandes */ - asm_x86_operand *value; /* Valeur empilée */ result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); - /* Utilisation des registres 32 bits ? */ - if (data[*pos] == 0x66) - { - oprsize = switch_x86_operand_size(proc); - (*pos)++; - } - else oprsize = get_x86_current_operand_size(proc); + oprsize = switch_x86_operand_size_if_needed(proc, data, pos); - ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; + ASM_INSTRUCTION(result)->opcode = data[*pos]; - value = create_new_x86_operand(); - if (!fill_imm_operand(ASM_OPERAND(value), oprsize, data, pos, len)) + if (!x86_read_one_operand(result, data, pos, len, X86_OTP_OP_R1632, oprsize, 0x50)) { - free(value); free(result); return NULL; } - ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(1, sizeof(asm_operand *)); - ASM_INSTRUCTION(result)->operands_count = 1; - - ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(value); - return result; } @@ -150,36 +123,23 @@ asm_x86_instr *x86_read_instr_push_imm1632(const uint8_t *data, off_t *pos, off_ * * ******************************************************************************/ -asm_x86_instr *x86_read_instr_push_reg1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +asm_x86_instr *x86_read_instr_push_rm1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) { asm_x86_instr *result; /* Instruction à retourner */ AsmOperandSize oprsize; /* Taille des opérandes */ - asm_x86_operand *reg; /* Registre de destination */ result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); - /* Utilisation des registres 32 bits ? */ - if (data[*pos] == 0x66) - { - oprsize = switch_x86_operand_size(proc); - (*pos)++; - } - else oprsize = get_x86_current_operand_size(proc); + oprsize = switch_x86_operand_size_if_needed(proc, data, pos); - ASM_INSTRUCTION(result)->opcode = data[*pos]; + ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; - reg = x86_create_reg1632_operand(data[(*pos)++], oprsize == AOS_32_BITS, 0x50); - if (reg == NULL) + if (!x86_read_one_operand(result, data, pos, len, X86_OTP_RM1632, oprsize)) { free(result); return NULL; } - ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(1, sizeof(asm_operand *)); - ASM_INSTRUCTION(result)->operands_count = 1; - - ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(reg); - return result; } diff --git a/src/arch/x86/op_sar.c b/src/arch/x86/op_sar.c index 187c2bb..70b57c9 100644 --- a/src/arch/x86/op_sar.c +++ b/src/arch/x86/op_sar.c @@ -50,43 +50,19 @@ asm_x86_instr *x86_read_instr_sar_rm1632_with_imm8(const uint8_t *data, off_t *p { asm_x86_instr *result; /* Instruction à retourner */ AsmOperandSize oprsize; /* Taille des opérandes */ - asm_x86_operand *reg; /* Registre de destination */ - asm_x86_operand *value; /* Valeur portée */ result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); - /* Utilisation des registres 32 bits ? */ - if (data[*pos] == 0x66) - { - oprsize = switch_x86_operand_size(proc); - (*pos)++; - } - else oprsize = get_x86_current_operand_size(proc); + oprsize = switch_x86_operand_size_if_needed(proc, data, pos); ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; - reg = x86_create_rm1632_operand(data, pos, len, oprsize == AOS_32_BITS, true); - if (reg == NULL) + if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM1632, X86_OTP_IMM8, oprsize)) { free(result); return NULL; } - value = create_new_x86_operand(); - if (!fill_imm_operand(ASM_OPERAND(value), AOS_8_BITS, data, pos, len)) - { - free(reg); - free(value); - free(result); - return NULL; - } - - ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(2, sizeof(asm_operand *)); - ASM_INSTRUCTION(result)->operands_count = 2; - - ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(reg); - ASM_INSTRUCTION(result)->operands[1] = ASM_OPERAND(value); - return result; } diff --git a/src/arch/x86/op_sbb.c b/src/arch/x86/op_sbb.c index b712320..eba4e04 100644 --- a/src/arch/x86/op_sbb.c +++ b/src/arch/x86/op_sbb.c @@ -46,53 +46,23 @@ * * ******************************************************************************/ -asm_x86_instr *x86_read_instr_sbb8_with_reg1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +asm_x86_instr *x86_read_instr_sbb_rm1632_with_imm8(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) { asm_x86_instr *result; /* Instruction à retourner */ AsmOperandSize oprsize; /* Taille des opérandes */ - asm_x86_operand *reg; /* Registre de destination */ - asm_x86_operand *value; /* Valeur empilée */ result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); - /* Utilisation des registres 32 bits ? */ - if (data[*pos] == 0x66) - { - oprsize = switch_x86_operand_size(proc); - (*pos)++; - } - else oprsize = get_x86_current_operand_size(proc); + oprsize = switch_x86_operand_size_if_needed(proc, data, pos); ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; - /* TODO ! */ - if ((data[*pos] & 0xc0) != 0xc0) - return NULL; - - reg = x86_create_reg1632_operand_from_modrm(data[*pos], oprsize == AOS_32_BITS, false); - if (reg == NULL) - { - free(result); - return NULL; - } - - (*pos)++; - - value = create_new_x86_operand(); - if (!fill_imm_operand(ASM_OPERAND(value), AOS_8_BITS, data, pos, len)) + if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM1632, X86_OTP_IMM8, oprsize)) { - free(reg); - free(value); free(result); return NULL; } - ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(2, sizeof(asm_operand *)); - ASM_INSTRUCTION(result)->operands_count = 2; - - ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(reg); - ASM_INSTRUCTION(result)->operands[1] = ASM_OPERAND(value); - return result; } diff --git a/src/arch/x86/op_sub.c b/src/arch/x86/op_sub.c index 18d8dce..7c282cc 100644 --- a/src/arch/x86/op_sub.c +++ b/src/arch/x86/op_sub.c @@ -46,53 +46,23 @@ * * ******************************************************************************/ -asm_x86_instr *x86_read_instr_sub8_with_reg1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +asm_x86_instr *x86_read_instr_sub_imm8_from_rm1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) { asm_x86_instr *result; /* Instruction à retourner */ AsmOperandSize oprsize; /* Taille des opérandes */ - asm_x86_operand *reg; /* Registre de destination */ - asm_x86_operand *value; /* Valeur empilée */ result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); - /* Utilisation des registres 32 bits ? */ - if (data[*pos] == 0x66) - { - oprsize = switch_x86_operand_size(proc); - (*pos)++; - } - else oprsize = get_x86_current_operand_size(proc); + oprsize = switch_x86_operand_size_if_needed(proc, data, pos); ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; - /* TODO ! */ - if ((data[*pos] & 0xc0) != 0xc0) - return NULL; - - reg = x86_create_reg1632_operand_from_modrm(data[*pos], oprsize == AOS_32_BITS, false); - if (reg == NULL) + if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM1632, X86_OTP_IMM8, oprsize)) { free(result); return NULL; } - (*pos)++; - - value = create_new_x86_operand(); - if (!fill_imm_operand(ASM_OPERAND(value), AOS_8_BITS, data, pos, len)) - { - free(reg); - free(value); - free(result); - return NULL; - } - - ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(2, sizeof(asm_operand *)); - ASM_INSTRUCTION(result)->operands_count = 2; - - ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(reg); - ASM_INSTRUCTION(result)->operands[1] = ASM_OPERAND(value); - return result; } @@ -114,50 +84,23 @@ asm_x86_instr *x86_read_instr_sub8_with_reg1632(const uint8_t *data, off_t *pos, * * ******************************************************************************/ -asm_x86_instr *x86_read_instr_sub_r1632_to_rm1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +asm_x86_instr *x86_read_instr_sub_r1632_from_rm1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) { asm_x86_instr *result; /* Instruction à retourner */ AsmOperandSize oprsize; /* Taille des opérandes */ - off_t reg1_pos; /* POsition après lecture #1 */ - asm_x86_operand *reg1; /* Registre de destination */ - asm_x86_operand *reg2; /* Registre de source */ result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); - /* Utilisation des registres 32 bits ? */ - if (data[*pos] == 0x66) - { - oprsize = switch_x86_operand_size(proc); - (*pos)++; - } - else oprsize = get_x86_current_operand_size(proc); + oprsize = switch_x86_operand_size_if_needed(proc, data, pos); ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; - reg1_pos = *pos; - reg1 = x86_create_rm1632_operand(data, ®1_pos, len, oprsize == AOS_32_BITS, true); - if (reg1 == NULL) + if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM1632, X86_OTP_R1632, oprsize)) { free(result); return NULL; } - reg2 = x86_create_r1632_operand(data[*pos], oprsize == AOS_32_BITS, false); - if (reg2 == NULL) - { - free(result); - free(reg1); - return NULL; - } - - *pos = reg1_pos; - - ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(2, sizeof(asm_operand *)); - ASM_INSTRUCTION(result)->operands_count = 2; - - ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(reg1); - ASM_INSTRUCTION(result)->operands[1] = ASM_OPERAND(reg2); - return result; } diff --git a/src/arch/x86/op_test.c b/src/arch/x86/op_test.c index aa80787..1d8d18a 100644 --- a/src/arch/x86/op_test.c +++ b/src/arch/x86/op_test.c @@ -49,35 +49,17 @@ asm_x86_instr *x86_read_instr_test_al(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) { asm_x86_instr *result; /* Instruction à retourner */ - asm_x86_operand *reg; /* Registre de destination */ - asm_x86_operand *value; /* Valeur portée */ result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; - reg = x86_create_r8_operand(0x00, true); - if (reg == NULL) + if (!x86_read_two_operands(result, data, pos, len, X86_OTP_AL, X86_OTP_IMM8)) { free(result); return NULL; } - value = create_new_x86_operand(); - if (!fill_imm_operand(ASM_OPERAND(value), AOS_8_BITS, data, pos, len)) - { - free(reg); - free(value); - free(result); - return NULL; - } - - ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(2, sizeof(asm_operand *)); - ASM_INSTRUCTION(result)->operands_count = 2; - - ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(reg); - ASM_INSTRUCTION(result)->operands[1] = ASM_OPERAND(value); - return result; } @@ -103,43 +85,19 @@ asm_x86_instr *x86_read_instr_test_e_ax(const uint8_t *data, off_t *pos, off_t l { asm_x86_instr *result; /* Instruction à retourner */ AsmOperandSize oprsize; /* Taille des opérandes */ - asm_x86_operand *reg; /* Registre de destination */ - asm_x86_operand *value; /* Valeur portée */ result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); - /* Utilisation des registres 32 bits ? */ - if (data[*pos] == 0x66) - { - oprsize = switch_x86_operand_size(proc); - (*pos)++; - } - else oprsize = get_x86_current_operand_size(proc); + oprsize = switch_x86_operand_size_if_needed(proc, data, pos); ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; - reg = x86_create_r1632_operand(0x00, oprsize == AOS_32_BITS, true); - if (reg == NULL) + if (!x86_read_two_operands(result, data, pos, len, X86_OTP_E_AX, X86_OTP_IMM1632, oprsize)) { free(result); return NULL; } - value = create_new_x86_operand(); - if (!fill_imm_operand(ASM_OPERAND(value), oprsize, data, pos, len)) - { - free(reg); - free(value); - free(result); - return NULL; - } - - ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(2, sizeof(asm_operand *)); - ASM_INSTRUCTION(result)->operands_count = 2; - - ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(reg); - ASM_INSTRUCTION(result)->operands[1] = ASM_OPERAND(value); - return result; } @@ -161,41 +119,20 @@ asm_x86_instr *x86_read_instr_test_e_ax(const uint8_t *data, off_t *pos, off_t l * * ******************************************************************************/ -asm_x86_instr *x86_read_instr_test_rm8(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +asm_x86_instr *x86_read_instr_test_rm8_with_r8(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) { asm_x86_instr *result; /* Instruction à retourner */ - off_t reg1_pos; /* POsition après lecture #1 */ - asm_x86_operand *reg1; /* Registre de destination */ - asm_x86_operand *reg2; /* Registre de source */ result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; - reg1_pos = *pos; - reg1 = x86_create_rm8_operand(data, ®1_pos, len, true); - if (reg1 == NULL) - { - free(result); - return NULL; - } - - reg2 = x86_create_r8_operand(data[*pos], false); - if (reg2 == NULL) + if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM8, X86_OTP_R8)) { free(result); - free(reg1); return NULL; } - *pos = reg1_pos; - - ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(2, sizeof(asm_operand *)); - ASM_INSTRUCTION(result)->operands_count = 2; - - ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(reg1); - ASM_INSTRUCTION(result)->operands[1] = ASM_OPERAND(reg2); - return result; } @@ -217,50 +154,23 @@ asm_x86_instr *x86_read_instr_test_rm8(const uint8_t *data, off_t *pos, off_t le * * ******************************************************************************/ -asm_x86_instr *x86_read_instr_test_rm1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +asm_x86_instr *x86_read_instr_test_rm1632_with_r1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) { asm_x86_instr *result; /* Instruction à retourner */ AsmOperandSize oprsize; /* Taille des opérandes */ - off_t reg1_pos; /* POsition après lecture #1 */ - asm_x86_operand *reg1; /* Registre de destination */ - asm_x86_operand *reg2; /* Registre de source */ result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); - /* Utilisation des registres 32 bits ? */ - if (data[*pos] == 0x66) - { - oprsize = switch_x86_operand_size(proc); - (*pos)++; - } - else oprsize = get_x86_current_operand_size(proc); + oprsize = switch_x86_operand_size_if_needed(proc, data, pos); ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; - reg1_pos = *pos; - reg1 = x86_create_rm1632_operand(data, ®1_pos, len, oprsize == AOS_32_BITS, true); - if (reg1 == NULL) + if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM1632, X86_OTP_R1632, oprsize)) { free(result); return NULL; } - reg2 = x86_create_r1632_operand(data[*pos], oprsize == AOS_32_BITS, false); - if (reg2 == NULL) - { - free(result); - free(reg1); - return NULL; - } - - *pos = reg1_pos; - - ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(2, sizeof(asm_operand *)); - ASM_INSTRUCTION(result)->operands_count = 2; - - ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(reg1); - ASM_INSTRUCTION(result)->operands[1] = ASM_OPERAND(reg2); - return result; } diff --git a/src/arch/x86/op_xor.c b/src/arch/x86/op_xor.c index 0f23f26..8d44f9c 100644 --- a/src/arch/x86/op_xor.c +++ b/src/arch/x86/op_xor.c @@ -38,7 +38,7 @@ * offset = adresse virtuelle de l'instruction. * * proc = architecture ciblée par le désassemblage. * * * -* Description : Décode une instruction de type 'xor' (16 ou 32 bits). * +* Description : Décode une instruction de type 'xor al, ...' (8 bits). * * * * Retour : Instruction mise en place ou NULL. * * * @@ -46,51 +46,168 @@ * * ******************************************************************************/ -asm_x86_instr *x86_read_instr_xor_with_reg1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +asm_x86_instr *x86_read_instr_xor_al_with_imm8(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) { asm_x86_instr *result; /* Instruction à retourner */ - AsmOperandSize oprsize; /* Taille des opérandes */ - asm_x86_operand *reg2; /* Registre de source */ - asm_x86_operand *reg1; /* Registre de destination */ result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); - /* Utilisation des registres 32 bits ? */ - if (data[*pos] == 0x66) + ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; + + if (!x86_read_two_operands(result, data, pos, len, X86_OTP_AL, X86_OTP_IMM8)) { - oprsize = switch_x86_operand_size(proc); - (*pos)++; + free(result); + return NULL; } - else oprsize = get_x86_current_operand_size(proc); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* offset = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'xor [e]ax, ...' (16/32 bits).* +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +asm_x86_instr *x86_read_instr_xor_e_ax_with_imm1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +{ + asm_x86_instr *result; /* Instruction à retourner */ + AsmOperandSize oprsize; /* Taille des opérandes */ + + result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); + + oprsize = switch_x86_operand_size_if_needed(proc, data, pos); ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; - /* TODO ! */ - if ((data[*pos] & 0xc0) != 0xc0) + if (!x86_read_two_operands(result, data, pos, len, X86_OTP_E_AX, X86_OTP_IMM1632, oprsize)) + { + free(result); return NULL; + } + + return result; - reg1 = x86_create_reg1632_operand_from_modrm(data[*pos], oprsize == AOS_32_BITS, true); - if (reg1 == NULL) +} + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* offset = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'xor' (8 bits). * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +asm_x86_instr *x86_read_instr_xor_rm8_with_imm8(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +{ + asm_x86_instr *result; /* Instruction à retourner */ + AsmOperandSize oprsize; /* Taille des opérandes */ + + result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); + + oprsize = switch_x86_operand_size_if_needed(proc, data, pos); + + ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; + + if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM8, X86_OTP_IMM8, oprsize)) { free(result); return NULL; } - reg2 = x86_create_reg1632_operand_from_modrm(data[*pos], oprsize == AOS_32_BITS, false); - if (reg2 == NULL) + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* offset = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'xor' (16 ou 32 bits). * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +asm_x86_instr *x86_read_instr_xor_rm1632_with_imm1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +{ + asm_x86_instr *result; /* Instruction à retourner */ + AsmOperandSize oprsize; /* Taille des opérandes */ + + result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); + + oprsize = switch_x86_operand_size_if_needed(proc, data, pos); + + ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; + + if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM1632, X86_OTP_IMM1632, oprsize)) { free(result); - free(reg1); return NULL; } - (*pos)++; + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* offset = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'xor' (8 bits). * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +asm_x86_instr *x86_read_instr_xor_r8_with_rm8(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +{ + asm_x86_instr *result; /* Instruction à retourner */ + + result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); - ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(2, sizeof(asm_operand *)); - ASM_INSTRUCTION(result)->operands_count = 2; + ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; - ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(reg1); - ASM_INSTRUCTION(result)->operands[1] = ASM_OPERAND(reg2); + if (!x86_read_two_operands(result, data, pos, len, X86_OTP_R8, X86_OTP_RM8)) + { + free(result); + return NULL; + } return result; @@ -113,52 +230,133 @@ asm_x86_instr *x86_read_instr_xor_with_reg1632(const uint8_t *data, off_t *pos, * * ******************************************************************************/ -asm_x86_instr *x86_read_instr_xor8_with_reg1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +asm_x86_instr *x86_read_instr_xor_r1632_with_rm1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) { asm_x86_instr *result; /* Instruction à retourner */ AsmOperandSize oprsize; /* Taille des opérandes */ - asm_x86_operand *reg; /* Registre de destination */ - asm_x86_operand *value; /* Valeur empilée */ result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); - /* Utilisation des registres 32 bits ? */ - if (data[*pos] == 0x66) - { - oprsize = switch_x86_operand_size(proc); - (*pos)++; - } - else oprsize = get_x86_current_operand_size(proc); + oprsize = switch_x86_operand_size_if_needed(proc, data, pos); ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; - /* TODO ! */ - if ((data[*pos] & 0xc0) != 0xc0) + if (!x86_read_two_operands(result, data, pos, len, X86_OTP_R1632, X86_OTP_RM1632, oprsize)) + { + free(result); return NULL; + } + + return result; + +} + - reg = x86_create_reg1632_operand_from_modrm(data[*pos], oprsize == AOS_32_BITS, false); - if (reg == NULL) +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* offset = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'xor' (8 bits). * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +asm_x86_instr *x86_read_instr_xor_rm8_with_r8(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +{ + asm_x86_instr *result; /* Instruction à retourner */ + + result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); + + ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; + + if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM8, X86_OTP_R8)) { free(result); return NULL; } - (*pos)++; + return result; - value = create_new_x86_operand(); - if (!fill_imm_operand(ASM_OPERAND(value), AOS_8_BITS, data, pos, len)) +} + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* offset = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'xor' (16 ou 32 bits). * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +asm_x86_instr *x86_read_instr_xor_rm1632_with_imm8(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +{ + asm_x86_instr *result; /* Instruction à retourner */ + AsmOperandSize oprsize; /* Taille des opérandes */ + + result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); + + oprsize = switch_x86_operand_size_if_needed(proc, data, pos); + + ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; + + if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM1632, X86_OTP_IMM8, oprsize)) { - free(reg); - free(value); free(result); return NULL; } - ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(2, sizeof(asm_operand *)); - ASM_INSTRUCTION(result)->operands_count = 2; + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* offset = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'xor' (16 ou 32 bits). * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +asm_x86_instr *x86_read_instr_xor_rm1632_with_r1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +{ + asm_x86_instr *result; /* Instruction à retourner */ + AsmOperandSize oprsize; /* Taille des opérandes */ + + result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); + + oprsize = switch_x86_operand_size_if_needed(proc, data, pos); - ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(reg); - ASM_INSTRUCTION(result)->operands[1] = ASM_OPERAND(value); + ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; + + if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM1632, X86_OTP_R1632, oprsize)) + { + free(result); + return NULL; + } return result; diff --git a/src/arch/x86/opcodes.h b/src/arch/x86/opcodes.h index 07d51e9..cbadcf5 100644 --- a/src/arch/x86/opcodes.h +++ b/src/arch/x86/opcodes.h @@ -35,19 +35,19 @@ /* Décode une instruction de type 'adc' (16 ou 32 bits). */ -asm_x86_instr *x86_read_instr_adc8_with_reg1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); +asm_x86_instr *x86_read_instr_adc_imm8_to_rm1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); /* Décode une instruction de type 'add' (16 ou 32 bits). */ -asm_x86_instr *x86_read_instr_add8_with_reg1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); +asm_x86_instr *x86_read_instr_add_imm8_to_rm1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); /* Décode une instruction de type 'add' (16 ou 32 bits). */ asm_x86_instr *x86_read_instr_add_imm1632_to_rm1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); /* Décode une instruction de type 'and' (16 ou 32 bits). */ -asm_x86_instr *x86_read_instr_and8_with_reg1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); +asm_x86_instr *x86_read_instr_and_rm1632_with_imm8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); /* Décode une instruction de type 'call'. */ -asm_x86_instr *x86_read_instr_call(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); +asm_x86_instr *x86_read_instr_call_rel1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); /* Décode une instruction de type 'call' (16 ou 32 bits). */ asm_x86_instr *x86_read_instr_call_rm1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); @@ -62,13 +62,13 @@ asm_x86_instr *x86_read_instr_cmp_rm1632_with_imm8(const uint8_t *, off_t *, off asm_x86_instr *x86_read_instr_cmp_rm1632_with_r1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); /* Décode une instruction de type 'dec'. */ -asm_x86_instr *x86_read_instr_dec_1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); +asm_x86_instr *x86_read_instr_dec_r1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); /* Décode une instruction de type 'hlt'. */ asm_x86_instr *x86_read_instr_hlt(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); /* Décode une instruction de type 'inc'. */ -asm_x86_instr *x86_read_instr_inc_1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); +asm_x86_instr *x86_read_instr_inc_r1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); /* Décode une instruction de type 'int'. */ asm_x86_instr *x86_read_instr_int(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); @@ -97,6 +97,12 @@ asm_x86_instr *x86_read_instr_mov_e_ax_to_moffs1632(const uint8_t *, off_t *, of /* Décode une instruction de type 'mov' (8 bits). */ asm_x86_instr *x86_read_instr_mov_imm8_to_rm8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); +/* Décode une instruction de type 'mov' (16 ou 32 bits). */ +asm_x86_instr *x86_read_instr_mov_imm1632_to_r1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); + +/* Décode une instruction de type 'mov' (16 ou 32 bits). */ +asm_x86_instr *x86_read_instr_mov_imm1632_to_rm1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); + /* Décode une instruction de type 'mov al, ...' (8 bits). */ asm_x86_instr *x86_read_instr_mov_moffs8_to_al(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); @@ -104,34 +110,28 @@ asm_x86_instr *x86_read_instr_mov_moffs8_to_al(const uint8_t *, off_t *, off_t, asm_x86_instr *x86_read_instr_mov_moffs1632_to_e_ax(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); /* Décode une instruction de type 'mov' (16 ou 32 bits). */ -asm_x86_instr *x86_read_instr_mov_from_content_1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); - -/* Décode une instruction de type 'mov' (16 ou 32 bits). */ -asm_x86_instr *x86_read_instr_mov_to_1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); - -/* Décode une instruction de type 'mov' (16 ou 32 bits). */ -asm_x86_instr *x86_read_instr_mov_to_content_1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); +asm_x86_instr *x86_read_instr_mov_r1632_to_rm1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); /* Décode une instruction de type 'mov' (16 ou 32 bits). */ -asm_x86_instr *x86_read_instr_mov_with_reg1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); +asm_x86_instr *x86_read_instr_mov_rm1632_to_r1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); /* Décode une instruction de type 'nop'. */ asm_x86_instr *x86_read_instr_nop(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); /* Décode une instruction de type 'or' (16 ou 32 bits). */ -asm_x86_instr *x86_read_instr_or8_with_reg1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); +asm_x86_instr *x86_read_instr_or_rm1632_with_imm8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); /* Décode une instruction de type 'pop' (16 ou 32 bits). */ -asm_x86_instr *x86_read_instr_pop_reg1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); +asm_x86_instr *x86_read_instr_pop_r1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); /* Décode une instruction de type 'push' (16 ou 32 bits). */ -asm_x86_instr *x86_read_instr_push_content(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); +asm_x86_instr *x86_read_instr_push_imm1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); /* Décode une instruction de type 'push' (16 ou 32 bits). */ -asm_x86_instr *x86_read_instr_push_imm1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); +asm_x86_instr *x86_read_instr_push_r1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); /* Décode une instruction de type 'push' (16 ou 32 bits). */ -asm_x86_instr *x86_read_instr_push_reg1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); +asm_x86_instr *x86_read_instr_push_rm1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); /* Décode une instruction de type 'ret'. */ asm_x86_instr *x86_read_instr_ret(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); @@ -140,13 +140,13 @@ asm_x86_instr *x86_read_instr_ret(const uint8_t *, off_t *, off_t, uint64_t, con asm_x86_instr *x86_read_instr_sar_rm1632_with_imm8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); /* Décode une instruction de type 'sbb'. */ -asm_x86_instr *x86_read_instr_sbb8_with_reg1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); +asm_x86_instr *x86_read_instr_sbb_rm1632_with_imm8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); /* Décode une instruction de type 'sub'. */ -asm_x86_instr *x86_read_instr_sub8_with_reg1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); +asm_x86_instr *x86_read_instr_sub_imm8_from_rm1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); /* Décode une instruction de type 'sub' (16 ou 32 bits). */ -asm_x86_instr *x86_read_instr_sub_r1632_to_rm1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); +asm_x86_instr *x86_read_instr_sub_r1632_from_rm1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); /* Décode une instruction de type 'test al, ...' (8 bits). */ asm_x86_instr *x86_read_instr_test_al(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); @@ -155,16 +155,37 @@ asm_x86_instr *x86_read_instr_test_al(const uint8_t *, off_t *, off_t, uint64_t, asm_x86_instr *x86_read_instr_test_e_ax(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); /* Décode une instruction de type 'test' (8 bits). */ -asm_x86_instr *x86_read_instr_test_rm8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); +asm_x86_instr *x86_read_instr_test_rm8_with_r8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); /* Décode une instruction de type 'test' (16 ou 32 bits). */ -asm_x86_instr *x86_read_instr_test_rm1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); +asm_x86_instr *x86_read_instr_test_rm1632_with_r1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); + +/* Décode une instruction de type 'xor al, ...' (8 bits). */ +asm_x86_instr *x86_read_instr_xor_al_with_imm8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); + +/* Décode une instruction de type 'xor [e]ax, ...' (16/32 bits). */ +asm_x86_instr *x86_read_instr_xor_e_ax_with_imm1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); + +/* Décode une instruction de type 'xor' (8 bits). */ +asm_x86_instr *x86_read_instr_xor_rm8_with_imm8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); + +/* Décode une instruction de type 'xor' (16 ou 32 bits). */ +asm_x86_instr *x86_read_instr_xor_rm1632_with_imm1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); + +/* Décode une instruction de type 'xor' (8 bits). */ +asm_x86_instr *x86_read_instr_xor_r8_with_rm8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); + +/* Décode une instruction de type 'xor' (16 ou 32 bits). */ +asm_x86_instr *x86_read_instr_xor_r1632_with_rm1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); + +/* Décode une instruction de type 'xor' (8 bits). */ +asm_x86_instr *x86_read_instr_xor_rm8_with_r8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); /* Décode une instruction de type 'xor' (16 ou 32 bits). */ -asm_x86_instr *x86_read_instr_xor_with_reg1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); +asm_x86_instr *x86_read_instr_xor_rm1632_with_imm8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); /* Décode une instruction de type 'xor' (16 ou 32 bits). */ -asm_x86_instr *x86_read_instr_xor8_with_reg1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); +asm_x86_instr *x86_read_instr_xor_rm1632_with_r1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); diff --git a/src/arch/x86/operand.c b/src/arch/x86/operand.c index 10a908e..375b0a5 100644 --- a/src/arch/x86/operand.c +++ b/src/arch/x86/operand.c @@ -25,6 +25,7 @@ #include #include +#include #include @@ -33,6 +34,9 @@ +#define MAX(a, b) ((a) > (b) ? (a) : (b)) + + /* Liste des registres 8 bits */ typedef enum _X868bRegister @@ -127,6 +131,12 @@ void _x86_print_reg_operand(const x86_register *reg, AsmOperandSize, char *, siz +/* Crée une opérande renvoyant vers un registre 16 ou 32 bits. */ +asm_x86_operand *x86_create_r1632_operand_from_opcode(uint8_t, bool, uint8_t); + + + + /****************************************************************************** * * @@ -471,7 +481,6 @@ asm_x86_operand *x86_create_r8_operand(uint8_t data, bool first) * Paramètres : data = flux de données à analyser. * * pos = position courante dans ce flux. [OUT] * * len = taille totale des données à analyser. * -* first = indique la partie du ModR/M à traiter. * * * * Description : Crée une opérande à partir d'un registre/une mémoire 8 bits. * * * @@ -481,14 +490,14 @@ asm_x86_operand *x86_create_r8_operand(uint8_t data, bool first) * * ******************************************************************************/ -asm_x86_operand *x86_create_rm8_operand(const uint8_t *data, off_t *pos, off_t len, bool first) +asm_x86_operand *x86_create_rm8_operand(const uint8_t *data, off_t *pos, off_t len, ...) { asm_x86_operand *result; /* Registre à retourner */ uint8_t mod; /* Modificateur présent */ /* Registre simple... */ - result = x86_create_r8_operand(data[*pos], first); + result = x86_create_r8_operand(data[*pos], true); if (result == NULL) return NULL; mod = (data[*pos] & 0xc0); @@ -628,11 +637,44 @@ asm_x86_operand *x86_create_r1632_operand(uint8_t data, bool is_reg32, bool firs /****************************************************************************** * * +* Paramètres : data = donnée à analyser. * +* is_reg32 = indique si le registre est un registre 32 bits. * +* base = valeur du premier registre. * +* * +* Description : Crée une opérande renvoyant vers un registre 16 ou 32 bits. * +* * +* Retour : Opérande mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +asm_x86_operand *x86_create_r1632_operand_from_opcode(uint8_t data, bool is_reg32, uint8_t base) +{ + asm_x86_operand *result; /* Registre à retourner */ + + result = create_new_x86_operand(); + + ASM_OPERAND(result)->type = AOT_REG; + ASM_OPERAND(result)->size = (is_reg32 ? AOS_32_BITS : AOS_16_BITS); + + if (!get_x86_register(&result->rindex, ASM_OPERAND(result)->size, data - base)) + { + free(result); + return NULL; + } + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : data = flux de données à analyser. * * pos = position courante dans ce flux. [OUT] * * len = taille totale des données à analyser. * * is_reg32 = indique si le registre est un registre 32 bits. * -* first = indique la partie du ModR/M à traiter. * * * * Description : Crée une opérande à partir d'un registre/une mémoire 16/32b. * * * @@ -642,14 +684,14 @@ asm_x86_operand *x86_create_r1632_operand(uint8_t data, bool is_reg32, bool firs * * ******************************************************************************/ -asm_x86_operand *x86_create_rm1632_operand(const uint8_t *data, off_t *pos, off_t len, bool is_reg32, bool first) +asm_x86_operand *x86_create_rm1632_operand(const uint8_t *data, off_t *pos, off_t len, bool is_reg32, ...) { asm_x86_operand *result; /* Registre à retourner */ uint8_t mod; /* Modificateur présent */ /* Registre simple... */ - result = x86_create_r1632_operand(data[*pos], is_reg32, first); + result = x86_create_r1632_operand(data[*pos], is_reg32, true); if (result == NULL) return NULL; mod = (data[*pos] & 0xc0); @@ -1169,8 +1211,6 @@ asm_x86_operand *x86_create_moffs1632_operand(const uint8_t *data, off_t *pos, o void x86_print_moffs_operand(const asm_x86_operand *operand, char *buffer, size_t len, AsmSyntax syntax) { - size_t pos; /* Position de traitement */ - switch (syntax) { case ASX_INTEL: @@ -1239,3 +1279,357 @@ asm_x86_operand *x86_create_rel8_operand_in_32b(uint64_t base, const uint8_t *da return result; } + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* is_reg32 = indique si le registre est un registre 32 bits. * +* * +* Description : Crée une opérande à partir d'une adresse relative (16/32b). * +* * +* Retour : Opérande mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +asm_x86_operand *x86_create_rel1632_operand_in_32b(uint64_t base, const uint8_t *data, off_t *pos, off_t len, bool is_reg32) +{ + asm_x86_operand *result; /* Emplacement à retourner */ + off_t init_pos; /* Position avant lecture */ + int8_t offset; /* Décallage à appliquer */ + uint32_t address; /* Adresse finale visée */ + + result = create_new_x86_operand(); + + init_pos = *pos; + address = base; + + if (!read_imm_value(is_reg32 ? AOS_32_BITS : AOS_16_BITS, data, pos, len, &offset)) + { + free(result); + return NULL; + } + + address = base + (*pos - init_pos) + offset; + + if (!fill_imm_operand_with_value(ASM_OPERAND(result), AOS_32_BITS, &address)) + { + free(result); + return NULL; + } + + return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* AIDE A LA CREATION D'OPERANDES */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : instr = instruction dont la définition est à compléter. [OUT]* +* data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* type = type de l'opérande. * +* ... = éventuelle(s) information(s) complémentaire(s). * +* * +* Description : Procède à la lecture d'un opérande donné. * +* * +* Retour : Bilan de l'opération : true en cas de succès, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool x86_read_one_operand(asm_x86_instr *instr, const uint8_t *data, off_t *pos, off_t len, X86OperandType type, ...) +{ + va_list ap; /* Liste des compléments */ + AsmOperandSize oprsize; /* Taille des opérandes */ + uint64_t offset; /* Adresse courante */ + uint8_t base; /* Indice du premier registre */ + asm_x86_operand *op; /* Opérande unique décodé */ + + va_start(ap, type); + + /* Lecture du premier opérande */ + + switch (type) + { + case X86_OTP_IMM8: + op = create_new_x86_operand(); + if (!fill_imm_operand(ASM_OPERAND(op), AOS_8_BITS, data, pos, len)) + { + free(op); + op = NULL; + } + break; + + case X86_OTP_IMM1632: + oprsize = va_arg(ap, AsmOperandSize); + op = create_new_x86_operand(); + if (!fill_imm_operand(ASM_OPERAND(op), oprsize, data, pos, len)) + { + free(op); + op = NULL; + } + break; + + case X86_OTP_REL8: + offset = va_arg(ap, uint64_t); + /* TODO : 64bits */ + op = x86_create_rel8_operand_in_32b(offset + 1, data, pos, len); + break; + + case X86_OTP_REL1632: + oprsize = va_arg(ap, AsmOperandSize); + offset = va_arg(ap, uint64_t); + /* TODO : 64bits */ + op = x86_create_rel1632_operand_in_32b(offset + 1, data, pos, len, oprsize == AOS_32_BITS); + break; + + case X86_OTP_R8: + op = x86_create_r8_operand(data[(*pos)++], true); + break; + + case X86_OTP_R1632: + oprsize = va_arg(ap, AsmOperandSize); + op = x86_create_r1632_operand(data[(*pos)++], oprsize == AOS_32_BITS, true); + break; + + case X86_OTP_OP_R1632: + oprsize = va_arg(ap, AsmOperandSize); + base = (uint8_t)va_arg(ap, int); + op = x86_create_r1632_operand_from_opcode(data[(*pos)++], oprsize == AOS_32_BITS, base); + break; + + case X86_OTP_RM8: + op = x86_create_rm8_operand(data, pos, len); + break; + + case X86_OTP_RM1632: + oprsize = va_arg(ap, AsmOperandSize); + op = x86_create_rm1632_operand(data, pos, len, oprsize == AOS_32_BITS); + break; + + case X86_OTP_AL: + op = x86_create_r8_operand(0x00, true); + break; + + case X86_OTP_E_AX: + oprsize = va_arg(ap, AsmOperandSize); + op = x86_create_r1632_operand(0x00, oprsize == AOS_32_BITS, true); + break; + + } + + va_end(ap); + + if (op == NULL) return false; + + /* Assemblage final */ + + ASM_INSTRUCTION(instr)->operands = (asm_operand **)calloc(1, sizeof(asm_operand *)); + ASM_INSTRUCTION(instr)->operands_count = 1; + + ASM_INSTRUCTION(instr)->operands[0] = ASM_OPERAND(op); + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : instr = instruction dont la définition est à compléter. [OUT]* +* data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* type1 = type du premier opérande. * +* type2 = type du second opérande. * +* ... = éventuelle(s) information(s) complémentaire(s). * +* * +* Description : Procède à la lecture de deux opérandes donnés. * +* * +* Retour : Bilan de l'opération : true en cas de succès, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool x86_read_two_operands(asm_x86_instr *instr, const uint8_t *data, off_t *pos, off_t len, X86OperandType type1, X86OperandType type2, ...) +{ + va_list ap; /* Liste des compléments */ + AsmOperandSize oprsize; /* Taille des opérandes */ + bool op1_first; /* Position de l'opérande #1 */ + bool op2_first; /* Position de l'opérande #2 */ + off_t op1_pos; /* Position après lecture #1 */ + asm_x86_operand *op1; /* Premier opérande décodé */ + off_t op2_pos; /* Position après lecture #2 */ + asm_x86_operand *op2; /* Second opérande décodé */ + + va_start(ap, type2); + + oprsize = AOS_UNDEFINED; + + if (type1 & X86_OTP_RM_TYPE) + { + op1_first = true; + op2_first = false; + } + else if (type2 & X86_OTP_RM_TYPE) + { + op1_first = false; + op2_first = true; + } + else + { + op1_first = true; + op2_first = false; + } + + /* Lecture du premier opérande */ + + op1_pos = *pos; + + switch (type1) + { + case X86_OTP_MOFFS8: + op1 = x86_create_moffs8_operand(data, &op1_pos, len); + break; + + case X86_OTP_MOFFS1632: + oprsize = va_arg(ap, AsmOperandSize); + op1 = x86_create_moffs1632_operand(data, &op1_pos, len, oprsize == AOS_32_BITS); + break; + + case X86_OTP_R8: + op1 = x86_create_r8_operand(data[op1_pos++], op1_first); + break; + + case X86_OTP_R1632: + oprsize = va_arg(ap, AsmOperandSize); + op1 = x86_create_r1632_operand(data[op1_pos++], oprsize == AOS_32_BITS, op1_first); + break; + + case X86_OTP_RM8: + op1 = x86_create_rm8_operand(data, &op1_pos, len); + break; + + case X86_OTP_RM1632: + oprsize = va_arg(ap, AsmOperandSize); + op1 = x86_create_rm1632_operand(data, &op1_pos, len, oprsize == AOS_32_BITS); + break; + + case X86_OTP_AL: + op1 = x86_create_r8_operand(0x00, op1_first); + break; + + case X86_OTP_E_AX: + oprsize = va_arg(ap, AsmOperandSize); + op1 = x86_create_r1632_operand(0x00, oprsize == AOS_32_BITS, op1_first); + break; + + } + + if (op1 == NULL) + { + va_end(ap); + return false; + } + + /* Lecture du second opérande */ + + if ((type1 & X86_OTP_REG_TYPE || type1 & X86_OTP_RM_TYPE) && (type2 & X86_OTP_IMM_TYPE)) + op2_pos = op1_pos; + else op2_pos = *pos; + + switch (type2) + { + case X86_OTP_IMM8: + op2 = create_new_x86_operand(); + if (!fill_imm_operand(ASM_OPERAND(op2), AOS_8_BITS, data, &op2_pos, len)) + { + free(op2); + op2 = NULL; + } + break; + + case X86_OTP_IMM1632: + if (oprsize == AOS_UNDEFINED) oprsize = va_arg(ap, AsmOperandSize); + op2 = create_new_x86_operand(); + if (!fill_imm_operand(ASM_OPERAND(op2), oprsize, data, &op2_pos, len)) + { + free(op2); + op2 = NULL; + } + break; + + case X86_OTP_MOFFS8: + op2 = x86_create_moffs8_operand(data, &op2_pos, len); + break; + + case X86_OTP_MOFFS1632: + if (oprsize == AOS_UNDEFINED) oprsize = va_arg(ap, AsmOperandSize); + op2 = x86_create_moffs1632_operand(data, &op2_pos, len, oprsize == AOS_32_BITS); + break; + + case X86_OTP_R8: + op2 = x86_create_r8_operand(data[op2_pos++], op2_first); + break; + + case X86_OTP_R1632: + if (oprsize == AOS_UNDEFINED) oprsize = va_arg(ap, AsmOperandSize); + op2 = x86_create_r1632_operand(data[op2_pos++], oprsize == AOS_32_BITS, op2_first); + break; + + case X86_OTP_RM8: + op2 = x86_create_rm8_operand(data, &op2_pos, len); + break; + + case X86_OTP_RM1632: + if (oprsize == AOS_UNDEFINED) oprsize = va_arg(ap, AsmOperandSize); + op2 = x86_create_rm1632_operand(data, &op2_pos, len, oprsize == AOS_32_BITS); + break; + + case X86_OTP_AL: + op2 = x86_create_r8_operand(0x00, op2_first); + break; + + case X86_OTP_E_AX: + if (oprsize == AOS_UNDEFINED) oprsize = va_arg(ap, AsmOperandSize); + op2 = x86_create_r1632_operand(0x00, oprsize == AOS_32_BITS, op2_first); + break; + + } + + if (op2 == NULL) + { + free(op1); + va_end(ap); + return false; + } + + va_end(ap); + + /* Assemblage final */ + + *pos = MAX(op1_pos, op2_pos); + + ASM_INSTRUCTION(instr)->operands = (asm_operand **)calloc(2, sizeof(asm_operand *)); + ASM_INSTRUCTION(instr)->operands_count = 2; + + ASM_INSTRUCTION(instr)->operands[0] = ASM_OPERAND(op1); + ASM_INSTRUCTION(instr)->operands[1] = ASM_OPERAND(op2); + + return true; + +} diff --git a/src/arch/x86/operand.h b/src/arch/x86/operand.h index 04c0cb6..c48a0be 100644 --- a/src/arch/x86/operand.h +++ b/src/arch/x86/operand.h @@ -29,7 +29,8 @@ #include -#include "../operand.h" /* TODO : AsmSyntax ? */ +#include "instruction.h" + /* Définition d'une opérande x86 */ @@ -57,13 +58,13 @@ asm_x86_operand *x86_create_content1632_operand(const uint8_t *, off_t *, off_t, asm_x86_operand *x86_create_r8_operand(uint8_t, bool); /* Crée une opérande à partir d'un registre/une mémoire 8 bits. */ -asm_x86_operand *x86_create_rm8_operand(const uint8_t *, off_t *, off_t, bool); +asm_x86_operand *x86_create_rm8_operand(const uint8_t *, off_t *, off_t, ...); /* Crée une opérande renvoyant vers un registre 16 ou 32 bits. */ asm_x86_operand *x86_create_r1632_operand(uint8_t, bool, bool); /* Crée une opérande à partir d'un registre/une mémoire 16/32b. */ -asm_x86_operand *x86_create_rm1632_operand(const uint8_t *, off_t *, off_t, bool, bool); +asm_x86_operand *x86_create_rm1632_operand(const uint8_t *, off_t *, off_t, bool, ...); @@ -92,6 +93,53 @@ void x86_print_moffs_operand(const asm_x86_operand *, char *, size_t, AsmSyntax) /* Crée une opérande à partir d'une adresse relative (8 bits). */ asm_x86_operand *x86_create_rel8_operand_in_32b(uint64_t, const uint8_t *, off_t *, off_t); +/* Crée une opérande à partir d'une adresse relative (16/32b). */ +asm_x86_operand *x86_create_rel1632_operand_in_32b(uint64_t, const uint8_t *, off_t *, off_t, bool); + + + +/* ------------------------- AIDE A LA CREATION D'OPERANDES ------------------------- */ + + +/* Construction d'identifiants typés */ + +#define X86_OTP_IMM_TYPE 0x8000 +#define X86_OTP_REG_TYPE 0x4000 +#define X86_OTP_RM_TYPE 0x2000 + +#define X86_OTP_IMM(b) X86_OTP_IMM_TYPE | (1 << b) +#define X86_OTP_REG(b) X86_OTP_REG_TYPE | (1 << b) +#define X86_OTP_RM(b) X86_OTP_RM_TYPE | (1 << b) + +/* Types d'opérandes supportés */ +typedef enum _X86OperandType +{ + X86_OTP_IMM8 = X86_OTP_IMM(1), /* Valeur immédiate sur 8 bits */ + X86_OTP_IMM1632 = X86_OTP_IMM(2), /* Valeur immédiate sur 16/32b */ + X86_OTP_MOFFS8 = X86_OTP_IMM(3), /* Décallage immédiat 8 bits */ + X86_OTP_MOFFS1632 = X86_OTP_IMM(4), /* Décallage immédiat 16/32b */ + X86_OTP_REL8 = X86_OTP_IMM(5), /* Adresse relative 8 bits */ + X86_OTP_REL1632 = X86_OTP_IMM(6), /* Adresse relative 16/32 bits */ + + X86_OTP_R8 = X86_OTP_REG(1), /* Registre 8 bits */ + X86_OTP_R1632 = X86_OTP_REG(2), /* Registre 16 ou 32 bits */ + X86_OTP_OP_R1632 = X86_OTP_REG(3), /* Registre 16 ou 32 bits */ + + X86_OTP_RM8 = X86_OTP_RM(1), /* Registre 8 bits ou mémoire */ + X86_OTP_RM1632 = X86_OTP_RM(2), /* Registre 16/32b ou mémoire */ + + X86_OTP_AL = 0x0ffe, /* Registre al */ + X86_OTP_E_AX = 0x0fff /* Registre eax ou ax */ + +} X86OperandType; + + +/* Procède à la lecture d'un opérande donné. */ +bool x86_read_one_operand(asm_x86_instr *, const uint8_t *, off_t *, off_t, X86OperandType, ...); + +/* Procède à la lecture de deux opérandes donnés. */ +bool x86_read_two_operands(asm_x86_instr *, const uint8_t *, off_t *, off_t, X86OperandType, X86OperandType, ...); + #endif /* _ARCH_X86_OPERAND_H */ diff --git a/src/arch/x86/processor.c b/src/arch/x86/processor.c index 5b93e0a..0b81a8c 100644 --- a/src/arch/x86/processor.c +++ b/src/arch/x86/processor.c @@ -164,6 +164,8 @@ AsmOperandSize get_x86_current_operand_size(const asm_x86_processor *proc) /****************************************************************************** * * * Paramètres : proc = architecture visée par la consultation. * +* data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * * * * Description : Fournit la taille supplantée des opérandes pour x86. * * * @@ -173,9 +175,18 @@ AsmOperandSize get_x86_current_operand_size(const asm_x86_processor *proc) * * ******************************************************************************/ -AsmOperandSize switch_x86_operand_size(const asm_x86_processor *proc) +AsmOperandSize switch_x86_operand_size_if_needed(const asm_x86_processor *proc, const uint8_t *data, off_t *pos) { - return (proc->operand_size == AOS_32_BITS ? AOS_16_BITS : AOS_32_BITS); + AsmOperandSize result; /* Taille à renvoyer */ + + if (data[*pos] == 0x66) + { + result = (proc->operand_size == AOS_32_BITS ? AOS_16_BITS : AOS_32_BITS); + (*pos)++; + } + else result = proc->operand_size; + + return result; } @@ -194,72 +205,80 @@ AsmOperandSize switch_x86_operand_size(const asm_x86_processor *proc) void x86_register_instructions(asm_x86_processor *proc) { - register_opcode(proc->opcodes[X86_OP_SUB_R1632_RM1632], 0x66, 0x29, "sub", x86_read_instr_sub_r1632_to_rm1632); + register_opcode(proc->opcodes[X86_OP_SUB_R1632_RM1632], 0x66, 0x29, "sub", x86_read_instr_sub_r1632_from_rm1632); - register_opcode(proc->opcodes[X86_OP_XOR_REG1632], 0x00/*0x66*/, 0x31, "xor", x86_read_instr_xor_with_reg1632); + register_opcode(proc->opcodes[X86_OP_XOR_RM8_R8], 0x00, 0x30, "xor", x86_read_instr_xor_rm8_with_r8); + register_opcode(proc->opcodes[X86_OP_XOR_RM1632_R1632], 0x66, 0x31, "xor", x86_read_instr_xor_rm1632_with_r1632); + register_opcode(proc->opcodes[X86_OP_XOR_R8_RM8], 0x00, 0x32, "xor", x86_read_instr_xor_r8_with_rm8); + register_opcode(proc->opcodes[X86_OP_XOR_R1632_RM1632], 0x66, 0x33, "xor", x86_read_instr_xor_r1632_with_rm1632); + register_opcode(proc->opcodes[X86_OP_XOR_AL_IMM8], 0x00, 0x34, "xor", x86_read_instr_xor_al_with_imm8); + register_opcode(proc->opcodes[X86_OP_XOR_E_AX_IMM1632], 0x66, 0x35, "xor", x86_read_instr_xor_e_ax_with_imm1632); register_opcode(proc->opcodes[X86_OP_CMP_RM1632_R1632], 0x66, 0x39, "cmp", x86_read_instr_cmp_rm1632_with_r1632); - register_opcode(proc->opcodes[X86_OP_INC_E_AX], 0x66, 0x40, "inc", x86_read_instr_inc_1632); - register_opcode(proc->opcodes[X86_OP_INC_E_CX], 0x66, 0x41, "inc", x86_read_instr_inc_1632); - register_opcode(proc->opcodes[X86_OP_INC_E_DX], 0x66, 0x42, "inc", x86_read_instr_inc_1632); - register_opcode(proc->opcodes[X86_OP_INC_E_BX], 0x66, 0x43, "inc", x86_read_instr_inc_1632); - register_opcode(proc->opcodes[X86_OP_INC_E_SP], 0x66, 0x44, "inc", x86_read_instr_inc_1632); - register_opcode(proc->opcodes[X86_OP_INC_E_BP], 0x66, 0x45, "inc", x86_read_instr_inc_1632); - register_opcode(proc->opcodes[X86_OP_INC_E_SI], 0x66, 0x46, "inc", x86_read_instr_inc_1632); - register_opcode(proc->opcodes[X86_OP_INC_E_DI], 0x66, 0x47, "inc", x86_read_instr_inc_1632); - - register_opcode(proc->opcodes[X86_OP_DEC_E_AX], 0x66, 0x48, "dec", x86_read_instr_dec_1632); - register_opcode(proc->opcodes[X86_OP_DEC_E_CX], 0x66, 0x49, "dec", x86_read_instr_dec_1632); - register_opcode(proc->opcodes[X86_OP_DEC_E_DX], 0x66, 0x4a, "dec", x86_read_instr_dec_1632); - register_opcode(proc->opcodes[X86_OP_DEC_E_BX], 0x66, 0x4b, "dec", x86_read_instr_dec_1632); - register_opcode(proc->opcodes[X86_OP_DEC_E_SP], 0x66, 0x4c, "dec", x86_read_instr_dec_1632); - register_opcode(proc->opcodes[X86_OP_DEC_E_BP], 0x66, 0x4d, "dec", x86_read_instr_dec_1632); - register_opcode(proc->opcodes[X86_OP_DEC_E_SI], 0x66, 0x4e, "dec", x86_read_instr_dec_1632); - register_opcode(proc->opcodes[X86_OP_DEC_E_DI], 0x66, 0x4f, "dec", x86_read_instr_dec_1632); - - register_opcode(proc->opcodes[X86_OP_PUSH_E_AX], 0x66, 0x50, "push", x86_read_instr_push_reg1632); - register_opcode(proc->opcodes[X86_OP_PUSH_E_CX], 0x66, 0x51, "push", x86_read_instr_push_reg1632); - register_opcode(proc->opcodes[X86_OP_PUSH_E_DX], 0x66, 0x52, "push", x86_read_instr_push_reg1632); - register_opcode(proc->opcodes[X86_OP_PUSH_E_BX], 0x66, 0x53, "push", x86_read_instr_push_reg1632); - register_opcode(proc->opcodes[X86_OP_PUSH_E_SP], 0x66, 0x54, "push", x86_read_instr_push_reg1632); - register_opcode(proc->opcodes[X86_OP_PUSH_E_BP], 0x66, 0x55, "push", x86_read_instr_push_reg1632); - register_opcode(proc->opcodes[X86_OP_PUSH_E_SI], 0x66, 0x56, "push", x86_read_instr_push_reg1632); - register_opcode(proc->opcodes[X86_OP_PUSH_E_DI], 0x66, 0x57, "push", x86_read_instr_push_reg1632); - - register_opcode(proc->opcodes[X86_OP_POP_E_AX], 0x66, 0x58, "pop", x86_read_instr_pop_reg1632); - register_opcode(proc->opcodes[X86_OP_POP_E_CX], 0x66, 0x59, "pop", x86_read_instr_pop_reg1632); - register_opcode(proc->opcodes[X86_OP_POP_E_DX], 0x66, 0x5a, "pop", x86_read_instr_pop_reg1632); - register_opcode(proc->opcodes[X86_OP_POP_E_BX], 0x66, 0x5b, "pop", x86_read_instr_pop_reg1632); - register_opcode(proc->opcodes[X86_OP_POP_E_SP], 0x66, 0x5c, "pop", x86_read_instr_pop_reg1632); - register_opcode(proc->opcodes[X86_OP_POP_E_BP], 0x66, 0x5d, "pop", x86_read_instr_pop_reg1632); - register_opcode(proc->opcodes[X86_OP_POP_E_SI], 0x66, 0x5e, "pop", x86_read_instr_pop_reg1632); - register_opcode(proc->opcodes[X86_OP_POP_E_DI], 0x66, 0x5f, "pop", x86_read_instr_pop_reg1632); + register_opcode(proc->opcodes[X86_OP_INC_E_AX], 0x66, 0x40, "inc", x86_read_instr_inc_r1632); + register_opcode(proc->opcodes[X86_OP_INC_E_CX], 0x66, 0x41, "inc", x86_read_instr_inc_r1632); + register_opcode(proc->opcodes[X86_OP_INC_E_DX], 0x66, 0x42, "inc", x86_read_instr_inc_r1632); + register_opcode(proc->opcodes[X86_OP_INC_E_BX], 0x66, 0x43, "inc", x86_read_instr_inc_r1632); + register_opcode(proc->opcodes[X86_OP_INC_E_SP], 0x66, 0x44, "inc", x86_read_instr_inc_r1632); + register_opcode(proc->opcodes[X86_OP_INC_E_BP], 0x66, 0x45, "inc", x86_read_instr_inc_r1632); + register_opcode(proc->opcodes[X86_OP_INC_E_SI], 0x66, 0x46, "inc", x86_read_instr_inc_r1632); + register_opcode(proc->opcodes[X86_OP_INC_E_DI], 0x66, 0x47, "inc", x86_read_instr_inc_r1632); + + register_opcode(proc->opcodes[X86_OP_DEC_E_AX], 0x66, 0x48, "dec", x86_read_instr_dec_r1632); + register_opcode(proc->opcodes[X86_OP_DEC_E_CX], 0x66, 0x49, "dec", x86_read_instr_dec_r1632); + register_opcode(proc->opcodes[X86_OP_DEC_E_DX], 0x66, 0x4a, "dec", x86_read_instr_dec_r1632); + register_opcode(proc->opcodes[X86_OP_DEC_E_BX], 0x66, 0x4b, "dec", x86_read_instr_dec_r1632); + register_opcode(proc->opcodes[X86_OP_DEC_E_SP], 0x66, 0x4c, "dec", x86_read_instr_dec_r1632); + register_opcode(proc->opcodes[X86_OP_DEC_E_BP], 0x66, 0x4d, "dec", x86_read_instr_dec_r1632); + register_opcode(proc->opcodes[X86_OP_DEC_E_SI], 0x66, 0x4e, "dec", x86_read_instr_dec_r1632); + register_opcode(proc->opcodes[X86_OP_DEC_E_DI], 0x66, 0x4f, "dec", x86_read_instr_dec_r1632); + + register_opcode(proc->opcodes[X86_OP_PUSH_E_AX], 0x66, 0x50, "push", x86_read_instr_push_r1632); + register_opcode(proc->opcodes[X86_OP_PUSH_E_CX], 0x66, 0x51, "push", x86_read_instr_push_r1632); + register_opcode(proc->opcodes[X86_OP_PUSH_E_DX], 0x66, 0x52, "push", x86_read_instr_push_r1632); + register_opcode(proc->opcodes[X86_OP_PUSH_E_BX], 0x66, 0x53, "push", x86_read_instr_push_r1632); + register_opcode(proc->opcodes[X86_OP_PUSH_E_SP], 0x66, 0x54, "push", x86_read_instr_push_r1632); + register_opcode(proc->opcodes[X86_OP_PUSH_E_BP], 0x66, 0x55, "push", x86_read_instr_push_r1632); + register_opcode(proc->opcodes[X86_OP_PUSH_E_SI], 0x66, 0x56, "push", x86_read_instr_push_r1632); + register_opcode(proc->opcodes[X86_OP_PUSH_E_DI], 0x66, 0x57, "push", x86_read_instr_push_r1632); + + register_opcode(proc->opcodes[X86_OP_POP_E_AX], 0x66, 0x58, "pop", x86_read_instr_pop_r1632); + register_opcode(proc->opcodes[X86_OP_POP_E_CX], 0x66, 0x59, "pop", x86_read_instr_pop_r1632); + register_opcode(proc->opcodes[X86_OP_POP_E_DX], 0x66, 0x5a, "pop", x86_read_instr_pop_r1632); + register_opcode(proc->opcodes[X86_OP_POP_E_BX], 0x66, 0x5b, "pop", x86_read_instr_pop_r1632); + register_opcode(proc->opcodes[X86_OP_POP_E_SP], 0x66, 0x5c, "pop", x86_read_instr_pop_r1632); + register_opcode(proc->opcodes[X86_OP_POP_E_BP], 0x66, 0x5d, "pop", x86_read_instr_pop_r1632); + register_opcode(proc->opcodes[X86_OP_POP_E_SI], 0x66, 0x5e, "pop", x86_read_instr_pop_r1632); + register_opcode(proc->opcodes[X86_OP_POP_E_DI], 0x66, 0x5f, "pop", x86_read_instr_pop_r1632); register_opcode(proc->opcodes[X86_OP_PUSH_IMM1632], 0x66, 0x68, "push", x86_read_instr_push_imm1632); + register_opcode_with_ext(proc->opcodes[X86_OP_XOR_RM8_IMM8], 0x00, 0x80, 6, "xor", x86_read_instr_xor_rm8_with_imm8); register_opcode_with_ext(proc->opcodes[X86_OP_CMP_RM8_IMM8], 0x00, 0x80, 7, "cmp", x86_read_instr_cmp_rm8_with_imm8); - register_opcode_with_ext(proc->opcodes[X86_OP_ADD_IMM1632_REG1632], 0x66, 0x81, 0, "add", x86_read_instr_add_imm1632_to_rm1632); + register_opcode_with_ext(proc->opcodes[X86_OP_ADD_RM1632_IMM1632], 0x66, 0x81, 0, "add", x86_read_instr_add_imm1632_to_rm1632); + + register_opcode_with_ext(proc->opcodes[X86_OP_XOR_RM1632_IMM1632], 0x66, 0x81, 6, "xor", x86_read_instr_xor_rm1632_with_imm1632); - register_opcode_with_ext(proc->opcodes[X86_OP_ADD8_REG1632], 0x66, 0x83, 0, "add", x86_read_instr_add8_with_reg1632); - register_opcode_with_ext(proc->opcodes[X86_OP_OR8_REG1632], 0x66, 0x83, 1, "or", x86_read_instr_or8_with_reg1632); - register_opcode_with_ext(proc->opcodes[X86_OP_ADC8_REG1632], 0x66, 0x83, 2, "adc", x86_read_instr_adc8_with_reg1632); - register_opcode_with_ext(proc->opcodes[X86_OP_SBB8_REG1632], 0x66, 0x83, 3, "sbb", x86_read_instr_sbb8_with_reg1632); - register_opcode_with_ext(proc->opcodes[X86_OP_AND8_REG1632], 0x66, 0x83, 4, "and", x86_read_instr_and8_with_reg1632); - register_opcode_with_ext(proc->opcodes[X86_OP_SUB8_REG1632], 0x66, 0x83, 5, "sub", x86_read_instr_sub8_with_reg1632); - register_opcode_with_ext(proc->opcodes[X86_OP_XOR8_REG1632], 0x66, 0x83, 6, "xor", x86_read_instr_xor8_with_reg1632); + register_opcode_with_ext(proc->opcodes[X86_OP_ADD_RM1632_IMM8], 0x66, 0x83, 0, "add", x86_read_instr_add_imm8_to_rm1632); + register_opcode_with_ext(proc->opcodes[X86_OP_OR_RM1632_IMM8], 0x66, 0x83, 1, "or", x86_read_instr_or_rm1632_with_imm8); + register_opcode_with_ext(proc->opcodes[X86_OP_ADC_RM1632_IMM8], 0x66, 0x83, 2, "adc", x86_read_instr_adc_imm8_to_rm1632); + register_opcode_with_ext(proc->opcodes[X86_OP_SBB_RM1632_IMM8], 0x66, 0x83, 3, "sbb", x86_read_instr_sbb_rm1632_with_imm8); + register_opcode_with_ext(proc->opcodes[X86_OP_AND_RM1632_IMM8], 0x66, 0x83, 4, "and", x86_read_instr_and_rm1632_with_imm8); + register_opcode_with_ext(proc->opcodes[X86_OP_SUB_RM1632_IMM8], 0x66, 0x83, 5, "sub", x86_read_instr_sub_imm8_from_rm1632); + register_opcode_with_ext(proc->opcodes[X86_OP_XOR_RM1632_IMM8], 0x66, 0x83, 6, "xor", x86_read_instr_xor_rm1632_with_imm8); register_opcode_with_ext(proc->opcodes[X86_OP_CMP_RM1632_IMM8], 0x66, 0x83, 7, "cmp", x86_read_instr_cmp_rm1632_with_imm8); register_opcode(proc->opcodes[X86_OP_JE_8], 0x00, 0x74, "je", x86_read_instr_je_8); register_opcode(proc->opcodes[X86_OP_JNE_8], 0x00, 0x75, "jne", x86_read_instr_jne_8); - register_opcode(proc->opcodes[X86_OP_TEST_RM8], 0x00, 0x84, "test", x86_read_instr_test_rm8); - register_opcode(proc->opcodes[X86_OP_TEST_RM1632], 0x66, 0x85, "test", x86_read_instr_test_rm1632); + register_opcode(proc->opcodes[X86_OP_TEST_RM8_R8], 0x00, 0x84, "test", x86_read_instr_test_rm8_with_r8); + register_opcode(proc->opcodes[X86_OP_TEST_RM1632_R1632], 0x66, 0x85, "test", x86_read_instr_test_rm1632_with_r1632); - register_opcode(proc->opcodes[X86_OP_MOV_REG1632], 0x66, 0x89, "mov", x86_read_instr_mov_with_reg1632); + register_opcode(proc->opcodes[X86_OP_MOV_RM1632_R1632], 0x66, 0x89, "mov", x86_read_instr_mov_r1632_to_rm1632); - register_opcode(proc->opcodes[X86_OP_MOV_FROM_CONTENT1632], 0x66, 0x8b, "mov", x86_read_instr_mov_from_content_1632); + register_opcode(proc->opcodes[X86_OP_MOV_R1632_RM1632], 0x66, 0x8b, "mov", x86_read_instr_mov_rm1632_to_r1632); register_opcode(proc->opcodes[X86_OP_LEA], 0x66, 0x8d, "lea", x86_read_instr_lea); @@ -273,35 +292,35 @@ void x86_register_instructions(asm_x86_processor *proc) register_opcode(proc->opcodes[X86_OP_TEST_AL], 0x00, 0xa8, "test", x86_read_instr_test_al); register_opcode(proc->opcodes[X86_OP_TEST_E_AX], 0x66, 0xa9, "test", x86_read_instr_test_e_ax); - register_opcode(proc->opcodes[X86_OP_MOV_E_AX], 0x66, 0xb8, "mov", x86_read_instr_mov_to_1632); - register_opcode(proc->opcodes[X86_OP_MOV_E_CX], 0x66, 0xb9, "mov", x86_read_instr_mov_to_1632); - register_opcode(proc->opcodes[X86_OP_MOV_E_DX], 0x66, 0xba, "mov", x86_read_instr_mov_to_1632); - register_opcode(proc->opcodes[X86_OP_MOV_E_BX], 0x66, 0xbb, "mov", x86_read_instr_mov_to_1632); - register_opcode(proc->opcodes[X86_OP_MOV_E_SP], 0x66, 0xbc, "mov", x86_read_instr_mov_to_1632); - register_opcode(proc->opcodes[X86_OP_MOV_E_BP], 0x66, 0xbd, "mov", x86_read_instr_mov_to_1632); - register_opcode(proc->opcodes[X86_OP_MOV_E_SI], 0x66, 0xbe, "mov", x86_read_instr_mov_to_1632); - register_opcode(proc->opcodes[X86_OP_MOV_E_DI], 0x66, 0xbf, "mov", x86_read_instr_mov_to_1632); + register_opcode(proc->opcodes[X86_OP_MOV_E_AX], 0x66, 0xb8, "mov", x86_read_instr_mov_imm1632_to_r1632); + register_opcode(proc->opcodes[X86_OP_MOV_E_CX], 0x66, 0xb9, "mov", x86_read_instr_mov_imm1632_to_r1632); + register_opcode(proc->opcodes[X86_OP_MOV_E_DX], 0x66, 0xba, "mov", x86_read_instr_mov_imm1632_to_r1632); + register_opcode(proc->opcodes[X86_OP_MOV_E_BX], 0x66, 0xbb, "mov", x86_read_instr_mov_imm1632_to_r1632); + register_opcode(proc->opcodes[X86_OP_MOV_E_SP], 0x66, 0xbc, "mov", x86_read_instr_mov_imm1632_to_r1632); + register_opcode(proc->opcodes[X86_OP_MOV_E_BP], 0x66, 0xbd, "mov", x86_read_instr_mov_imm1632_to_r1632); + register_opcode(proc->opcodes[X86_OP_MOV_E_SI], 0x66, 0xbe, "mov", x86_read_instr_mov_imm1632_to_r1632); + register_opcode(proc->opcodes[X86_OP_MOV_E_DI], 0x66, 0xbf, "mov", x86_read_instr_mov_imm1632_to_r1632); register_opcode_with_ext(proc->opcodes[X86_OP_SAR_RM1632_IMM8], 0x66, 0xc1, 7, "sar", x86_read_instr_sar_rm1632_with_imm8); register_opcode(proc->opcodes[X86_OP_RET], 0x00, 0xc3, "ret", x86_read_instr_ret); register_opcode(proc->opcodes[X86_OP_MOV_IMM8_TO_RM8], 0x00, 0xc6, "mov", x86_read_instr_mov_imm8_to_rm8); - register_opcode(proc->opcodes[X86_OP_MOV_TO_CONTENT1632], 0x66, 0xc7, "mov", x86_read_instr_mov_to_content_1632); + register_opcode(proc->opcodes[X86_OP_MOV_IMM1632_TO_RM1632], 0x66, 0xc7, "mov", x86_read_instr_mov_imm1632_to_rm1632); register_opcode(proc->opcodes[X86_OP_LEAVE], 0x00, 0xc9, "leave", x86_read_instr_leave); register_opcode(proc->opcodes[X86_OP_INT], 0x00, 0xcd, "int", x86_read_instr_int); - register_opcode(proc->opcodes[X86_OP_CALL], 0x00, 0xe8, "call", x86_read_instr_call); + register_opcode(proc->opcodes[X86_OP_CALL_REL1632], 0x66, 0xe8, "call", x86_read_instr_call_rel1632); register_opcode(proc->opcodes[X86_OP_JMP_8], 0x00, 0xeb, "jmp", x86_read_instr_jmp_8); register_opcode(proc->opcodes[X86_OP_HLT], 0x00, 0xf4, "hlt", x86_read_instr_hlt); register_opcode_with_ext(proc->opcodes[X86_OP_CALL_RM1632], 0x66, 0xff, 2, "call", x86_read_instr_call_rm1632); - register_opcode_with_ext(proc->opcodes[X86_OP_PUSH_CONTENT], 0x66, 0xff, 6, "push", x86_read_instr_push_content); + register_opcode_with_ext(proc->opcodes[X86_OP_PUSH_RM1632], 0x66, 0xff, 6, "push", x86_read_instr_push_rm1632); } diff --git a/src/arch/x86/processor.h b/src/arch/x86/processor.h index c898d80..036966f 100644 --- a/src/arch/x86/processor.h +++ b/src/arch/x86/processor.h @@ -41,8 +41,7 @@ asm_processor *create_x86_processor(void); AsmOperandSize get_x86_current_operand_size(const asm_x86_processor *); /* Fournit la taille supplantée des opérandes pour x86. */ -AsmOperandSize switch_x86_operand_size(const asm_x86_processor *); - +AsmOperandSize switch_x86_operand_size_if_needed(const asm_x86_processor *, const uint8_t *, off_t *); -- cgit v0.11.2-87-g4458