summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog74
-rw-r--r--plugins/fmtp/parser.c26
-rw-r--r--plugins/fmtp/parser.h3
-rw-r--r--plugins/readdex/class.c38
-rw-r--r--plugins/readdex/class.h3
-rw-r--r--plugins/readdex/code.c48
-rw-r--r--plugins/readdex/code.h3
-rw-r--r--plugins/readdex/header.c5
-rw-r--r--plugins/readdex/header.h3
-rw-r--r--plugins/readdex/ids.c32
-rw-r--r--plugins/readdex/ids.h11
-rw-r--r--plugins/readdex/reader.c21
-rw-r--r--plugins/readdex/reader.h2
-rw-r--r--plugins/readelf/header.c11
-rw-r--r--plugins/readelf/header.h3
-rw-r--r--plugins/readelf/program.c22
-rw-r--r--plugins/readelf/program.h3
-rw-r--r--plugins/readelf/reader.c15
-rw-r--r--plugins/readelf/reader.h2
-rw-r--r--plugins/readelf/section.c22
-rw-r--r--plugins/readelf/section.h3
-rw-r--r--plugins/readelf/strtab.c17
-rw-r--r--plugins/readelf/strtab.h3
-rw-r--r--src/analysis/db/items/comment.c2
-rw-r--r--src/analysis/db/items/comment.h2
-rw-r--r--src/analysis/disass/area.c354
-rw-r--r--src/analysis/disass/area.h7
-rw-r--r--src/analysis/disass/disassembler.c4
-rw-r--r--src/analysis/disass/fetch.c4
-rw-r--r--src/analysis/disass/output.c75
-rw-r--r--src/analysis/disass/output.h3
-rw-r--r--src/arch/arm/v7/fetch.c81
-rw-r--r--src/arch/context-int.h7
-rw-r--r--src/arch/context.c2
-rw-r--r--src/arch/instruction.c10
-rw-r--r--src/arch/instruction.h4
-rw-r--r--src/common/array.c61
-rw-r--r--src/common/array.h4
-rw-r--r--src/format/Makefile.am2
-rw-r--r--src/format/format.c6
-rw-r--r--src/format/format.h3
-rw-r--r--src/format/preload-int.h54
-rw-r--r--src/format/preload.c534
-rw-r--r--src/format/preload.h98
-rw-r--r--src/plugins/pglist.h3
-rw-r--r--src/plugins/plugin-def.h3
-rw-r--r--src/plugins/plugin-int.h5
-rw-r--r--src/plugins/plugin.c29
-rw-r--r--src/plugins/plugin.h4
49 files changed, 1392 insertions, 339 deletions
diff --git a/ChangeLog b/ChangeLog
index 9c94285..e677156 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,79 @@
17-05-05 Cyrille Bagard <nocbos@gmail.com>
+ * plugins/fmtp/parser.c:
+ * plugins/fmtp/parser.h:
+ * plugins/readdex/class.c:
+ * plugins/readdex/class.h:
+ * plugins/readdex/code.c:
+ * plugins/readdex/code.h:
+ * plugins/readdex/header.c:
+ * plugins/readdex/header.h:
+ * plugins/readdex/ids.c:
+ * plugins/readdex/ids.h:
+ * plugins/readdex/reader.c:
+ * plugins/readdex/reader.h:
+ * plugins/readelf/header.c:
+ * plugins/readelf/header.h:
+ * plugins/readelf/program.c:
+ * plugins/readelf/program.h:
+ * plugins/readelf/reader.c:
+ * plugins/readelf/reader.h:
+ * plugins/readelf/section.c:
+ * plugins/readelf/section.h:
+ * plugins/readelf/strtab.c:
+ * plugins/readelf/strtab.h:
+ Update code.
+
+ * src/analysis/db/items/comment.c:
+ * src/analysis/db/items/comment.h:
+ Constify the parameter of g_db_comment_get_address().
+
+ * src/analysis/disass/area.c:
+ * src/analysis/disass/area.h:
+ Insert preloaded format information from instructions instead of symbols.
+
+ * src/analysis/disass/disassembler.c:
+ * src/analysis/disass/fetch.c:
+ * src/analysis/disass/output.c:
+ * src/analysis/disass/output.h:
+ Update code.
+
+ * src/arch/arm/v7/fetch.c:
+ Insert loaded values as instructions instead of symbols.
+
+ * src/arch/context-int.h:
+ * src/arch/context.c:
+ Make disassembly contexts inherit from preload information.
+
+ * src/arch/instruction.c:
+ * src/arch/instruction.h:
+ Typo.
+
+ * src/common/array.c:
+ * src/common/array.h:
+ Allow to build sorted arrays.
+
+ * src/format/Makefile.am:
+ Add the 'preload[ch]' files into libformat_la_SOURCES.
+
+ * src/format/format.c:
+ * src/format/format.h:
+ Preload format information on disassembly context setup.
+
+ * src/format/preload-int.h:
+ * src/format/preload.c:
+ * src/format/preload.h:
+ New entries: store information loaded from binary formats.
+
+ * src/plugins/pglist.h:
+ * src/plugins/plugin-def.h:
+ * src/plugins/plugin-int.h:
+ * src/plugins/plugin.c:
+ * src/plugins/plugin.h:
+ Define a new action for plugins in order to preload information.
+
+17-05-05 Cyrille Bagard <nocbos@gmail.com>
+
* src/gui/dialogs/about.c:
Restore a valid copyright in the About dialog box.
diff --git a/plugins/fmtp/parser.c b/plugins/fmtp/parser.c
index 8fc693f..ea1e5d8 100644
--- a/plugins/fmtp/parser.c
+++ b/plugins/fmtp/parser.c
@@ -33,7 +33,7 @@
/* Effectue l'interprétation d'une définition de champ. */
-static bool parse_field_definition(const fmt_field_def *, GBinFormat *, vmpa2t *, void *);
+static bool parse_field_definition(const fmt_field_def *, GBinFormat *, GPreloadInfo *, vmpa2t *, void *);
@@ -41,6 +41,7 @@ static bool parse_field_definition(const fmt_field_def *, GBinFormat *, vmpa2t *
* *
* Paramètres : def = définition de champ à considérer. *
* format = description de l'exécutable à compléter. *
+* info = informations à constituer en avance de phase. *
* pos = tête de lecture pour les données. *
* data = infos complémentaires éventuellement fournies. *
* *
@@ -52,7 +53,7 @@ static bool parse_field_definition(const fmt_field_def *, GBinFormat *, vmpa2t *
* *
******************************************************************************/
-static bool parse_field_definition(const fmt_field_def *def, GBinFormat *format, vmpa2t *pos, void *data)
+static bool parse_field_definition(const fmt_field_def *def, GBinFormat *format, GPreloadInfo *info, vmpa2t *pos, void *data)
{
GBinContent *content; /* Contenu binaire à lire */
SourceEndian endian; /* Boutisme utilisé */
@@ -66,10 +67,6 @@ static bool parse_field_definition(const fmt_field_def *def, GBinFormat *format,
uint64_t raw; /* Valeur brute à étudier */
const comment_part *part; /* Accès plus direct */
-
- GBinSymbol *symbol; /* Symbole à intégrer */
-
-
/* Lecture */
content = g_binary_format_get_content(format);
@@ -193,17 +190,11 @@ static bool parse_field_definition(const fmt_field_def *def, GBinFormat *format,
}
- /* Insertion */
+ /* Insertions */
- symbol = g_binary_symbol_new(STP_DATA);
+ g_preload_info_add_instruction(info, instr);
- g_binary_symbol_attach_instruction(symbol, instr);
- g_binary_symbol_set_comment(symbol, comment);
-
- result = g_binary_format_add_symbol(format, symbol);
-
- if (!result)
- g_object_unref(G_OBJECT(instr));
+ g_preload_info_add_comment(info, comment);
pfd_exit:
@@ -219,6 +210,7 @@ static bool parse_field_definition(const fmt_field_def *def, GBinFormat *format,
* Paramètres : defs = liste de définitions à traiter. *
* count = taille de cette liste. *
* format = description de l'exécutable à compléter. *
+* info = informations à constituer en avance de phase. *
* pos = tête de lecture pour les données. *
* data = infos complémentaires éventuellement fournies. *
* *
@@ -230,7 +222,7 @@ static bool parse_field_definition(const fmt_field_def *def, GBinFormat *format,
* *
******************************************************************************/
-bool parse_field_definitions(const fmt_field_def *defs, size_t count, GBinFormat *format, vmpa2t *pos, void *data)
+bool parse_field_definitions(const fmt_field_def *defs, size_t count, GBinFormat *format, GPreloadInfo *info, vmpa2t *pos, void *data)
{
bool result; /* Bilan à retourner */
size_t i; /* Boucle de parcours */
@@ -238,7 +230,7 @@ bool parse_field_definitions(const fmt_field_def *defs, size_t count, GBinFormat
result = true;
for (i = 0; i < count && result; i++)
- result = parse_field_definition(defs + i, format, pos, data);
+ result = parse_field_definition(defs + i, format, info, pos, data);
return result;
diff --git a/plugins/fmtp/parser.h b/plugins/fmtp/parser.h
index 0d5dff3..310ff37 100644
--- a/plugins/fmtp/parser.h
+++ b/plugins/fmtp/parser.h
@@ -29,6 +29,7 @@
#include <format/format.h>
+#include <format/preload.h>
#include "def.h"
@@ -36,7 +37,7 @@
/* Lance l'interprétation d'une série de définitions de champs. */
-bool parse_field_definitions(const fmt_field_def *, size_t, GBinFormat *, vmpa2t *, void *);
+bool parse_field_definitions(const fmt_field_def *, size_t, GBinFormat *, GPreloadInfo *, vmpa2t *, void *);
diff --git a/plugins/readdex/class.c b/plugins/readdex/class.c
index 7b7b253..7911c6f 100644
--- a/plugins/readdex/class.c
+++ b/plugins/readdex/class.c
@@ -236,19 +236,20 @@ static fmt_field_def _dex_encoded_method[] = {
/* Commente les définitions des classes pour la VM Dalvik. */
-static bool annotate_dex_class_data(const GDexFormat *, const GDexClass *, uint32_t );
+static bool annotate_dex_class_data(const GDexFormat *, GPreloadInfo *, const GDexClass *, uint32_t );
/* Commente les définitions des champs encodés. */
-static bool annotate_dex_encoded_field(const GDexFormat *, vmpa2t *);
+static bool annotate_dex_encoded_field(const GDexFormat *, GPreloadInfo *, vmpa2t *);
/* Commente les définitions des méthodes encodées. */
-static bool annotate_dex_encoded_method(const GDexFormat *, const encoded_method *, vmpa2t *);
+static bool annotate_dex_encoded_method(const GDexFormat *, GPreloadInfo *, const encoded_method *, vmpa2t *);
/******************************************************************************
* *
* Paramètres : format = description de l'exécutable à compléter. *
+* info = informations à constituer en avance de phase. *
* status = barre de statut à tenir informée. *
* *
* Description : Commente les définitions des classes pour la VM Dalvik. *
@@ -259,7 +260,7 @@ static bool annotate_dex_encoded_method(const GDexFormat *, const encoded_method
* *
******************************************************************************/
-bool annotate_dex_class_defs(const GDexFormat *format, GtkStatusStack *status)
+bool annotate_dex_class_defs(const GDexFormat *format, GPreloadInfo *info, GtkStatusStack *status)
{
bool result; /* Bilan à retourner */
const dex_header *header; /* En-tête principale */
@@ -284,7 +285,7 @@ bool annotate_dex_class_defs(const GDexFormat *format, GtkStatusStack *status)
for (i = 0; i < header->class_defs_size && result; i++)
{
- result = parse_field_definitions(PARSING_DEFS(_dex_class_defs), bformat, &pos, NULL);
+ result = parse_field_definitions(PARSING_DEFS(_dex_class_defs), bformat, info, &pos, NULL);
if (!result) break;
/* Annotations supplémentaires */
@@ -294,7 +295,7 @@ bool annotate_dex_class_defs(const GDexFormat *format, GtkStatusStack *status)
def = g_dex_class_get_definition(class);
if (def->class_data_off > 0)
- result = annotate_dex_class_data(format, class, def->class_data_off);
+ result = annotate_dex_class_data(format, info, class, def->class_data_off);
/* TODO : g_object_unref(G_OBJECT(class));*/
@@ -314,6 +315,7 @@ bool annotate_dex_class_defs(const GDexFormat *format, GtkStatusStack *status)
/******************************************************************************
* *
* Paramètres : format = description de l'exécutable à compléter. *
+* info = informations à constituer en avance de phase. *
* class = classe Dex dont les données sont à commenter. *
* offset = tête de lecture physique des symboles. *
* *
@@ -325,7 +327,7 @@ bool annotate_dex_class_defs(const GDexFormat *format, GtkStatusStack *status)
* *
******************************************************************************/
-static bool annotate_dex_class_data(const GDexFormat *format, const GDexClass *class, uint32_t offset)
+static bool annotate_dex_class_data(const GDexFormat *format, GPreloadInfo *info, const GDexClass *class, uint32_t offset)
{
bool result; /* Bilan à retourner */
vmpa2t pos; /* Tête de lecture des symboles*/
@@ -340,7 +342,7 @@ static bool annotate_dex_class_data(const GDexFormat *format, const GDexClass *c
bformat = G_BIN_FORMAT(format);
- result = parse_field_definitions(PARSING_DEFS(_dex_class_data), bformat, &pos, NULL);
+ result = parse_field_definitions(PARSING_DEFS(_dex_class_data), bformat, info, &pos, NULL);
if (!result)
goto adcd_exit;
@@ -352,16 +354,16 @@ static bool annotate_dex_class_data(const GDexFormat *format, const GDexClass *c
if (data != NULL)
{
for (i = 0; i < data->static_fields_size && result; i++)
- result = annotate_dex_encoded_field(format, &pos);
+ result = annotate_dex_encoded_field(format, info, &pos);
for (i = 0; i < data->instance_fields_size && result; i++)
- result = annotate_dex_encoded_field(format, &pos);
+ result = annotate_dex_encoded_field(format, info, &pos);
for (i = 0; i < data->direct_methods_size && result; i++)
- result = annotate_dex_encoded_method(format, &data->direct_methods[i], &pos);
+ result = annotate_dex_encoded_method(format, info, &data->direct_methods[i], &pos);
for (i = 0; i < data->virtual_methods_size && result; i++)
- result = annotate_dex_encoded_method(format, &data->virtual_methods[i], &pos);
+ result = annotate_dex_encoded_method(format, info, &data->virtual_methods[i], &pos);
}
@@ -375,6 +377,7 @@ static bool annotate_dex_class_data(const GDexFormat *format, const GDexClass *c
/******************************************************************************
* *
* Paramètres : format = description de l'exécutable à compléter. *
+* info = informations à constituer en avance de phase. *
* pos = tête de lecture à faire progresser. [OUT] *
* *
* Description : Commente les définitions des champs encodés. *
@@ -385,14 +388,14 @@ static bool annotate_dex_class_data(const GDexFormat *format, const GDexClass *c
* *
******************************************************************************/
-static bool annotate_dex_encoded_field(const GDexFormat *format, vmpa2t *pos)
+static bool annotate_dex_encoded_field(const GDexFormat *format, GPreloadInfo *info, vmpa2t *pos)
{
bool result; /* Bilan à retourner */
GBinFormat *bformat; /* Autre version du format */
bformat = G_BIN_FORMAT(format);
- result = parse_field_definitions(PARSING_DEFS(_dex_encoded_field), bformat, pos, NULL);
+ result = parse_field_definitions(PARSING_DEFS(_dex_encoded_field), bformat, info, pos, NULL);
return result;
@@ -402,6 +405,7 @@ static bool annotate_dex_encoded_field(const GDexFormat *format, vmpa2t *pos)
/******************************************************************************
* *
* Paramètres : format = description de l'exécutable à compléter. *
+* info = informations à constituer en avance de phase. *
* method = méthode à décrire. *
* pos = tête de lecture à faire progresser. [OUT] *
* *
@@ -413,19 +417,19 @@ static bool annotate_dex_encoded_field(const GDexFormat *format, vmpa2t *pos)
* *
******************************************************************************/
-static bool annotate_dex_encoded_method(const GDexFormat *format, const encoded_method *method, vmpa2t *pos)
+static bool annotate_dex_encoded_method(const GDexFormat *format, GPreloadInfo *info, const encoded_method *method, vmpa2t *pos)
{
bool result; /* Bilan à retourner */
GBinFormat *bformat; /* Autre version du format */
bformat = G_BIN_FORMAT(format);
- result = parse_field_definitions(PARSING_DEFS(_dex_encoded_method), bformat, pos, NULL);
+ result = parse_field_definitions(PARSING_DEFS(_dex_encoded_method), bformat, info, pos, NULL);
/* Chargements complémentaires, si non abstraite ni native */
if (result && method->code_off > 0)
- result = annotate_dex_code_item(format, method->code_off);
+ result = annotate_dex_code_item(format, info, method->code_off);
return result;
diff --git a/plugins/readdex/class.h b/plugins/readdex/class.h
index 2df7097..4e71fb2 100644
--- a/plugins/readdex/class.h
+++ b/plugins/readdex/class.h
@@ -25,12 +25,13 @@
#define _PLUGINS_READDEX_CLASS_H
+#include <format/preload.h>
#include <format/dex/dex.h>
/* Commente les définitions des classes pour la VM Dalvik. */
-bool annotate_dex_class_defs(const GDexFormat *, GtkStatusStack *);
+bool annotate_dex_class_defs(const GDexFormat *, GPreloadInfo *, GtkStatusStack *);
diff --git a/plugins/readdex/code.c b/plugins/readdex/code.c
index 23e82ac..3a36c19 100644
--- a/plugins/readdex/code.c
+++ b/plugins/readdex/code.c
@@ -255,16 +255,16 @@ static fmt_field_def _dex_encoded_type_addr_pair[] = {
/* Commente les définitions d'une protection contre exceptions. */
-static bool annotate_dex_try_item(const GDexFormat *, vmpa2t *);
+static bool annotate_dex_try_item(const GDexFormat *, GPreloadInfo *, vmpa2t *);
/*Commente les définitions des listes de gestion d'exceptions. */
-static bool annotate_dex_encoded_catch_handler_list(const GDexFormat *, vmpa2t *);
+static bool annotate_dex_encoded_catch_handler_list(const GDexFormat *, GPreloadInfo *, vmpa2t *);
/* Commente les définitions d'une prise en compte d'exceptions. */
-static bool annotate_dex_encoded_catch_handler(const GDexFormat *, vmpa2t *);
+static bool annotate_dex_encoded_catch_handler(const GDexFormat *, GPreloadInfo *, vmpa2t *);
/* Commente les définitions des gestions d'exceptions par type. */
-static bool annotate_dex_encoded_type_addr_pair(const GDexFormat *, vmpa2t *);
+static bool annotate_dex_encoded_type_addr_pair(const GDexFormat *, GPreloadInfo *, vmpa2t *);
@@ -379,6 +379,7 @@ static bool get_encoded_catch_handler_size_value(const fmt_field_def *def, GBinC
/******************************************************************************
* *
* Paramètres : format = description de l'exécutable à compléter. *
+* info = informations à constituer en avance de phase. *
* *
* Description : Commente les définitions d'un corps de méthode. *
* *
@@ -388,7 +389,7 @@ static bool get_encoded_catch_handler_size_value(const fmt_field_def *def, GBinC
* *
******************************************************************************/
-bool annotate_dex_code_item(const GDexFormat *format, uleb128_t offset)
+bool annotate_dex_code_item(const GDexFormat *format, GPreloadInfo *info, uleb128_t offset)
{
bool result; /* Bilan à retourner */
vmpa2t pos; /* Tête de lecture des symboles*/
@@ -400,7 +401,7 @@ bool annotate_dex_code_item(const GDexFormat *format, uleb128_t offset)
if (!result)
goto adci_exit;
- result = parse_field_definitions(PARSING_DEFS(_dex_code_item), G_BIN_FORMAT(format), &pos, &data);
+ result = parse_field_definitions(PARSING_DEFS(_dex_code_item), G_BIN_FORMAT(format), info, &pos, &data);
if (!result)
goto adci_exit;
@@ -412,15 +413,16 @@ bool annotate_dex_code_item(const GDexFormat *format, uleb128_t offset)
/* padding */
if (data.insns_size % 2 != 0)
- result = parse_field_definitions(PARSING_DEFS(_dex_code_item_padding), G_BIN_FORMAT(format), &pos, NULL);
+ result = parse_field_definitions(PARSING_DEFS(_dex_code_item_padding),
+ G_BIN_FORMAT(format), info, &pos, NULL);
/* tries */
for (i = 0; i < data.tries_size && result; i++)
- result = annotate_dex_try_item(format, &pos);
+ result = annotate_dex_try_item(format, info, &pos);
if (data.tries_size > 0 && result)
- result = annotate_dex_encoded_catch_handler_list(format, &pos);
+ result = annotate_dex_encoded_catch_handler_list(format, info, &pos);
adci_exit:
@@ -432,6 +434,7 @@ bool annotate_dex_code_item(const GDexFormat *format, uleb128_t offset)
/******************************************************************************
* *
* Paramètres : format = description de l'exécutable à compléter. *
+* info = informations à constituer en avance de phase. *
* pos = tête de lecture pour les symboles. *
* *
* Description : Commente les définitions d'une protection contre exceptions. *
@@ -442,11 +445,11 @@ bool annotate_dex_code_item(const GDexFormat *format, uleb128_t offset)
* *
******************************************************************************/
-static bool annotate_dex_try_item(const GDexFormat *format, vmpa2t *pos)
+static bool annotate_dex_try_item(const GDexFormat *format, GPreloadInfo *info, vmpa2t *pos)
{
bool result; /* Bilan à retourner */
- result = parse_field_definitions(PARSING_DEFS(_dex_try_item), G_BIN_FORMAT(format), pos, NULL);
+ result = parse_field_definitions(PARSING_DEFS(_dex_try_item), G_BIN_FORMAT(format), info, pos, NULL);
return result;
@@ -456,6 +459,7 @@ static bool annotate_dex_try_item(const GDexFormat *format, vmpa2t *pos)
/******************************************************************************
* *
* Paramètres : format = description de l'exécutable à compléter. *
+* info = informations à constituer en avance de phase. *
* pos = tête de lecture physique des symboles. *
* *
* Description : Commente les définitions des listes de gestion d'exceptions. *
@@ -466,17 +470,17 @@ static bool annotate_dex_try_item(const GDexFormat *format, vmpa2t *pos)
* *
******************************************************************************/
-static bool annotate_dex_encoded_catch_handler_list(const GDexFormat *format, vmpa2t *pos)
+static bool annotate_dex_encoded_catch_handler_list(const GDexFormat *format, GPreloadInfo *info, vmpa2t *pos)
{
bool result; /* Bilan à retourner */
uleb128_t size; /* Nombre d'entrées */
uleb128_t i; /* Boucle de parcours */
result = parse_field_definitions(PARSING_DEFS(_dex_encoded_catch_handler_list),
- G_BIN_FORMAT(format), pos, &size);
+ G_BIN_FORMAT(format), info, pos, &size);
for (i = 0; i < size && result; i++)
- result = annotate_dex_encoded_catch_handler(format, pos);
+ result = annotate_dex_encoded_catch_handler(format, info, pos);
return result;
@@ -486,6 +490,7 @@ static bool annotate_dex_encoded_catch_handler_list(const GDexFormat *format, vm
/******************************************************************************
* *
* Paramètres : format = description de l'exécutable à compléter. *
+* info = informations à constituer en avance de phase. *
* pos = tête de lecture physique des symboles. *
* *
* Description : Commente les définitions d'une prise en compte d'exceptions. *
@@ -496,14 +501,15 @@ static bool annotate_dex_encoded_catch_handler_list(const GDexFormat *format, vm
* *
******************************************************************************/
-static bool annotate_dex_encoded_catch_handler(const GDexFormat *format, vmpa2t *pos)
+static bool annotate_dex_encoded_catch_handler(const GDexFormat *format, GPreloadInfo *info, vmpa2t *pos)
{
bool result; /* Bilan à retourner */
leb128_t size; /* Nombre de gestionnaires */
bool has_catch_all; /* Gestion par défaut ? */
uleb128_t i; /* Boucle de parcours */
- result = parse_field_definitions(PARSING_DEFS(_dex_encoded_catch_handler), G_BIN_FORMAT(format), pos, &size);
+ result = parse_field_definitions(PARSING_DEFS(_dex_encoded_catch_handler),
+ G_BIN_FORMAT(format), info, pos, &size);
if (!result)
goto adech_exit;
@@ -516,13 +522,13 @@ static bool annotate_dex_encoded_catch_handler(const GDexFormat *format, vmpa2t
/* handlers */
for (i = 0; i < size && result; i++)
- result = annotate_dex_encoded_type_addr_pair(format, pos);
+ result = annotate_dex_encoded_type_addr_pair(format, info, pos);
/* catch_all_addr */
if (result && has_catch_all)
result = parse_field_definitions(PARSING_DEFS(_dex_encoded_catch_handler_all),
- G_BIN_FORMAT(format), pos, &size);
+ G_BIN_FORMAT(format), info, pos, &size);
adech_exit:
@@ -534,6 +540,7 @@ static bool annotate_dex_encoded_catch_handler(const GDexFormat *format, vmpa2t
/******************************************************************************
* *
* Paramètres : format = description de l'exécutable à compléter. *
+* info = informations à constituer en avance de phase. *
* pos = tête de lecture des symboles. *
* *
* Description : Commente les définitions des gestions d'exceptions par type. *
@@ -544,11 +551,12 @@ static bool annotate_dex_encoded_catch_handler(const GDexFormat *format, vmpa2t
* *
******************************************************************************/
-static bool annotate_dex_encoded_type_addr_pair(const GDexFormat *format, vmpa2t *pos)
+static bool annotate_dex_encoded_type_addr_pair(const GDexFormat *format, GPreloadInfo *info, vmpa2t *pos)
{
bool result; /* Bilan à retourner */
- result = parse_field_definitions(PARSING_DEFS(_dex_encoded_type_addr_pair), G_BIN_FORMAT(format), pos, NULL);
+ result = parse_field_definitions(PARSING_DEFS(_dex_encoded_type_addr_pair),
+ G_BIN_FORMAT(format), info, pos, NULL);
return result;
diff --git a/plugins/readdex/code.h b/plugins/readdex/code.h
index 7f23ee7..ea70df8 100644
--- a/plugins/readdex/code.h
+++ b/plugins/readdex/code.h
@@ -25,12 +25,13 @@
#define _PLUGINS_READDEX_CODE_H
+#include <format/preload.h>
#include <format/dex/dex.h>
/* Commente les définitions d'un corps de méthode. */
-bool annotate_dex_code_item(const GDexFormat *, uleb128_t);
+bool annotate_dex_code_item(const GDexFormat *, GPreloadInfo *, uleb128_t);
diff --git a/plugins/readdex/header.c b/plugins/readdex/header.c
index d0d0cd7..b5ea776 100644
--- a/plugins/readdex/header.c
+++ b/plugins/readdex/header.c
@@ -294,6 +294,7 @@ static fmt_field_def _dex_header[] = {
/******************************************************************************
* *
* Paramètres : format = description de l'exécutable à compléter. *
+* info = informations à constituer en avance de phase. *
* *
* Description : Charge tous les symboles de l'en-tête DEX. *
* *
@@ -303,7 +304,7 @@ static fmt_field_def _dex_header[] = {
* *
******************************************************************************/
-bool annotate_dex_header(GDexFormat *format)
+bool annotate_dex_header(GDexFormat *format, GPreloadInfo *info)
{
bool result; /* Bilan à retourner */
vmpa2t pos; /* Tête de lecture des symboles*/
@@ -311,7 +312,7 @@ bool annotate_dex_header(GDexFormat *format)
result = g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), 0, &pos);
if (result)
- result = parse_field_definitions(PARSING_DEFS(_dex_header), G_BIN_FORMAT(format), &pos, NULL);
+ result = parse_field_definitions(PARSING_DEFS(_dex_header), G_BIN_FORMAT(format), info, &pos, NULL);
return result;
diff --git a/plugins/readdex/header.h b/plugins/readdex/header.h
index 0d147f7..17c6ccd 100644
--- a/plugins/readdex/header.h
+++ b/plugins/readdex/header.h
@@ -25,12 +25,13 @@
#define _PLUGINS_READDEX_HEADER_H
+#include <format/preload.h>
#include <format/dex/dex.h>
/* Charge tous les symboles de l'en-tête DEX. */
-bool annotate_dex_header(GDexFormat *);
+bool annotate_dex_header(GDexFormat *, GPreloadInfo *);
diff --git a/plugins/readdex/ids.c b/plugins/readdex/ids.c
index 2586eaf..14ad6fb 100644
--- a/plugins/readdex/ids.c
+++ b/plugins/readdex/ids.c
@@ -227,6 +227,7 @@ static bool get_dex_string_length_value(const fmt_field_def *def, GBinContent *c
/******************************************************************************
* *
* Paramètres : format = description de l'exécutable à compléter. *
+* info = informations à constituer en avance de phase. *
* status = barre de statut à tenir informée. *
* *
* Description : Commente les définitions des chaînes de caractères. *
@@ -237,7 +238,7 @@ static bool get_dex_string_length_value(const fmt_field_def *def, GBinContent *c
* *
******************************************************************************/
-bool annotate_dex_string_ids(const GDexFormat *format, GtkStatusStack *status)
+bool annotate_dex_string_ids(const GDexFormat *format, GPreloadInfo *info, GtkStatusStack *status)
{
bool result; /* Bilan à retourner */
GBinContent *content; /* Contenu binaire à lire */
@@ -258,7 +259,7 @@ bool annotate_dex_string_ids(const GDexFormat *format, GtkStatusStack *status)
content = g_binary_format_get_content(G_BIN_FORMAT(format));
header = g_dex_format_get_header(format);
- endian = SRE_LITTLE;//g_dex_format_get_endianness(format);
+ endian = g_binary_format_get_endianness(G_BIN_FORMAT(format));
result = g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), header->string_ids_off, &pos);
@@ -307,7 +308,7 @@ bool annotate_dex_string_ids(const GDexFormat *format, GtkStatusStack *status)
field.comment.parts = parts;
field.comment.pcount = ARRAY_SIZE(parts);
- result = parse_field_definitions(&field, 1, bformat, &pos, &loc);
+ result = parse_field_definitions(&field, 1, bformat, info, &pos, &loc);
if (!result)
break;
@@ -317,7 +318,7 @@ bool annotate_dex_string_ids(const GDexFormat *format, GtkStatusStack *status)
if (!g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), loc, &item_pos))
continue;
- result = parse_field_definitions(PARSING_DEFS(_dex_string_ids_length), bformat, &item_pos, &length);
+ result = parse_field_definitions(PARSING_DEFS(_dex_string_ids_length), bformat, info, &item_pos, &length);
/* Description de la chaîne : contenu */
@@ -327,6 +328,9 @@ bool annotate_dex_string_ids(const GDexFormat *format, GtkStatusStack *status)
g_raw_instruction_mark_as_string(G_RAW_INSTRUCTION(instr), true);
+ g_preload_info_add_instruction(info, instr);
+
+ g_object_ref(G_OBJECT(instr));
ADD_STR_AS_SYM(format, symbol, instr);
}
@@ -349,6 +353,7 @@ bool annotate_dex_string_ids(const GDexFormat *format, GtkStatusStack *status)
/******************************************************************************
* *
* Paramètres : format = description de l'exécutable à compléter. *
+* info = informations à constituer en avance de phase. *
* status = barre de statut à tenir informée. *
* *
* Description : Commente les définitions des identifiants de types. *
@@ -359,7 +364,7 @@ bool annotate_dex_string_ids(const GDexFormat *format, GtkStatusStack *status)
* *
******************************************************************************/
-bool annotate_dex_type_ids(const GDexFormat *format, GtkStatusStack *status)
+bool annotate_dex_type_ids(const GDexFormat *format, GPreloadInfo *info, GtkStatusStack *status)
{
bool result; /* Bilan à retourner */
const dex_header *header; /* En-tête principale */
@@ -382,7 +387,7 @@ bool annotate_dex_type_ids(const GDexFormat *format, GtkStatusStack *status)
for (i = 0; i < header->type_ids_size && result; i++)
{
- result = parse_field_definitions(PARSING_DEFS(_dex_type_ids), bformat, &pos, NULL);
+ result = parse_field_definitions(PARSING_DEFS(_dex_type_ids), bformat, info, &pos, NULL);
gtk_status_stack_update_activity_value(status, msg, 1);
@@ -400,6 +405,7 @@ bool annotate_dex_type_ids(const GDexFormat *format, GtkStatusStack *status)
/******************************************************************************
* *
* Paramètres : format = description de l'exécutable à compléter. *
+* info = informations à constituer en avance de phase. *
* status = barre de statut à tenir informée. *
* *
* Description : Commente les définitions des identifiants de prototypes. *
@@ -410,7 +416,7 @@ bool annotate_dex_type_ids(const GDexFormat *format, GtkStatusStack *status)
* *
******************************************************************************/
-bool annotate_dex_proto_ids(const GDexFormat *format, GtkStatusStack *status)
+bool annotate_dex_proto_ids(const GDexFormat *format, GPreloadInfo *info, GtkStatusStack *status)
{
bool result; /* Bilan à retourner */
const dex_header *header; /* En-tête principale */
@@ -433,7 +439,7 @@ bool annotate_dex_proto_ids(const GDexFormat *format, GtkStatusStack *status)
for (i = 0; i < header->proto_ids_size && result; i++)
{
- result = parse_field_definitions(PARSING_DEFS(_dex_proto_ids), bformat, &pos, NULL);
+ result = parse_field_definitions(PARSING_DEFS(_dex_proto_ids), bformat, info, &pos, NULL);
gtk_status_stack_update_activity_value(status, msg, 1);
@@ -451,6 +457,7 @@ bool annotate_dex_proto_ids(const GDexFormat *format, GtkStatusStack *status)
/******************************************************************************
* *
* Paramètres : format = description de l'exécutable à compléter. *
+* info = informations à constituer en avance de phase. *
* status = barre de statut à tenir informée. *
* *
* Description : Commente les définitions des identifiants de champs. *
@@ -461,7 +468,7 @@ bool annotate_dex_proto_ids(const GDexFormat *format, GtkStatusStack *status)
* *
******************************************************************************/
-bool annotate_dex_field_ids(const GDexFormat *format, GtkStatusStack *status)
+bool annotate_dex_field_ids(const GDexFormat *format, GPreloadInfo *info, GtkStatusStack *status)
{
bool result; /* Bilan à retourner */
const dex_header *header; /* En-tête principale */
@@ -484,7 +491,7 @@ bool annotate_dex_field_ids(const GDexFormat *format, GtkStatusStack *status)
for (i = 0; i < header->field_ids_size && result; i++)
{
- result = parse_field_definitions(PARSING_DEFS(_dex_field_ids), bformat, &pos, NULL);
+ result = parse_field_definitions(PARSING_DEFS(_dex_field_ids), bformat, info, &pos, NULL);
gtk_status_stack_update_activity_value(status, msg, 1);
@@ -502,6 +509,7 @@ bool annotate_dex_field_ids(const GDexFormat *format, GtkStatusStack *status)
/******************************************************************************
* *
* Paramètres : format = description de l'exécutable à compléter. *
+* info = informations à constituer en avance de phase. *
* status = barre de statut à tenir informée. *
* *
* Description : Commente les définitions des identifiants de méthodes. *
@@ -512,7 +520,7 @@ bool annotate_dex_field_ids(const GDexFormat *format, GtkStatusStack *status)
* *
******************************************************************************/
-bool annotate_dex_method_ids(const GDexFormat *format, GtkStatusStack *status)
+bool annotate_dex_method_ids(const GDexFormat *format, GPreloadInfo *info, GtkStatusStack *status)
{
bool result; /* Bilan à retourner */
const dex_header *header; /* En-tête principale */
@@ -535,7 +543,7 @@ bool annotate_dex_method_ids(const GDexFormat *format, GtkStatusStack *status)
for (i = 0; i < header->method_ids_size && result; i++)
{
- result = parse_field_definitions(PARSING_DEFS(_dex_method_ids), bformat, &pos, NULL);
+ result = parse_field_definitions(PARSING_DEFS(_dex_method_ids), bformat, info, &pos, NULL);
gtk_status_stack_update_activity_value(status, msg, 1);
diff --git a/plugins/readdex/ids.h b/plugins/readdex/ids.h
index 8fe9626..79618ce 100644
--- a/plugins/readdex/ids.h
+++ b/plugins/readdex/ids.h
@@ -25,24 +25,25 @@
#define _PLUGINS_READDEX_IDS_H
+#include <format/preload.h>
#include <format/dex/dex.h>
/* Charge tous les symboles de l'en-tête DEX. */
-bool annotate_dex_string_ids(const GDexFormat *, GtkStatusStack *);
+bool annotate_dex_string_ids(const GDexFormat *, GPreloadInfo *, GtkStatusStack *);
/* Commente les définitions des identifiants de types. */
-bool annotate_dex_type_ids(const GDexFormat *, GtkStatusStack *);
+bool annotate_dex_type_ids(const GDexFormat *, GPreloadInfo *, GtkStatusStack *);
/* Commente les définitions des identifiants de prototypes. */
-bool annotate_dex_proto_ids(const GDexFormat *, GtkStatusStack *);
+bool annotate_dex_proto_ids(const GDexFormat *, GPreloadInfo *, GtkStatusStack *);
/* Commente les définitions des identifiants de champs. */
-bool annotate_dex_field_ids(const GDexFormat *, GtkStatusStack *);
+bool annotate_dex_field_ids(const GDexFormat *, GPreloadInfo *, GtkStatusStack *);
/* Commente les définitions des identifiants de méthodes. */
-bool annotate_dex_method_ids(const GDexFormat *, GtkStatusStack *);
+bool annotate_dex_method_ids(const GDexFormat *, GPreloadInfo *, GtkStatusStack *);
diff --git a/plugins/readdex/reader.c b/plugins/readdex/reader.c
index 5bd7649..645ec5b 100644
--- a/plugins/readdex/reader.c
+++ b/plugins/readdex/reader.c
@@ -33,8 +33,8 @@
-DEFINE_CHRYSALIDE_ACTIVE_PLUGIN("readdex", "Displays information about DEX files", "0.1.0",
- PGA_FORMAT_LOADER_LAST);
+DEFINE_CHRYSALIDE_ACTIVE_PLUGIN("readdex", "Displays information about DEX files", "0.2.0",
+ PGA_FORMAT_PRELOAD);
/******************************************************************************
@@ -42,6 +42,7 @@ DEFINE_CHRYSALIDE_ACTIVE_PLUGIN("readdex", "Displays information about DEX files
* Paramètres : plugin = greffon à manipuler. *
* action = type d'action attendue. *
* format = description de l'exécutable à compléter. *
+* info = informations à constituer en avance de phase. *
* status = barre de statut à tenir informée. *
* *
* Description : Etablit des symboles complémentaires dans un format DEX. *
@@ -52,7 +53,7 @@ DEFINE_CHRYSALIDE_ACTIVE_PLUGIN("readdex", "Displays information about DEX files
* *
******************************************************************************/
-G_MODULE_EXPORT bool handle_binary_format(const GPluginModule *plugin, PluginAction action, GBinFormat *format, GtkStatusStack *status)
+G_MODULE_EXPORT bool preload_binary_format(const GPluginModule *plugin, PluginAction action, GBinFormat *format, GPreloadInfo *info, GtkStatusStack *status)
{
bool result; /* Bilan à retourner */
GDexFormat *dex_fmt; /* Version DEX */
@@ -65,19 +66,19 @@ G_MODULE_EXPORT bool handle_binary_format(const GPluginModule *plugin, PluginAct
dex_fmt = G_DEX_FORMAT(format);
- result = annotate_dex_header(dex_fmt);
+ result = annotate_dex_header(dex_fmt, info);
- result &= annotate_dex_string_ids(dex_fmt, status);
+ result &= annotate_dex_string_ids(dex_fmt, info, status);
- result &= annotate_dex_type_ids(dex_fmt, status);
+ result &= annotate_dex_type_ids(dex_fmt, info, status);
- result &= annotate_dex_proto_ids(dex_fmt, status);
+ result &= annotate_dex_proto_ids(dex_fmt, info, status);
- result &= annotate_dex_field_ids(dex_fmt, status);
+ result &= annotate_dex_field_ids(dex_fmt, info, status);
- result &= annotate_dex_method_ids(dex_fmt, status);
+ result &= annotate_dex_method_ids(dex_fmt, info, status);
- result &= annotate_dex_class_defs(dex_fmt, status);
+ result &= annotate_dex_class_defs(dex_fmt, info, status);
hbf_exit:
diff --git a/plugins/readdex/reader.h b/plugins/readdex/reader.h
index f56d928..74a2968 100644
--- a/plugins/readdex/reader.h
+++ b/plugins/readdex/reader.h
@@ -32,7 +32,7 @@
/* Etablit des symboles complémentaires dans un format DEX. */
-G_MODULE_EXPORT bool handle_binary_format(const GPluginModule *, PluginAction, GBinFormat *, GtkStatusStack *);
+G_MODULE_EXPORT bool preload_binary_format(const GPluginModule *, PluginAction, GBinFormat *, GPreloadInfo *, GtkStatusStack *);
diff --git a/plugins/readelf/header.c b/plugins/readelf/header.c
index 4b3cdbc..a83f690 100644
--- a/plugins/readelf/header.c
+++ b/plugins/readelf/header.c
@@ -451,6 +451,7 @@ static fmt_field_def _elf_header_ending[] = {
/******************************************************************************
* *
* Paramètres : format = description de l'exécutable à compléter. *
+* info = informations à constituer en avance de phase. *
* *
* Description : Charge tous les symboles de l'en-tête ELF. *
* *
@@ -460,7 +461,7 @@ static fmt_field_def _elf_header_ending[] = {
* *
******************************************************************************/
-bool annotate_elf_header(GBinFormat *format)
+bool annotate_elf_header(GBinFormat *format, GPreloadInfo *info)
{
bool result; /* Bilan à retourner */
const elf_header *header; /* En-tête principale */
@@ -471,15 +472,15 @@ bool annotate_elf_header(GBinFormat *format)
result = g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), 0, &pos);
if (result)
- result = parse_field_definitions(PARSING_DEFS(_elf_header_base), format, &pos, NULL);
+ result = parse_field_definitions(PARSING_DEFS(_elf_header_base), format, info, &pos, NULL);
if (result)
{
if (header->hdr32.e_ident[EI_CLASS] == ELFCLASS32)
- result = parse_field_definitions(PARSING_DEFS(_elf_header_offset_32), format, &pos, NULL);
+ result = parse_field_definitions(PARSING_DEFS(_elf_header_offset_32), format, info, &pos, NULL);
else if (header->hdr32.e_ident[EI_CLASS] == ELFCLASS64)
- result = parse_field_definitions(PARSING_DEFS(_elf_header_offset_64), format, &pos, NULL);
+ result = parse_field_definitions(PARSING_DEFS(_elf_header_offset_64), format, info, &pos, NULL);
else
result = false;
@@ -487,7 +488,7 @@ bool annotate_elf_header(GBinFormat *format)
}
if (result)
- result = parse_field_definitions(PARSING_DEFS(_elf_header_ending), format, &pos, NULL);
+ result = parse_field_definitions(PARSING_DEFS(_elf_header_ending), format, info, &pos, NULL);
return result;
diff --git a/plugins/readelf/header.h b/plugins/readelf/header.h
index 9d1744e..060a363 100644
--- a/plugins/readelf/header.h
+++ b/plugins/readelf/header.h
@@ -25,12 +25,13 @@
#define _PLUGINS_READELF_HEADER_H
+#include <format/preload.h>
#include <format/elf/elf.h>
/* Charge tous les symboles de l'en-tête ELF. */
-bool annotate_elf_header(GBinFormat *);
+bool annotate_elf_header(GBinFormat *, GPreloadInfo *);
diff --git a/plugins/readelf/program.c b/plugins/readelf/program.c
index b1e253a..a71e1d1 100644
--- a/plugins/readelf/program.c
+++ b/plugins/readelf/program.c
@@ -206,13 +206,14 @@ static fmt_field_def _elf_phdr_64b[] = {
/* Charge tous les symboles liés à un en-tête de programme ELF. */
-static bool annotate_elf_program_header(GElfFormat *, SourceEndian, vmpa2t *);
+static bool annotate_elf_program_header(GElfFormat *, GPreloadInfo *, SourceEndian, vmpa2t *);
/******************************************************************************
* *
* Paramètres : format = description de l'exécutable à compléter. *
+* info = informations à constituer en avance de phase. *
* endian = boutisme présentement utilisé. *
* pos = tête de lecture à déplacer. [OUT] *
* *
@@ -224,7 +225,7 @@ static bool annotate_elf_program_header(GElfFormat *, SourceEndian, vmpa2t *);
* *
******************************************************************************/
-static bool annotate_elf_program_header(GElfFormat *format, SourceEndian endian, vmpa2t *pos)
+static bool annotate_elf_program_header(GElfFormat *format, GPreloadInfo *info, SourceEndian endian, vmpa2t *pos)
{
bool result; /* Bilan à retourner */
elf_phdr phdr; /* En-tête de programme ELF */
@@ -287,28 +288,28 @@ static bool annotate_elf_program_header(GElfFormat *format, SourceEndian endian,
bformat = G_BIN_FORMAT(format);
- result = parse_field_definitions(PARSING_DEFS(_elf_phdr_base), bformat, pos, NULL);
+ result = parse_field_definitions(PARSING_DEFS(_elf_phdr_base), bformat, info, pos, NULL);
if (format->is_32b)
{
if (result)
- result = parse_field_definitions(PARSING_DEFS(_elf_phdr_32b_a), bformat, pos, NULL);
+ result = parse_field_definitions(PARSING_DEFS(_elf_phdr_32b_a), bformat, info, pos, NULL);
if (result)
- result = parse_field_definitions(&flags_field, 1, bformat, pos, NULL);
+ result = parse_field_definitions(&flags_field, 1, bformat, info, pos, NULL);
if (result)
- result = parse_field_definitions(PARSING_DEFS(_elf_phdr_32b_b), bformat, pos, NULL);
+ result = parse_field_definitions(PARSING_DEFS(_elf_phdr_32b_b), bformat, info, pos, NULL);
}
else
{
if (result)
- result = parse_field_definitions(&flags_field, 1, bformat, pos, NULL);
+ result = parse_field_definitions(&flags_field, 1, bformat, info, pos, NULL);
if (result)
- result = parse_field_definitions(PARSING_DEFS(_elf_phdr_64b), bformat, pos, NULL);
+ result = parse_field_definitions(PARSING_DEFS(_elf_phdr_64b), bformat, info, pos, NULL);
}
@@ -322,6 +323,7 @@ static bool annotate_elf_program_header(GElfFormat *format, SourceEndian endian,
/******************************************************************************
* *
* Paramètres : format = description de l'exécutable à compléter. *
+* info = informations à constituer en avance de phase. *
* status = barre de statut à tenir informée. *
* *
* Description : Charge tous les symboles liés aux en-têtes de programme ELF. *
@@ -332,7 +334,7 @@ static bool annotate_elf_program_header(GElfFormat *format, SourceEndian endian,
* *
******************************************************************************/
-bool annotate_elf_program_header_table(GElfFormat *format, GtkStatusStack *status)
+bool annotate_elf_program_header_table(GElfFormat *format, GPreloadInfo *info, GtkStatusStack *status)
{
bool result; /* Bilan à retourner */
const elf_header *header; /* En-tête principale */
@@ -359,7 +361,7 @@ bool annotate_elf_program_header_table(GElfFormat *format, GtkStatusStack *statu
for (i = 0; i < e_phnum && result; i++)
{
- result = annotate_elf_program_header(format, endian, &pos);
+ result = annotate_elf_program_header(format, info, endian, &pos);
gtk_status_stack_update_activity_value(status, msg, 1);
diff --git a/plugins/readelf/program.h b/plugins/readelf/program.h
index bee0fa0..0710577 100644
--- a/plugins/readelf/program.h
+++ b/plugins/readelf/program.h
@@ -25,12 +25,13 @@
#define _PLUGINS_READELF_PROGRAM_H
+#include <format/preload.h>
#include <format/elf/elf.h>
/* Charge tous les symboles liés aux en-têtes de programme ELF. */
-bool annotate_elf_program_header_table(GElfFormat *, GtkStatusStack *);
+bool annotate_elf_program_header_table(GElfFormat *, GPreloadInfo *, GtkStatusStack *);
diff --git a/plugins/readelf/reader.c b/plugins/readelf/reader.c
index 62efdf4..47b33a0 100644
--- a/plugins/readelf/reader.c
+++ b/plugins/readelf/reader.c
@@ -34,8 +34,8 @@
-DEFINE_CHRYSALIDE_ACTIVE_PLUGIN("readelf", "Displays information about ELF files", "0.1.0",
- PGA_FORMAT_LOADER_LAST);
+DEFINE_CHRYSALIDE_ACTIVE_PLUGIN("readelf", "Displays information about ELF files", "0.2.0",
+ PGA_FORMAT_PRELOAD);
/******************************************************************************
@@ -43,6 +43,7 @@ DEFINE_CHRYSALIDE_ACTIVE_PLUGIN("readelf", "Displays information about ELF files
* Paramètres : plugin = greffon à manipuler. *
* action = type d'action attendue. *
* format = description de l'exécutable à compléter. *
+* info = informations à constituer en avance de phase. *
* status = barre de statut à tenir informée. *
* *
* Description : Etablit des symboles complémentaires dans un format ELF. *
@@ -53,7 +54,7 @@ DEFINE_CHRYSALIDE_ACTIVE_PLUGIN("readelf", "Displays information about ELF files
* *
******************************************************************************/
-G_MODULE_EXPORT bool handle_binary_format(const GPluginModule *plugin, PluginAction action, GBinFormat *format, GtkStatusStack *status)
+G_MODULE_EXPORT bool preload_binary_format(const GPluginModule *plugin, PluginAction action, GBinFormat *format, GPreloadInfo *info, GtkStatusStack *status)
{
bool result; /* Bilan à retourner */
GElfFormat *elf_fmt; /* Version ELF */
@@ -66,13 +67,13 @@ G_MODULE_EXPORT bool handle_binary_format(const GPluginModule *plugin, PluginAct
elf_fmt = G_ELF_FORMAT(format);
- result = annotate_elf_header(format);
+ result = annotate_elf_header(format, info);
- result &= annotate_elf_program_header_table(elf_fmt, status);
+ result &= annotate_elf_program_header_table(elf_fmt, info, status);
- result &= annotate_elf_section_header_table(elf_fmt, status);
+ result &= annotate_elf_section_header_table(elf_fmt, info, status);
- show_elf_section_string_table(elf_fmt, status);
+ show_elf_section_string_table(elf_fmt, info, status);
hbf_exit:
diff --git a/plugins/readelf/reader.h b/plugins/readelf/reader.h
index 2da1b43..8dfdeb8 100644
--- a/plugins/readelf/reader.h
+++ b/plugins/readelf/reader.h
@@ -32,7 +32,7 @@
/* Etablit des symboles complémentaires dans un format ELF. */
-G_MODULE_EXPORT bool handle_binary_format(const GPluginModule *, PluginAction, GBinFormat *, GtkStatusStack *);
+G_MODULE_EXPORT bool preload_binary_format(const GPluginModule *, PluginAction, GBinFormat *, GPreloadInfo *, GtkStatusStack *);
diff --git a/plugins/readelf/section.c b/plugins/readelf/section.c
index 6161892..eee20b5 100644
--- a/plugins/readelf/section.c
+++ b/plugins/readelf/section.c
@@ -247,13 +247,14 @@ static fmt_field_def _elf_shdr_64b[] = {
/* Charge tous les symboles liés à un en-tête de section ELF. */
-static bool annotate_elf_section_header(GElfFormat *, SourceEndian, const elf_shdr *, vmpa2t *);
+static bool annotate_elf_section_header(GElfFormat *, GPreloadInfo *, SourceEndian, const elf_shdr *, vmpa2t *);
/******************************************************************************
* *
* Paramètres : format = description de l'exécutable à compléter. *
+* info = informations à constituer en avance de phase. *
* endian = boutisme présentement utilisé. *
* strings = section renvoyant vers des chaînes de caractères. *
* pos = tête de lecture à déplacer. [OUT] *
@@ -266,7 +267,7 @@ static bool annotate_elf_section_header(GElfFormat *, SourceEndian, const elf_sh
* *
******************************************************************************/
-static bool annotate_elf_section_header(GElfFormat *format, SourceEndian endian, const elf_shdr *strings, vmpa2t *pos)
+static bool annotate_elf_section_header(GElfFormat *format, GPreloadInfo *info, SourceEndian endian, const elf_shdr *strings, vmpa2t *pos)
{
bool result; /* Bilan à retourner */
elf_shdr shdr; /* En-tête de programme ELF */
@@ -370,21 +371,21 @@ static bool annotate_elf_section_header(GElfFormat *format, SourceEndian endian,
bformat = G_BIN_FORMAT(format);
- result = parse_field_definitions(&name_field, 1, bformat, pos, NULL);
+ result = parse_field_definitions(&name_field, 1, bformat, info, pos, NULL);
if (result)
- result = parse_field_definitions(PARSING_DEFS(_elf_sh_type), bformat, pos, NULL);
+ result = parse_field_definitions(PARSING_DEFS(_elf_sh_type), bformat, info, pos, NULL);
if (format->is_32b)
{
if (result)
{
flags_field.size = MDS_32_BITS;
- result = parse_field_definitions(&flags_field, 1, bformat, pos, NULL);
+ result = parse_field_definitions(&flags_field, 1, bformat, info, pos, NULL);
}
if (result)
- result = parse_field_definitions(PARSING_DEFS(_elf_shdr_32b), bformat, pos, NULL);
+ result = parse_field_definitions(PARSING_DEFS(_elf_shdr_32b), bformat, info, pos, NULL);
}
else
@@ -392,11 +393,11 @@ static bool annotate_elf_section_header(GElfFormat *format, SourceEndian endian,
if (result)
{
flags_field.size = MDS_64_BITS;
- result = parse_field_definitions(&flags_field, 1, bformat, pos, NULL);
+ result = parse_field_definitions(&flags_field, 1, bformat, info, pos, NULL);
}
if (result)
- result = parse_field_definitions(PARSING_DEFS(_elf_shdr_64b), bformat, pos, NULL);
+ result = parse_field_definitions(PARSING_DEFS(_elf_shdr_64b), bformat, info, pos, NULL);
}
@@ -410,6 +411,7 @@ static bool annotate_elf_section_header(GElfFormat *format, SourceEndian endian,
/******************************************************************************
* *
* Paramètres : format = description de l'exécutable à compléter. *
+* info = informations à constituer en avance de phase. *
* status = barre de statut à tenir informée. *
* *
* Description : Charge tous les symboles liés aux en-têtes de section ELF. *
@@ -420,7 +422,7 @@ static bool annotate_elf_section_header(GElfFormat *format, SourceEndian endian,
* *
******************************************************************************/
-bool annotate_elf_section_header_table(GElfFormat *format, GtkStatusStack *status)
+bool annotate_elf_section_header_table(GElfFormat *format, GPreloadInfo *info, GtkStatusStack *status)
{
bool result; /* Bilan à retourner */
const elf_header *header; /* En-tête principale */
@@ -451,7 +453,7 @@ bool annotate_elf_section_header_table(GElfFormat *format, GtkStatusStack *statu
for (i = 0; i < e_shnum && result; i++)
{
- result = annotate_elf_section_header(format, endian, &strings, &pos);
+ result = annotate_elf_section_header(format, info, endian, &strings, &pos);
gtk_status_stack_update_activity_value(status, msg, 1);
diff --git a/plugins/readelf/section.h b/plugins/readelf/section.h
index 3168dab..60e8f34 100644
--- a/plugins/readelf/section.h
+++ b/plugins/readelf/section.h
@@ -25,12 +25,13 @@
#define _PLUGINS_READELF_SECTION_H
+#include <format/preload.h>
#include <format/elf/elf.h>
/* Charge tous les symboles liés aux en-têtes de section ELF. */
-bool annotate_elf_section_header_table(GElfFormat *, GtkStatusStack *);
+bool annotate_elf_section_header_table(GElfFormat *, GPreloadInfo *, GtkStatusStack *);
diff --git a/plugins/readelf/strtab.c b/plugins/readelf/strtab.c
index c94deed..9e625fd 100644
--- a/plugins/readelf/strtab.c
+++ b/plugins/readelf/strtab.c
@@ -33,13 +33,14 @@
/* Affiche les chaînes présentes dans une zone de données. */
-static void parse_elf_string_table(GElfFormat *, const GBinContent *, const mrange_t *, GtkStatusStack *);
+static void parse_elf_string_table(GElfFormat *, GPreloadInfo *, const GBinContent *, const mrange_t *, GtkStatusStack *);
/******************************************************************************
* *
* Paramètres : format = description de l'exécutable à compléter. *
+* info = informations à constituer en avance de phase. *
* content = contenu binaire à analyser. *
* range = espace à couvrir pendant l'analyse. *
* status = barre de statut à tenir informée. *
@@ -52,7 +53,7 @@ static void parse_elf_string_table(GElfFormat *, const GBinContent *, const mran
* *
******************************************************************************/
-static void parse_elf_string_table(GElfFormat *format, const GBinContent *content, const mrange_t *range, GtkStatusStack *status)
+static void parse_elf_string_table(GElfFormat *format, GPreloadInfo *info, const GBinContent *content, const mrange_t *range, GtkStatusStack *status)
{
phys_t length; /* Taille de la couverture */
vmpa2t pos; /* Tête de lecture */
@@ -94,6 +95,9 @@ static void parse_elf_string_table(GElfFormat *format, const GBinContent *conten
g_raw_instruction_mark_as_string(G_RAW_INSTRUCTION(instr), true);
+ g_preload_info_add_instruction(info, instr);
+
+ g_object_ref(G_OBJECT(instr));
ADD_STR_AS_SYM(format, symbol, instr);
/* Jointure avec la chaîne précédente ? */
@@ -126,6 +130,7 @@ static void parse_elf_string_table(GElfFormat *format, const GBinContent *conten
/******************************************************************************
* *
* Paramètres : format = description de l'exécutable à compléter. *
+* info = informations à constituer en avance de phase. *
* status = barre de statut à tenir informée. *
* *
* Description : Affiche les chaînes liées aux sections ELF. *
@@ -136,7 +141,7 @@ static void parse_elf_string_table(GElfFormat *format, const GBinContent *conten
* *
******************************************************************************/
-void show_elf_section_string_table(GElfFormat *format, GtkStatusStack *status)
+void show_elf_section_string_table(GElfFormat *format, GPreloadInfo *info, GtkStatusStack *status)
{
GBinContent *content; /* Contenu binaire à lire */
mrange_t range; /* Espace à parcourir */
@@ -147,17 +152,17 @@ void show_elf_section_string_table(GElfFormat *format, GtkStatusStack *status)
found = find_elf_section_range_by_name(format, ".interp", &range);
if (found)
- parse_elf_string_table(format, content, &range, status);
+ parse_elf_string_table(format, info, content, &range, status);
found = find_elf_section_range_by_name(format, ".shstrtab", &range);
if (found)
- parse_elf_string_table(format, content, &range, status);
+ parse_elf_string_table(format, info, content, &range, status);
found = find_elf_section_range_by_name(format, ".strtab", &range);
if (found)
- parse_elf_string_table(format, content, &range, status);
+ parse_elf_string_table(format, info, content, &range, status);
g_object_unref(G_OBJECT(content));
diff --git a/plugins/readelf/strtab.h b/plugins/readelf/strtab.h
index a3c8c8b..89c178d 100644
--- a/plugins/readelf/strtab.h
+++ b/plugins/readelf/strtab.h
@@ -25,12 +25,13 @@
#define _PLUGINS_READELF_STRTAB_H
+#include <format/preload.h>
#include <format/elf/elf.h>
/* Affiche les chaînes liées aux sections ELF. */
-void show_elf_section_string_table(GElfFormat *, GtkStatusStack *);
+void show_elf_section_string_table(GElfFormat *, GPreloadInfo *, GtkStatusStack *);
diff --git a/src/analysis/db/items/comment.c b/src/analysis/db/items/comment.c
index beec629..3e1c06f 100644
--- a/src/analysis/db/items/comment.c
+++ b/src/analysis/db/items/comment.c
@@ -1095,7 +1095,7 @@ static bool g_db_comment_load(GDbComment *comment, const bound_value *values, si
* *
******************************************************************************/
-const vmpa2t *g_db_comment_get_address(GDbComment *comment)
+const vmpa2t *g_db_comment_get_address(const GDbComment *comment)
{
return &comment->addr;
diff --git a/src/analysis/db/items/comment.h b/src/analysis/db/items/comment.h
index ee68491..9fdfa32 100644
--- a/src/analysis/db/items/comment.h
+++ b/src/analysis/db/items/comment.h
@@ -64,7 +64,7 @@ GDbComment *g_db_comment_new_inlined(const vmpa2t *, BufferLineFlags, bool);
GDbComment *g_db_comment_new_area(const vmpa2t *, BufferLineFlags, const char *, bool);
/* Fournit l'adresse associée à un commentaire. */
-const vmpa2t *g_db_comment_get_address(GDbComment *);
+const vmpa2t *g_db_comment_get_address(const GDbComment *);
/* Fournit le commentaire associé à un commentaire. */
char *g_db_comment_get_text(GDbComment *);
diff --git a/src/analysis/disass/area.c b/src/analysis/disass/area.c
index 5dab3ab..130a7f0 100644
--- a/src/analysis/disass/area.c
+++ b/src/analysis/disass/area.c
@@ -96,6 +96,8 @@ static void fill_mem_area(mem_area *, mem_area *, size_t, GProcContext *, GtkSta
/* Rassemble les instructions conservées dans une zone donnée. */
static GArchInstruction **get_instructions_from_mem_area(const mem_area *, GArchInstruction **, size_t *);
+/* Insère une instruction dans un découpage en aires. */
+static void insert_extra_instr_into_mem_areas(mem_area *, size_t, GArchInstruction *);
/* ----------------------- MANIPULATIONS PARALLELES DES ZONES ----------------------- */
@@ -123,7 +125,7 @@ typedef struct _GAreaCollector
{
struct
{
- size_t acount; /* Nombre de zones créées */
+ size_t created; /* Nombre de zones créées */
GLoadedBinary *binary; /* Binaire à associer aux zones*/
@@ -136,6 +138,17 @@ typedef struct _GAreaCollector
struct
{
+ size_t available; /* Nombre de zones créées */
+
+ GPreloadInfo *info; /* Préchargements à intégrer */
+
+ size_t start; /* Départ des intégrations */
+ size_t stop; /* Fin des intégrations */
+
+ };
+
+ struct
+ {
size_t begin; /* Début du parcours à mener */
size_t end; /* Fin de ce même parcours */
@@ -180,6 +193,12 @@ static GAreaCollector *g_area_collector_new_intro(activity_id_t, GLoadedBinary *
/* Construit une liste bornée de zones contigües. */
static void g_area_collector_do_compute(GAreaCollector *, GtkStatusStack *);
+/* Crée une tâche de calcul des zones binaires à remplir. */
+static GAreaCollector *g_area_collector_new_insert(activity_id_t, mem_area *, size_t, GPreloadInfo *, size_t, size_t);
+
+/* Insère dans les zones contigües les instructions préchargées. */
+static void g_area_collector_do_insert(GAreaCollector *, GtkStatusStack *);
+
/* Crée une tâche de récupération d'instructions différée. */
static GAreaCollector *g_area_collector_new_outro(activity_id_t, mem_area *, size_t, size_t);
@@ -388,12 +407,19 @@ static bool mark_range_in_mem_area_as_processed(mem_area *area, GArchInstruction
if (old != NULL)
{
g_object_unref(G_OBJECT(old));
- area->instructions[offset + 1] = NULL;
+ area->instructions[offset + i] = NULL;
g_atomic_pointer_add(&area->count, -1);
}
}
+#ifndef NDEBUG
+
+ for (i = 0; i < len; i++)
+ assert(area->instructions[offset + i] == NULL);
+
+#endif
+
area->instructions[offset] = instr;
g_atomic_pointer_add(&area->count, 1);
@@ -593,10 +619,7 @@ void load_code_from_mem_area(mem_area *area, mem_area *list, size_t count, GProc
bool done; /* Enregistrement effectué ? */
- vmpa2t sym_addr; /* Adresse de nouveau symbole */
- bool has_new_sym; /* Statut d'un dépilement */
-
- GBinSymbol *symbol; /* Symbole créé en parallèle */
+ GArchInstruction *extra; /* Instruction supplémentaire */
@@ -679,18 +702,11 @@ void load_code_from_mem_area(mem_area *area, mem_area *list, size_t count, GProc
/* Insertion des symboles découverts en parallèle */
- for (has_new_sym = g_proc_context_pop_new_symbol_at(ctx, &sym_addr);
- has_new_sym;
- has_new_sym = g_proc_context_pop_new_symbol_at(ctx, &sym_addr))
+ for (extra = g_preload_info_pop_instruction(G_PRELOAD_INFO(ctx));
+ extra != NULL;
+ extra = g_preload_info_pop_instruction(G_PRELOAD_INFO(ctx)))
{
- has_new_sym = g_binary_format_find_symbol_at(format, &sym_addr, &symbol);
-
- if (has_new_sym)
- {
- insert_extra_symbol_into_mem_areas(list, count, symbol);
- g_object_unref(G_OBJECT(symbol));
- }
-
+ insert_extra_instr_into_mem_areas(list, count, extra);
}
/* Rupture du flot d'exécution ? */
@@ -932,11 +948,11 @@ mem_area *find_memory_area_by_addr(mem_area *list, size_t count, const vmpa2t *a
/******************************************************************************
* *
-* Paramètres : areas = liste de zones délimitant des contenus à traiter. *
-* count = nombre de zones à disposition. *
-* symbol = élément nouveau à venir insérer dans les zones. *
+* Paramètres : areas = liste de zones délimitant des contenus à traiter. *
+* count = nombre de zones à disposition. *
+* instr = nouvelle instruction à venir insérer dans les zones. *
* *
-* Description : Insère un symbole dans un découpage en aires. *
+* Description : Insère une instruction dans un découpage en aires. *
* *
* Retour : - *
* *
@@ -944,22 +960,16 @@ mem_area *find_memory_area_by_addr(mem_area *list, size_t count, const vmpa2t *a
* *
******************************************************************************/
-void insert_extra_symbol_into_mem_areas(mem_area *areas, size_t count, const GBinSymbol *symbol)
+static void insert_extra_instr_into_mem_areas(mem_area *areas, size_t count, GArchInstruction *instr)
{
- SymbolType type; /* Type de symbole */
- GArchInstruction *instr; /* Instruction à insérer */
const mrange_t *range; /* Emplacement d'instruction */
const vmpa2t *addr; /* Départ de cet emplacement */
mem_area *area; /* Zone d'accueil désignée */
VMPA_BUFFER(loc); /* Description d'un emplacement*/
phys_t start; /* Point de départ */
-
- type = g_binary_symbol_get_target_type(symbol);
-
- if (!HAS_DATA_INSTR(type))
- return;
-
- instr = g_binary_symbol_get_instruction(symbol);
+#ifndef NDEBUG
+ bool status; /* Validation d'une insertion */
+#endif
range = g_arch_instruction_get_range(instr);
addr = get_mrange_addr(range);
@@ -972,13 +982,13 @@ void insert_extra_symbol_into_mem_areas(mem_area *areas, size_t count, const GBi
{
vmpa2_virt_to_string(addr, MDS_UNDEFINED, loc, NULL);
- log_variadic_message(LMT_WARNING, _("No place found for symbol located at %s."), loc);
- return;
+ log_variadic_message(LMT_WARNING, _("No place found for an instruction located at %s."), loc);
+ goto ieiima_failed;
}
/**
- * Un symbole (au sens large) ne peut avoir une adresse virtuelle que s'il
+ * Une instruction ne peut avoir une adresse virtuelle que s'il
* est compris dans une zone chargée en mémoire (en toute logique).
*/
assert(has_virt_addr(get_mrange_addr(&area->range)) == has_virt_addr(addr));
@@ -991,16 +1001,25 @@ void insert_extra_symbol_into_mem_areas(mem_area *areas, size_t count, const GBi
{
vmpa2_virt_to_string(addr, MDS_UNDEFINED, loc, NULL);
- log_variadic_message(LMT_WARNING, _("The symbol located at %s is too big for one place only."), loc);
- return;
+ log_variadic_message(LMT_WARNING, _("The instruction located at %s is too big for one place only."), loc);
+ goto ieiima_failed;
}
- /* Inscription d'une instruction de symbole (sans retour arrière possible :/ ) */
+ /* Inscription d'une instruction (sans retour arrière possible :/ ) */
+#ifndef NDEBUG
+ status = mark_range_in_mem_area_as_processed(area, instr, true);
+ assert(status);
+#else
mark_range_in_mem_area_as_processed(area, instr, true);
+#endif
+
+ return;
- g_object_ref(G_OBJECT(instr));
+ ieiima_failed:
+
+ g_object_unref(G_OBJECT(instr));
}
@@ -1106,6 +1125,9 @@ static void g_area_collector_dispose(GAreaCollector *collector)
if (collector->run == (run_task_fc)g_area_collector_do_compute)
g_object_unref(G_OBJECT(collector->binary));
+ else if (collector->run == (run_task_fc)g_area_collector_do_insert)
+ g_object_unref(G_OBJECT(collector->info));
+
G_OBJECT_CLASS(g_area_collector_parent_class)->dispose(G_OBJECT(collector));
}
@@ -1160,6 +1182,7 @@ static void g_area_collector_process(GAreaCollector *collector, GtkStatusStack *
* *
* Paramètres : id = identifiant pour signaler la progression courante. *
* binary = binaire chargé à conserver dans les zones définies.*
+* info = préchargements effectués via le format binaire. *
* first = localisation du début de la portion à traiter. *
* last = localisation de la fin de la portion à traiter. *
* closing = indique si la tâche doit terminer l'analyse. *
@@ -1183,7 +1206,7 @@ static GAreaCollector *g_area_collector_new_intro(activity_id_t id, GLoadedBinar
result->areas = NULL;
- result->acount = 0;
+ result->created = 0;
result->binary = binary;
g_object_ref(G_OBJECT(binary));
@@ -1220,60 +1243,8 @@ static void g_area_collector_do_compute(GAreaCollector *collector, GtkStatusStac
GExeFormat *format; /* Format du binaire */
vmpa2t prev; /* Dernière bordure rencontrée */
bool state; /* Bilan d'une conversion */
- GBinSymbol **symbols; /* Symboles à représenter */
- size_t sym_count; /* Qté de symboles présents */
- bool has_sym_index; /* Détermine une validité */
- size_t sym_index; /* Prochain symbole non traité */
GBinPortion *portions; /* Couche première de portions */
- void populate_with_symbols(const vmpa2t *limit)
- {
- GBinSymbol *symbol; /* Symbole en cours d'analyse */
- SymbolType type; /* Nature d'un symbole */
- const mrange_t *range; /* Couverture d'un symbole */
- vmpa2t end; /* Adresse de fin du symbole */
-
- for (; sym_index < sym_count; sym_index++)
- {
- symbol = symbols[sym_index];
-
- type = g_binary_symbol_get_target_type(symbol);
-
- /**
- * On ne garde que les symboles renvoyant directement une ou
- * plusieurs instructions, c'est à dire les symboles valides
- * pour un appel à g_binary_symbol_get_instruction().
- *
- * Les instructions des autres symboles sont obtenues et mises
- * en place durant la procédure de désassemblage.
- */
-
- if (type == STP_ROUTINE || type == STP_ENTRY_POINT || type == STP_CODE_LABEL)
- continue;
-
- range = g_binary_symbol_get_range(symbol);
-
- if (get_mrange_length(range) == 0)
- continue;
-
- if (cmp_vmpa(get_mrange_addr(range), limit) >= 0)
- break;
-
- compute_mrange_end_addr(range, &end);
-
- /**
- * Si un symbole est à cheval entre deux zones, tant pis pour lui !
- */
-
- if (cmp_vmpa(&end, limit) > 0)
- break;
-
- insert_extra_symbol_into_mem_areas(*list, *count, symbol);
-
- }
-
- }
-
void fill_gap(vmpa2t *old, vmpa2t *new, bool alloc, bool exec)
{
phys_t diff; /* Espace entre bordures */
@@ -1300,24 +1271,6 @@ static void g_area_collector_do_compute(GAreaCollector *collector, GtkStatusStac
init_mem_area_from_addr(area, old, diff, collector->binary);
area->is_exec = exec;
- /* Insertion des symboles existants */
-
- if (!has_sym_index)
- {
- int cmp_vmpa_with_symbol(const vmpa2t *a, const GBinSymbol **s)
- {
- return g_binary_symbol_cmp_with_vmpa(*s, a);
- }
-
- bsearch_index(old, symbols, sym_count, sizeof(GBinSymbol *),
- (__compar_fn_t)cmp_vmpa_with_symbol, &sym_index);
-
- has_sym_index = true;
-
- }
-
- populate_with_symbols(new);
-
/* Avancée du curseur */
copy_vmpa(old, new);
@@ -1423,7 +1376,7 @@ static void g_area_collector_do_compute(GAreaCollector *collector, GtkStatusStac
}
list = &collector->areas;
- count = &collector->acount;
+ count = &collector->created;
init_vmpa(&first, collector->first, VMPA_NO_VIRTUAL);
init_vmpa(&last, collector->last, VMPA_NO_VIRTUAL);
@@ -1437,10 +1390,6 @@ static void g_area_collector_do_compute(GAreaCollector *collector, GtkStatusStac
g_exe_format_translate_offset_into_vmpa(format, 0, &prev);
#endif
- symbols = g_binary_format_get_symbols(G_BIN_FORMAT(format), &sym_count);
-
- has_sym_index = false;
-
portions = g_exe_format_get_portions(format);
g_binary_portion_visit(portions, (visit_portion_fc)build_area_from_portion, NULL);
@@ -1518,10 +1467,10 @@ mem_area *collect_memory_areas(wgroup_id_t gid, GtkStatusStack *status, GLoadedB
for (i = 0; i < runs_count; i++)
{
- result = (mem_area *)realloc(result, (*count + collectors[i]->acount) * sizeof(mem_area));
+ result = (mem_area *)realloc(result, (*count + collectors[i]->created) * sizeof(mem_area));
- memcpy(&result[*count], collectors[i]->areas, collectors[i]->acount * sizeof(mem_area));
- *count += collectors[i]->acount;
+ memcpy(&result[*count], collectors[i]->areas, collectors[i]->created * sizeof(mem_area));
+ *count += collectors[i]->created;
g_object_unref(G_OBJECT(collectors[i]));
@@ -1540,6 +1489,177 @@ mem_area *collect_memory_areas(wgroup_id_t gid, GtkStatusStack *status, GLoadedB
/******************************************************************************
* *
+* Paramètres : id = identifiant pour signaler la progression. *
+* areas = liste des zones en place à parcourir. *
+* available = nombre de zones disponibles pour les traitements.*
+* info = préchargements effectués via le format binaire. *
+* start = indice de la première instruction à insérer. *
+* stop = indice de la première instruction à ignorer. *
+* *
+* Description : Crée une tâche de calcul des zones binaires à remplir. *
+* *
+* Retour : Tâche créée. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GAreaCollector *g_area_collector_new_insert(activity_id_t id, mem_area *areas, size_t available, GPreloadInfo *info, size_t start, size_t stop)
+{
+ GAreaCollector *result; /* Tâche à retourner */
+
+ result = g_object_new(G_TYPE_AREA_COLLECTOR, NULL);
+
+ result->id = id;
+ result->run = (run_task_fc)g_area_collector_do_insert;
+
+ result->areas = areas;
+
+ result->available = available;
+
+ result->info = info;
+ g_object_ref(G_OBJECT(info));
+
+ result->start = start;
+ result->stop = stop;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : fetching = récupération à mener. *
+* status = barre de statut à tenir informée. *
+* *
+* Description : Insère dans les zones contigües les instructions préchargées.*
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_area_collector_do_insert(GAreaCollector *collector, GtkStatusStack *status)
+{
+ mem_area *area; /* Zone d'appartenance */
+ size_t i; /* Boucle de parcours */
+ GArchInstruction *instr; /* Instruction à analyser */
+ const mrange_t *range; /* Emplacement d'instruction */
+ const vmpa2t *addr; /* Localisation précise */
+#ifndef NDEBUG
+ bool inserted; /* Validation d'une insertion */
+#endif
+
+ area = NULL;
+
+ for (i = collector->start; i < collector->stop; i++)
+ {
+ instr = _g_preload_info_get_instruction(collector->info, i);
+ range = g_arch_instruction_get_range(instr);
+ addr = get_mrange_addr(range);
+
+ if (area != NULL)
+ {
+ if (!mrange_contains_addr(&area->range, addr))
+ area = NULL;
+ }
+
+ if (area == NULL)
+ area = find_memory_area_by_addr(collector->areas, collector->available, addr);
+
+ assert(area != NULL);
+
+#ifndef NDEBUG
+ inserted = mark_range_in_mem_area_as_processed(area, instr, false);
+ assert(inserted);
+#else
+ mark_range_in_mem_area_as_processed(area, instr, false);
+#endif
+
+ gtk_status_stack_update_activity_value(status, collector->id, 1);
+
+ }
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : gid = groupe de travail impliqué. *
+* status = barre de statut à tenir informée. *
+* area = nombre de zones mises en place. *
+* count = quantité de ces zones. *
+* info = préchargements effectués via le format binaire. *
+* *
+* Description : Intègre toutes les instructions préchargées dans des zones. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void populate_fresh_memory_areas(wgroup_id_t gid, GtkStatusStack *status, mem_area *areas, size_t count, GPreloadInfo *info)
+{
+ size_t icount; /* Quantité d'instructions */
+ guint runs_count; /* Qté d'exécutions parallèles */
+ GAreaCollector **collectors; /* Collecteurs à suivre */
+ phys_t run_size; /* Volume réparti par exécution*/
+ GWorkQueue *queue; /* Gestionnaire de différés */
+ activity_id_t id; /* Identifiant de progression */
+ guint i; /* Boucle de parcours */
+ size_t start; /* Premier indice à traiter */
+ size_t stop; /* Premier indice à ignorer */
+
+ g_preload_info_lock_instructions(info);
+
+ icount = _g_preload_info_count_instructions(info);
+
+ runs_count = g_get_num_processors();
+
+ collectors = (GAreaCollector **)calloc(runs_count, sizeof(GAreaCollector *));
+
+ run_size = icount / runs_count;
+
+ queue = get_work_queue();
+
+ id = gtk_status_stack_add_activity(status, _("Inserting all preloaded instructions"), icount);
+
+ for (i = 0; i < runs_count; i++)
+ {
+ start = i * run_size;
+
+ if ((i + 1) == runs_count)
+ stop = icount;
+ else
+ stop = start + run_size;
+
+ collectors[i] = g_area_collector_new_insert(id, areas, count, info, start, stop);
+
+ g_object_ref(G_OBJECT(collectors[i]));
+ g_work_queue_schedule_work(queue, G_DELAYED_WORK(collectors[i]), gid);
+
+ }
+
+ g_work_queue_wait_for_completion(queue, gid);
+
+ /* Fin */
+
+ free(collectors);
+
+ _g_preload_info_drain_instructions(info);
+
+ g_preload_info_unlock_instructions(info);
+
+ gtk_status_stack_remove_activity(status, id);
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : id = identifiant pour signaler la progression courante. *
* list = liste des zones en place à parcourir. *
* begin = indice de la première zone à traiter. *
diff --git a/src/analysis/disass/area.h b/src/analysis/disass/area.h
index 173f4be..5ee71a3 100644
--- a/src/analysis/disass/area.h
+++ b/src/analysis/disass/area.h
@@ -27,6 +27,7 @@
#include "../binary.h"
#include "../../arch/instruction.h"
+#include "../../format/preload.h"
#include "../../format/symbol.h"
#include "../../glibext/delayed.h"
#include "../../gtkext/gtkstatusstack.h"
@@ -46,9 +47,6 @@ void load_code_from_mem_area(mem_area *, mem_area *, size_t, GProcContext *, con
/* Détermine une liste de zones contigües à traiter. */
mem_area *find_memory_area_by_addr(mem_area *, size_t, const vmpa2t *);
-/* Insère un symbole dans un découpage en aires. */
-void insert_extra_symbol_into_mem_areas(mem_area *, size_t, const GBinSymbol *);
-
/* S'assure que l'ensemble des aires est entièrement décodé. */
void ensure_all_mem_areas_are_filled(mem_area *, size_t, GProcContext *, GtkStatusStack *, activity_id_t);
@@ -59,6 +57,9 @@ void ensure_all_mem_areas_are_filled(mem_area *, size_t, GProcContext *, GtkStat
/* Détermine une liste de zones contigües à traiter. */
mem_area *collect_memory_areas(wgroup_id_t, GtkStatusStack *, GLoadedBinary *, phys_t, size_t *);
+/* Intègre toutes les instructions préchargées dans des zones. */
+void populate_fresh_memory_areas(wgroup_id_t, GtkStatusStack *, mem_area *, size_t, GPreloadInfo *);
+
/* Rassemble les instructions conservées dans des zones données. */
GArchInstruction **collect_disassembled_instructions(wgroup_id_t, GtkStatusStack *, mem_area *, size_t, size_t *);
diff --git a/src/analysis/disass/disassembler.c b/src/analysis/disass/disassembler.c
index c9aa472..0ffcccd 100644
--- a/src/analysis/disass/disassembler.c
+++ b/src/analysis/disass/disassembler.c
@@ -409,8 +409,6 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkStatus
-
-
/* Première étape */
//id = gtk_extended_status_bar_push(statusbar, _("Disassembling..."), true);
@@ -576,7 +574,7 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkStatus
- print_disassembled_instructions(disass->cache, disass->lang, disass->binary, status);
+ print_disassembled_instructions(disass->cache, disass->lang, disass->binary, G_PRELOAD_INFO(ctx), status);
diff --git a/src/analysis/disass/fetch.c b/src/analysis/disass/fetch.c
index 211ed31..c5489d6 100644
--- a/src/analysis/disass/fetch.c
+++ b/src/analysis/disass/fetch.c
@@ -417,6 +417,8 @@ GArchInstruction **disassemble_binary_content(GLoadedBinary *binary, GProcContex
template.areas = collect_memory_areas(gid, status, binary, length, &template.count);
+ populate_fresh_memory_areas(gid, status, template.areas, template.count, G_PRELOAD_INFO(ctx));
+
template.status = status;
/* Amorce des traitements */
@@ -443,7 +445,7 @@ GArchInstruction **disassemble_binary_content(GLoadedBinary *binary, GProcContex
_("Disassembling following the execution flow..."),
length);
- g_binary_format_setup_disassembling_context(format, template.ctx);
+ g_binary_format_setup_disassembling_context(format, template.ctx, status);
g_work_queue_wait_for_completion(queue, gid);
diff --git a/src/analysis/disass/output.c b/src/analysis/disass/output.c
index fcbc0c6..5a74d92 100644
--- a/src/analysis/disass/output.c
+++ b/src/analysis/disass/output.c
@@ -38,6 +38,7 @@
* Paramètres : cache = tampon de récueil des résultats d'impression. *
* lang = langage de haut niveau préféré pour l'impression. *
* binary = tampon de récueil des résultats d'impression. *
+* info = informations complémentaires à intégrer. *
* status = barre de statut avec progression à mettre à jour. *
* *
* Description : Transcrit du code désassemblé en texte humainement lisible. *
@@ -48,7 +49,7 @@
* *
******************************************************************************/
-void print_disassembled_instructions(GBufferCache *cache, GCodingLanguage *lang, GLoadedBinary *binary, GtkStatusStack *status)
+void print_disassembled_instructions(GBufferCache *cache, GCodingLanguage *lang, GLoadedBinary *binary, GPreloadInfo *info, GtkStatusStack *status)
{
GExeFormat *format; /* Format associé au binaire */
GArchProcessor *proc; /* Processeur de l'architecture*/
@@ -64,6 +65,11 @@ void print_disassembled_instructions(GBufferCache *cache, GCodingLanguage *lang,
size_t count; /* Nombre total d'instructions */
activity_id_t id; /* Identifiant de progression */
bool expect_outro; /* Fin de zone de code définie */
+
+
+ GDbComment *comment; /* Commentaire à ajouter */
+ const vmpa2t *caddr; /* Localisation du commentaire */
+
size_t i; /* Boucle de parcours */
GArchInstruction *instr; /* Instruction à traiter */
const vmpa2t *iaddr; /* Adresse d'instruction */
@@ -78,7 +84,7 @@ void print_disassembled_instructions(GBufferCache *cache, GCodingLanguage *lang,
BufferLineFlags flags; /* Propriétés pour la ligne */
//mrange_t range; /* Couverture sans surface */
- GDbComment *comment; /* Commentaire à ajouter */
+ GDbComment *_comment; /* Commentaire à ajouter */
@@ -131,6 +137,20 @@ void print_disassembled_instructions(GBufferCache *cache, GCodingLanguage *lang,
expect_outro = false;
+ comment = g_preload_info_pop_comment(info);
+
+ if (comment != NULL)
+ caddr = g_db_comment_get_address(comment);
+
+
+ /*
+ if (comment != NULL)
+ log_variadic_message(LMT_BAD_BINARY,
+ _("Got comment '%s' @ 0x%08x"),
+ g_db_comment_get_text(comment), get_phy_addr(caddr));
+ */
+
+
for (i = 0; i < count; i++)
{
instr = g_arch_processor_get_instruction(proc, i);
@@ -184,7 +204,7 @@ void print_disassembled_instructions(GBufferCache *cache, GCodingLanguage *lang,
{
log_variadic_message(LMT_BAD_BINARY,
_("Unable to find a proper location for symbol '%s' @ 0x%08x"),
- g_binary_symbol_get_label(symbols[sym_index]), get_virt_addr(saddr));
+ g_binary_symbol_get_label(symbols[sym_index]), get_phy_addr(saddr));
_missing++;
@@ -261,18 +281,61 @@ void print_disassembled_instructions(GBufferCache *cache, GCodingLanguage *lang,
g_buffer_cache_append(cache, G_LINE_GENERATOR(instr), flags);
+
+
+ //////////////////////////////////
if (compared == 0)
{
/* Commentaire ? */
- comment = g_binary_symbol_get_comment(symbols[sym_index]);
+ _comment = g_binary_symbol_get_comment(symbols[sym_index]);
- if (comment != NULL)
- g_db_item_apply(G_DB_ITEM(comment), binary);
+ if (_comment != NULL)
+ g_db_item_apply(G_DB_ITEM(_comment), binary);
sym_index++;
}
+ ///////////////////////////////////////
+
+
+
+ /* Commentaire en bout de ligne ? */
+
+ if (comment != NULL)
+ {
+ compared = cmp_vmpa(iaddr, caddr);
+
+ if (compared == 0)
+ {
+ if (g_loaded_binary_add_to_collection(binary, G_DB_ITEM(comment)))
+ g_db_item_apply(G_DB_ITEM(comment), binary);
+
+ else
+ g_object_unref(G_OBJECT(comment));
+
+ }
+
+ else if (compared > 0)
+ {
+ log_variadic_message(LMT_BAD_BINARY,
+ _("Unable to find a proper location for comment '%s' @ 0x%08x"),
+ g_db_comment_get_text(comment), get_phy_addr(caddr));
+
+ g_object_unref(G_OBJECT(comment));
+
+ }
+
+ if (compared >= 0)
+ {
+ comment = g_preload_info_pop_comment(info);
+
+ if (comment != NULL)
+ caddr = g_db_comment_get_address(comment);
+
+ }
+
+ }
g_object_unref(G_OBJECT(instr));
diff --git a/src/analysis/disass/output.h b/src/analysis/disass/output.h
index 7a4cf8f..a05a3c4 100644
--- a/src/analysis/disass/output.h
+++ b/src/analysis/disass/output.h
@@ -27,13 +27,14 @@
#include "../binary.h"
#include "../human/lang.h"
+#include "../../format/preload.h"
#include "../../glibext/gbuffercache.h"
#include "../../gtkext/gtkstatusstack.h"
/* Transcrit du code désassemblé en texte humainement lisible. */
-void print_disassembled_instructions(GBufferCache *, GCodingLanguage *, GLoadedBinary *, GtkStatusStack *);
+void print_disassembled_instructions(GBufferCache *, GCodingLanguage *, GLoadedBinary *, GPreloadInfo *, GtkStatusStack *);
diff --git a/src/arch/arm/v7/fetch.c b/src/arch/arm/v7/fetch.c
index 11864f6..788d7ab 100644
--- a/src/arch/arm/v7/fetch.c
+++ b/src/arch/arm/v7/fetch.c
@@ -25,7 +25,7 @@
#include <assert.h>
-#include <malloc.h>
+#include <stdio.h>
#include <i18n.h>
@@ -36,6 +36,7 @@
#include "../../raw.h"
#include "../../sharing/container.h"
#include "../../../format/format.h"
+#include "../../../format/preload.h"
@@ -361,18 +362,15 @@ void help_fetching_with_instruction_ldr_literal_with_orig(GArchInstruction *inst
uint32_t offset; /* Décallage encodé en dur */
bool ret; /* Bilan d'une récupération */
off_t val_offset; /* Position de valeur à lire */
- vmpa2t sym_addr; /* Adresse de nouveau symbole */
+ vmpa2t loaded_addr; /* Adresse de valeur chargée */
+ mrange_t loaded_range; /* Espace de chargement */
GBinContent *content; /* Contenu binaire à relire */
uint32_t target; /* Adresse virtuelle visée */
vmpa2t pos; /* Tête de lecture de valeur */
- mrange_t sym_range; /* Espace du nouveau symbole */
VMPA_BUFFER(loc); /* Adresse au format texte */
- size_t name_len; /* Taille de nomination finale */
- char *name; /* Désignation humaine */
- GArchInstruction *sym_instr; /* Instruction de symbole */
- GBinSymbol *symbol; /* Nouveau symbole construit */
+ GArchInstruction *loaded; /* Instruction de valeur */
+ char *desc; /* Description d'accompagnement*/
GDbComment *comment; /* Définition de commentaire */
- bool added; /* Bilan de l'insertion */
GArchOperand *new; /* Instruction de ciblage */
/* Récupération de l'adresse visée par le chargement */
@@ -410,32 +408,24 @@ void help_fetching_with_instruction_ldr_literal_with_orig(GArchInstruction *inst
return;
}
- /* Transformations et conservation d'une position de symbole */
+ /* Transformations et conservation d'une position de chargement */
val_offset = phys_pc + offset;
- if (!g_exe_format_translate_offset_into_vmpa(format, val_offset, &sym_addr))
+ if (!g_exe_format_translate_offset_into_vmpa(format, val_offset, &loaded_addr))
{
assert(0);
g_arch_instruction_unlock_operands(instr);
return;
}
- //init_vmpa(&sym_addr, val_offset, VMPA_NO_VIRTUAL);
- init_mrange(&sym_range, &sym_addr, 4);
-
-
-
-
-
-
-
+ init_mrange(&loaded_range, &loaded_addr, 4);
/* Lecture de la valeur vers laquelle renvoyer */
content = g_binary_format_get_content(G_BIN_FORMAT(format));
- copy_vmpa(&pos, &sym_addr);
+ copy_vmpa(&pos, &loaded_addr);
ret = g_binary_content_read_u32(content, &pos, SRE_LITTLE /* FIXME */, &target);
g_object_unref(G_OBJECT(content));
@@ -446,55 +436,24 @@ void help_fetching_with_instruction_ldr_literal_with_orig(GArchInstruction *inst
return;
}
- /* Réalise l'intégration du symbole associé */
+ /* Réalise l'intégration de la valeur chargée */
- sym_instr = g_raw_instruction_new_from_value(&sym_addr, MDS_32_BITS_UNSIGNED, target);
+ copy_vmpa(&pos, &loaded_addr);
- name_len = strlen(_("Value used @ %s")) + VMPA_MAX_LEN + 1;
+ loaded = g_raw_instruction_new_from_value(&pos, MDS_32_BITS_UNSIGNED, target);
- name = (char *)calloc(name_len, sizeof(char));
+ g_preload_info_add_instruction(G_PRELOAD_INFO(context), loaded);
vmpa2_virt_to_string(get_mrange_addr(range), MDS_32_BITS, loc, NULL);
- snprintf(name, name_len, _("Value used @ %s"), loc);
-
- added = ADD_RAW_AS_SYM(G_BIN_FORMAT(format), symbol, sym_instr, comment, name);
-
- free(name);
-
-
-
- if (added)
- g_proc_context_push_new_symbol_at(G_PROC_CONTEXT(context), &sym_addr);
-
-
-
- //g_proc_context_push_new_symbol_at(context, &sym_addr);
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- //g_imm_operand_set_value(G_IMM_OPERAND(sub_op), MDS_32_BITS_UNSIGNED, target, G_SHARE_CONTAINER(instr));
-
+ asprintf(&desc, _("Value used @ %s"), loc);
- /// FIXME ?!
- //if (target < 0x8000) return;
+ comment = g_db_comment_new_inlined(&loaded_addr, BLF_HAS_CODE, false);
+ g_db_comment_add_static_text(comment, desc);
+ g_db_item_set_volatile(G_DB_ITEM(comment), true);
- //if (target > 0x6966c) return;
+ g_preload_info_add_comment(G_PRELOAD_INFO(context), comment);
+ /* Mise à jour de l'affichage et conclusion */
new = g_imm_operand_new_from_value(MDS_32_BITS_UNSIGNED, target);
_g_arch_instruction_replace_operand(instr, op, new);
diff --git a/src/arch/context-int.h b/src/arch/context-int.h
index 4e188cc..3a5c7ee 100644
--- a/src/arch/context-int.h
+++ b/src/arch/context-int.h
@@ -31,6 +31,9 @@
#include <stdarg.h>
+#include "../format/preload-int.h"
+
+
/* Granularité des allocations */
#define DP_ALLOC_BLOCK 10
@@ -43,7 +46,7 @@ typedef void (* push_drop_point_fc) (GProcContext *, DisassPriorityLevel, virt_t
/* Définition d'un contexte pour processeur (instance) */
struct _GProcContext
{
- GObject parent; /* A laisser en premier */
+ GPreloadInfo parent; /* A laisser en premier */
virt_t *drop_points[DPL_COUNT]; /* Liste de points de départ */
size_t dp_allocated[DPL_COUNT]; /* Taille de liste allouée */
@@ -67,7 +70,7 @@ struct _GProcContext
/* Définition d'un contexte pour processeur (classe) */
struct _GProcContextClass
{
- GObjectClass parent; /* A laisser en premier */
+ GPreloadInfoClass parent; /* A laisser en premier */
push_drop_point_fc push_point; /* Inclusion de points de chute*/
diff --git a/src/arch/context.c b/src/arch/context.c
index ddb74fd..c7a59da 100644
--- a/src/arch/context.c
+++ b/src/arch/context.c
@@ -55,7 +55,7 @@ static void _g_proc_context_push_drop_point(GProcContext *, DisassPriorityLevel,
/* Indique le type définit par la GLib pour le contexte de processeur. */
-G_DEFINE_TYPE(GProcContext, g_proc_context, G_TYPE_OBJECT);
+G_DEFINE_TYPE(GProcContext, g_proc_context, G_TYPE_PRELOAD_INFO);
diff --git a/src/arch/instruction.c b/src/arch/instruction.c
index a9bc4f2..807bbbb 100644
--- a/src/arch/instruction.c
+++ b/src/arch/instruction.c
@@ -463,7 +463,7 @@ void g_arch_instruction_get_rw_registers(const GArchInstruction *instr, GArchReg
* *
* Paramètres : instr = instruction à mettre à jour. *
* *
-* Description : Verrouille les accès la liste des opérandes. *
+* Description : Verrouille les accès à la liste des opérandes. *
* *
* Retour : - *
* *
@@ -482,7 +482,7 @@ void g_arch_instruction_lock_operands(GArchInstruction *instr)
* *
* Paramètres : instr = instruction à mettre à jour. *
* *
-* Description : Déverrouille les accès la liste des opérandes. *
+* Description : Déverrouille les accès à la liste des opérandes. *
* *
* Retour : - *
* *
@@ -546,12 +546,12 @@ size_t _g_arch_instruction_count_operands(const GArchInstruction *instr)
/******************************************************************************
* *
-* Paramètres : instr = instance à mettre à jour. *
-* index = indice de l'opérande concernée. *
+* Paramètres : instr = instance à consulter. *
+* index = indice de l'opérande concerné. *
* *
* Description : Fournit un opérande donné d'une instruction. *
* *
-* Retour : Opérande trouvée ou NULL si aucune. *
+* Retour : Opérande trouvée. *
* *
* Remarques : - *
* *
diff --git a/src/arch/instruction.h b/src/arch/instruction.h
index 55c845e..64b8dd5 100644
--- a/src/arch/instruction.h
+++ b/src/arch/instruction.h
@@ -131,10 +131,10 @@ void g_arch_instruction_get_rw_registers(const GArchInstruction *, GArchRegister
/* --------------------------- MANIPULATION DES OPERANDES --------------------------- */
-/* Verrouille les accès la liste des opérandes. */
+/* Verrouille les accès à la liste des opérandes. */
void g_arch_instruction_lock_operands(GArchInstruction *);
-/* Déverrouille les accès la liste des opérandes. */
+/* Déverrouille les accès à la liste des opérandes. */
void g_arch_instruction_unlock_operands(GArchInstruction *);
/* Attache un opérande supplémentaire à une instruction. */
diff --git a/src/common/array.c b/src/common/array.c
index 641a885..e4e7bb1 100644
--- a/src/common/array.c
+++ b/src/common/array.c
@@ -34,6 +34,9 @@
#include <string.h>
+#include "sort.h"
+
+
/**
* L'expression du besoin d'une gestion optimisée des tableaux se base sur la
@@ -259,6 +262,64 @@ void add_item_to_flat_array(flat_array_t **array, const void *item, size_t size)
/******************************************************************************
* *
+* Paramètres : array = tableau compressé à mettre à jour. [OUT] *
+* item = adresse de l'élément à rajouter. *
+* size = taille de ce nouvel élément. *
+* compar = méthode de comparaison entre éléments. *
+* *
+* Description : Ajoute un élément supplémentaire à un tableau trié. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void insert_item_into_flat_array(flat_array_t **array, void *item, size_t size, __compar_fn_t compar)
+{
+ ext_flat_array_t *extended; /* Version de tableau étendue */
+
+ assert(FLAT_ARRAY_IS_LOCKED(*array));
+
+ if (FLAT_ARRAY_IS_EMPTY(*array))
+ {
+ *array = malloc(size);
+ memcpy(*array, item, size);
+
+ lock_flat_array(array);
+
+ }
+
+ else
+ {
+ if (FLAT_ARRAY_HAS_NO_INDEX(*array))
+ {
+ extended = (ext_flat_array_t *)malloc(sizeof(ext_flat_array_t));
+
+ extended->items = malloc(size);
+ extended->count = 1;
+
+ memcpy(extended->items, GET_LONELY_ITEM(*array), size);
+
+ FLAT_ARRAY_SET_INDEX(extended);
+
+ *array = (flat_array_t *)extended;
+
+ lock_flat_array(array);
+
+ }
+
+ extended = EXTENDED_ARRAY(*array);
+
+ extended->items = qinsert(extended->items, &extended->count, size, compar, item);
+
+ }
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : array = tableau compressé à mettre à jour. *
* index = indice de l'élément à remplacer. *
* new = adresse de l'élément à rajouter. *
diff --git a/src/common/array.h b/src/common/array.h
index 416800d..2dd5b9f 100644
--- a/src/common/array.h
+++ b/src/common/array.h
@@ -25,6 +25,7 @@
#define _COMMON_ARRAY_H
+#include <stdlib.h>
#include <sys/types.h>
@@ -45,6 +46,9 @@ size_t count_flat_array_items(const flat_array_t *);
/* Ajoute un élément supplémentaire à un tableau. */
void add_item_to_flat_array(flat_array_t **, const void *, size_t);
+/* Ajoute un élément supplémentaire à un tableau trié. */
+void insert_item_into_flat_array(flat_array_t **, void *, size_t, __compar_fn_t);
+
/* Remplace un élément d'un tableau compressé par un autre. */
void rpl_item_in_flat_array(flat_array_t *, size_t, void *, size_t);
diff --git a/src/format/Makefile.am b/src/format/Makefile.am
index 3f18b88..2fef6c6 100644
--- a/src/format/Makefile.am
+++ b/src/format/Makefile.am
@@ -8,6 +8,8 @@ libformat_la_SOURCES = \
executable.h executable.c \
format-int.h \
format.h format.c \
+ preload-int.h \
+ preload.h preload.c \
symbol.h symbol.c
libformat_la_LIBADD = \
diff --git a/src/format/format.c b/src/format/format.c
index 978a3d2..11216a2 100644
--- a/src/format/format.c
+++ b/src/format/format.c
@@ -31,6 +31,7 @@
#include "format-int.h"
+#include "preload.h"
#include "dex/dex.h"
#include "dwarf/dwarf.h"
#include "elf/elf.h"
@@ -247,6 +248,7 @@ void g_binary_format_register_code_point(GBinFormat *format, virt_t pt, bool ent
* *
* Paramètres : format = description de l'exécutable à consulter. *
* ctx = contexte de désassemblage à préparer. *
+* status = barre de statut à tenir informée. *
* *
* Description : Fournit un contexte initialisé pour un désassemblage. *
* *
@@ -256,10 +258,12 @@ void g_binary_format_register_code_point(GBinFormat *format, virt_t pt, bool ent
* *
******************************************************************************/
-void g_binary_format_setup_disassembling_context(GBinFormat *format, GProcContext *ctx)
+void g_binary_format_setup_disassembling_context(GBinFormat *format, GProcContext *ctx, GtkStatusStack *status)
{
size_t i; /* Boucle de parcours */
+ preload_binary_format(PGA_FORMAT_PRELOAD, format, G_PRELOAD_INFO(ctx), status);
+
g_rw_lock_reader_lock(&format->pt_lock);
for (i = 0; i < format->ep_count; i++)
diff --git a/src/format/format.h b/src/format/format.h
index c2ef895..b04f11b 100644
--- a/src/format/format.h
+++ b/src/format/format.h
@@ -34,6 +34,7 @@
#include "../analysis/content.h"
#include "../analysis/routine.h"
#include "../arch/context.h"
+#include "../gtkext/gtkstatusstack.h"
@@ -65,7 +66,7 @@ SourceEndian g_binary_format_get_endianness(const GBinFormat *);
void g_binary_format_register_code_point(GBinFormat *, virt_t, bool);
/* Fournit un contexte initialisé pour un désassemblage. */
-void g_binary_format_setup_disassembling_context(GBinFormat *, GProcContext *);
+void g_binary_format_setup_disassembling_context(GBinFormat *, GProcContext *, GtkStatusStack *);
/* Ajoute un symbole à la collection du format binaire. */
bool g_binary_format_add_symbol(GBinFormat *, GBinSymbol *);
diff --git a/src/format/preload-int.h b/src/format/preload-int.h
new file mode 100644
index 0000000..ccc59e3
--- /dev/null
+++ b/src/format/preload-int.h
@@ -0,0 +1,54 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * preload.c - préchargement d'instructions à partir d'un format
+ *
+ * Copyright (C) 2017 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide 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.
+ *
+ * Chrysalide 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/>.
+ */
+
+
+#ifndef _FORMAT_PRELOAD_INT_H
+#define _FORMAT_PRELOAD_INT_H
+
+
+#include "preload.h"
+
+
+#include "../common/array.h"
+
+
+
+/* Préchargement d'origine formatée (instance) */
+struct _GPreloadInfo
+{
+ GObject parent; /* A laisser en premier */
+
+ flat_array_t *instructions; /* Liste d'instructions */
+ flat_array_t *comments; /* Liste de commentaires */
+
+};
+
+/* Préchargement d'origine formatée (classe) */
+struct _GPreloadInfoClass
+{
+ GObjectClass parent; /* A laisser en premier */
+
+};
+
+
+
+#endif /* _FORMAT_PRELOAD_INT_H */
diff --git a/src/format/preload.c b/src/format/preload.c
new file mode 100644
index 0000000..145dfd9
--- /dev/null
+++ b/src/format/preload.c
@@ -0,0 +1,534 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * preload.c - préchargement d'instructions à partir d'un format
+ *
+ * Copyright (C) 2017 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide 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.
+ *
+ * Chrysalide 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 "preload.h"
+
+
+#include "preload-int.h"
+
+
+
+/* Initialise la classe des préchargements à partir d'un format. */
+static void g_preload_info_class_init(GPreloadInfoClass *);
+
+/* Initialise une instance de préchargement à partir de format. */
+static void g_preload_info_init(GPreloadInfo *);
+
+/* Supprime toutes les références externes. */
+static void g_preload_info_dispose(GPreloadInfo *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_preload_info_finalize(GPreloadInfo *);
+
+
+
+/* Indique le type défini pour un préchargement à partir d'un format. */
+G_DEFINE_TYPE(GPreloadInfo, g_preload_info, G_TYPE_OBJECT);
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des préchargements à partir d'un format.*
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_preload_info_class_init(GPreloadInfoClass *klass)
+{
+ GObjectClass *object; /* Autre version de la classe */
+
+ object = G_OBJECT_CLASS(klass);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_preload_info_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_preload_info_finalize;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : info = instance à initialiser. *
+* *
+* Description : Initialise une instance de préchargement à partir de format. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_preload_info_init(GPreloadInfo *info)
+{
+ info->instructions = NULL;
+
+ info->comments = NULL;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : info = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_preload_info_dispose(GPreloadInfo *info)
+{
+ GArchInstruction *instr; /* Instruction à libérer */
+ GDbComment *comment; /* Commentaire à libérer */
+
+ g_preload_info_lock_instructions(info);
+
+ _g_preload_info_drain_instructions(info);
+
+ g_preload_info_unlock_instructions(info);
+
+ g_preload_info_lock_comments(info);
+
+ while (_g_preload_info_count_comments(info) > 0)
+ {
+ comment = _g_preload_info_get_comment(info, 0);
+
+ rem_item_from_flat_array(&info->comments, 0, sizeof(GDbComment *));
+
+ g_object_unref(G_OBJECT(comment));
+
+ }
+
+ g_preload_info_unlock_comments(info);
+
+ G_OBJECT_CLASS(g_preload_info_parent_class)->dispose(G_OBJECT(info));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : info = instance d'objet GLib à traiter. *
+* *
+* Description : Procède à la libération totale de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_preload_info_finalize(GPreloadInfo *info)
+{
+ G_OBJECT_CLASS(g_preload_info_parent_class)->finalize(G_OBJECT(info));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Crée une nouvelle collecte d'informations préchargées. *
+* *
+* Retour : Adresse de l'instance mise en place ou NULL en cas d'échec. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GPreloadInfo *g_preload_info_new(void)
+{
+ GPreloadInfo *result; /* Nouveau preloade à renvoyer */
+
+ result = g_object_new(G_TYPE_PRELOAD_INFO, NULL);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : info = préchargements à mettre à jour. *
+* *
+* Description : Verrouille les accès à la liste des instructions. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_preload_info_lock_instructions(GPreloadInfo *info)
+{
+ lock_flat_array(&info->instructions);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : info = préchargements à mettre à jour. *
+* *
+* Description : Déverrouille les accès à la liste des instructions. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_preload_info_unlock_instructions(GPreloadInfo *info)
+{
+ unlock_flat_array(&info->instructions);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : info = instance à mettre à jour. *
+* instr = instruction à venir associer. *
+* *
+* Description : Ajoute une instruction supplémentaire aux préchargements. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_preload_info_add_instruction(GPreloadInfo *info, GArchInstruction *instr)
+{
+ int cmp_instr_by_addr(const GArchInstruction **a, const GArchInstruction **b)
+ {
+ const mrange_t *range_a; /* Emplacement pour l'instr. A */
+ const mrange_t *range_b; /* Emplacement pour l'instr. B */
+
+ range_a = g_arch_instruction_get_range(*a);
+ range_b = g_arch_instruction_get_range(*b);
+
+ return cmp_vmpa(get_mrange_addr(range_a), get_mrange_addr(range_b));
+
+ }
+
+ g_preload_info_lock_instructions(info);
+
+ insert_item_into_flat_array(&info->instructions, &instr, sizeof(GArchInstruction *),
+ (__compar_fn_t)cmp_instr_by_addr);
+
+ g_preload_info_unlock_instructions(info);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : info = instance à consulter. *
+* *
+* Description : Indique la quantité d'instructions préchargées disponibles. *
+* *
+* Retour : Nombre d'instructions attachées. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+size_t _g_preload_info_count_instructions(const GPreloadInfo *info)
+{
+ size_t result; /* Décompte à retourner */
+
+ result = count_flat_array_items(info->instructions);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : info = instance à consulter. *
+* index = indice de l'instruction concernée. *
+* *
+* Description : Fournit une instruction préchargée donnée. *
+* *
+* Retour : Instruction trouvée. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchInstruction *_g_preload_info_get_instruction(const GPreloadInfo *info, size_t index)
+{
+ GArchInstruction *result; /* Opérande à retourner */
+ GArchInstruction **ptr; /* Adresse dans le tableau */
+
+ ptr = get_flat_array_item(info->instructions, index, sizeof(GArchInstruction *));
+
+ result = *ptr;
+
+ g_object_ref(G_OBJECT(result));
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : info = instance à manipuler. *
+* *
+* Description : Dépile une instruction présente dans les préchargements. *
+* *
+* Retour : Instruction retirée ou NULL si aucune. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchInstruction *g_preload_info_pop_instruction(GPreloadInfo *info)
+{
+ GArchInstruction *result; /* Instruction à retourner */
+ GArchInstruction **ptr; /* Adresse dans le tableau */
+
+ g_preload_info_lock_instructions(info);
+
+ if (_g_preload_info_count_instructions(info) == 0)
+ result = NULL;
+
+ else
+ {
+ ptr = get_flat_array_item(info->instructions, 0, sizeof(GArchInstruction *));
+ result = *ptr;
+
+ rem_item_from_flat_array(&info->instructions, 0, sizeof(GArchInstruction *));
+
+ }
+
+ g_preload_info_unlock_instructions(info);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : info = instance à manipuler. *
+* *
+* Description : Retire des préchargements toutes les instructions. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void _g_preload_info_drain_instructions(GPreloadInfo *info)
+{
+ GArchInstruction *instr; /* Instruction à libérer */
+
+ while (_g_preload_info_count_instructions(info) > 0)
+ {
+ instr = _g_preload_info_get_instruction(info, 0);
+
+ rem_item_from_flat_array(&info->instructions, 0, sizeof(GArchInstruction *));
+
+ g_object_unref(G_OBJECT(instr));
+
+ }
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : info = préchargements à mettre à jour. *
+* *
+* Description : Verrouille les accès à la liste des commentaires. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_preload_info_lock_comments(GPreloadInfo *info)
+{
+ lock_flat_array(&info->comments);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : info = préchargements à mettre à jour. *
+* *
+* Description : Déverrouille les accès à la liste des commentaires. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_preload_info_unlock_comments(GPreloadInfo *info)
+{
+ unlock_flat_array(&info->comments);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : info = instance à mettre à jour. *
+* comment = commentaire à venir associer. *
+* *
+* Description : Ajoute un commentaire supplémentaire aux préchargements. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_preload_info_add_comment(GPreloadInfo *info, GDbComment *comment)
+{
+ int cmp_comment_by_addr(const GDbComment * const *a, const GDbComment * const *b)
+ {
+ const vmpa2t *addr_a; /* Position du commentaire A */
+ const vmpa2t *addr_b; /* Position du commentaire B */
+
+ addr_a = g_db_comment_get_address(*a);
+ addr_b = g_db_comment_get_address(*b);
+
+ return cmp_vmpa(addr_a, addr_b);
+
+ }
+
+ g_preload_info_lock_comments(info);
+
+ insert_item_into_flat_array(&info->comments, &comment, sizeof(GDbComment *),
+ (__compar_fn_t)cmp_comment_by_addr);
+
+ g_preload_info_unlock_comments(info);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : info = instance à consulter. *
+* *
+* Description : Indique la quantité de commentaires préchargés disponibles. *
+* *
+* Retour : Nombre de commentaires attachés. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+size_t _g_preload_info_count_comments(const GPreloadInfo *info)
+{
+ size_t result; /* Décompte à retourner */
+
+ result = count_flat_array_items(info->comments);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : info = instance à consulter. *
+* index = indice de l'instruction concernée. *
+* *
+* Description : Fournit un commentaire préchargé donné. *
+* *
+* Retour : Commentaire trouvé. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GDbComment *_g_preload_info_get_comment(const GPreloadInfo *info, size_t index)
+{
+ GDbComment *result; /* Opérande à retourner */
+ GDbComment **ptr; /* Adresse dans le tableau */
+
+ ptr = get_flat_array_item(info->comments, index, sizeof(GDbComment *));
+
+ result = *ptr;
+
+ g_object_ref(G_OBJECT(result));
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : info = instance à manipuler. *
+* *
+* Description : Dépile un commentaire présent dans les préchargements. *
+* *
+* Retour : Commentaire retiré ou NULL si aucune. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GDbComment *g_preload_info_pop_comment(GPreloadInfo *info)
+{
+ GDbComment *result; /* Instruction à retourner */
+ GDbComment **ptr; /* Adresse dans le tableau */
+
+ g_preload_info_lock_comments(info);
+
+ if (_g_preload_info_count_comments(info) == 0)
+ result = NULL;
+
+ else
+ {
+ ptr = get_flat_array_item(info->comments, 0, sizeof(GDbComment *));
+ result = *ptr;
+
+ rem_item_from_flat_array(&info->comments, 0, sizeof(GDbComment *));
+
+ }
+
+ g_preload_info_unlock_comments(info);
+
+ return result;
+
+}
diff --git a/src/format/preload.h b/src/format/preload.h
new file mode 100644
index 0000000..a915462
--- /dev/null
+++ b/src/format/preload.h
@@ -0,0 +1,98 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * preload.h - prototypes pour le préchargement d'instructions à partir d'un format
+ *
+ * Copyright (C) 2017 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide 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.
+ *
+ * Chrysalide 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/>.
+ */
+
+
+#ifndef _FORMAT_PRELOAD_H
+#define _FORMAT_PRELOAD_H
+
+
+#include <glib-object.h>
+
+
+#include "../analysis/db/items/comment.h"
+#include "../arch/instruction.h"
+
+
+
+#define G_TYPE_PRELOAD_INFO g_preload_info_get_type()
+#define G_PRELOAD_INFO(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_PRELOAD_INFO, GPreloadInfo))
+#define G_IS_PRELOAD_INFO(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_PRELOAD_INFO))
+#define G_PRELOAD_INFO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_PRELOAD_INFO, GPreloadInfoClass))
+#define G_IS_PRELOAD_INFO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_PRELOAD_INFO))
+#define G_PRELOAD_INFO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_PRELOAD_INFO, GPreloadInfoClass))
+
+
+/* Préchargement d'origine formatée (instance) */
+typedef struct _GPreloadInfo GPreloadInfo;
+
+/* Préchargement d'origine formatée (classe) */
+typedef struct _GPreloadInfoClass GPreloadInfoClass;
+
+
+/* Indique le type défini pour un préchargement à partir d'un format. */
+GType g_preload_info_get_type(void);
+
+/* Crée une nouvelle collecte d'informations préchargées. */
+GPreloadInfo *g_preload_info_new(void);
+
+/* Verrouille les accès à la liste des instructions. */
+void g_preload_info_lock_instructions(GPreloadInfo *);
+
+/* Déverrouille les accès à la liste des instructions. */
+void g_preload_info_unlock_instructions(GPreloadInfo *);
+
+/* Ajoute une instruction supplémentaire aux préchargements. */
+void g_preload_info_add_instruction(GPreloadInfo *, GArchInstruction *);
+
+/* Indique la quantité d'instructions préchargées disponibles. */
+size_t _g_preload_info_count_instructions(const GPreloadInfo *);
+
+/* Fournit une instruction préchargée donnée. */
+GArchInstruction *_g_preload_info_get_instruction(const GPreloadInfo *, size_t);
+
+/* Dépile une instruction présente dans les préchargements. */
+GArchInstruction *g_preload_info_pop_instruction(GPreloadInfo *);
+
+/* Retire des préchargements toutes les instructions. */
+void _g_preload_info_drain_instructions(GPreloadInfo *);
+
+/* Verrouille les accès à la liste des commentaires. */
+void g_preload_info_lock_comments(GPreloadInfo *);
+
+/* Déverrouille les accès à la liste des commentaires. */
+void g_preload_info_unlock_comments(GPreloadInfo *);
+
+/* Ajoute un commentaire supplémentaire aux préchargements. */
+void g_preload_info_add_comment(GPreloadInfo *, GDbComment *);
+
+/* Indique la quantité de commentaires préchargés disponibles. */
+size_t _g_preload_info_count_comments(const GPreloadInfo *);
+
+/* Fournit un commentaire préchargé donné. */
+GDbComment *_g_preload_info_get_comment(const GPreloadInfo *, size_t);
+
+/* Dépile un commentaire présent dans les préchargements. */
+GDbComment *g_preload_info_pop_comment(GPreloadInfo *);
+
+
+
+#endif /* _FORMAT_PRELOAD_H */
diff --git a/src/plugins/pglist.h b/src/plugins/pglist.h
index 53556b3..e085102 100644
--- a/src/plugins/pglist.h
+++ b/src/plugins/pglist.h
@@ -68,7 +68,8 @@ const GPluginModule **get_all_plugins_for_action(PluginAction, size_t *);
#define handle_binary_format(a, f, s) \
process_all_plugins_for(a, g_plugin_module_handle_binary_format, f, s)
-
+#define preload_binary_format(a, f, i, s) \
+ process_all_plugins_for(a, g_plugin_module_preload_binary_format, f, i, s)
/* DPS_DISASSEMBLY */
diff --git a/src/plugins/plugin-def.h b/src/plugins/plugin-def.h
index b0523e1..7344a06 100644
--- a/src/plugins/plugin-def.h
+++ b/src/plugins/plugin-def.h
@@ -122,6 +122,9 @@ typedef enum _PluginAction
/* Accompagnement du chargement (fin) */
PGA_FORMAT_LOADER_LAST = DPC_BINARY_PROCESSING | DPS_FORMAT | DEFINE_PLUGIN_ACTION(1),
+ /* Accompagnement du chargement (fin) */
+ PGA_FORMAT_PRELOAD = DPC_BINARY_PROCESSING | DPS_FORMAT | DEFINE_PLUGIN_ACTION(2),
+
/**
* DPC_BINARY_PROCESSING | DPS_DISASSEMBLY
*/
diff --git a/src/plugins/plugin-int.h b/src/plugins/plugin-int.h
index 6f02369..7ccd2a6 100644
--- a/src/plugins/plugin-int.h
+++ b/src/plugins/plugin-int.h
@@ -51,6 +51,9 @@ typedef void (* pg_process_disassembly_fc) (const GPluginModule *, PluginAction,
/* Procède à une opération liée au format de fichier uniquement. */
typedef bool (* pg_handle_format) (const GPluginModule *, PluginAction, GBinFormat *, GtkStatusStack *);
+/* Procède à un préchargement de format de fichier. */
+typedef bool (* pg_preload_format) (const GPluginModule *, PluginAction, GBinFormat *, GPreloadInfo *, GtkStatusStack *);
+
@@ -109,7 +112,7 @@ struct _GPluginModule
//pg_format_is_matching is_matching; /* Recherche de correspondance */
pg_handle_format handle_format; /* Manipulation du format */
-
+ pg_preload_format preload_format; /* Préchargement d'un format */
};
diff --git a/src/plugins/plugin.c b/src/plugins/plugin.c
index 7a5c680..0c287d6 100644
--- a/src/plugins/plugin.c
+++ b/src/plugins/plugin.c
@@ -279,6 +279,12 @@ GPluginModule *g_plugin_module_new(const gchar *filename, GObject *ref)
goto bad_plugin;
break;
+ case PGA_FORMAT_PRELOAD:
+ if (!load_plugin_symbol(result->module,
+ "preload_binary_format", &result->preload_format))
+ goto bad_plugin;
+ break;
+
default:
log_variadic_message(LMT_WARNING,
_("Unknown action '0x%02x' in plugin '%s'..."),
@@ -509,6 +515,29 @@ bool g_plugin_module_handle_binary_format(const GPluginModule *plugin, PluginAct
* *
* Paramètres : plugin = greffon à manipuler. *
* action = type d'action attendue. *
+* format = format de binaire à manipuler pendant l'opération. *
+* info = informations à constituer en avance de phase. *
+* status = barre de statut à tenir informée. *
+* *
+* Description : Procède à un préchargement de format de fichier. *
+* *
+* Retour : Bilan de l'exécution du traitement. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_plugin_module_preload_binary_format(const GPluginModule *plugin, PluginAction action, GBinFormat *format, GPreloadInfo *info, GtkStatusStack *status)
+{
+ return plugin->preload_format(plugin, action, format, info, status);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : plugin = greffon à manipuler. *
+* action = type d'action attendue. *
* binary = binaire dont le contenu est en cours de traitement. *
* *
* Description : Exécute une action pendant un désassemblage de binaire. *
diff --git a/src/plugins/plugin.h b/src/plugins/plugin.h
index e09189d..bc52c93 100644
--- a/src/plugins/plugin.h
+++ b/src/plugins/plugin.h
@@ -32,6 +32,7 @@
#include "plugin-def.h"
#include "../analysis/binary.h"
#include "../format/format.h"
+#include "../format/preload.h"
#include "../gtkext/gtkstatusstack.h"
@@ -66,6 +67,9 @@ const plugin_interface *g_plugin_module_get_interface(const GPluginModule *);
/* Procède à une opération liée au format de fichier uniquement. */
bool g_plugin_module_handle_binary_format(const GPluginModule *, PluginAction, GBinFormat *, GtkStatusStack *);
+/* Procède à un préchargement de format de fichier. */
+bool g_plugin_module_preload_binary_format(const GPluginModule *, PluginAction, GBinFormat *, GPreloadInfo *, GtkStatusStack *);
+
/* Exécute une action pendant un désassemblage de binaire. */
void g_plugin_module_process_disassembly_event(const GPluginModule *, PluginAction, GLoadedBinary *);