diff options
49 files changed, 1392 insertions, 339 deletions
@@ -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 *); |