From 0c638aecff9482b93621d77279ac77a8788584e9 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sun, 1 Mar 2020 23:54:45 +0100 Subject: Given some priority to Elf PLT entries during the disassembly process. --- plugins/arm/v7/context.c | 1 + plugins/elf/symbols.c | 37 +++++++++++++++--------- plugins/mobicore/symbols.c | 4 +-- plugins/pychrysalide/arch/constants.c | 42 +++++++++++++++++++++++++++ plugins/pychrysalide/arch/constants.h | 3 ++ plugins/pychrysalide/arch/context.c | 4 +++ plugins/pychrysalide/format/format.c | 6 ++-- src/arch/context.h | 1 + src/format/executable.c | 4 +-- src/format/flat.c | 8 ++++-- src/format/format-int.h | 12 +++----- src/format/format.c | 54 ++++++++++++++--------------------- src/format/format.h | 2 +- 13 files changed, 113 insertions(+), 65 deletions(-) diff --git a/plugins/arm/v7/context.c b/plugins/arm/v7/context.c index ed9cf2f..f028f05 100644 --- a/plugins/arm/v7/context.c +++ b/plugins/arm/v7/context.c @@ -216,6 +216,7 @@ static void g_armv7_context_push_drop_point(GArmV7Context *ctx, DisassPriorityLe switch (level) { case DPL_ENTRY_POINT: + case DPL_FORMAT_POINT: case DPL_SYMBOL: if (addr & 0x1) diff --git a/plugins/elf/symbols.c b/plugins/elf/symbols.c index 2a164a0..004ac6a 100644 --- a/plugins/elf/symbols.c +++ b/plugins/elf/symbols.c @@ -109,10 +109,10 @@ static bool load_imported_elf_symbols(GElfFormat *, wgroup_id_t, GtkStatusStack /* Enregistre un point d'entrée au sein d'un binaire ELF. */ -static bool register_elf_entry_point(GElfFormat *, virt_t, GBinRoutine *); +static bool register_elf_entry_point(GElfFormat *, virt_t, GBinRoutine *, DisassPriorityLevel); /* Désigne tous les points d'entrée par une étiquette dédiée. */ -static bool load_elf_entry_points_from_array(GElfFormat *, const elf_dyn *, const elf_dyn *, const char *); +static bool load_elf_entry_points_from_array(GElfFormat *, const elf_dyn *, const elf_dyn *, const char *, DisassPriorityLevel); /* Enumère tous les points d'entrée principaux d'un binaire ELF. */ static bool load_all_elf_basic_entry_points(GElfFormat *, GtkStatusStack *); @@ -295,7 +295,7 @@ static bool do_elf_symbol_loading(GElfLoading *loading, GElfFormat *format, bool /* Comptabilisation pour le désassemblage brut */ - g_binary_format_register_code_point(base, original_virt, false); + g_binary_format_register_code_point(base, original_virt, DPL_SYMBOL); break; @@ -982,6 +982,10 @@ static GBinSymbol *do_elf_relocation_convert(GElfLoading *loading, GElfFormat *f g_binary_symbol_set_status(result, SSS_IMPORTED); + /* Comptabilisation pour le désassemblage brut */ + + g_binary_format_register_code_point(G_BIN_FORMAT(format), start.virtual, DPL_FORMAT_POINT); + exit: return result; @@ -1165,6 +1169,7 @@ static bool load_imported_elf_symbols(GElfFormat *format, wgroup_id_t gid, GtkSt * Paramètres : format = description de l'exécutable à compléter. * * vaddr = adresse virtuelle du symbole à insérer. * * routine = représentation de la fonction repérée. * +* level = indication de priorité et d'origine de l'adresse. * * * * Description : Enregistre un point d'entrée au sein d'un binaire ELF. * * * @@ -1174,7 +1179,7 @@ static bool load_imported_elf_symbols(GElfFormat *format, wgroup_id_t gid, GtkSt * * ******************************************************************************/ -static bool register_elf_entry_point(GElfFormat *format, virt_t vaddr, GBinRoutine *routine) +static bool register_elf_entry_point(GElfFormat *format, virt_t vaddr, GBinRoutine *routine, DisassPriorityLevel level) { bool result; /* Bilan à renvoyer */ virt_t final_vaddr; /* Adresse virtuelle retenue */ @@ -1226,7 +1231,7 @@ static bool register_elf_entry_point(GElfFormat *format, virt_t vaddr, GBinRouti g_object_unref(G_OBJECT(symbol)); /* Comptabilisation pour le désassemblage brut */ - g_binary_format_register_code_point(base, vaddr, true); + g_binary_format_register_code_point(base, vaddr, level); exit: @@ -1241,6 +1246,7 @@ static bool register_elf_entry_point(GElfFormat *format, virt_t vaddr, GBinRouti * array = indications quant au tableau à charger. * * size = indications quant à la taille de ce tableau. * * prefix = désignation de base des éléments du tableau. * +* level = indication de priorité et d'origine de l'adresse. * * * * Description : Désigne tous les points d'entrée par une étiquette dédiée. * * * @@ -1250,7 +1256,7 @@ static bool register_elf_entry_point(GElfFormat *format, virt_t vaddr, GBinRouti * * ******************************************************************************/ -static bool load_elf_entry_points_from_array(GElfFormat *format, const elf_dyn *array, const elf_dyn *size, const char *prefix) +static bool load_elf_entry_points_from_array(GElfFormat *format, const elf_dyn *array, const elf_dyn *size, const char *prefix, DisassPriorityLevel level) { bool result; /* Bilan à renvoyer */ GBinFormat *base; /* Autre version du format */ @@ -1313,7 +1319,7 @@ static bool load_elf_entry_points_from_array(GElfFormat *format, const elf_dyn * snprintf(fullname, sizeof(fullname), "%s%u", prefix, i); routine = g_binary_format_decode_routine(base, fullname); - result = register_elf_entry_point(format, ep, routine); + result = register_elf_entry_point(format, ep, routine, level); } @@ -1363,7 +1369,7 @@ static bool load_all_elf_basic_entry_points(GElfFormat *format, GtkStatusStack * if (ep != 0x0) { routine = g_binary_format_decode_routine(base, "entry_point"); - result = register_elf_entry_point(format, ep, routine); + result = register_elf_entry_point(format, ep, routine, DPL_ENTRY_POINT); if (!result) goto exit; } @@ -1381,7 +1387,7 @@ static bool load_all_elf_basic_entry_points(GElfFormat *format, GtkStatusStack * if (ep != 0x0) { routine = g_binary_format_decode_routine(base, "init_function"); - result = register_elf_entry_point(format, ep, routine); + result = register_elf_entry_point(format, ep, routine, DPL_ENTRY_POINT); if (!result) goto exit; } @@ -1394,7 +1400,7 @@ static bool load_all_elf_basic_entry_points(GElfFormat *format, GtkStatusStack * if (ep != 0x0) { routine = g_binary_format_decode_routine(base, "termination_function"); - result = register_elf_entry_point(format, ep, routine); + result = register_elf_entry_point(format, ep, routine, DPL_FORMAT_POINT); if (!result) goto exit; } @@ -1404,7 +1410,8 @@ static bool load_all_elf_basic_entry_points(GElfFormat *format, GtkStatusStack * { if (_find_elf_dynamic_item_by_type(format, &dynamic, DT_INIT_ARRAYSZ, &item_b)) { - result = load_elf_entry_points_from_array(format, &item_a, &item_b, "init_array_function_"); + result = load_elf_entry_points_from_array(format, &item_a, &item_b, + "init_array_function_", DPL_ENTRY_POINT); if (!result) goto exit; } @@ -1414,7 +1421,8 @@ static bool load_all_elf_basic_entry_points(GElfFormat *format, GtkStatusStack * { if (_find_elf_dynamic_item_by_type(format, &dynamic, DT_FINI_ARRAYSZ, &item_b)) { - result = load_elf_entry_points_from_array(format, &item_a, &item_b, "fini_array_function_"); + result = load_elf_entry_points_from_array(format, &item_a, &item_b, + "fini_array_function_", DPL_FORMAT_POINT); if (!result) goto exit; } @@ -1424,7 +1432,8 @@ static bool load_all_elf_basic_entry_points(GElfFormat *format, GtkStatusStack * { if (_find_elf_dynamic_item_by_type(format, &dynamic, DT_PREINIT_ARRAYSZ, &item_b)) { - result = load_elf_entry_points_from_array(format, &item_a, &item_b, "preinit_array_function_"); + result = load_elf_entry_points_from_array(format, &item_a, &item_b, + "preinit_array_function_", DPL_ENTRY_POINT); if (!result) goto exit; } @@ -1437,7 +1446,7 @@ static bool load_all_elf_basic_entry_points(GElfFormat *format, GtkStatusStack * if (ep != 0x0) { routine = g_binary_format_decode_routine(base, "plt_entry"); - result = register_elf_entry_point(format, ep, routine); + result = register_elf_entry_point(format, ep, routine, DPL_FORMAT_POINT); } } diff --git a/plugins/mobicore/symbols.c b/plugins/mobicore/symbols.c index a0425ee..2523cbc 100644 --- a/plugins/mobicore/symbols.c +++ b/plugins/mobicore/symbols.c @@ -68,9 +68,7 @@ static void register_mclf_entry_point(GMCLFFormat *format, virt_t vaddr, phys_t /* Comptabilisation pour le désassemblage brut */ - base->entry_points = (virt_t *)realloc(base->entry_points, ++base->ep_count * sizeof(virt_t)); - - base->entry_points[base->ep_count - 1] = vaddr; + g_binary_format_register_code_point(base, vaddr, DPL_ENTRY_POINT); /* Comptabilisation en tant que symbole */ diff --git a/plugins/pychrysalide/arch/constants.c b/plugins/pychrysalide/arch/constants.c index b7dd8a1..f738ec3 100644 --- a/plugins/pychrysalide/arch/constants.c +++ b/plugins/pychrysalide/arch/constants.c @@ -150,3 +150,45 @@ bool define_arch_vmpa_constants(PyTypeObject *type) return result; } + + +/****************************************************************************** +* * +* Paramètres : type = type dont le dictionnaire est à compléter. * +* * +* Description : Définit les constantes relatives aux contextes. * +* * +* Retour : true en cas de succès de l'opération, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool define_proc_context_constants(PyTypeObject *type) +{ + bool result; /* Bilan à retourner */ + PyObject *values; /* Groupe de valeurs à établir */ + + values = PyDict_New(); + + result = add_const_to_group(values, "ENTRY_POINT", DPL_ENTRY_POINT); + if (result) result = add_const_to_group(values, "FORMAT_POINT", DPL_FORMAT_POINT); + if (result) result = add_const_to_group(values, "SYMBOL", DPL_SYMBOL); + if (result) result = add_const_to_group(values, "OTHER", DPL_OTHER); + if (result) result = add_const_to_group(values, "COUNT", DPL_COUNT); + + if (!result) + { + Py_DECREF(values); + goto exit; + } + + result = attach_constants_group_to_type(type, true, "DisassPriorityLevel", values, + "Level of priority for a given point during the" \ + " disassembling process."); + + exit: + + return result; + +} diff --git a/plugins/pychrysalide/arch/constants.h b/plugins/pychrysalide/arch/constants.h index ecd6ce8..f047c56 100644 --- a/plugins/pychrysalide/arch/constants.h +++ b/plugins/pychrysalide/arch/constants.h @@ -37,6 +37,9 @@ bool define_arch_instruction_constants(PyTypeObject *); /* Définit les constantes relatives aux emplacements. */ bool define_arch_vmpa_constants(PyTypeObject *); +/* Définit les constantes relatives aux contextes. */ +bool define_proc_context_constants(PyTypeObject *); + #endif /* _PLUGINS_PYCHRYSALIDE_ARCH_CONSTANTS_H */ diff --git a/plugins/pychrysalide/arch/context.c b/plugins/pychrysalide/arch/context.c index 4428075..f7c6549 100644 --- a/plugins/pychrysalide/arch/context.c +++ b/plugins/pychrysalide/arch/context.c @@ -32,6 +32,7 @@ #include +#include "constants.h" #include "../access.h" #include "../helpers.h" @@ -111,6 +112,9 @@ bool ensure_python_proc_context_is_registered(void) if (!register_class_for_pygobject(dict, G_TYPE_PROC_CONTEXT, type, &PyGObject_Type)) return false; + if (!define_proc_context_constants(type)) + return false; + } return true; diff --git a/plugins/pychrysalide/format/format.c b/plugins/pychrysalide/format/format.c index 6cd706c..3709f6d 100644 --- a/plugins/pychrysalide/format/format.c +++ b/plugins/pychrysalide/format/format.c @@ -118,16 +118,16 @@ static bool define_python_binary_format_constants(PyTypeObject *); static PyObject *py_binary_format_register_code_point(PyObject *self, PyObject *args) { unsigned long long pt; /* Adresse virtuelle du point */ - int entry; /* Nature du point fourni */ + unsigned long level; /* Nature du point fourni */ int ret; /* Bilan de lecture des args. */ GBinFormat *format; /* Format de binaire manipulé */ - ret = PyArg_ParseTuple(args, "Kp", &pt, &entry); + ret = PyArg_ParseTuple(args, "Kk", &pt, &level); if (!ret) return NULL; format = G_BIN_FORMAT(pygobject_get(self)); - g_binary_format_register_code_point(format, pt, entry); + g_binary_format_register_code_point(format, pt, level); Py_RETURN_NONE; diff --git a/src/arch/context.h b/src/arch/context.h index 4b37cdb..255909f 100644 --- a/src/arch/context.h +++ b/src/arch/context.h @@ -53,6 +53,7 @@ typedef struct _GProcContextClass GProcContextClass; typedef enum _DisassPriorityLevel { DPL_ENTRY_POINT, /* Validité indiscutable */ + DPL_FORMAT_POINT, /* Entrée liée au format #2 */ DPL_SYMBOL, /* Symboles utilisés */ DPL_OTHER, /* Injections complémentaires */ diff --git a/src/format/executable.c b/src/format/executable.c index b081f64..553b157 100644 --- a/src/format/executable.c +++ b/src/format/executable.c @@ -286,8 +286,8 @@ bool g_exe_format_get_main_address(GExeFormat *format, vmpa2t *addr) g_rw_lock_reader_lock(&base->pt_lock); - if (base->ep_count > 0) - result = g_exe_format_translate_address_into_vmpa(format, base->entry_points[0], addr); + if (base->pt_count[DPL_ENTRY_POINT] > 0) + result = g_exe_format_translate_address_into_vmpa(format, base->start_points[DPL_ENTRY_POINT][0], addr); g_rw_lock_reader_unlock(&base->pt_lock); diff --git a/src/format/flat.c b/src/format/flat.c index 1ae813a..a9081d8 100644 --- a/src/format/flat.c +++ b/src/format/flat.c @@ -377,10 +377,14 @@ static bool g_flat_format_get_main_address(GFlatFormat *format, vmpa2t *addr) base = G_BIN_FORMAT(format); - result = (base->ep_count > 0); + g_rw_lock_reader_lock(&base->pt_lock); + + result = (base->pt_count[DPL_ENTRY_POINT] > 0); if (result) - init_vmpa(addr, 0, base->entry_points[0]); + init_vmpa(addr, 0, base->start_points[DPL_ENTRY_POINT][0]); + + g_rw_lock_reader_unlock(&base->pt_lock); return result; diff --git a/src/format/format-int.h b/src/format/format-int.h index d5ee2b4..c8f2b1a 100644 --- a/src/format/format-int.h +++ b/src/format/format-int.h @@ -54,7 +54,7 @@ typedef void (* format_complete_analysis_fc) (GBinFormat *, wgroup_id_t, GtkStat /* Rythme des allocations pour les entrées de code */ -#define EXTRA_POINT_BLOCK 100 +#define EXTRA_POINT_BLOCK 20 /* Description d'une erreur */ @@ -75,13 +75,9 @@ struct _GBinFormat GBinContent *content; /* Contenu binaire à étudier */ - virt_t *entry_points; /* Points d'entrée du code */ - size_t ep_count; /* Nombre de ces points */ - - virt_t *extra_points; /* Autres débuts de code */ - size_t xp_allocated; /* Taille d'inscription allouée*/ - size_t xp_count; /* Nombre de points enregistrés*/ - + virt_t *start_points[DPL_COUNT]; /* Départ de désassemblage */ + size_t pt_allocated[DPL_COUNT]; /* Taille d'inscription allouée*/ + size_t pt_count[DPL_COUNT]; /* Nombre de points enregistrés*/ GRWLock pt_lock; /* Accès à la liste des points */ GPreloadInfo *info; /* Préchargements du format */ diff --git a/src/format/format.c b/src/format/format.c index e782996..533d641 100644 --- a/src/format/format.c +++ b/src/format/format.c @@ -192,22 +192,21 @@ static void g_binary_format_dispose(GBinFormat *format) static void g_binary_format_finalize(GBinFormat *format) { - size_t i; /* Boucle de parcours */ - - if (format->entry_points != NULL) - free(format->entry_points); + DisassPriorityLevel i; /* Boucle de parcours #1 */ + size_t k; /* Boucle de parcours #2 */ - if (format->extra_points != NULL) - free(format->extra_points); + for (i = 0; i < DPL_COUNT; i++) + if (format->start_points[i] != NULL) + free(format->start_points[i]); if (format->symbols != NULL) free(format->symbols); if (format->errors != NULL) { - for (i = 0; i < format->error_count; i++) - if (format->errors[i].desc != NULL) - free(format->errors[i].desc); + for (k = 0; k < format->error_count; k++) + if (format->errors[k].desc != NULL) + free(format->errors[k].desc); free(format->errors); @@ -388,7 +387,7 @@ SourceEndian g_binary_format_get_endianness(const GBinFormat *format) * * * Paramètres : format = description de l'exécutable à compléter. * * pt = point de l'espace mémoire à considérer. * -* entry = nature du point fourni. * +* level = indication de priorité et d'origine de l'adresse. * * * * Description : Enregistre une adresse comme début d'une zone de code. * * * @@ -398,30 +397,22 @@ SourceEndian g_binary_format_get_endianness(const GBinFormat *format) * * ******************************************************************************/ -void g_binary_format_register_code_point(GBinFormat *format, virt_t pt, bool entry) +void g_binary_format_register_code_point(GBinFormat *format, virt_t pt, DisassPriorityLevel level) { + assert(level < DPL_COUNT); + g_rw_lock_writer_lock(&format->pt_lock); - if (entry) + if (format->pt_count[level] == format->pt_allocated[level]) { - format->entry_points = realloc(format->entry_points, ++format->ep_count * sizeof(virt_t)); + format->pt_allocated[level] += EXTRA_POINT_BLOCK; - format->entry_points[format->ep_count - 1] = pt; + format->start_points[level] = realloc(format->start_points[level], + format->pt_allocated[level] * sizeof(virt_t)); } - else - { - if (format->xp_count == format->xp_allocated) - { - format->xp_allocated += EXTRA_POINT_BLOCK; - format->extra_points = realloc(format->extra_points, format->xp_allocated * sizeof(virt_t)); - - } - - format->extra_points[format->xp_count++] = pt; - - } + format->start_points[level][format->pt_count[level]++] = pt; g_rw_lock_writer_unlock(&format->pt_lock); @@ -465,15 +456,14 @@ void g_binary_format_preload_disassembling_context(GBinFormat *format, GProcCont void g_binary_format_activate_disassembling_context(GBinFormat *format, GProcContext *ctx, GtkStatusStack *status) { - size_t i; /* Boucle de parcours */ + DisassPriorityLevel i; /* Boucle de parcours #1 */ + size_t k; /* Boucle de parcours #2 */ g_rw_lock_reader_lock(&format->pt_lock); - for (i = 0; i < format->ep_count; i++) - g_proc_context_push_drop_point(ctx, DPL_ENTRY_POINT, format->entry_points[i]); - - for (i = 0; i < format->xp_count; i++) - g_proc_context_push_drop_point(ctx, DPL_SYMBOL, format->extra_points[i]); + for (i = 0; i < DPL_COUNT; i++) + for (k = 0; k < format->pt_count[i]; k++) + g_proc_context_push_drop_point(ctx, i, format->start_points[i][k]); g_rw_lock_reader_unlock(&format->pt_lock); diff --git a/src/format/format.h b/src/format/format.h index 450ebdc..626bb8a 100644 --- a/src/format/format.h +++ b/src/format/format.h @@ -76,7 +76,7 @@ bool g_binary_format_analyze(GBinFormat *, wgroup_id_t, GtkStatusStack *); SourceEndian g_binary_format_get_endianness(const GBinFormat *); /* Enregistre une adresse comme début d'une zone de code. */ -void g_binary_format_register_code_point(GBinFormat *, virt_t, bool); +void g_binary_format_register_code_point(GBinFormat *, virt_t, DisassPriorityLevel); /* Intègre dans un contexte les informations tirées d'un format. */ void g_binary_format_preload_disassembling_context(GBinFormat *, GProcContext *, GtkStatusStack *); -- cgit v0.11.2-87-g4458