From 722539ffc6005c6cd9c8ebd37f93999014ae6d24 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Fri, 14 Oct 2016 18:24:34 +0200 Subject: Handled Dalvik simple switch cases without fallthrough. --- ChangeLog | 54 +++++++++++++ src/analysis/binary.c | 16 ++-- src/analysis/binary.h | 6 +- src/analysis/db/item-int.h | 2 + src/analysis/db/item.c | 20 +++++ src/analysis/db/item.h | 4 + src/analysis/db/items/bookmark.c | 2 + src/analysis/db/items/comment.c | 2 + src/analysis/db/items/move.c | 2 + src/analysis/db/items/switcher.c | 2 + src/analysis/disass/disassembler.c | 44 +++++++---- src/analysis/disass/fetch.c | 10 +-- src/analysis/disass/fetch.h | 2 +- src/analysis/disass/instructions.c | 9 ++- src/analysis/disass/instructions.h | 2 +- src/arch/context-int.h | 5 ++ src/arch/context.c | 127 ++++++++++++++++++++++++++++++ src/arch/context.h | 7 ++ src/arch/dalvik/Makefile.am | 2 +- src/arch/dalvik/context.c | 16 ++++ src/arch/dalvik/link.c | 154 +++++++++++++++++++++++++++++++++++++ src/arch/dalvik/link.h | 4 + src/arch/dalvik/opdefs/switch_2b.d | 6 ++ src/arch/dalvik/opdefs/switch_2c.d | 6 ++ src/arch/link.c | 2 +- src/gui/editem.c | 2 +- src/gui/menus/edition.c | 4 +- 27 files changed, 472 insertions(+), 40 deletions(-) create mode 100644 src/arch/dalvik/link.c diff --git a/ChangeLog b/ChangeLog index 515d4b9..2921865 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,57 @@ +16-10-14 Cyrille Bagard + + * src/analysis/binary.c: + * src/analysis/binary.h: + Establish a connection to the database before the analysis. Do not trust + the provided argument but guess the database item feature from its class. + + * src/analysis/db/item-int.h: + * src/analysis/db/item.c: + * src/analysis/db/item.h: + * src/analysis/db/items/bookmark.c: + * src/analysis/db/items/comment.c: + * src/analysis/db/items/move.c: + * src/analysis/db/items/switcher.c: + Store the feature for database items in their class. + + * src/analysis/disass/disassembler.c: + Create a disassembling context here and provide it to all operations + on instructions. + + * src/analysis/disass/fetch.c: + * src/analysis/disass/fetch.h: + * src/analysis/disass/instructions.c: + * src/analysis/disass/instructions.h: + Update code. + + * src/arch/context-int.h: + * src/arch/context.c: + * src/arch/context.h: + Store database items which need to be processed later. + + * src/arch/dalvik/Makefile.am: + Add the 'link.c' file to libarchdalvik_la_SOURCES. + + * src/arch/dalvik/context.c: + Fix a bug by adding a control access. + + * src/arch/dalvik/link.c: + New entry: handle Dalvik simple switch cases without fallthrough. + + * src/arch/dalvik/link.h: + Update code. + + * src/arch/dalvik/opdefs/switch_2b.d: + * src/arch/dalvik/opdefs/switch_2c.d: + Register new hooks for switch cases processing. + + * src/arch/link.c: + Remove debug code. + + * src/gui/editem.c: + * src/gui/menus/edition.c: + Update code. + 16-10-10 Cyrille Bagard * src/analysis/contents/restricted.c: diff --git a/src/analysis/binary.c b/src/analysis/binary.c index 75c6e14..96d61c2 100644 --- a/src/analysis/binary.c +++ b/src/analysis/binary.c @@ -1230,10 +1230,9 @@ GDbCollection *g_loaded_binary_find_collection(const GLoadedBinary *binary, DBFe /****************************************************************************** * * -* Paramètres : binary = élément binaire à consulter. * -* feature = fonctionnalité visée par la requête. * -* item = élémnent à pousser vers un serveur de collection. * -* lock = indique si le verrou d'écriture doit être posé. * +* Paramètres : binary = élément binaire à consulter. * +* item = élémnent à pousser vers un serveur de collection. * +* lock = indique si le verrou d'écriture doit être posé. * * * * Description : Demande l'intégration d'une modification dans une collection.* * * @@ -1243,14 +1242,17 @@ GDbCollection *g_loaded_binary_find_collection(const GLoadedBinary *binary, DBFe * * ******************************************************************************/ -bool _g_loaded_binary_add_to_collection(GLoadedBinary *binary, DBFeatures feature, GDbItem *item, bool lock) +bool _g_loaded_binary_add_to_collection(GLoadedBinary *binary, GDbItem *item, bool lock) { bool result; /* Bilan à faire remonter */ + DBFeatures feature; /* Domaine de fonctionnalité */ GDbCollection *collec; /* Collection visée au final */ DBStorage storage; /* Forme d'enregistrement */ GDbClient *client; /* Liaison à utiliser */ int fd; /* Identifiant du canal de com.*/ + feature = g_db_item_get_feature(item); + collec = g_loaded_binary_find_collection(binary, feature); if (collec == NULL) return false; @@ -1373,6 +1375,8 @@ void g_loaded_binary_analyse(GLoadedBinary *binary) // Déconnexion... + g_loaded_binary_connect_internal(binary); + disassemble_binary(binary, &binary->instrs, &binary->disass_buffer, ack_completed_disassembly); @@ -1634,7 +1638,7 @@ void ack_completed_disassembly(GDelayedDisassembly *disass, GLoadedBinary *binar g_object_unref(G_OBJECT(disass)); - /* ... = */g_loaded_binary_connect_internal(binary); + /* ... = *///g_loaded_binary_connect_internal(binary); /* Décompilation... */ diff --git a/src/analysis/binary.h b/src/analysis/binary.h index 8d87bf0..d39a961 100644 --- a/src/analysis/binary.h +++ b/src/analysis/binary.h @@ -142,10 +142,10 @@ GList *g_loaded_binary_get_all_collections(const GLoadedBinary *); GDbCollection *g_loaded_binary_find_collection(const GLoadedBinary *, DBFeatures); /* Demande l'intégration d'une modification dans une collection. */ -bool _g_loaded_binary_add_to_collection(GLoadedBinary *, DBFeatures, GDbItem *, bool); +bool _g_loaded_binary_add_to_collection(GLoadedBinary *, GDbItem *, bool); -#define g_loaded_binary_add_to_collection(b, f, i) \ - _g_loaded_binary_add_to_collection(b, f, i, true) +#define g_loaded_binary_add_to_collection(b, i) \ + _g_loaded_binary_add_to_collection(b, i, true) /* Demande la suppression de modification dans une collection. */ bool _g_loaded_binary_remove_from_collection(GLoadedBinary *, DBFeatures, GDbItem *, bool); diff --git a/src/analysis/db/item-int.h b/src/analysis/db/item-int.h index c2c8b31..d907100 100644 --- a/src/analysis/db/item-int.h +++ b/src/analysis/db/item-int.h @@ -80,6 +80,8 @@ struct _GDbItemClass { GObjectClass parent; /* A laisser en premier */ + DBFeatures feature; /* Fonctionnalité représentée */ + cmp_db_item_fc cmp; /* Comparaison entre éléments */ recv_db_item_fc recv; /* Réception depuis le réseau */ diff --git a/src/analysis/db/item.c b/src/analysis/db/item.c index 013703d..62e8ce9 100644 --- a/src/analysis/db/item.c +++ b/src/analysis/db/item.c @@ -174,6 +174,26 @@ static void g_db_item_finalize(GDbItem *item) } + +/****************************************************************************** +* * +* Paramètres : item = élément de collection à consulter. * +* * +* Description : Indique la fonctionnalité représentée par l'élément. * +* * +* Retour : Identifiant valide pour le protocole. * +* * +* Remarques : - * +* * +******************************************************************************/ + +DBFeatures g_db_item_get_feature(const GDbItem *item) +{ + return G_DB_ITEM_GET_CLASS(item)->feature; + +} + + /****************************************************************************** * * * Paramètres : item = élément de collection à traiter. * diff --git a/src/analysis/db/item.h b/src/analysis/db/item.h index 2edf594..f8bb707 100644 --- a/src/analysis/db/item.h +++ b/src/analysis/db/item.h @@ -29,6 +29,7 @@ #include +#include "protocol.h" #include "misc/timestamp.h" #include "../../common/sqlite.h" @@ -56,6 +57,9 @@ typedef struct _GDbItemClass GDbItemClass; /* Indique le type défini pour une base d'élément de collection générique. */ GType g_db_item_get_type(void); +/* Indique la fonctionnalité représentée par l'élément. */ +DBFeatures g_db_item_get_feature(const GDbItem *); + /* Indique à l'élément qu'il se trouve du côté serveur. */ void g_db_item_set_server_side(GDbItem *); diff --git a/src/analysis/db/items/bookmark.c b/src/analysis/db/items/bookmark.c index 747053c..231e461 100644 --- a/src/analysis/db/items/bookmark.c +++ b/src/analysis/db/items/bookmark.c @@ -175,6 +175,8 @@ static void g_db_bookmark_class_init(GDbBookmarkClass *klass) item = G_DB_ITEM_CLASS(klass); + item->feature = DBF_BOOKMARKS; + item->cmp = (cmp_db_item_fc)g_db_bookmark_cmp; item->recv = (recv_db_item_fc)g_db_bookmark_recv_from_fd; diff --git a/src/analysis/db/items/comment.c b/src/analysis/db/items/comment.c index f601bd6..6ce3d05 100644 --- a/src/analysis/db/items/comment.c +++ b/src/analysis/db/items/comment.c @@ -188,6 +188,8 @@ static void g_db_comment_class_init(GDbCommentClass *klass) item = G_DB_ITEM_CLASS(klass); + item->feature = DBF_COMMENTS; + item->cmp = (cmp_db_item_fc)g_db_comment_cmp; item->recv = (recv_db_item_fc)g_db_comment_recv_from_fd; diff --git a/src/analysis/db/items/move.c b/src/analysis/db/items/move.c index ad574b0..cf54c9b 100644 --- a/src/analysis/db/items/move.c +++ b/src/analysis/db/items/move.c @@ -181,6 +181,8 @@ static void g_db_move_class_init(GDbMoveClass *klass) item = G_DB_ITEM_CLASS(klass); + item->feature = DBF_MOVES; + item->cmp = (cmp_db_item_fc)g_db_move_cmp; item->recv = (recv_db_item_fc)g_db_move_recv_from_fd; diff --git a/src/analysis/db/items/switcher.c b/src/analysis/db/items/switcher.c index e9182b4..a67040f 100644 --- a/src/analysis/db/items/switcher.c +++ b/src/analysis/db/items/switcher.c @@ -181,6 +181,8 @@ static void g_db_switcher_class_init(GDbSwitcherClass *klass) item = G_DB_ITEM_CLASS(klass); + item->feature = DBF_DISPLAY_SWITCHERS; + item->cmp = (cmp_db_item_fc)g_db_switcher_cmp; item->recv = (recv_db_item_fc)g_db_switcher_recv_from_fd; diff --git a/src/analysis/disass/disassembler.c b/src/analysis/disass/disassembler.c index 2cfa6a5..364348a 100644 --- a/src/analysis/disass/disassembler.c +++ b/src/analysis/disass/disassembler.c @@ -79,7 +79,7 @@ static void g_delayed_disassembly_init(GDelayedDisassembly *); static GDelayedDisassembly *g_delayed_disassembly_new(GLoadedBinary *, GArchInstruction **, GCodeBuffer *); /* Opère sur toutes les instructions. */ -static void process_all_instructions(wgroup_id_t, GtkStatusStack *, const char *, ins_fallback_cb, GArchProcessor *, GExeFormat *); +static void process_all_instructions(wgroup_id_t, GtkStatusStack *, const char *, ins_fallback_cb, GArchProcessor *, GProcContext *, GExeFormat *); /* Opère sur toutes les routines. */ static void process_all_routines(wgroup_id_t, GtkStatusStack *, const char *, rtn_fallback_cb, GArchProcessor *, GExeFormat *); @@ -182,10 +182,11 @@ static GDelayedDisassembly *g_delayed_disassembly_new(GLoadedBinary *binary, GAr /****************************************************************************** * * * Paramètres : gid = groupe de travail impliqué. * - status = barre de statut à tenir informée. * +* status = barre de statut à tenir informée. * * msg = message à faire paraître pour la patience. * * fallback = routine de traitements particuliers. * * proc = ensemble d'instructions désassemblées. * +* ctx = contexte fourni pour suivre le désassemblage. * * format = accès aux données du binaire d'origine. * * * * Description : Opère sur toutes les instructions. * @@ -196,7 +197,7 @@ static GDelayedDisassembly *g_delayed_disassembly_new(GLoadedBinary *binary, GAr * * ******************************************************************************/ -static void process_all_instructions(wgroup_id_t gid, GtkStatusStack *status, const char *msg, ins_fallback_cb fallback, GArchProcessor *proc, GExeFormat *format) +static void process_all_instructions(wgroup_id_t gid, GtkStatusStack *status, const char *msg, ins_fallback_cb fallback, GArchProcessor *proc, GProcContext *ctx, GExeFormat *format) { guint runs_count; /* Qté d'exécutions parallèles */ size_t ins_count; /* Quantité d'instructions */ @@ -227,7 +228,7 @@ static void process_all_instructions(wgroup_id_t gid, GtkStatusStack *status, co else end = begin + run_size; - study = g_instructions_study_new(proc, G_BIN_FORMAT(format), begin, end, id, fallback); + study = g_instructions_study_new(proc, ctx, G_BIN_FORMAT(format), begin, end, id, fallback); g_work_queue_schedule_work(queue, G_DELAYED_WORK(study), gid); @@ -329,24 +330,26 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkStatus //GBinFormat *format; /* Format du fichier binaire */ GArchProcessor *proc; /* Architecture du binaire */ - + GProcContext *ctx; /* Contexte de suivi dédié */ //size_t i; /* Boucle de parcours */ + _curbin = disass->binary; + //format = G_BIN_FORMAT(g_loaded_binary_get_format(binary)); + proc = g_loaded_binary_get_processor(disass->binary); + ctx = g_arch_processor_get_context(proc); - gid = g_work_queue_define_work_group(get_work_queue()); + gid = g_work_queue_define_work_group(get_work_queue()); - //format = G_BIN_FORMAT(g_loaded_binary_get_format(binary)); - proc = g_loaded_binary_get_processor(disass->binary); @@ -361,7 +364,7 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkStatus - *disass->instrs = disassemble_binary_content(disass->binary, gid, status); + *disass->instrs = disassemble_binary_content(disass->binary, ctx, gid, status); g_arch_processor_set_disassembled_instructions(proc, *disass->instrs); @@ -374,7 +377,7 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkStatus process_all_instructions(gid, status, _("Calling 'link' hook on all instructions..."), g_instructions_study_do_link_operation, - proc, disass->format); + proc, ctx, disass->format); // plugins ////////////////////////// @@ -390,7 +393,7 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkStatus process_all_instructions(gid, status, _("Calling 'post' hook on all instructions..."), g_instructions_study_do_post_operation, - proc, disass->format); + proc, ctx, disass->format); @@ -426,7 +429,7 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkStatus process_all_instructions(gid, status, _("Establishing links betweek all instructions..."), g_instructions_study_establish_links, - proc, disass->format); + proc, ctx, disass->format); @@ -515,16 +518,29 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkStatus - proc = g_loaded_binary_get_processor(disass->binary); print_disassembled_instructions(disass->buffer, disass->format, proc, status); - g_object_unref(G_OBJECT(proc)); + /* Rajout de tous les éléments mis en place automatiquement */ + + void add_to_collection(GDbItem *item, GLoadedBinary *binary) + { + g_object_ref(G_OBJECT(item)); + g_loaded_binary_add_to_collection(binary, item); + + } + g_proc_context_foreach_db_item(ctx, (GFunc)add_to_collection, disass->binary); + + /* Nettoyage final et sortie ! */ + + g_object_unref(G_OBJECT(ctx)); + + g_object_unref(G_OBJECT(proc)); process_disassembly_event(PGA_DISASSEMBLY_ENDED, disass->binary); diff --git a/src/analysis/disass/fetch.c b/src/analysis/disass/fetch.c index 4b162e8..7d8161a 100644 --- a/src/analysis/disass/fetch.c +++ b/src/analysis/disass/fetch.c @@ -480,6 +480,7 @@ static GDelayedFetching template; /* Patron des tâches à venir /****************************************************************************** * * * Paramètres : binary = représentation de binaire chargé. * +* ctx = contexte fourni pour suivre le désassemblage. * * gid = identifiant du groupe de travail à utiliser. * * status = barre de statut avec progression à mettre à jour. * * * @@ -491,12 +492,11 @@ static GDelayedFetching template; /* Patron des tâches à venir * * ******************************************************************************/ -GArchInstruction *disassemble_binary_content(const GLoadedBinary *binary, wgroup_id_t gid, GtkStatusStack *status) +GArchInstruction *disassemble_binary_content(const GLoadedBinary *binary, GProcContext *ctx, wgroup_id_t gid, GtkStatusStack *status) { GArchInstruction *result; /* Instruction désassemblées */ //GDelayedFetching template; /* Patron des tâches à venir */ GBinFormat *format; /* Format du fichier binaire */ - GArchProcessor *proc; /* Architecture du binaire */ GBinContent *content; /* Contenu binaire à manipuler */ phys_t length; /* Taille des données à lire */ GWorkQueue *queue; /* Gestionnaire de différés */ @@ -509,9 +509,7 @@ GArchInstruction *disassemble_binary_content(const GLoadedBinary *binary, wgroup template.format = g_loaded_binary_get_format(binary); format = G_BIN_FORMAT(template.format); - proc = g_loaded_binary_get_processor(binary); - template.ctx = g_arch_processor_get_context(proc); - g_object_unref(G_OBJECT(proc)); + template.ctx = ctx; content = g_binary_format_get_content(format); length = g_binary_content_compute_size(content); @@ -577,8 +575,6 @@ GArchInstruction *disassemble_binary_content(const GLoadedBinary *binary, wgroup //g_object_unref(G_OBJECT(template.format)); - g_object_unref(G_OBJECT(template.ctx)); - /* TODO / del(areas); */ return result; diff --git a/src/analysis/disass/fetch.h b/src/analysis/disass/fetch.h index 3ebb4d8..eb1d0d3 100644 --- a/src/analysis/disass/fetch.h +++ b/src/analysis/disass/fetch.h @@ -32,7 +32,7 @@ /* Procède au désassemblage basique d'un contenu binaire. */ -GArchInstruction *disassemble_binary_content(const GLoadedBinary *, wgroup_id_t, GtkStatusStack *); +GArchInstruction *disassemble_binary_content(const GLoadedBinary *, GProcContext *, wgroup_id_t, GtkStatusStack *); diff --git a/src/analysis/disass/instructions.c b/src/analysis/disass/instructions.c index b88d69f..47633d0 100644 --- a/src/analysis/disass/instructions.c +++ b/src/analysis/disass/instructions.c @@ -39,6 +39,7 @@ struct _GInstructionsStudy GDelayedWork parent; /* A laisser en premier */ GArchProcessor *proc; /* Processeurs avec ses instr. */ + GProcContext *ctx; /* Suivi du désassemblage */ GBinFormat *format; /* Format binaire à manipuler */ ins_fallback_cb fallback; /* Routine de traitement finale*/ @@ -169,6 +170,7 @@ static void g_instructions_study_finalize(GInstructionsStudy *study) /****************************************************************************** * * * Paramètres : proc = ensemble d'instructions désassemblées. * +* ctx = contexte fourni pour suivre le désassemblage. * * format = accès aux données du binaire d'origine. * * begin = point de départ du parcours de liste. * * end = point d'arrivée exclu du parcours. * @@ -183,13 +185,14 @@ static void g_instructions_study_finalize(GInstructionsStudy *study) * * ******************************************************************************/ -GInstructionsStudy *g_instructions_study_new(GArchProcessor *proc, GBinFormat *format, size_t begin, size_t end, activity_id_t id, ins_fallback_cb fallback) +GInstructionsStudy *g_instructions_study_new(GArchProcessor *proc, GProcContext *ctx, GBinFormat *format, size_t begin, size_t end, activity_id_t id, ins_fallback_cb fallback) { GInstructionsStudy *result; /* Tâche à retourner */ result = g_object_new(G_TYPE_INSTRUCTIONS_STUDY, NULL); result->proc = proc; + result->ctx = ctx; result->format = format; result->fallback = fallback; @@ -250,7 +253,7 @@ void g_instructions_study_do_link_operation(GInstructionsStudy *study, size_t in instr = g_arch_processor_get_disassembled_instruction(study->proc, index); - g_arch_instruction_call_hook(instr, IPH_LINK, study->proc, NULL, study->format); + g_arch_instruction_call_hook(instr, IPH_LINK, study->proc, study->ctx, study->format); } @@ -274,7 +277,7 @@ void g_instructions_study_do_post_operation(GInstructionsStudy *study, size_t in instr = g_arch_processor_get_disassembled_instruction(study->proc, index); - g_arch_instruction_call_hook(instr, IPH_POST, study->proc, NULL, study->format); + g_arch_instruction_call_hook(instr, IPH_POST, study->proc, study->ctx, study->format); } diff --git a/src/analysis/disass/instructions.h b/src/analysis/disass/instructions.h index 20b853d..c18322c 100644 --- a/src/analysis/disass/instructions.h +++ b/src/analysis/disass/instructions.h @@ -52,7 +52,7 @@ typedef void (* ins_fallback_cb) (GInstructionsStudy *, size_t); /* Crée une tâche d'étude de instructions différée. */ -GInstructionsStudy *g_instructions_study_new(GArchProcessor *, GBinFormat *, size_t, size_t, activity_id_t, ins_fallback_cb); +GInstructionsStudy *g_instructions_study_new(GArchProcessor *, GProcContext *, GBinFormat *, size_t, size_t, activity_id_t, ins_fallback_cb); /* Réalise l'appel de type IPH_LINK sur une instruction. */ void g_instructions_study_do_link_operation(GInstructionsStudy *, size_t); diff --git a/src/arch/context-int.h b/src/arch/context-int.h index 1ea8b6c..df62090 100644 --- a/src/arch/context-int.h +++ b/src/arch/context-int.h @@ -56,6 +56,11 @@ struct _GProcContext gint *counter; + GDbItem **items; /* Eléments à insérer plus tard*/ + size_t items_allocated; /* Taille allouée à la liste */ + size_t items_count; /* Nombre d'éléments présents */ + GMutex items_mutex; /* Accès à la liste */ + }; diff --git a/src/arch/context.c b/src/arch/context.c index 979a403..dacd5ed 100644 --- a/src/arch/context.c +++ b/src/arch/context.c @@ -33,12 +33,22 @@ +/* Taille des blocs d'allocations */ +#define DB_ALLOC_SIZE 20 + + /* Initialise la classe des contextes de processeur. */ static void g_proc_context_class_init(GProcContextClass *); /* Initialise une instance de contexte de processeur. */ static void g_proc_context_init(GProcContext *); +/* Supprime toutes les références externes. */ +static void g_proc_context_dispose(GProcContext *); + +/* Procède à la libération totale de la mémoire. */ +static void g_proc_context_finalize(GProcContext *); + /* Ajoute une adresse virtuelle comme point de départ de code. */ static void _g_proc_context_push_drop_point(GProcContext *, DisassPriorityLevel, virt_t, va_list); @@ -63,6 +73,13 @@ G_DEFINE_TYPE(GProcContext, g_proc_context, G_TYPE_OBJECT); static void g_proc_context_class_init(GProcContextClass *klass) { + GObjectClass *object; /* Autre version de la classe */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_proc_context_dispose; + object->finalize = (GObjectFinalizeFunc)g_proc_context_finalize; + klass->push_point = (push_drop_point_fc)_g_proc_context_push_drop_point; g_signal_new("drop-point-pushed", @@ -105,6 +122,56 @@ static void g_proc_context_init(GProcContext *ctx) ctx->esyms_count = 0; g_mutex_init(&ctx->es_access); + g_mutex_init(&ctx->items_mutex); + +} + + +/****************************************************************************** +* * +* Paramètres : ctx = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_proc_context_dispose(GProcContext *ctx) +{ + size_t i; /* Boucle de parcours */ + + for (i = 0; i < ctx->items_count; i++) + g_object_unref(G_OBJECT(ctx->items[i])); + + g_mutex_clear(&ctx->items_mutex); + + G_OBJECT_CLASS(g_proc_context_parent_class)->dispose(G_OBJECT(ctx)); + +} + + +/****************************************************************************** +* * +* Paramètres : ctx = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_proc_context_finalize(GProcContext *ctx) +{ + if (ctx->items != NULL) + free(ctx->items); + + G_OBJECT_CLASS(g_proc_context_parent_class)->finalize(G_OBJECT(ctx)); + } @@ -304,3 +371,63 @@ bool g_proc_context_pop_new_symbol_at(GProcContext *ctx, vmpa2t *addr) return result; } + + +/****************************************************************************** +* * +* Paramètres : ctx = contexte de désassemblage générique à consulter. * +* item = élément pour base de données à conserver. * +* * +* Description : Note la mise en place d'un élément pendant le désassemblage. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_proc_context_add_db_item(GProcContext *ctx, GDbItem *item) +{ + g_mutex_lock(&ctx->items_mutex); + + if ((ctx->items_count + 1) > ctx->items_allocated) + { + ctx->items_allocated += DB_ALLOC_SIZE; + + ctx->items = (GDbItem **)realloc(ctx->items, sizeof(GDbItem *) * ctx->items_allocated); + + } + + ctx->items[ctx->items_count++] = item; + + g_mutex_unlock(&ctx->items_mutex); + +} + + +/****************************************************************************** +* * +* Paramètres : ctx = contexte de désassemblage générique à consulter. * +* func = fonction à appeler pour chaque élément. * +* data = éventuelles données à associer à l'appel. * +* * +* Description : Effectue un traitement sur chaque élement de base de données.* +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_proc_context_foreach_db_item(GProcContext *ctx, GFunc func, void *data) +{ + size_t i; /* Boucle de parcours */ + + g_mutex_lock(&ctx->items_mutex); + + for (i = 0; i < ctx->items_count; i++) + func(ctx->items[i], data); + + g_mutex_unlock(&ctx->items_mutex); + +} diff --git a/src/arch/context.h b/src/arch/context.h index d8b5793..dee6d81 100644 --- a/src/arch/context.h +++ b/src/arch/context.h @@ -30,6 +30,7 @@ #include "vmpa.h" +#include "../analysis/db/item.h" @@ -78,6 +79,12 @@ void g_proc_context_push_new_symbol_at(GProcContext *, const vmpa2t *); /* Dépile une adresse de nouveau symbole à prendre en compte. */ bool g_proc_context_pop_new_symbol_at(GProcContext *, vmpa2t *); +/* Note la mise en place d'un élément pendant le désassemblage. */ +void g_proc_context_add_db_item(GProcContext *, GDbItem *); + +/* Effectue un traitement sur chaque élement de base de données. */ +void g_proc_context_foreach_db_item(GProcContext *, GFunc, void *); + #endif /* _ARCH_CONTEXT_H */ diff --git a/src/arch/dalvik/Makefile.am b/src/arch/dalvik/Makefile.am index f0c6ced..0d1fa88 100644 --- a/src/arch/dalvik/Makefile.am +++ b/src/arch/dalvik/Makefile.am @@ -8,7 +8,7 @@ libarchdalvik_la_SOURCES = \ instruction-def.h \ instruction-int.h \ instruction.h instruction.c \ - link.h \ + link.h link.c \ operand.h operand.c \ post.h \ processor.h processor.c \ diff --git a/src/arch/dalvik/context.c b/src/arch/dalvik/context.c index b093345..dad9008 100644 --- a/src/arch/dalvik/context.c +++ b/src/arch/dalvik/context.c @@ -59,6 +59,7 @@ struct _GDalvikContext raw_data_area *data; /* Liste de zones brutes */ size_t count; /* Taille de cette liste */ + GMutex mutex; /* Accès à la liste */ }; @@ -179,6 +180,7 @@ static void g_dalvik_context_class_init(GDalvikContextClass *klass) static void g_dalvik_context_init(GDalvikContext *ctx) { + g_mutex_init(&ctx->mutex); } @@ -197,6 +199,8 @@ static void g_dalvik_context_init(GDalvikContext *ctx) static void g_dalvik_context_dispose(GDalvikContext *ctx) { + g_mutex_clear(&ctx->mutex); + G_OBJECT_CLASS(g_dalvik_context_parent_class)->dispose(G_OBJECT(ctx)); } @@ -269,6 +273,8 @@ bool g_dalvik_context_register_switch_data(GDalvikContext *ctx, const vmpa2t *st result = true; + g_mutex_lock(&ctx->mutex); + /* Vérification quant aux chevauchements */ init_mrange(&new.range, start, length); @@ -287,6 +293,8 @@ bool g_dalvik_context_register_switch_data(GDalvikContext *ctx, const vmpa2t *st } + g_mutex_unlock(&ctx->mutex); + return result; } @@ -315,6 +323,8 @@ bool g_dalvik_context_register_array_data(GDalvikContext *ctx, const vmpa2t *sta result = true; + g_mutex_lock(&ctx->mutex); + /* Vérification quant aux chevauchements */ init_mrange(&new.range, start, length); @@ -333,6 +343,8 @@ bool g_dalvik_context_register_array_data(GDalvikContext *ctx, const vmpa2t *sta } + g_mutex_unlock(&ctx->mutex); + return result; } @@ -360,6 +372,8 @@ GArchInstruction *g_dalvik_context_get_raw_data(GDalvikContext *ctx, const GBinC result = NULL; + g_mutex_lock(&ctx->mutex); + found = bsearch(pos, ctx->data, ctx->count, sizeof(raw_data_area), (__compar_fn_t)cmp_mrange_with_vmpa_swapped); @@ -396,6 +410,8 @@ GArchInstruction *g_dalvik_context_get_raw_data(GDalvikContext *ctx, const GBinC } + g_mutex_unlock(&ctx->mutex); + return result; } diff --git a/src/arch/dalvik/link.c b/src/arch/dalvik/link.c new file mode 100644 index 0000000..b698f03 --- /dev/null +++ b/src/arch/dalvik/link.c @@ -0,0 +1,154 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * link.c - édition des liens après la phase de désassemblage + * + * Copyright (C) 2016 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA 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. + * + * OpenIDA 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 . + */ + + +#include "link.h" + + +#include +#include +#include + + +#include + + +#include "pseudo/switch.h" +#include "../target.h" + + + +/****************************************************************************** +* * +* Paramètres : instr = instruction ARMv7 à traiter. * +* proc = représentation de l'architecture utilisée. * +* context = contexte associé à la phase de désassemblage. * +* format = acès aux données du binaire d'origine. * +* * +* Description : Etablit tous les liens liés à un embranchement compressé. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void handle_dalvik_packed_switch_links(GArchInstruction *instr, GArchProcessor *proc, GProcContext *context, GBinFormat *format) +{ + GArchOperand *op; /* Opérande numérique en place */ + virt_t virt; /* Adresse virtuelle */ + vmpa2t addr; /* Adresse de destination */ + GArchInstruction *switch_ins; /* Instruction de branchements */ + const mrange_t *range; /* Zone d'occupation */ + const vmpa2t *start_addr; /* Adresse de référentiel */ + vmpa2t def_addr; /* Traitement par défaut */ + GArchInstruction *target; /* Ligne visée par la référence*/ + GDbComment *comment; /* Indication sur la condition */ + const uint32_t *keys; /* Conditions de sauts */ + const uint32_t *targets; /* Positions relatives liées */ + uint16_t count; /* Taille de ces tableaux */ + uint16_t i; /* Boucle de parcours */ + char *int_val;/* Valeur en chaîne de carac. */ + + assert(g_arch_instruction_count_operands(instr) == 2); + + op = g_arch_instruction_get_operand(instr, 1); + + virt = VMPA_NO_VIRTUAL; + + if (G_IS_TARGET_OPERAND(op)) + virt = g_target_operand_get_addr(G_TARGET_OPERAND(op)); + + else if (G_IS_IMM_OPERAND(op)) + { + if (!g_imm_operand_to_virt_t(G_IMM_OPERAND(op), &virt)) + virt = VMPA_NO_VIRTUAL; + } + + if (virt != VMPA_NO_VIRTUAL) + { + /* TODO : utiliser format pour contruire une adresse avec une position physique, + * ce qui accélèrerait les recherches. + */ + init_vmpa(&addr, VMPA_NO_PHYSICAL, virt); + + switch_ins = g_arch_processor_find_instr_by_address(proc, &addr); + + if (G_IS_DALVIK_SWITCH_INSTR(switch_ins)) + { + range = g_arch_instruction_get_range(instr); + + start_addr = get_mrange_addr(range); + + /* Cas par défaut */ + + compute_mrange_end_addr(range, &def_addr); + + target = g_arch_processor_find_instr_by_address(proc, &def_addr); + + if (target != NULL) + { + comment = g_db_comment_new_area(&def_addr, BLF_NONE, _("Defaut case"), true); + + // FIXME g_db_item_set_volatile(G_DB_ITEM(comment), true); + g_proc_context_add_db_item(context, G_DB_ITEM(comment)); + + g_arch_instruction_link_with(instr, target, ILT_CASE_JUMP); + + } + + /* Autres cas */ + + assert(G_IS_DALVIK_SWITCH_INSTR(switch_ins)); + + count = g_dalvik_switch_get_data(G_DALVIK_SWITCH_INSTR(switch_ins), &keys, &targets); + + for (i = 0; i < count; i++) + { + copy_vmpa(&addr, start_addr); + advance_vmpa(&addr, targets[i] * sizeof(uint16_t)); + + if (cmp_vmpa(&addr, &def_addr) == 0) + continue; + + target = g_arch_processor_find_instr_by_address(proc, &addr); + + if (target != NULL) + { + asprintf(&int_val, _("Case %d"), keys[i]); + comment = g_db_comment_new_area(&addr, BLF_NONE, int_val, true); + free(int_val); + + // FIXME g_db_item_set_volatile(G_DB_ITEM(comment), true); + g_proc_context_add_db_item(context, G_DB_ITEM(comment)); + + g_arch_instruction_link_with(instr, target, ILT_CASE_JUMP); + + } + + } + + } + + } + +} diff --git a/src/arch/dalvik/link.h b/src/arch/dalvik/link.h index 14af01d..4e4418f 100644 --- a/src/arch/dalvik/link.h +++ b/src/arch/dalvik/link.h @@ -40,5 +40,9 @@ static inline void handle_dalvik_ifz_branch_as_link(GArchInstruction *ins, GArch } +/* Etablit tous les liens liés à un embranchement compressé. */ +void handle_dalvik_packed_switch_links(GArchInstruction *, GArchProcessor *, GProcContext *, GBinFormat *); + + #endif /* _ARCH_DALVIK_LINK_H */ diff --git a/src/arch/dalvik/opdefs/switch_2b.d b/src/arch/dalvik/opdefs/switch_2b.d index 2d13992..2ff6b33 100644 --- a/src/arch/dalvik/opdefs/switch_2b.d +++ b/src/arch/dalvik/opdefs/switch_2b.d @@ -27,4 +27,10 @@ @format 31t + @hooks { + + link = handle_dalvik_packed_switch_links + + } + } diff --git a/src/arch/dalvik/opdefs/switch_2c.d b/src/arch/dalvik/opdefs/switch_2c.d index b56cd9d..0a4d248 100644 --- a/src/arch/dalvik/opdefs/switch_2c.d +++ b/src/arch/dalvik/opdefs/switch_2c.d @@ -27,4 +27,10 @@ @format 31t + @hooks { + + link = handle_dalvik_packed_switch_links + + } + } diff --git a/src/arch/link.c b/src/arch/link.c index 48bc3a3..9f341d1 100644 --- a/src/arch/link.c +++ b/src/arch/link.c @@ -88,7 +88,7 @@ void handle_jump_as_link(GArchInstruction *instr, GArchProcessor *proc, GProcCon * Remarques : - * * * ******************************************************************************/ -#include "instruction-int.h" // REMME + void handle_branch_as_link(GArchInstruction *instr, GArchProcessor *proc, GProcContext *context, GBinFormat *format, size_t index) { GArchOperand *op; /* Opérande numérique en place */ diff --git a/src/gui/editem.c b/src/gui/editem.c index 5f326ce..7718581 100644 --- a/src/gui/editem.c +++ b/src/gui/editem.c @@ -328,7 +328,7 @@ static void start_moving_to_address_in_view_panel(GtkViewPanel *vpanel, const vm move = g_db_move_new(src, addr); binary = gtk_view_panel_get_binary(vpanel); - g_loaded_binary_add_to_collection(binary, DBF_MOVES, G_DB_ITEM(move)); + g_loaded_binary_add_to_collection(binary, G_DB_ITEM(move)); } diff --git a/src/gui/menus/edition.c b/src/gui/menus/edition.c index b507f0a..0a92e3e 100644 --- a/src/gui/menus/edition.c +++ b/src/gui/menus/edition.c @@ -394,7 +394,7 @@ static void mcb_edition_switch_numeric_operand(GtkMenuItem *menuitem, GMenuBar * switcher = g_db_switcher_new(instr, G_IMM_OPERAND(creator), display); - g_loaded_binary_add_to_collection(binary, DBF_DISPLAY_SWITCHERS, G_DB_ITEM(switcher)); + g_loaded_binary_add_to_collection(binary, G_DB_ITEM(switcher)); g_object_unref(G_OBJECT(proc)); @@ -642,7 +642,7 @@ static void mcb_edition_bookmarks_toggle(GtkMenuItem *menuitem, GMenuBar *bar) } - _g_loaded_binary_add_to_collection(binary, DBF_BOOKMARKS, G_DB_ITEM(bookmark), false); + _g_loaded_binary_add_to_collection(binary, G_DB_ITEM(bookmark), false); mcb_ebt_add_finish: -- cgit v0.11.2-87-g4458