diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2021-04-06 21:46:59 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2021-04-06 21:46:59 (GMT) |
commit | c4d2e0fa48eab453d5c43a3c0938427617449a6a (patch) | |
tree | 6717960d8eeebe05a8a33b9a6e4dd618c1258be9 /plugins/winordinals/assign.c | |
parent | b0347ca45a08ac63bc6dd6f244b046c6d19a6cdd (diff) |
Inject known names for PE imports by ordinals.
Diffstat (limited to 'plugins/winordinals/assign.c')
-rw-r--r-- | plugins/winordinals/assign.c | 348 |
1 files changed, 348 insertions, 0 deletions
diff --git a/plugins/winordinals/assign.c b/plugins/winordinals/assign.c new file mode 100644 index 0000000..16b7eaa --- /dev/null +++ b/plugins/winordinals/assign.c @@ -0,0 +1,348 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * assign.c - renseignement des importations sous forme d'ordinaux + * + * Copyright (C) 2021 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 Chrysalide. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "assign.h" + + +#include <i18n.h> +#include <core/global.h> +#include <core/nproc.h> +#include <glibext/delayed-int.h> +#include <plugins/pe/routine.h> + + +#include "ordinals.h" + + + +#define G_TYPE_ORDINAL_RESOLVER g_ordinal_resolver_get_type() +#define G_ORDINAL_RESOLVER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_ORDINAL_RESOLVER, GOrdinalResolver)) +#define G_IS_ORDINAL_RESOLVER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_ORDINAL_RESOLVER)) +#define G_ORDINAL_RESOLVER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_ORDINAL_RESOLVER, GOrdinalResolverClass)) +#define G_IS_ORDINAL_RESOLVER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_ORDINAL_RESOLVER)) +#define G_ORDINAL_RESOLVER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ORDINAL_RESOLVER, GOrdinalResolverClass)) + + +/* Tâche de résolution d'ordinaux (instance) */ +typedef struct _GOrdinalResolver +{ + GDelayedWork parent; /* A laisser en premier */ + + GPeFormat *format; /* Format à faire évoluer */ + + size_t begin; /* Point de départ du parcours */ + size_t end; /* Point d'arrivée exclu */ + + activity_id_t id; /* Identifiant pour messages */ + +} GOrdinalResolver; + +/* Tâche de résolution d'ordinaux (classe) */ +typedef struct _GOrdinalResolverClass +{ + GDelayedWorkClass parent; /* A laisser en premier */ + +} GOrdinalResolverClass; + + +/* Indique le type défini pour les tâches de résolution d'ordinaux. */ +GType g_ordinal_resolver_get_type(void); + +/* Initialise la classe des tâches des resolutions d'ordinaux. */ +static void g_ordinal_resolver_class_init(GOrdinalResolverClass *); + +/* Initialise une tâche de résolution d'ordinaux importés. */ +static void g_ordinal_resolver_init(GOrdinalResolver *); + +/* Supprime toutes les références externes. */ +static void g_ordinal_resolver_dispose(GOrdinalResolver *); + +/* Procède à la libération totale de la mémoire. */ +static void g_ordinal_resolver_finalize(GOrdinalResolver *); + +/* Crée une tâche de résolution des ordinaux importés. */ +static GOrdinalResolver *g_ordinal_resolver_new(GPeFormat *, size_t, size_t, activity_id_t); + +/* Effectue une résolution d'ordinaux importés. */ +static void g_ordinal_resolver_process(GOrdinalResolver *, GtkStatusStack *); + + + +/* Indique le type défini pour les tâches de résolution d'ordinaux. */ +G_DEFINE_TYPE(GOrdinalResolver, g_ordinal_resolver, G_TYPE_DELAYED_WORK); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des tâches des resolutions d'ordinaux. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_ordinal_resolver_class_init(GOrdinalResolverClass *klass) +{ + GObjectClass *object; /* Autre version de la classe */ + GDelayedWorkClass *work; /* Version en classe parente */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_ordinal_resolver_dispose; + object->finalize = (GObjectFinalizeFunc)g_ordinal_resolver_finalize; + + work = G_DELAYED_WORK_CLASS(klass); + + work->run = (run_task_fc)g_ordinal_resolver_process; + +} + + +/****************************************************************************** +* * +* Paramètres : resolver = instance à initialiser. * +* * +* Description : Initialise une tâche de résolution d'ordinaux importés. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_ordinal_resolver_init(GOrdinalResolver *resolver) +{ + resolver->format = NULL; + + resolver->begin = 0; + resolver->end = 0; + + resolver->id = 0; + +} + + +/****************************************************************************** +* * +* Paramètres : resolver = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_ordinal_resolver_dispose(GOrdinalResolver *resolver) +{ + g_clear_object(&resolver->format); + + G_OBJECT_CLASS(g_ordinal_resolver_parent_class)->dispose(G_OBJECT(resolver)); + +} + + +/****************************************************************************** +* * +* Paramètres : resolver = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_ordinal_resolver_finalize(GOrdinalResolver *resolver) +{ + G_OBJECT_CLASS(g_ordinal_resolver_parent_class)->finalize(G_OBJECT(resolver)); + +} + + +/****************************************************************************** +* * +* Paramètres : format = ensemble d'instructions désassemblées. * +* begin = point de départ du parcours de liste. * +* end = point d'arrivée exclu du parcours. * +* id = identifiant du message affiché à l'utilisateur. * +* * +* Description : Crée une tâche de résolution des ordinaux importés. * +* * +* Retour : Tâche créée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GOrdinalResolver *g_ordinal_resolver_new(GPeFormat *format, size_t begin, size_t end, activity_id_t id) +{ + GOrdinalResolver *result; /* Tâche à retourner */ + + result = g_object_new(G_TYPE_ORDINAL_RESOLVER, NULL); + + result->format = format; + g_object_ref(G_OBJECT(format)); + + result->begin = begin; + result->end = end; + + result->id = id; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : resolver = étude de routines à mener. * +* status = barre de statut à tenir informée. * +* * +* Description : Effectue une résolution d'ordinaux importés. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_ordinal_resolver_process(GOrdinalResolver *resolver, GtkStatusStack *status) +{ + GBinFormat *base; /* Format basique du binaire */ + size_t i; /* Boucle de parcours #1 */ + GBinSymbol *symbol; /* Commodité d'accès */ + uint16_t ordinal; /* Ordinal défini */ + const char *name; /* Désignation actuelle */ + const char *library; /* Fichier DLL à charger */ + + base = G_BIN_FORMAT(resolver->format); + + for (i = resolver->begin; i < resolver->end; i++) + { + symbol = g_binary_format_get_symbol(base, i); + + if (!G_IS_PE_IMPORTED_ROUTINE(symbol)) + goto next; + + ordinal = g_pe_exported_routine_get_ordinal(G_PE_EXPORTED_ROUTINE(symbol)); + + if (ordinal == UNDEF_PE_ORDINAL) + goto next; + + name = g_binary_routine_get_name(G_BIN_ROUTINE(symbol)); + + if (name != NULL) + goto next; + + library = g_pe_imported_routine_get_library(G_PE_IMPORTED_ROUTINE(symbol)); + + if (library == NULL) + goto next; + + name = get_symbol_by_ordinal(library, ordinal); + + if (name != NULL) + g_binary_routine_set_name(G_BIN_ROUTINE(symbol), strdup(name)); + + next: + + gtk_status_stack_update_activity_value(status, resolver->id, 1); + + g_object_unref(G_OBJECT(symbol)); + + } + +} + + +/****************************************************************************** +* * +* Paramètres : format = format PE à traiter. * +* status = barre de statut à tenir informée. * +* * +* Description : Attribue un nom aux symboles PE importés par ordinal. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void assign_name_imported_ordinals(GPeFormat *format, GtkStatusStack *status) +{ + GBinFormat *base; /* Format basique du binaire */ + size_t sym_count; /* Nombre de ces symboles */ + guint runs_count; /* Qté d'exécutions parallèles */ + size_t run_size; /* Volume réparti par exécution*/ + activity_id_t id; /* Identifiant de progression */ + GWorkQueue *queue; /* Gestionnaire de différés */ + wgroup_id_t gid; /* Identifiant pour les tâches */ + guint i; /* Boucle de parcours */ + size_t begin; /* Début de bloc de traitement */ + size_t end; /* Fin d'un bloc de traitement */ + GOrdinalResolver *resolver; /* Tâche d'étude à programmer */ + + base = G_BIN_FORMAT(format); + + g_binary_format_lock_symbols_rd(base); + + sym_count = g_binary_format_count_symbols(base); + + run_size = compute_run_size(sym_count, &runs_count); + + id = gtk_status_stack_add_activity(status, _("Resolving names for imported ordinals..."), sym_count); + + queue = get_work_queue(); + + gid = g_work_queue_define_work_group(queue); + + for (i = 0; i < runs_count; i++) + { + begin = i * run_size; + + if ((i + 1) == runs_count) + end = sym_count; + else + end = begin + run_size; + + resolver = g_ordinal_resolver_new(format, begin, end, id); + + g_work_queue_schedule_work(queue, G_DELAYED_WORK(resolver), gid); + + } + + g_work_queue_wait_for_completion(queue, gid); + + g_work_queue_delete_work_group(queue, gid); + + gtk_status_stack_remove_activity(status, id); + + g_binary_format_unlock_symbols_rd(base); + +} |