From 57758c2cd11938e3e4c6e45b983cee4c2269ff44 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Tue, 29 Jul 2008 22:31:55 +0000 Subject: Loaded the executable part of an ELF file. git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@10 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a --- ChangeLog | 42 ++++++++++++++++++ src/arch/x86/Makefile.am | 5 +++ src/arch/x86/instruction.h | 106 +++++++++++++++++++++++++++++++++++++------- src/arch/x86/op_dec.c | 78 ++++++++++++++++++++++++++++++++ src/arch/x86/op_hlt.c | 56 +++++++++++++++++++++++ src/arch/x86/op_inc.c | 78 ++++++++++++++++++++++++++++++++ src/arch/x86/op_mov.c | 2 +- src/arch/x86/op_nop.c | 2 +- src/arch/x86/op_pop.c | 78 ++++++++++++++++++++++++++++++++ src/arch/x86/op_push.c | 78 ++++++++++++++++++++++++++++++++ src/arch/x86/opcodes.h | 15 +++++++ src/arch/x86/operand.c | 11 ++--- src/arch/x86/operand.h | 2 +- src/arch/x86/processor.c | 79 ++++++++++++++++++++++++++++++++- src/binary.c | 37 +++++++++++++++- src/format/elf/format_elf.c | 101 +++++++++++++++++++++++++++++++++++++++++ src/format/elf/format_elf.h | 6 +++ 17 files changed, 748 insertions(+), 28 deletions(-) create mode 100644 src/arch/x86/op_dec.c create mode 100644 src/arch/x86/op_hlt.c create mode 100644 src/arch/x86/op_inc.c create mode 100644 src/arch/x86/op_pop.c create mode 100644 src/arch/x86/op_push.c diff --git a/ChangeLog b/ChangeLog index 2e95604..202b23d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,45 @@ +2008-07-30 Cyrille Bagard + + * src/arch/x86/instruction.h: + Register new opcodes. + + * src/arch/x86/Makefile.am: + Add op_(dec|hlt|inc|pop|push).c to libarchx86_a_SOURCES. + + * src/arch/x86/opcodes.h: + Register new opcodes. + + * src/arch/x86/op_dec.c: + Register this new opcode. + + * src/arch/x86/operand.c: + * src/arch/x86/operand.h: + Fix a mistake: define a base when reading the target register. + + * src/arch/x86/op_hlt.c: + * src/arch/x86/op_inc.c: + Register these new opcodes. + + * src/arch/x86/op_mov.c: + Update the call to x86_create_reg1632_operand(). + + * src/arch/x86/op_nop.c: + Typo. + + * src/arch/x86/op_pop.c: + * src/arch/x86/op_push.c: + Register these new opcodes. + + * src/arch/x86/processor.c: + Register the new opcodes and fix a bug with X86_OP_MOV_CX (s/D/C). + + * src/binary.c: + Load the content of the file '/tmp/hello'. + + * src/format/elf/format_elf.c: + * src/format/elf/format_elf.h: + Look for the executable part of an ELF file. + 2008-07-29 Cyrille Bagard * src/binary.c: diff --git a/src/arch/x86/Makefile.am b/src/arch/x86/Makefile.am index 4947118..c610592 100644 --- a/src/arch/x86/Makefile.am +++ b/src/arch/x86/Makefile.am @@ -3,9 +3,14 @@ lib_LIBRARIES = libarchx86.a libarchx86_a_SOURCES = \ instruction.h \ + op_dec.c \ + op_hlt.c \ + op_inc.c \ op_int.c \ op_nop.c \ op_mov.c \ + op_pop.c \ + op_push.c \ opcodes.h \ operand.h operand.c \ processor.h processor.c diff --git a/src/arch/x86/instruction.h b/src/arch/x86/instruction.h index c3c417b..83f8cf0 100644 --- a/src/arch/x86/instruction.h +++ b/src/arch/x86/instruction.h @@ -38,27 +38,101 @@ typedef struct _asm_x86_instr asm_x86_instr; /* Enumération de tous les opcodes */ typedef enum _X86Opcodes { + X86_OP_INC_EAX, /* inc (0x40) */ + X86_OP_INC_ECX, /* inc (0x41) */ + X86_OP_INC_EDX, /* inc (0x42) */ + X86_OP_INC_EBX, /* inc (0x43) */ + X86_OP_INC_ESP, /* inc (0x44) */ + X86_OP_INC_EBP, /* inc (0x45) */ + X86_OP_INC_ESI, /* inc (0x46) */ + X86_OP_INC_EDI, /* inc (0x47) */ + + X86_OP_DEC_EAX, /* dec (0x48) */ + X86_OP_DEC_ECX, /* dec (0x49) */ + X86_OP_DEC_EDX, /* dec (0x4a) */ + X86_OP_DEC_EBX, /* dec (0x4b) */ + X86_OP_DEC_ESP, /* dec (0x4c) */ + X86_OP_DEC_EBP, /* dec (0x4d) */ + X86_OP_DEC_ESI, /* dec (0x4e) */ + X86_OP_DEC_EDI, /* dec (0x4f) */ + + X86_OP_PUSH_EAX, /* push (0x50) */ + X86_OP_PUSH_ECX, /* push (0x51) */ + X86_OP_PUSH_EDX, /* push (0x52) */ + X86_OP_PUSH_EBX, /* push (0x53) */ + X86_OP_PUSH_ESP, /* push (0x54) */ + X86_OP_PUSH_EBP, /* push (0x55) */ + X86_OP_PUSH_ESI, /* push (0x56) */ + X86_OP_PUSH_EDI, /* push (0x57) */ + + X86_OP_POP_EAX, /* pop (0x58) */ + X86_OP_POP_ECX, /* pop (0x59) */ + X86_OP_POP_EDX, /* pop (0x5a) */ + X86_OP_POP_EBX, /* pop (0x5b) */ + X86_OP_POP_ESP, /* pop (0x5c) */ + X86_OP_POP_EBP, /* pop (0x5d) */ + X86_OP_POP_ESI, /* pop (0x5e) */ + X86_OP_POP_EDI, /* pop (0x5f) */ + X86_OP_NOP, /* nop (0x90) */ - X86_OP_MOV_AX, /* mov (0xb0) */ - X86_OP_MOV_CX, /* mov (0xb1) */ - X86_OP_MOV_DX, /* mov (0xb2) */ - X86_OP_MOV_BX, /* mov (0xb3) */ - X86_OP_MOV_SP, /* mov (0xb4) */ - X86_OP_MOV_BP, /* mov (0xb5) */ - X86_OP_MOV_SI, /* mov (0xb6) */ - X86_OP_MOV_DI, /* mov (0xb7) */ + X86_OP_MOV_AX, /* mov (0xb8) */ + X86_OP_MOV_CX, /* mov (0xb9) */ + X86_OP_MOV_DX, /* mov (0xba) */ + X86_OP_MOV_BX, /* mov (0xbb) */ + X86_OP_MOV_SP, /* mov (0xbc) */ + X86_OP_MOV_BP, /* mov (0xbd) */ + X86_OP_MOV_SI, /* mov (0xbe) */ + X86_OP_MOV_DI, /* mov (0xbf) */ X86_OP_INT, /* int (0xcd) */ - X86_OP_MOV_EAX, /* mov (0x66 0xb0) */ - X86_OP_MOV_ECX, /* mov (0x66 0xb1) */ - X86_OP_MOV_EDX, /* mov (0x66 0xb2) */ - X86_OP_MOV_EBX, /* mov (0x66 0xb3) */ - X86_OP_MOV_ESP, /* mov (0x66 0xb4) */ - X86_OP_MOV_EBP, /* mov (0x66 0xb5) */ - X86_OP_MOV_ESI, /* mov (0x66 0xb6) */ - X86_OP_MOV_EDI, /* mov (0x66 0xb7) */ + X86_OP_HLT, /* hlt (0xf4) */ + + X86_OP_INC_AX, /* inc (0x66 0x40) */ + X86_OP_INC_CX, /* inc (0x66 0x41) */ + X86_OP_INC_DX, /* inc (0x66 0x42) */ + X86_OP_INC_BX, /* inc (0x66 0x43) */ + X86_OP_INC_SP, /* inc (0x66 0x44) */ + X86_OP_INC_BP, /* inc (0x66 0x45) */ + X86_OP_INC_SI, /* inc (0x66 0x46) */ + X86_OP_INC_DI, /* inc (0x66 0x47) */ + + X86_OP_DEC_AX, /* dec (0x66 0x48) */ + X86_OP_DEC_CX, /* dec (0x66 0x49) */ + X86_OP_DEC_DX, /* dec (0x66 0x4a) */ + X86_OP_DEC_BX, /* dec (0x66 0x4b) */ + X86_OP_DEC_SP, /* dec (0x66 0x4c) */ + X86_OP_DEC_BP, /* dec (0x66 0x4d) */ + X86_OP_DEC_SI, /* dec (0x66 0x4e) */ + X86_OP_DEC_DI, /* dec (0x66 0x4f) */ + + X86_OP_PUSH_AX, /* push (0x66 0x50) */ + X86_OP_PUSH_CX, /* push (0x66 0x51) */ + X86_OP_PUSH_DX, /* push (0x66 0x52) */ + X86_OP_PUSH_BX, /* push (0x66 0x53) */ + X86_OP_PUSH_SP, /* push (0x66 0x54) */ + X86_OP_PUSH_BP, /* push (0x66 0x55) */ + X86_OP_PUSH_SI, /* push (0x66 0x56) */ + X86_OP_PUSH_DI, /* push (0x66 0x57) */ + + X86_OP_POP_AX, /* pop (0x66 0x58) */ + X86_OP_POP_CX, /* pop (0x66 0x59) */ + X86_OP_POP_DX, /* pop (0x66 0x5a) */ + X86_OP_POP_BX, /* pop (0x66 0x5b) */ + X86_OP_POP_SP, /* pop (0x66 0x5c) */ + X86_OP_POP_BP, /* pop (0x66 0x5d) */ + X86_OP_POP_SI, /* pop (0x66 0x5e) */ + X86_OP_POP_DI, /* pop (0x66 0x5f) */ + + X86_OP_MOV_EAX, /* mov (0x66 0xb8) */ + X86_OP_MOV_ECX, /* mov (0x66 0xb9) */ + X86_OP_MOV_EDX, /* mov (0x66 0xba) */ + X86_OP_MOV_EBX, /* mov (0x66 0xbb) */ + X86_OP_MOV_ESP, /* mov (0x66 0xbc) */ + X86_OP_MOV_EBP, /* mov (0x66 0xbd) */ + X86_OP_MOV_ESI, /* mov (0x66 0xbe) */ + X86_OP_MOV_EDI, /* mov (0x66 0xbf) */ X86_OP_COUNT diff --git a/src/arch/x86/op_dec.c b/src/arch/x86/op_dec.c new file mode 100644 index 0000000..9bdbf74 --- /dev/null +++ b/src/arch/x86/op_dec.c @@ -0,0 +1,78 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * op_dec.c - décodage des décrémentations + * + * Copyright (C) 2008 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#include + + +#include "../instruction-int.h" +#include "opcodes.h" +#include "operand.h" + + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* * +* Description : Décode une instruction de type 'inc' (16 ou 32 bits). * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +asm_x86_instr *read_instr_dec_1632(const uint8_t *data, off_t *pos, off_t len) +{ + asm_x86_instr *result; /* Instruction à retourner */ + bool is_reg32; /* Implique un registre 32 bits*/ + asm_x86_operand *reg; /* Registre de destination */ + + result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); + + /* Utilisation des registres 32 bits ? */ + is_reg32 = (data[*pos] != 0x66); + if (!is_reg32) + { + (*pos)++; + } + + ASM_INSTRUCTION(result)->opcode = data[*pos]; + + reg = x86_create_reg1632_operand(data[(*pos)++], is_reg32, 0x48); + if (reg == NULL) + { + 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_hlt.c b/src/arch/x86/op_hlt.c new file mode 100644 index 0000000..ddb5882 --- /dev/null +++ b/src/arch/x86/op_hlt.c @@ -0,0 +1,56 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * op_hlt.c - décodage de la mise en pause du processeur + * + * Copyright (C) 2008 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#include + + +#include "../instruction-int.h" +#include "opcodes.h" + + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* * +* Description : Décode une instruction de type 'hlt'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +asm_x86_instr *read_instr_hlt(const uint8_t *data, off_t *pos, off_t len) +{ + asm_x86_instr *result; + + result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); + + ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; + + return result; + +} diff --git a/src/arch/x86/op_inc.c b/src/arch/x86/op_inc.c new file mode 100644 index 0000000..dd21471 --- /dev/null +++ b/src/arch/x86/op_inc.c @@ -0,0 +1,78 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * op_inc.c - décodage des incrémentations + * + * Copyright (C) 2008 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#include + + +#include "../instruction-int.h" +#include "opcodes.h" +#include "operand.h" + + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* * +* Description : Décode une instruction de type 'inc' (16 ou 32 bits). * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +asm_x86_instr *read_instr_inc_1632(const uint8_t *data, off_t *pos, off_t len) +{ + asm_x86_instr *result; /* Instruction à retourner */ + bool is_reg32; /* Implique un registre 32 bits*/ + asm_x86_operand *reg; /* Registre de destination */ + + result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); + + /* Utilisation des registres 32 bits ? */ + is_reg32 = (data[*pos] != 0x66); + if (!is_reg32) + { + (*pos)++; + } + + ASM_INSTRUCTION(result)->opcode = data[*pos]; + + reg = x86_create_reg1632_operand(data[(*pos)++], is_reg32, 0x40); + if (reg == NULL) + { + 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_mov.c b/src/arch/x86/op_mov.c index 22cb828..2ce8464 100644 --- a/src/arch/x86/op_mov.c +++ b/src/arch/x86/op_mov.c @@ -62,7 +62,7 @@ asm_x86_instr *read_instr_mov_to_1632(const uint8_t *data, off_t *pos, off_t len ASM_INSTRUCTION(result)->opcode = data[*pos]; - reg = x86_create_reg1632_operand(data[(*pos)++], is_reg32); + reg = x86_create_reg1632_operand(data[(*pos)++], is_reg32, 0xb8); if (reg == NULL) { free(result); diff --git a/src/arch/x86/op_nop.c b/src/arch/x86/op_nop.c index c23b5f1..0062186 100644 --- a/src/arch/x86/op_nop.c +++ b/src/arch/x86/op_nop.c @@ -1,6 +1,6 @@ /* OpenIDA - Outil d'analyse de fichiers binaires - * op_nop.c - décodage des instructions nulles + * op_nop.c - décodage de l'instruction nulle * * Copyright (C) 2008 Cyrille Bagard * diff --git a/src/arch/x86/op_pop.c b/src/arch/x86/op_pop.c new file mode 100644 index 0000000..3e725eb --- /dev/null +++ b/src/arch/x86/op_pop.c @@ -0,0 +1,78 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * op_pop.c - décodage des dépilements + * + * Copyright (C) 2008 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#include + + +#include "../instruction-int.h" +#include "opcodes.h" +#include "operand.h" + + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* * +* Description : Décode une instruction de type 'pop' (16 ou 32 bits). * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +asm_x86_instr *read_instr_pop_1632(const uint8_t *data, off_t *pos, off_t len) +{ + asm_x86_instr *result; /* Instruction à retourner */ + bool is_reg32; /* Implique un registre 32 bits*/ + asm_x86_operand *reg; /* Registre de destination */ + + result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); + + /* Utilisation des registres 32 bits ? */ + is_reg32 = (data[*pos] != 0x66); + if (!is_reg32) + { + (*pos)++; + } + + ASM_INSTRUCTION(result)->opcode = data[*pos]; + + reg = x86_create_reg1632_operand(data[(*pos)++], is_reg32, 0x58); + if (reg == NULL) + { + 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 new file mode 100644 index 0000000..ac5319d --- /dev/null +++ b/src/arch/x86/op_push.c @@ -0,0 +1,78 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * op_push.c - décodage des empilements + * + * Copyright (C) 2008 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#include + + +#include "../instruction-int.h" +#include "opcodes.h" +#include "operand.h" + + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* * +* Description : Décode une instruction de type 'push' (16 ou 32 bits). * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +asm_x86_instr *read_instr_push_1632(const uint8_t *data, off_t *pos, off_t len) +{ + asm_x86_instr *result; /* Instruction à retourner */ + bool is_reg32; /* Implique un registre 32 bits*/ + asm_x86_operand *reg; /* Registre de destination */ + + result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); + + /* Utilisation des registres 32 bits ? */ + is_reg32 = (data[*pos] != 0x66); + if (!is_reg32) + { + (*pos)++; + } + + ASM_INSTRUCTION(result)->opcode = data[*pos]; + + reg = x86_create_reg1632_operand(data[(*pos)++], is_reg32, 0x50); + if (reg == NULL) + { + 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/opcodes.h b/src/arch/x86/opcodes.h index d6be6a1..f847b48 100644 --- a/src/arch/x86/opcodes.h +++ b/src/arch/x86/opcodes.h @@ -32,6 +32,15 @@ +/* Décode une instruction de type 'dec'. */ +asm_x86_instr *read_instr_dec_1632(const uint8_t *, off_t *, off_t); + +/* Décode une instruction de type 'hlt'. */ +asm_x86_instr *read_instr_hlt(const uint8_t *, off_t *, off_t); + +/* Décode une instruction de type 'inc'. */ +asm_x86_instr *read_instr_inc_1632(const uint8_t *, off_t *, off_t); + /* Décode une instruction de type 'int'. */ asm_x86_instr *read_instr_int(const uint8_t *, off_t *, off_t); @@ -41,6 +50,12 @@ asm_x86_instr *read_instr_mov_to_1632(const uint8_t *, off_t *, off_t); /* Décode une instruction de type 'nop'. */ asm_x86_instr *read_instr_nop(const uint8_t *, off_t *, off_t); +/* Décode une instruction de type 'pop' (16 ou 32 bits). */ +asm_x86_instr *read_instr_pop_1632(const uint8_t *, off_t *, off_t); + +/* Décode une instruction de type 'push' (16 ou 32 bits). */ +asm_x86_instr *read_instr_push_1632(const uint8_t *, off_t *, off_t); + #endif /* _ARCH_X86_OPCODES_H */ diff --git a/src/arch/x86/operand.c b/src/arch/x86/operand.c index 84d4038..4b8eef8 100644 --- a/src/arch/x86/operand.c +++ b/src/arch/x86/operand.c @@ -130,6 +130,7 @@ asm_x86_operand *create_new_x86_operand(void) * * * 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. * * * @@ -139,17 +140,17 @@ asm_x86_operand *create_new_x86_operand(void) * * ******************************************************************************/ -asm_x86_operand *x86_create_reg1632_operand(uint8_t data, bool is_reg32) +asm_x86_operand *x86_create_reg1632_operand(uint8_t data, bool is_reg32, uint8_t base) { asm_x86_operand *result; /* Registre à retourner */ X8616bRegister reg16; /* Registre 16 bits */ X8632bRegister reg32; /* Registre 32 bits */ if (is_reg32) - switch (data - 0xb8) + switch (data - base) { case 0 ... 7: - reg32 = (X8632bRegister)(data - 0xb8); + reg32 = (X8632bRegister)(data - base); break; default: return NULL; @@ -157,10 +158,10 @@ asm_x86_operand *x86_create_reg1632_operand(uint8_t data, bool is_reg32) } else - switch (data - 0xb0) + switch (data - base) { case 0 ... 7: - reg16 = (X8616bRegister)(data - 0xb0); + reg16 = (X8616bRegister)(data - base); break; default: return NULL; diff --git a/src/arch/x86/operand.h b/src/arch/x86/operand.h index 0773333..ebbdd50 100644 --- a/src/arch/x86/operand.h +++ b/src/arch/x86/operand.h @@ -43,7 +43,7 @@ asm_x86_operand *create_new_x86_operand(void); /* Crée une opérande renvoyant vers un registre 16 ou 32 bits. */ -asm_x86_operand *x86_create_reg1632_operand(uint8_t, bool); +asm_x86_operand *x86_create_reg1632_operand(uint8_t, bool, uint8_t); /*Traduit une opérande de registre en texte. */ void x86_print_reg_operand(const asm_x86_operand *, char *, size_t, AsmSyntax); diff --git a/src/arch/x86/processor.c b/src/arch/x86/processor.c index 895c8b1..9c7f2bd 100644 --- a/src/arch/x86/processor.c +++ b/src/arch/x86/processor.c @@ -130,14 +130,50 @@ asm_processor *create_x86_processor(void) void x86_register_instructions(asm_x86_processor *proc) { - + /* TODO : voir pour une inversion avec le mode 16 bits ! */ + + register_opcode(proc->opcodes[X86_OP_INC_EAX], 0x00, 0x40, "inc", read_instr_inc_1632); + register_opcode(proc->opcodes[X86_OP_INC_ECX], 0x00, 0x41, "inc", read_instr_inc_1632); + register_opcode(proc->opcodes[X86_OP_INC_EDX], 0x00, 0x42, "inc", read_instr_inc_1632); + register_opcode(proc->opcodes[X86_OP_INC_EBX], 0x00, 0x43, "inc", read_instr_inc_1632); + register_opcode(proc->opcodes[X86_OP_INC_ESP], 0x00, 0x44, "inc", read_instr_inc_1632); + register_opcode(proc->opcodes[X86_OP_INC_EBP], 0x00, 0x45, "inc", read_instr_inc_1632); + register_opcode(proc->opcodes[X86_OP_INC_ESI], 0x00, 0x46, "inc", read_instr_inc_1632); + register_opcode(proc->opcodes[X86_OP_INC_EDI], 0x00, 0x47, "inc", read_instr_inc_1632); + + register_opcode(proc->opcodes[X86_OP_DEC_EAX], 0x00, 0x48, "dec", read_instr_dec_1632); + register_opcode(proc->opcodes[X86_OP_DEC_ECX], 0x00, 0x49, "dec", read_instr_dec_1632); + register_opcode(proc->opcodes[X86_OP_DEC_EDX], 0x00, 0x4a, "dec", read_instr_dec_1632); + register_opcode(proc->opcodes[X86_OP_DEC_EBX], 0x00, 0x4b, "dec", read_instr_dec_1632); + register_opcode(proc->opcodes[X86_OP_DEC_ESP], 0x00, 0x4c, "dec", read_instr_dec_1632); + register_opcode(proc->opcodes[X86_OP_DEC_EBP], 0x00, 0x4d, "dec", read_instr_dec_1632); + 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_NOP], 0x00, 0x90, "nop", read_instr_nop); register_opcode(proc->opcodes[X86_OP_MOV_AX], 0x00, 0xb8, "mov", read_instr_mov_to_1632); - register_opcode(proc->opcodes[X86_OP_MOV_DX], 0x00, 0xb9, "mov", read_instr_mov_to_1632); + register_opcode(proc->opcodes[X86_OP_MOV_CX], 0x00, 0xb9, "mov", read_instr_mov_to_1632); register_opcode(proc->opcodes[X86_OP_MOV_DX], 0x00, 0xba, "mov", read_instr_mov_to_1632); register_opcode(proc->opcodes[X86_OP_MOV_BX], 0x00, 0xbb, "mov", read_instr_mov_to_1632); register_opcode(proc->opcodes[X86_OP_MOV_SP], 0x00, 0xbc, "mov", read_instr_mov_to_1632); @@ -149,6 +185,44 @@ 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_HLT], 0x00, 0xf4, "hlt", read_instr_hlt); + + + register_opcode(proc->opcodes[X86_OP_INC_AX], 0x66, 0x40, "inc", read_instr_inc_1632); + register_opcode(proc->opcodes[X86_OP_INC_CX], 0x66, 0x41, "inc", read_instr_inc_1632); + register_opcode(proc->opcodes[X86_OP_INC_DX], 0x66, 0x42, "inc", read_instr_inc_1632); + register_opcode(proc->opcodes[X86_OP_INC_BX], 0x66, 0x43, "inc", read_instr_inc_1632); + register_opcode(proc->opcodes[X86_OP_INC_SP], 0x66, 0x44, "inc", read_instr_inc_1632); + register_opcode(proc->opcodes[X86_OP_INC_BP], 0x66, 0x45, "inc", read_instr_inc_1632); + register_opcode(proc->opcodes[X86_OP_INC_SI], 0x66, 0x46, "inc", read_instr_inc_1632); + register_opcode(proc->opcodes[X86_OP_INC_DI], 0x66, 0x47, "inc", read_instr_inc_1632); + + register_opcode(proc->opcodes[X86_OP_DEC_AX], 0x66, 0x48, "dec", read_instr_dec_1632); + register_opcode(proc->opcodes[X86_OP_DEC_CX], 0x66, 0x49, "dec", read_instr_dec_1632); + register_opcode(proc->opcodes[X86_OP_DEC_DX], 0x66, 0x4a, "dec", read_instr_dec_1632); + register_opcode(proc->opcodes[X86_OP_DEC_BX], 0x66, 0x4b, "dec", read_instr_dec_1632); + register_opcode(proc->opcodes[X86_OP_DEC_SP], 0x66, 0x4c, "dec", read_instr_dec_1632); + register_opcode(proc->opcodes[X86_OP_DEC_BP], 0x66, 0x4d, "dec", read_instr_dec_1632); + 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_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); @@ -194,6 +268,7 @@ asm_instr *x86_fetch_instruction(const asm_x86_processor *proc, const uint8_t *d { result = proc->opcodes[i].read(data, pos, len); if (result != NULL) result->type = i; + printf("err while decoding :: [0x%02hhx] 0x%02hhx\n", proc->opcodes[i].prefix, proc->opcodes[i].opcode); break; } diff --git a/src/binary.c b/src/binary.c index eee4d2b..5f07703 100644 --- a/src/binary.c +++ b/src/binary.c @@ -35,6 +35,9 @@ #include "arch/processor.h" +#include "format/elf/format_elf.h" + + /* Charge en mémoire le contenu d'un fichier. */ @@ -116,6 +119,7 @@ void fill_snippet(GtkSnippet *snippet) //uint8_t *data = "\x66\xbb\x00\x00\x00\x00\x66\xb8\x01\x00\x00\x00\xcd\x80\x90"; + off_t start; off_t pos; off_t len; @@ -133,11 +137,13 @@ void fill_snippet(GtkSnippet *snippet) bin_data = map_binary_file("/tmp/hello", &length); - printf(" ~~ bin_data ~~ :: %p\n", bin_data); + printf(" ~~ bin_data ~~ :: %p (%d)\n", bin_data, length); + if (bin_data != NULL) + find_text_data(bin_data, &pos, &len); + - ret = munmap(bin_data, length); gtk_snippet_set_processor(snippet, proc); @@ -146,6 +152,32 @@ void fill_snippet(GtkSnippet *snippet) gtk_snippet_add_line(snippet, offset, NULL, "Simple HelloWorld !"); +#if 1 + + start = pos; + pos = 0; + + while (pos < len) + { + offset = base + pos; + + instr = decode_instruction(proc, &bin_data[start], &pos, len); + + gtk_snippet_add_line(snippet, offset, instr, NULL); + + + } + + + ret = munmap(bin_data, length); + + +#else + + pos = 0; + len = 0x28; + + while (pos < len) { offset = base + pos; @@ -187,6 +219,7 @@ void fill_snippet(GtkSnippet *snippet) } +#endif /* gtk_snippet_build_content(snippet); diff --git a/src/format/elf/format_elf.c b/src/format/elf/format_elf.c index f043d0a..b70eef5 100644 --- a/src/format/elf/format_elf.c +++ b/src/format/elf/format_elf.c @@ -22,3 +22,104 @@ #include "elf.h" + + + + + + + + + + +#include +#include +#include +#include +#include +#include +#include + + +char *read_section_names(const uint8_t *content, Elf32_Off offset) +{ + char *result; + Elf32_Shdr section; + + result = NULL; + + memcpy(§ion, &content[offset], sizeof(Elf32_Shdr)); + + result = (char *)calloc(section.sh_size + 1, sizeof(char)); + + memcpy(result, &content[section.sh_offset], section.sh_size); + + return result; + +} + + +bool find_target_section(const uint8_t *content, const char *target, const char *names, Elf32_Off offset, Elf32_Shdr *data) +{ + bool result; + Elf32_Shdr section; + + result = false; + + memcpy(§ion, &content[offset], sizeof(Elf32_Shdr)); + + result = (strcmp(target, &names[section.sh_name]) == 0); + + if (result) + { + printf("section: %s (0x%08x)\n", &names[section.sh_name], section.sh_addr); + *data = section; + } + + return result; + +} + + + +bool find_text_data(const uint8_t *content, off_t *offset, off_t *size) +{ + bool result; + Elf32_Ehdr header; + char *names; + Elf32_Half i; + Elf32_Shdr data; + + result = false; + + memcpy(&header, content, sizeof(Elf32_Ehdr)); + + names = read_section_names(content, header.e_shoff + header.e_shentsize * header.e_shstrndx); + if (names == NULL) + { + fprintf(stderr, "no section header string table\n"); + return NULL; + } + + for (i = 0; i < header.e_shnum; i++) + { + if (i == header.e_shstrndx) continue; + + if (find_target_section(content, ".text", names, header.e_shoff + header.e_shentsize * i, &data)) + { + printf("Find it !\n"); + + *offset = data.sh_offset; + *size = data.sh_size; + + result = true; + + } + + } + + free(names); + + return result; + +} diff --git a/src/format/elf/format_elf.h b/src/format/elf/format_elf.h index 894623a..feca71d 100644 --- a/src/format/elf/format_elf.h +++ b/src/format/elf/format_elf.h @@ -26,9 +26,15 @@ +#include +#include +#include +bool find_text_data(const uint8_t *content, off_t *, off_t *); + + #endif /* _FORMAT_ELF_H */ -- cgit v0.11.2-87-g4458