From 57758c2cd11938e3e4c6e45b983cee4c2269ff44 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
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 <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 */
-- 
cgit v0.11.2-87-g4458