diff options
Diffstat (limited to 'src/arch/x86/processor.c')
-rw-r--r-- | src/arch/x86/processor.c | 138 |
1 files changed, 92 insertions, 46 deletions
diff --git a/src/arch/x86/processor.c b/src/arch/x86/processor.c index 9c7f2bd..94f2a51 100644 --- a/src/arch/x86/processor.c +++ b/src/arch/x86/processor.c @@ -35,7 +35,7 @@ -typedef asm_x86_instr * (* read_instr) (const uint8_t *, off_t *, off_t); +typedef asm_x86_instr * (* read_instr) (const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); /* Carte d'identité d'un opcode */ @@ -59,13 +59,15 @@ target.read = func; \ /* Définition générique d'une architecture */ -typedef struct _asm_x86_processor +struct _asm_x86_processor { asm_processor base; /* A laisser en premier... */ + AsmOperandSize operand_size; /* Taille par défaut */ + x86_opcode opcodes[X86_OP_COUNT]; /* Liste des opcodes supportés */ -} asm_x86_processor; +}; @@ -76,7 +78,7 @@ void x86_register_instructions(asm_x86_processor *); /* Décode une instruction dans un flux de données. */ -asm_instr *x86_fetch_instruction(const asm_x86_processor *, const uint8_t *, off_t *, off_t); +asm_instr *x86_fetch_instruction(const asm_x86_processor *, const uint8_t *, off_t *, off_t, uint64_t); /* Traduit une instruction en version humainement lisible. */ void x86_print_instruction(const asm_x86_processor *, const asm_x86_instr *, char *, size_t, AsmSyntax); @@ -103,17 +105,54 @@ asm_processor *create_x86_processor(void) result = (asm_x86_processor *)calloc(1, sizeof(asm_x86_processor)); + result->operand_size = AOS_32_BITS; + x86_register_instructions(result); - ASM_PROCESSOR(result)->fetch_instr = x86_fetch_instruction; - ASM_PROCESSOR(result)->print_instr = x86_print_instruction; + ASM_PROCESSOR(result)->fetch_instr = (fetch_instruction)x86_fetch_instruction; + ASM_PROCESSOR(result)->print_instr = (print_instruction)x86_print_instruction; return ASM_PROCESSOR(result); } +/****************************************************************************** +* * +* Paramètres : proc = architecture visée par la consultation. * +* * +* Description : Fournit la taille courante des opérandes pour x86. * +* * +* Retour : Taille d'opérande (16 ou 32 bits). * +* * +* Remarques : - * +* * +******************************************************************************/ + +AsmOperandSize get_x86_current_operand_size(const asm_x86_processor *proc) +{ + return proc->operand_size; + +} + + +/****************************************************************************** +* * +* Paramètres : proc = architecture visée par la consultation. * +* * +* Description : Fournit la taille supplantée des opérandes pour x86. * +* * +* Retour : Taille d'opérande (16 ou 32 bits). * +* * +* Remarques : - * +* * +******************************************************************************/ +AsmOperandSize switch_x86_operand_size(const asm_x86_processor *proc) +{ + return (proc->operand_size == AOS_32_BITS ? AOS_16_BITS : AOS_32_BITS); + +} /****************************************************************************** @@ -150,23 +189,25 @@ void x86_register_instructions(asm_x86_processor *proc) register_opcode(proc->opcodes[X86_OP_DEC_ESI], 0x00, 0x4e, "dec", read_instr_dec_1632); register_opcode(proc->opcodes[X86_OP_DEC_EDI], 0x00, 0x4f, "dec", read_instr_dec_1632); - register_opcode(proc->opcodes[X86_OP_PUSH_EAX], 0x00, 0x50, "push", read_instr_push_1632); - register_opcode(proc->opcodes[X86_OP_PUSH_ECX], 0x00, 0x51, "push", read_instr_push_1632); - register_opcode(proc->opcodes[X86_OP_PUSH_EDX], 0x00, 0x52, "push", read_instr_push_1632); - register_opcode(proc->opcodes[X86_OP_PUSH_EBX], 0x00, 0x53, "push", read_instr_push_1632); - register_opcode(proc->opcodes[X86_OP_PUSH_ESP], 0x00, 0x54, "push", read_instr_push_1632); - register_opcode(proc->opcodes[X86_OP_PUSH_EBP], 0x00, 0x55, "push", read_instr_push_1632); - register_opcode(proc->opcodes[X86_OP_PUSH_ESI], 0x00, 0x56, "push", read_instr_push_1632); - register_opcode(proc->opcodes[X86_OP_PUSH_EDI], 0x00, 0x57, "push", read_instr_push_1632); - - register_opcode(proc->opcodes[X86_OP_POP_EAX], 0x00, 0x58, "pop", read_instr_pop_1632); - register_opcode(proc->opcodes[X86_OP_POP_ECX], 0x00, 0x59, "pop", read_instr_pop_1632); - register_opcode(proc->opcodes[X86_OP_POP_EDX], 0x00, 0x5a, "pop", read_instr_pop_1632); - register_opcode(proc->opcodes[X86_OP_POP_EBX], 0x00, 0x5b, "pop", read_instr_pop_1632); - register_opcode(proc->opcodes[X86_OP_POP_ESP], 0x00, 0x5c, "pop", read_instr_pop_1632); - register_opcode(proc->opcodes[X86_OP_POP_EBP], 0x00, 0x5d, "pop", read_instr_pop_1632); - register_opcode(proc->opcodes[X86_OP_POP_ESI], 0x00, 0x5e, "pop", read_instr_pop_1632); - register_opcode(proc->opcodes[X86_OP_POP_EDI], 0x00, 0x5f, "pop", read_instr_pop_1632); + register_opcode(proc->opcodes[X86_OP_PUSH_EAX], 0x00, 0x50, "push", read_instr_push_reg1632); + register_opcode(proc->opcodes[X86_OP_PUSH_ECX], 0x00, 0x51, "push", read_instr_push_reg1632); + register_opcode(proc->opcodes[X86_OP_PUSH_EDX], 0x00, 0x52, "push", read_instr_push_reg1632); + register_opcode(proc->opcodes[X86_OP_PUSH_EBX], 0x00, 0x53, "push", read_instr_push_reg1632); + register_opcode(proc->opcodes[X86_OP_PUSH_ESP], 0x00, 0x54, "push", read_instr_push_reg1632); + register_opcode(proc->opcodes[X86_OP_PUSH_EBP], 0x00, 0x55, "push", read_instr_push_reg1632); + register_opcode(proc->opcodes[X86_OP_PUSH_ESI], 0x00, 0x56, "push", read_instr_push_reg1632); + register_opcode(proc->opcodes[X86_OP_PUSH_EDI], 0x00, 0x57, "push", read_instr_push_reg1632); + + register_opcode(proc->opcodes[X86_OP_POP_EAX], 0x00, 0x58, "pop", read_instr_pop_reg1632); + register_opcode(proc->opcodes[X86_OP_POP_ECX], 0x00, 0x59, "pop", read_instr_pop_reg1632); + register_opcode(proc->opcodes[X86_OP_POP_EDX], 0x00, 0x5a, "pop", read_instr_pop_reg1632); + register_opcode(proc->opcodes[X86_OP_POP_EBX], 0x00, 0x5b, "pop", read_instr_pop_reg1632); + register_opcode(proc->opcodes[X86_OP_POP_ESP], 0x00, 0x5c, "pop", read_instr_pop_reg1632); + register_opcode(proc->opcodes[X86_OP_POP_EBP], 0x00, 0x5d, "pop", read_instr_pop_reg1632); + register_opcode(proc->opcodes[X86_OP_POP_ESI], 0x00, 0x5e, "pop", read_instr_pop_reg1632); + register_opcode(proc->opcodes[X86_OP_POP_EDI], 0x00, 0x5f, "pop", read_instr_pop_reg1632); + + register_opcode(proc->opcodes[X86_OP_PUSH_IMM32], 0x00, 0x68, "push", read_instr_push_imm1632); register_opcode(proc->opcodes[X86_OP_NOP], 0x00, 0x90, "nop", read_instr_nop); @@ -185,6 +226,8 @@ void x86_register_instructions(asm_x86_processor *proc) register_opcode(proc->opcodes[X86_OP_INT], 0x00, 0xcd, "int", read_instr_int); + register_opcode(proc->opcodes[X86_OP_CALL], 0x00, 0xe8, "call", read_instr_call); + register_opcode(proc->opcodes[X86_OP_HLT], 0x00, 0xf4, "hlt", read_instr_hlt); @@ -206,23 +249,25 @@ void x86_register_instructions(asm_x86_processor *proc) register_opcode(proc->opcodes[X86_OP_DEC_SI], 0x66, 0x4e, "dec", read_instr_dec_1632); register_opcode(proc->opcodes[X86_OP_DEC_DI], 0x66, 0x4f, "dec", read_instr_dec_1632); - register_opcode(proc->opcodes[X86_OP_PUSH_AX], 0x66, 0x50, "push", read_instr_push_1632); - register_opcode(proc->opcodes[X86_OP_PUSH_CX], 0x66, 0x51, "push", read_instr_push_1632); - register_opcode(proc->opcodes[X86_OP_PUSH_DX], 0x66, 0x52, "push", read_instr_push_1632); - register_opcode(proc->opcodes[X86_OP_PUSH_BX], 0x66, 0x53, "push", read_instr_push_1632); - register_opcode(proc->opcodes[X86_OP_PUSH_SP], 0x66, 0x54, "push", read_instr_push_1632); - register_opcode(proc->opcodes[X86_OP_PUSH_BP], 0x66, 0x55, "push", read_instr_push_1632); - register_opcode(proc->opcodes[X86_OP_PUSH_SI], 0x66, 0x56, "push", read_instr_push_1632); - register_opcode(proc->opcodes[X86_OP_PUSH_DI], 0x66, 0x57, "push", read_instr_push_1632); - - register_opcode(proc->opcodes[X86_OP_POP_AX], 0x66, 0x58, "pop", read_instr_pop_1632); - register_opcode(proc->opcodes[X86_OP_POP_CX], 0x66, 0x59, "pop", read_instr_pop_1632); - register_opcode(proc->opcodes[X86_OP_POP_DX], 0x66, 0x5a, "pop", read_instr_pop_1632); - register_opcode(proc->opcodes[X86_OP_POP_BX], 0x66, 0x5b, "pop", read_instr_pop_1632); - register_opcode(proc->opcodes[X86_OP_POP_SP], 0x66, 0x5c, "pop", read_instr_pop_1632); - register_opcode(proc->opcodes[X86_OP_POP_BP], 0x66, 0x5d, "pop", read_instr_pop_1632); - register_opcode(proc->opcodes[X86_OP_POP_SI], 0x66, 0x5e, "pop", read_instr_pop_1632); - register_opcode(proc->opcodes[X86_OP_POP_DI], 0x66, 0x5f, "pop", read_instr_pop_1632); + register_opcode(proc->opcodes[X86_OP_PUSH_AX], 0x66, 0x50, "push", read_instr_push_reg1632); + register_opcode(proc->opcodes[X86_OP_PUSH_CX], 0x66, 0x51, "push", read_instr_push_reg1632); + register_opcode(proc->opcodes[X86_OP_PUSH_DX], 0x66, 0x52, "push", read_instr_push_reg1632); + register_opcode(proc->opcodes[X86_OP_PUSH_BX], 0x66, 0x53, "push", read_instr_push_reg1632); + register_opcode(proc->opcodes[X86_OP_PUSH_SP], 0x66, 0x54, "push", read_instr_push_reg1632); + register_opcode(proc->opcodes[X86_OP_PUSH_BP], 0x66, 0x55, "push", read_instr_push_reg1632); + register_opcode(proc->opcodes[X86_OP_PUSH_SI], 0x66, 0x56, "push", read_instr_push_reg1632); + register_opcode(proc->opcodes[X86_OP_PUSH_DI], 0x66, 0x57, "push", read_instr_push_reg1632); + + register_opcode(proc->opcodes[X86_OP_POP_AX], 0x66, 0x58, "pop", read_instr_pop_reg1632); + register_opcode(proc->opcodes[X86_OP_POP_CX], 0x66, 0x59, "pop", read_instr_pop_reg1632); + register_opcode(proc->opcodes[X86_OP_POP_DX], 0x66, 0x5a, "pop", read_instr_pop_reg1632); + register_opcode(proc->opcodes[X86_OP_POP_BX], 0x66, 0x5b, "pop", read_instr_pop_reg1632); + register_opcode(proc->opcodes[X86_OP_POP_SP], 0x66, 0x5c, "pop", read_instr_pop_reg1632); + register_opcode(proc->opcodes[X86_OP_POP_BP], 0x66, 0x5d, "pop", read_instr_pop_reg1632); + register_opcode(proc->opcodes[X86_OP_POP_SI], 0x66, 0x5e, "pop", read_instr_pop_reg1632); + register_opcode(proc->opcodes[X86_OP_POP_DI], 0x66, 0x5f, "pop", read_instr_pop_reg1632); + + register_opcode(proc->opcodes[X86_OP_PUSH_IMM16], 0x66, 0x68, "push", read_instr_push_imm1632); register_opcode(proc->opcodes[X86_OP_MOV_EAX], 0x66, 0xb8, "mov", read_instr_mov_to_1632); register_opcode(proc->opcodes[X86_OP_MOV_ECX], 0x66, 0xb9, "mov", read_instr_mov_to_1632); @@ -241,10 +286,11 @@ void x86_register_instructions(asm_x86_processor *proc) /****************************************************************************** * * -* Paramètres : proc = architecture visée par la procédure. * -* data = flux de données à analyser. * -* pos = position courante dans ce flux. [OUT] * -* len = taille totale des données à analyser. * +* Paramètres : proc = architecture visée par la procédure. * +* 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. * * * * Description : Décode une instruction dans un flux de données. * * * @@ -254,7 +300,7 @@ void x86_register_instructions(asm_x86_processor *proc) * * ******************************************************************************/ -asm_instr *x86_fetch_instruction(const asm_x86_processor *proc, const uint8_t *data, off_t *pos, off_t len) +asm_instr *x86_fetch_instruction(const asm_x86_processor *proc, const uint8_t *data, off_t *pos, off_t len, uint64_t offset) { asm_x86_instr *result; /* Résultat à faire remonter */ X86Opcodes i; /* Boucle de parcours */ @@ -266,7 +312,7 @@ asm_instr *x86_fetch_instruction(const asm_x86_processor *proc, const uint8_t *d if ((proc->opcodes[i].prefix > 0 && data[*pos] == proc->opcodes[i].prefix && data[*pos + 1] == proc->opcodes[i].opcode) || (proc->opcodes[i].prefix == 0 && data[*pos] == proc->opcodes[i].opcode)) { - result = proc->opcodes[i].read(data, pos, len); + result = proc->opcodes[i].read(data, pos, len, offset, proc); if (result != NULL) result->type = i; printf("err while decoding :: [0x%02hhx] 0x%02hhx\n", proc->opcodes[i].prefix, proc->opcodes[i].opcode); break; |