summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/analysis/binary.c98
-rw-r--r--src/analysis/line-int.h5
-rw-r--r--src/analysis/line.c49
-rw-r--r--src/analysis/line.h3
-rw-r--r--src/analysis/line_code.c19
-rw-r--r--src/analysis/line_code.h3
-rw-r--r--src/arch/artificial.c25
-rw-r--r--src/arch/immediate.c43
-rw-r--r--src/arch/immediate.h4
-rw-r--r--src/arch/instruction-int.h6
-rw-r--r--src/arch/instruction.c45
-rw-r--r--src/arch/instruction.h24
-rw-r--r--src/arch/x86/instruction.c75
-rw-r--r--src/arch/x86/operand.c20
-rw-r--r--src/arch/x86/operand.h4
15 files changed, 407 insertions, 16 deletions
diff --git a/src/analysis/binary.c b/src/analysis/binary.c
index 61d344e..6b5697a 100644
--- a/src/analysis/binary.c
+++ b/src/analysis/binary.c
@@ -87,6 +87,9 @@ GRenderingLine *build_binary_prologue(const char *, const uint8_t *, off_t);
/* Procède au désassemblage basique d'un contenu binaire. */
void disassemble_openida_binary(openida_binary *);
+/* Etablit les liens entres les différentes lignes de code. */
+void establish_links_in_openida_binary(const openida_binary *);
+
/******************************************************************************
@@ -665,7 +668,7 @@ void disassemble_openida_binary(openida_binary *binary)
}
-
+ establish_links_in_openida_binary(binary);
line = g_rendering_line_find_by_address(binary->lines, NULL, get_exe_entry_point(binary->format));
if (line != NULL) g_rendering_line_add_flag(line, RLF_ENTRY_POINT);
@@ -674,3 +677,96 @@ void disassemble_openida_binary(openida_binary *binary)
}
+
+
+/******************************************************************************
+* *
+* Paramètres : binary = binaire dont le contenu est à lier. *
+* *
+* Description : Etablit les liens entres les différentes lignes de code. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void establish_links_in_openida_binary(const openida_binary *binary)
+{
+ GBinRoutine **routines; /* Liste des routines trouvées */
+ size_t routines_count; /* Nombre de ces routines */
+ size_t i; /* Boucle de parcours */
+ vmpa_t start; /* Adresse de départ */
+ vmpa_t end; /* Adresse de fin */
+ GRenderingLine *iter; /* Boucle de parcours */
+ GArchInstruction *instr; /* Instruction à ausculter */
+ vmpa_t addr; /* Adresse référencée */
+ InstructionLinkType type; /* Type de référence */
+ GRenderingLine *target; /* Ligne visée par la référence*/
+
+ routines = get_all_exe_routines(binary->format, &routines_count);
+
+ for (i = 0; i < routines_count; i++)
+ {
+ start = g_binary_routine_get_address(routines[i]);
+ end = start + g_binary_routine_get_size(routines[i]);
+
+ for (iter = g_rendering_line_find_by_address(binary->lines, NULL, start);
+ iter != NULL;
+ iter = g_rendering_line_get_next_iter(binary->lines, iter, NULL))
+ {
+ /* Si on sort de la zone... */
+ if (get_rendering_line_address(iter) >= end) break;
+
+ /* On ne traite que du code ici ! */
+ if (!G_IS_CODE_LINE(iter)) continue;
+
+ instr = g_code_line_get_instruction(G_CODE_LINE(iter));
+ type = g_arch_instruction_get_link(instr, &addr);
+
+ switch (type)
+ {
+ case ILT_NONE:
+ break;
+
+ case ILT_JUMP:
+
+ target = g_rendering_line_find_by_address(binary->lines, NULL, addr);
+
+ if (target != NULL)
+ g_rendering_line_link_with(iter, target, type);
+
+ break;
+
+ case ILT_JUMP_IF_TRUE:
+
+ target = g_rendering_line_find_by_address(binary->lines, NULL, addr);
+
+ if (target != NULL)
+ {
+ g_rendering_line_link_with(iter, target, type);
+
+ target = g_rendering_line_get_next_iter(binary->lines, iter, NULL);
+ if (target != NULL)
+ g_rendering_line_link_with(iter, target, ILT_JUMP_IF_FALSE);
+
+ }
+
+ break;
+
+ case ILT_CALL:
+
+ target = g_rendering_line_find_by_address(binary->lines, NULL, addr);
+
+ if (target != NULL)
+ g_rendering_line_link_with(iter, target, type);
+
+ break;
+
+ }
+
+ }
+
+ }
+
+}
diff --git a/src/analysis/line-int.h b/src/analysis/line-int.h
index a70df85..97aa93c 100644
--- a/src/analysis/line-int.h
+++ b/src/analysis/line-int.h
@@ -51,6 +51,11 @@ struct _GRenderingLine
RenderingLineType type; /* Type de représentation */
RenderingLineFlag flags; /* Extension d'informations */
+ GRenderingLine **from; /* Origines des références */
+ size_t from_count; /* Nombre de ces origines */
+ GRenderingLine *to; /* Eventuelle ligne visée */
+ InstructionLinkType link_type; /* Type de visée */
+
PangoLayout *layout; /* Moteur de rendu du code/txt */
get_bin_len_fc get_bin_len; /* Nbre d'octets représentés */
diff --git a/src/analysis/line.c b/src/analysis/line.c
index 08ef3c1..31a8a36 100644
--- a/src/analysis/line.c
+++ b/src/analysis/line.c
@@ -48,6 +48,9 @@ static void g_rendering_line_class_init(GRenderingLineClass *);
/* Initialise une instance de ligne de représentation. */
static void g_rendering_line_init(GRenderingLine *);
+/* Etablit un lien entre deux lignes de représentation. */
+static void g_rendering_line_add_link_reference(GRenderingLine *, GRenderingLine *);
+
/* Charge une image destinée à être rendue avec la ligne. */
static GdkPixbuf *g_rendering_line_render_icon(const GRenderingLine *, const char *, GtkIconSize);
@@ -247,6 +250,52 @@ RenderingLineFlag g_rendering_line_get_flags(const GRenderingLine *line)
/******************************************************************************
* *
+* Paramètres : line = ligne dont les informations sont à consulter. *
+* src = ligne visée par la liaison (côté origine). *
+* *
+* Description : Etablit un lien entre deux lignes de représentation. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_rendering_line_add_link_reference(GRenderingLine *line, GRenderingLine *src)
+{
+ line->from = (GRenderingLine **)realloc(line->from, ++line->from_count * sizeof(GRenderingLine *));
+
+ line->from[line->from_count - 1] = src;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : line = ligne dont les informations sont à consulter. *
+* dest = ligne visée par la liaison (côté destination). *
+* type = type de lien à construire. *
+* *
+* Description : Etablit un lien entre deux lignes de représentation. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_rendering_line_link_with(GRenderingLine *line, GRenderingLine *dest, InstructionLinkType type)
+{
+ g_rendering_line_add_link_reference(dest, line);
+
+ line->to = dest;
+ line->link_type = type;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : line = ligne dont les informations sont à consulter. *
* stock_id = identifiant GTK de l'image à charger. *
* size = taille de l'image souhaitée. *
diff --git a/src/analysis/line.h b/src/analysis/line.h
index 69deb57..b27bd9b 100644
--- a/src/analysis/line.h
+++ b/src/analysis/line.h
@@ -101,6 +101,9 @@ void g_rendering_line_toggle_flag(GRenderingLine *, RenderingLineFlag);
/* Fournit les informations supplémentaires d'une ligne. */
RenderingLineFlag g_rendering_line_get_flags(const GRenderingLine *);
+/* Etablit un lien entre deux lignes de représentation. */
+void g_rendering_line_link_with(GRenderingLine *, GRenderingLine *, InstructionLinkType);
+
/* Procède à l'initialisation des bases d'une représentation. */
void g_rendering_line_draw(GRenderingLine *, GdkDrawable *, GdkGC *, gint, gint, gint, gint);
diff --git a/src/analysis/line_code.c b/src/analysis/line_code.c
index cd7eba6..dcb8c5e 100644
--- a/src/analysis/line_code.c
+++ b/src/analysis/line_code.c
@@ -294,3 +294,22 @@ GRenderingLine *g_code_line_new(uint64_t offset, GArchInstruction *instr, const
return G_RENDERING_LINE(result);
}
+
+
+/******************************************************************************
+* *
+* Paramètres : line = line de rendu à consulter. *
+* *
+* Description : Fournit l'instruction associée à la ligne de code binaire. *
+* *
+* Retour : Adresse de l'instruction associée. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchInstruction *g_code_line_get_instruction(const GCodeLine *line)
+{
+ return line->instr;
+
+}
diff --git a/src/analysis/line_code.h b/src/analysis/line_code.h
index 8a06f28..9c9d8e9 100644
--- a/src/analysis/line_code.h
+++ b/src/analysis/line_code.h
@@ -54,6 +54,9 @@ GType g_code_line_get_type(void);
/* Crée une ligne de code binaire. */
GRenderingLine *g_code_line_new(uint64_t, GArchInstruction *, const disass_options *);
+/* Fournit l'instruction associée à la ligne de code binaire. */
+GArchInstruction *g_code_line_get_instruction(const GCodeLine *);
+
#endif /* _ANALYSIS_LINE_CODE_H */
diff --git a/src/arch/artificial.c b/src/arch/artificial.c
index d718a8c..6783579 100644
--- a/src/arch/artificial.c
+++ b/src/arch/artificial.c
@@ -56,6 +56,10 @@ static void g_db_instruction_init(GDbInstruction *);
/* Traduit une instruction en version humainement lisible. */
static const char *g_db_instruction_get_text(const GDbInstruction *, const exe_format *, AsmSyntax);
+/* Informe sur une éventuelle référence à une autre instruction. */
+static InstructionLinkType g_db_instruction_get_link(const GDbInstruction *, vmpa_t *);
+
+
/* ---------------------------------------------------------------------------------- */
/* INSTRUCTION INCONNUE / DONNEES */
@@ -103,6 +107,7 @@ static void g_db_instruction_init(GDbInstruction *instr)
parent = G_ARCH_INSTRUCTION(instr);
parent->get_text = (get_instruction_text_fc)g_db_instruction_get_text;
+ parent->get_link = (get_instruction_link_fc)g_db_instruction_get_link;
}
@@ -166,3 +171,23 @@ static const char *g_db_instruction_get_text(const GDbInstruction *instr, const
return "db";
}
+
+
+/******************************************************************************
+* *
+* Paramètres : instr = instruction à consulter. *
+* addr = eventuelle adresse associée à faire connaître. [OUT] *
+* *
+* Description : Informe sur une éventuelle référence à une autre instruction.*
+* *
+* Retour : Type de lien trouvé ou ILT_NONE si aucun. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static InstructionLinkType g_db_instruction_get_link(const GDbInstruction *instr, vmpa_t *addr)
+{
+ return ILT_NONE;
+
+}
diff --git a/src/arch/immediate.c b/src/arch/immediate.c
index f8c2474..3bc4712 100644
--- a/src/arch/immediate.c
+++ b/src/arch/immediate.c
@@ -466,3 +466,46 @@ static char *g_imm_operand_get_text(const GImmOperand *operand, const exe_format
return result;
}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = opérande à traiter. *
+* addr = valeur résultante. [OUT] *
+* *
+* Description : Convertit une valeur immédiate en adresse de type vmpa_t. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_imm_operand_to_vmpa_t(const GImmOperand *operand, vmpa_t *addr)
+{
+ bool result; /* Bilan à renvoyer */
+
+ result = true;
+
+ switch (operand->size)
+ {
+ case AOS_8_BITS_UNSIGNED:
+ *addr = operand->unsigned_imm.val8;
+ break;
+ case AOS_16_BITS_UNSIGNED:
+ *addr = operand->unsigned_imm.val16;
+ break;
+ case AOS_32_BITS_UNSIGNED:
+ *addr = operand->unsigned_imm.val32;
+ break;
+ case AOS_64_BITS_UNSIGNED:
+ *addr = operand->unsigned_imm.val64;
+ break;
+ default:
+ result = false;
+ break;
+ }
+
+ return result;
+
+}
diff --git a/src/arch/immediate.h b/src/arch/immediate.h
index 1b77290..1dcc548 100644
--- a/src/arch/immediate.h
+++ b/src/arch/immediate.h
@@ -26,6 +26,7 @@
#include <glib-object.h>
+#include <stdbool.h>
#include "archbase.h"
@@ -59,6 +60,9 @@ GArchOperand *g_imm_operand_new_from_value(AsmOperandSize, ...);
/* Indique le signe d'une valeur immédiate. */
bool g_imm_operand_is_negative(const GImmOperand *);
+/* Convertit une valeur immédiate en adresse de type vmpa_t. */
+bool g_imm_operand_to_vmpa_t(const GImmOperand *, vmpa_t *);
+
#endif /* _ARCH_IMMEDIATE_H */
diff --git a/src/arch/instruction-int.h b/src/arch/instruction-int.h
index f61485f..6ae0597 100644
--- a/src/arch/instruction-int.h
+++ b/src/arch/instruction-int.h
@@ -33,14 +33,15 @@
/* Traduit une instruction en version humainement lisible. */
typedef const char * (* get_instruction_text_fc) (const GArchInstruction *, const exe_format *, AsmSyntax);
+/* Informe sur une éventuelle référence à une autre instruction. */
+typedef InstructionLinkType (* get_instruction_link_fc) (const GArchInstruction *, vmpa_t *);
+
/* Définition générique d'une instruction d'architecture (instance) */
struct _GArchInstruction
{
GObject parent; /* A laisser en premier */
- ArchInstructionType type; /* Type d'instruction */
-
off_t offset; /* Position physique de départ */
off_t length; /* Taille de l'instruction */
@@ -50,6 +51,7 @@ struct _GArchInstruction
size_t operands_count; /* Nbre. d'opérandes utilisées */
get_instruction_text_fc get_text; /* Texte humain équivalent */
+ get_instruction_link_fc get_link; /* Référence à une instruction */
};
diff --git a/src/arch/instruction.c b/src/arch/instruction.c
index 21e72b7..69644dc 100644
--- a/src/arch/instruction.c
+++ b/src/arch/instruction.c
@@ -202,6 +202,31 @@ void g_arch_instruction_attach_extra_operand(GArchInstruction *instr, GArchOpera
/******************************************************************************
* *
+* Paramètres : instr = instance à mettre à jour. *
+* index = indice de l'opérande concernée. *
+* *
+* Description : Fournit un opérande donné d'une instruction. *
+* *
+* Retour : Opérande trouvée ou NULL si aucune. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+const GArchOperand *g_arch_instruction_get_operand(GArchInstruction *instr, size_t index)
+{
+ const GArchOperand *result; /* Opérande à retourner */
+
+ if (index >= instr->operands_count) result = NULL;
+ else result = instr->operands[index];
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : instr = instance à mettre à jour. *
* opererand = instruction à venir dissocier. *
* *
@@ -276,3 +301,23 @@ char *g_arch_instruction_get_text(const GArchInstruction *instr, const exe_forma
return result;
}
+
+
+/******************************************************************************
+* *
+* Paramètres : instr = instruction à consulter. *
+* addr = eventuelle adresse associée à faire connaître. [OUT] *
+* *
+* Description : Informe sur une éventuelle référence à une autre instruction.*
+* *
+* Retour : Type de lien trouvé ou ILT_NONE si aucun. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+InstructionLinkType g_arch_instruction_get_link(const GArchInstruction *instr, vmpa_t *addr)
+{
+ return instr->get_link(instr, addr);
+
+}
diff --git a/src/arch/instruction.h b/src/arch/instruction.h
index ff0fd4a..b8be830 100644
--- a/src/arch/instruction.h
+++ b/src/arch/instruction.h
@@ -36,19 +36,15 @@
/* Typage des instructions rencontrées */
-typedef enum _ArchInstructionType
+typedef enum _InstructionLinkType
{
- AIT_OTHER, /* Instruction inintéressante */
+ ILT_NONE, /* Aucune instruction visée */
+ ILT_JUMP, /* Saut inconditionnel */
+ ILT_JUMP_IF_TRUE, /* Saut conditionnel (si vrai) */
+ ILT_JUMP_IF_FALSE, /* Saut conditionnel (si faux) */
+ ILT_CALL /* Appel d'une fonction */
- AIT_DB, /* Instruction non décodée */
-
- AIT_PUSH, /* Empilement de valeur */
- AIT_POP, /* Dépilement de valeur */
- AIT_JUMP, /* Saut à une adresse */
-
- AIT_CALL /* Appel d'une fonction */
-
-} ArchInstructionType;
+} InstructionLinkType;
#define G_TYPE_ARCH_INSTRUCTION g_arch_instruction_get_type()
@@ -82,12 +78,18 @@ void g_arch_instruction_attach_two_operands(GArchInstruction *, GArchOperand *,
/* Attache un opérande supplémentaire à une instruction. */
void g_arch_instruction_attach_extra_operand(GArchInstruction *, GArchOperand *);
+/* Fournit un opérande donné d'une instruction. */
+const GArchOperand *g_arch_instruction_get_operand(GArchInstruction *, size_t);
+
/* Détache un opérande liée d'une instruction. */
void g_arch_instruction_detach_operand(GArchInstruction *, GArchOperand *);
/* Traduit une instruction en version humainement lisible. */
char *g_arch_instruction_get_text(const GArchInstruction *, const exe_format *, AsmSyntax);
+/* Informe sur une éventuelle référence à une autre instruction. */
+InstructionLinkType g_arch_instruction_get_link(const GArchInstruction *, vmpa_t *);
+
#endif /* _ARCH_INSTRUCTION_H */
diff --git a/src/arch/x86/instruction.c b/src/arch/x86/instruction.c
index f9dd828..67a1fe0 100644
--- a/src/arch/x86/instruction.c
+++ b/src/arch/x86/instruction.c
@@ -24,6 +24,7 @@
#include "instruction.h"
+#include "operand.h"
#include "../instruction-int.h"
#include "../../common/extstr.h"
@@ -312,7 +313,8 @@ static x86_instruction _instructions[XOP_COUNT] = {
/* Traduit une instruction en version humainement lisible. */
static const char *x86_get_instruction_text(const GX86Instruction *, const exe_format *, AsmSyntax);
-
+/* Informe sur une éventuelle référence à une autre instruction. */
+static InstructionLinkType x86_get_instruction_link(const GX86Instruction *, vmpa_t *);
@@ -359,6 +361,7 @@ static void g_x86_instruction_init(GX86Instruction *instr)
parent = G_ARCH_INSTRUCTION(instr);
parent->get_text = (get_instruction_text_fc)x86_get_instruction_text;
+ parent->get_link = (get_instruction_link_fc)x86_get_instruction_link;
}
@@ -510,3 +513,73 @@ static const char *x86_get_instruction_text(const GX86Instruction *instr, const
return result;
}
+
+
+/******************************************************************************
+* *
+* Paramètres : instr = instruction à consulter. *
+* addr = eventuelle adresse associée à faire connaître. [OUT] *
+* *
+* Description : Informe sur une éventuelle référence à une autre instruction.*
+* *
+* Retour : Type de lien trouvé ou ILT_NONE si aucun. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static InstructionLinkType x86_get_instruction_link(const GX86Instruction *instr, vmpa_t *addr)
+{
+ InstructionLinkType result; /* Type de lien à retourner */
+ const GX86RelativeOperand *relative; /* Adresse relative */
+
+ switch (instr->type)
+ {
+ case XOP_JO_REL8:
+ case XOP_JNO_REL8:
+ case XOP_JB_REL8:
+ case XOP_JNB_REL8:
+ case XOP_JE_REL8:
+ case XOP_JNE_REL8:
+ case XOP_JNA_REL8:
+ case XOP_JA_REL8:
+ case XOP_JS_REL8:
+ case XOP_JNS_REL8:
+ case XOP_JP_REL8:
+ case XOP_JNP_REL8:
+ case XOP_JL_REL8:
+ case XOP_JNL_REL8:
+ case XOP_JNG_REL8:
+ case XOP_JG_REL8:
+ relative = G_X86_RELATIVE_OPERAND(g_arch_instruction_get_operand(G_ARCH_INSTRUCTION(instr), 0));
+ if (g_imm_operand_to_vmpa_t(g_x86_relative_operand_get_value(relative), addr)) result = ILT_JUMP_IF_TRUE;
+ else result = ILT_NONE;
+ break;
+
+ case XOP_CALL_REL1632:
+ relative = G_X86_RELATIVE_OPERAND(g_arch_instruction_get_operand(G_ARCH_INSTRUCTION(instr), 0));
+ if (g_imm_operand_to_vmpa_t(g_x86_relative_operand_get_value(relative), addr)) result = ILT_CALL;
+ else result = ILT_NONE;
+ break;
+
+ case XOP_JMP_REL1632:
+ relative = G_X86_RELATIVE_OPERAND(g_arch_instruction_get_operand(G_ARCH_INSTRUCTION(instr), 0));
+ if (g_imm_operand_to_vmpa_t(g_x86_relative_operand_get_value(relative), addr)) result = ILT_JUMP;
+ else result = ILT_NONE;
+ break;
+
+ case XOP_JMP_REL8:
+ relative = G_X86_RELATIVE_OPERAND(g_arch_instruction_get_operand(G_ARCH_INSTRUCTION(instr), 0));
+ if (g_imm_operand_to_vmpa_t(g_x86_relative_operand_get_value(relative), addr)) result = ILT_JUMP;
+ else result = ILT_NONE;
+ break;
+
+ default:
+ result = ILT_NONE;
+ break;
+
+ }
+
+ return result;
+
+}
diff --git a/src/arch/x86/operand.c b/src/arch/x86/operand.c
index 5e01fd7..8f218fc 100644
--- a/src/arch/x86/operand.c
+++ b/src/arch/x86/operand.c
@@ -30,7 +30,6 @@
#include "registers.h"
-#include "../immediate.h"
#include "../operand.h"
#include "../operand-int.h"
#include "../../common/extstr.h"
@@ -787,6 +786,25 @@ static char *g_x86_relative_operand_get_text(const GX86RelativeOperand *operand,
}
+/******************************************************************************
+* *
+* Paramètres : operand = opérande à traiter. *
+* *
+* Description : Fournit l'adresse relative représentée par une opérande X86. *
+* *
+* Retour : Valeur portée par l'opérande. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+const GImmOperand *g_x86_relative_operand_get_value(const GX86RelativeOperand *operand)
+{
+ return operand->immediate;
+
+}
+
+
/* ---------------------------------------------------------------------------------- */
/* OPERANDES D'EMPLACEMENTS MEMOIRE */
diff --git a/src/arch/x86/operand.h b/src/arch/x86/operand.h
index 1139fe2..9f4db09 100644
--- a/src/arch/x86/operand.h
+++ b/src/arch/x86/operand.h
@@ -28,6 +28,7 @@
#include <stdbool.h>
+#include "../immediate.h"
#include "../instruction.h"
@@ -129,6 +130,9 @@ GType g_x86_relative_operand_get_type(void);
/* Crée un opérande X86 d'adresse relative. */
GArchOperand *g_x86_relative_operand_new(const bin_t *, off_t *, off_t, AsmOperandSize, vmpa_t);
+/* Fournit l'adresse relative représentée par une opérande X86. */
+const GImmOperand *g_x86_relative_operand_get_value(const GX86RelativeOperand *);
+
/* ------------------------ OPERANDES D'EMPLACEMENTS MEMOIRE ------------------------ */