diff options
Diffstat (limited to 'src/arch/dalvik/link.c')
-rw-r--r-- | src/arch/dalvik/link.c | 322 |
1 files changed, 0 insertions, 322 deletions
diff --git a/src/arch/dalvik/link.c b/src/arch/dalvik/link.c deleted file mode 100644 index 6508b03..0000000 --- a/src/arch/dalvik/link.c +++ /dev/null @@ -1,322 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * link.c - édition des liens après la phase de désassemblage - * - * Copyright (C) 2016-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 "link.h" - - -#include <assert.h> -#include <malloc.h> -#include <stdbool.h> -#include <stdio.h> - - -#include <i18n.h> - - -#include "pseudo/switch.h" -#include "../target.h" -#include "../../analysis/db/items/comment.h" -#include "../../common/extstr.h" - - - -/* Mémorisation des cas rencontrés */ -typedef struct _case_comment -{ - bool valid; /* Entrée utilisable ? */ - - vmpa2t handler; /* Position du code associé */ - - bool is_default; /* Gestion par défaut ? */ - union - { - int32_t key; /* Clef unique */ - int32_t *keys; /* Ensemble de clefs dynamique */ - }; - - size_t count; /* Nombre de clefs conservées */ - -} case_comment; - - -/* REMME */ -#define COMMENT_LINE_SEP "\n" - - -/****************************************************************************** -* * -* 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, GExeFormat *format) -{ - GArchOperand *op; /* Opérande numérique en place */ - bool defined; /* Adresse définie ? */ - vmpa2t addr; /* Adresse de destination */ - virt_t virt; /* Adresse virtuelle */ - GArchInstruction *switch_ins; /* Instruction de branchements */ - const mrange_t *range; /* Zone d'occupation */ - const vmpa2t *start_addr; /* Adresse de référentiel */ - const int32_t *keys; /* Conditions de sauts */ - const int32_t *targets; /* Positions relatives liées */ - uint16_t count; /* Taille de ces tableaux */ - case_comment *comments; /* Mémorisation progressive */ - vmpa2t def_addr; /* Traitement par défaut */ - GArchInstruction *target; /* Ligne visée par la référence*/ - case_comment *comment; /* Commentaire à éditer */ - uint16_t i; /* Boucle de parcours #1 */ - size_t j; /* Boucle de parcours #2 */ - int32_t tmp; /* Sauvegarde temporaire */ - char *msg; /* Indication à imprimer */ - size_t k; /* Boucle de parcours #3 */ - char *int_val; /* Valeur en chaîne de carac. */ - GDbComment *item; /* Indication sur la condition */ - - g_arch_instruction_lock_operands(instr); - - assert(_g_arch_instruction_count_operands(instr) == 2); - - op = _g_arch_instruction_get_operand(instr, 1); - - g_arch_instruction_unlock_operands(instr); - - defined = false; - - if (G_IS_TARGET_OPERAND(op)) - { - g_target_operand_get_addr(G_TARGET_OPERAND(op), &addr); - defined = true; - } - - else if (G_IS_IMM_OPERAND(op)) - { - if (g_imm_operand_to_virt_t(G_IMM_OPERAND(op), &virt)) - { - init_vmpa(&addr, VMPA_NO_PHYSICAL, virt); - defined = true; - } - } - - if (defined) - { - 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); - - /* Préparation de l'édition des commentaires */ - - count = g_dalvik_switch_get_data(G_DALVIK_SWITCH_INSTR(switch_ins), &keys, &targets); - - comments = (case_comment *)calloc(1 + count, sizeof(case_comment)); - - /* 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 = &comments[0]; - - comment->valid = true; - - copy_vmpa(&comment->handler, &def_addr); - - comment->is_default = true; - - g_arch_instruction_link_with(instr, target, ILT_CASE_JUMP); - - g_object_unref(G_OBJECT(target)); - - } - - /* Autres cas */ - - 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) - { - for (j = 0; j < (1 + count); j++) - { - if (!comments[j].valid) - break; - - if (cmp_vmpa(&addr, &comments[j].handler) == 0) - break; - - } - - assert(j < (1 + count)); - - comment = &comments[j]; - - if (!comment->valid) - { - comment->valid = true; - - copy_vmpa(&comment->handler, &addr); - - comment->key = keys[i]; - comment->count = 1; - - } - else - { - if (comment->count == 0) - comment->key = keys[i]; - - if (comment->count == 1) - { - tmp = comment->key; - - comment->keys = (int32_t *)calloc(2, sizeof(int32_t)); - - comment->keys[0] = tmp; - comment->keys[1] = keys[i]; - - comment->count = 2; - - } - - else - { - comment->count++; - - comment->keys = (int32_t *)realloc(comment->keys, comment->count * sizeof(int32_t)); - - comment->keys[comment->count - 1] = keys[i]; - - } - - } - - g_arch_instruction_link_with(instr, target, ILT_CASE_JUMP); - - g_object_unref(G_OBJECT(target)); - - } - - } - - /* Edition des commentaires et nettoyage */ - - for (j = 0; j < (1 + count); j++) - { - comment = &comments[j]; - - if (!comment->valid) - break; - - switch (comment->count) - { - case 0: - msg = NULL; - break; - - case 1: - asprintf(&msg, _("Case %d"), comment->key); - break; - - default: - - msg = NULL; - - /** - * Les spécifications indiquent que les clefs sont triées. - * Donc nul besoin de s'occuper de leur ordre ici. - */ - - for (k = 0; k < comment->count; k++) - { - if (k > 0) - /* FIXME : encapsuler ! */ - msg = stradd(msg, COMMENT_LINE_SEP); - - asprintf(&int_val, _("Case %d:"), comment->keys[k]); - msg = stradd(msg, int_val); - free(int_val); - - } - - break; - - } - - if (comment->is_default) - { - if (msg == NULL) - msg = strdup(_("Defaut case:")); - else - { - /* FIXME : encapsuler ! */ - msg = stradd(msg, COMMENT_LINE_SEP); - msg = stradd(msg, _("Defaut case")); - } - - } - - item = g_db_comment_new_area(&comment->handler, BLF_NONE, msg, true); - - g_db_item_set_volatile(G_DB_ITEM(item), true); - g_proc_context_add_db_item(context, G_DB_ITEM(item)); - - free(msg); - - if (comment->count > 1) - free(comment->keys); - - } - - free(comments); - - } - - if (switch_ins != NULL) - g_object_unref(G_OBJECT(switch_ins)); - - } - -} |