summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2008-07-29 22:31:55 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2008-07-29 22:31:55 (GMT)
commit57758c2cd11938e3e4c6e45b983cee4c2269ff44 (patch)
treeade6e434f0a5e68dec379c20432a09dd1cc75a1a
parent4d004094424bb1fc52082f2e442c4c43a5525fe1 (diff)
Loaded the executable part of an ELF file.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@10 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
-rw-r--r--ChangeLog42
-rw-r--r--src/arch/x86/Makefile.am5
-rw-r--r--src/arch/x86/instruction.h106
-rw-r--r--src/arch/x86/op_dec.c78
-rw-r--r--src/arch/x86/op_hlt.c56
-rw-r--r--src/arch/x86/op_inc.c78
-rw-r--r--src/arch/x86/op_mov.c2
-rw-r--r--src/arch/x86/op_nop.c2
-rw-r--r--src/arch/x86/op_pop.c78
-rw-r--r--src/arch/x86/op_push.c78
-rw-r--r--src/arch/x86/opcodes.h15
-rw-r--r--src/arch/x86/operand.c11
-rw-r--r--src/arch/x86/operand.h2
-rw-r--r--src/arch/x86/processor.c79
-rw-r--r--src/binary.c37
-rw-r--r--src/format/elf/format_elf.c101
-rw-r--r--src/format/elf/format_elf.h6
17 files changed, 748 insertions, 28 deletions
diff --git a/ChangeLog b/ChangeLog
index 2e95604..202b23d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,45 @@
+2008-07-30 Cyrille Bagard <nocbos@gmail.com>
+
+ * 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 <nocbos@gmail.com>
* 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include <malloc.h>
+
+
+#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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include <malloc.h>
+
+
+#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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include <malloc.h>
+
+
+#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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include <malloc.h>
+
+
+#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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include <malloc.h>
+
+
+#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 <ctype.h>
+#include <elf.h>
+#include <malloc.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+char *read_section_names(const uint8_t *content, Elf32_Off offset)
+{
+ char *result;
+ Elf32_Shdr section;
+
+ result = NULL;
+
+ memcpy(&section, &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(&section, &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 <stdbool.h>
+#include <stdint.h>
+#include <sys/types.h>
+bool find_text_data(const uint8_t *content, off_t *, off_t *);
+
+
#endif /* _FORMAT_ELF_H */