/* Chrysalide - Outil d'analyse de fichiers binaires * registers.c - aides auxiliaires relatives aux registres Dalvik * * Copyright (C) 2012-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 . */ #include "register.h" #include "register-int.h" /* ---------------------------- PUR REGISTRE DU MATERIEL ---------------------------- */ /* Initialise la classe des registres. */ static void g_arch_register_class_init(GArchRegisterClass *); /* Initialise une instance de registre. */ static void g_arch_register_init(GArchRegister *); /* Procède à l'initialisation de l'interface de partage. */ static void g_arch_register_interface_init(GSharedInstanceInterface *); /* Supprime toutes les références externes. */ static void g_arch_register_dispose(GArchRegister *); /* Procède à la libération totale de la mémoire. */ static void g_arch_register_finalize(GArchRegister *); /* Initialise un nouvel objet partagé avec des informations. */ static bool g_arch_register_do_init(GArchRegister *, const void *); /* Fournit la valeur du compteur de partage. */ static unsigned int g_arch_register_get_references(const GArchRegister *); /* Incrémente le compteur de partage. */ static void g_arch_register_inc_references(GArchRegister *); /* Décrémente le compteur de partage. */ static void g_arch_register_dec_references(GArchRegister *); /* Compare de façon accélérée un registre avec un autre. */ static int g_arch_register_quickly_compare(const GArchRegister **, const GArchRegister **); /* ------------------------- REGISTRE SOUS FORME D'OPERANDE ------------------------- */ /* Initialise la classe des opérandes de registre. */ static void g_register_operand_class_init(GRegisterOperandClass *); /* Initialise une instance d'opérande de registre. */ static void g_register_operand_init(GRegisterOperand *); /* Supprime toutes les références externes. */ static void g_register_operand_dispose(GRegisterOperand *); /* Procède à la libération totale de la mémoire. */ static void g_register_operand_finalize(GRegisterOperand *); /* Compare un opérande avec un autre. */ static int g_register_operand_compare(const GRegisterOperand **, const GRegisterOperand **); /* Traduit un opérande en version humainement lisible. */ static void g_register_operand_print(const GRegisterOperand *, GBufferLine *, AsmSyntax); /* ---------------------------------------------------------------------------------- */ /* PUR REGISTRE DU MATERIEL */ /* ---------------------------------------------------------------------------------- */ /* Indique le type défini pour une représentation d'un registre. */ G_DEFINE_TYPE_WITH_CODE(GArchRegister, g_arch_register, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE(G_TYPE_SHARED_INSTANCE, g_arch_register_interface_init)); /****************************************************************************** * * * Paramètres : klass = classe à initialiser. * * * * Description : Initialise la classe des registres. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_arch_register_class_init(GArchRegisterClass *klass) { GObjectClass *object; /* Autre version de la classe */ object = G_OBJECT_CLASS(klass); object->dispose = (GObjectFinalizeFunc/* ! */)g_arch_register_dispose; object->finalize = (GObjectFinalizeFunc)g_arch_register_finalize; } /****************************************************************************** * * * Paramètres : reg = instance à initialiser. * * * * Description : Initialise une instance de registre. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_arch_register_init(GArchRegister *reg) { } /****************************************************************************** * * * Paramètres : iface = interface GLib à initialiser. * * * * Description : Procède à l'initialisation de l'interface de partage. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_arch_register_interface_init(GSharedInstanceInterface *iface) { iface->init = (init_shared_fc)g_arch_register_do_init; iface->get_ref = (get_shared_ref_fc)g_arch_register_get_references; iface->inc_ref = (inc_shared_ref_fc)g_arch_register_inc_references; iface->dec_ref = (dec_shared_ref_fc)g_arch_register_dec_references; iface->qck_cmp = (qck_compare_shared_fc)g_arch_register_quickly_compare; } /****************************************************************************** * * * Paramètres : binary = instance d'objet GLib à traiter. * * * * Description : Supprime toutes les références externes. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_arch_register_dispose(GArchRegister *reg) { G_OBJECT_CLASS(g_arch_register_parent_class)->dispose(G_OBJECT(reg)); } /****************************************************************************** * * * Paramètres : binary = instance d'objet GLib à traiter. * * * * Description : Procède à la libération totale de la mémoire. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_arch_register_finalize(GArchRegister *reg) { G_OBJECT_CLASS(g_arch_register_parent_class)->finalize(G_OBJECT(reg)); } /****************************************************************************** * * * Paramètres : reg = objet partagé à initialiser. * * info = information à utiliser pour la mise en place. * * * * Description : Initialise un nouvel objet partagé avec des informations. * * * * Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ static bool g_arch_register_do_init(GArchRegister *reg, const void *info) { bool result; /* Bilan à retourner */ result = G_ARCH_REGISTER_GET_CLASS(reg)->init(G_SHARED_INSTANCE(reg), info); return result; } /****************************************************************************** * * * Paramètres : reg = objet partagé à consulter. * * * * Description : Fournit la valeur du compteur de partage. * * * * Retour : Nombre de partages courant. * * * * Remarques : - * * * ******************************************************************************/ static unsigned int g_arch_register_get_references(const GArchRegister *reg) { return reg->shared_count; } /****************************************************************************** * * * Paramètres : reg = objet partagé à modifier. * * * * Description : Incrémente le compteur de partage. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_arch_register_inc_references(GArchRegister *reg) { reg->shared_count++; } /****************************************************************************** * * * Paramètres : reg = objet partagé à modifier. * * * * Description : Décrémente le compteur de partage. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_arch_register_dec_references(GArchRegister *reg) { reg->shared_count--; } /****************************************************************************** * * * Paramètres : a = premier registre à consulter. * * b = second registre à consulter. * * * * Description : Compare de façon accélérée un registre avec un autre. * * * * Retour : Bilan de la comparaison. * * * * Remarques : - * * * ******************************************************************************/ static int g_arch_register_quickly_compare(const GArchRegister **a, const GArchRegister **b) { int result; /* Bilan à faire remonter */ result = G_ARCH_REGISTER_GET_CLASS(*a)->compare(a, b); return result; } /****************************************************************************** * * * Paramètres : reg = opérande à consulter pour le calcul. * * * * Description : Produit une empreinte à partir d'un registre. * * * * Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ guint g_arch_register_hash(const GArchRegister *reg) { return G_ARCH_REGISTER_GET_CLASS(reg)->hash(reg); } /****************************************************************************** * * * Paramètres : a = premier opérande à consulter. * * b = second opérande à consulter. * * * * Description : Compare un registre avec un autre. * * * * Retour : Bilan de la comparaison. * * * * Remarques : - * * * ******************************************************************************/ int g_arch_register_compare(const GArchRegister * const *a, const GArchRegister * const *b) { return G_ARCH_REGISTER_GET_CLASS(*a)->compare(a, b); } /****************************************************************************** * * * Paramètres : reg = registre à transcrire. * * line = ligne tampon où imprimer l'opérande donné. * * syntax = type de représentation demandée. * * * * Description : Traduit un registre en version humainement lisible. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void g_arch_register_print(const GArchRegister *reg, GBufferLine *line, AsmSyntax syntax) { G_ARCH_REGISTER_GET_CLASS(reg)->print(reg, line, syntax); } /****************************************************************************** * * * Paramètres : reg = registre à consulter. * * * * Description : Indique si le registre correspond à ebp ou similaire. * * * * Retour : true si la correspondance est avérée, false sinon. * * * * Remarques : - * * * ******************************************************************************/ bool g_arch_register_is_base_pointer(const GArchRegister *reg) { bool result; /* Bilan à renvoyer */ if (G_ARCH_REGISTER_GET_CLASS(reg)->is_bp != NULL) result = G_ARCH_REGISTER_GET_CLASS(reg)->is_bp(reg); else result = false; return result; } /****************************************************************************** * * * Paramètres : reg = registre à consulter. * * * * Description : Indique si le registre correspond à esp ou similaire. * * * * Retour : true si la correspondance est avérée, false sinon. * * * * Remarques : - * * * ******************************************************************************/ bool g_arch_register_is_stack_pointer(const GArchRegister *reg) { bool result; /* Bilan à renvoyer */ if (G_ARCH_REGISTER_GET_CLASS(reg)->is_sp != NULL) result = G_ARCH_REGISTER_GET_CLASS(reg)->is_sp(reg); else result = false; return result; } /* ---------------------------------------------------------------------------------- */ /* REGISTRE SOUS FORME D'OPERANDE */ /* ---------------------------------------------------------------------------------- */ /* Indique le type défini par la GLib pour un opérande de registre Dalvik. */ G_DEFINE_TYPE(GRegisterOperand, g_register_operand, G_TYPE_ARCH_OPERAND); /****************************************************************************** * * * Paramètres : klass = classe à initialiser. * * * * Description : Initialise la classe des opérandes de registre Dalvik. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_register_operand_class_init(GRegisterOperandClass *klass) { GObjectClass *object; /* Autre version de la classe */ GArchOperandClass *operand; /* Version de classe parente */ object = G_OBJECT_CLASS(klass); operand = G_ARCH_OPERAND_CLASS(klass); object->dispose = (GObjectFinalizeFunc/* ! */)g_register_operand_dispose; object->finalize = (GObjectFinalizeFunc)g_register_operand_finalize; operand->compare = (operand_compare_fc)g_register_operand_compare; operand->print = (operand_print_fc)g_register_operand_print; } /****************************************************************************** * * * Paramètres : operand = instance à initialiser. * * * * Description : Initialise une instance d'opérande de registre Dalvik. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_register_operand_init(GRegisterOperand *operand) { operand->is_written = false; } /****************************************************************************** * * * Paramètres : binary = instance d'objet GLib à traiter. * * * * Description : Supprime toutes les références externes. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_register_operand_dispose(GRegisterOperand *operand) { g_object_unref(G_OBJECT(operand->reg)); G_OBJECT_CLASS(g_register_operand_parent_class)->dispose(G_OBJECT(operand)); } /****************************************************************************** * * * Paramètres : binary = instance d'objet GLib à traiter. * * * * Description : Procède à la libération totale de la mémoire. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_register_operand_finalize(GRegisterOperand *operand) { G_OBJECT_CLASS(g_register_operand_parent_class)->finalize(G_OBJECT(operand)); } /****************************************************************************** * * * Paramètres : reg = registre déjà en place. * * * * Description : Crée un opérande visant un registre. * * * * Retour : Opérande mis en place. * * * * Remarques : - * * * ******************************************************************************/ GArchOperand *g_register_operand_new(GArchRegister *reg) { GRegisterOperand *result; /* Structure à retourner */ result = g_object_new(G_TYPE_REGISTER_OPERAND, NULL); result->reg = reg; return G_ARCH_OPERAND(result); } /****************************************************************************** * * * Paramètres : operand = opérande représentant un registre. * * * * Description : Fournit le registre Dalvik associé à l'opérande. * * * * Retour : Représentation interne du registre. * * * * Remarques : - * * * ******************************************************************************/ GArchRegister *g_register_operand_get_register(const GRegisterOperand *operand) { return operand->reg; } /****************************************************************************** * * * Paramètres : a = premier opérande à consulter. * * b = second opérande à consulter. * * * * Description : Compare un opérande avec un autre. * * * * Retour : Bilan de la comparaison. * * * * Remarques : - * * * ******************************************************************************/ static int g_register_operand_compare(const GRegisterOperand **a, const GRegisterOperand **b) { int result; /* Bilan à retourner */ result = g_arch_register_compare((const GArchRegister * const *)&(*a)->reg, (const GArchRegister * const *)&(*b)->reg); return result; } /****************************************************************************** * * * Paramètres : operand = opérande à traiter. * * line = ligne tampon où imprimer l'opérande donné. * * syntax = type de représentation demandée. * * * * Description : Traduit un opérande en version humainement lisible. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_register_operand_print(const GRegisterOperand *operand, GBufferLine *line, AsmSyntax syntax) { g_arch_register_print(operand->reg, line, syntax); } /****************************************************************************** * * * Paramètres : operand = opérande représentant un registre à mettre à jour. * * * * Description : Marque l'opérande comme étant écrit plutôt que consulté. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void g_register_operand_mark_as_written(GRegisterOperand *operand) { operand->is_written = true; } /****************************************************************************** * * * Paramètres : operand = opérande représentant un registre à consulter. * * * * Description : Indique le type d'accès réalisé sur l'opérande. * * * * Retour : Type d'accès : true en cas d'écriture, false sinon. * * * * Remarques : - * * * ******************************************************************************/ bool g_register_operand_is_written(const GRegisterOperand *operand) { return operand->is_written; }