diff options
Diffstat (limited to 'src/arch/arm/v456/instruction.c')
-rw-r--r-- | src/arch/arm/v456/instruction.c | 683 |
1 files changed, 0 insertions, 683 deletions
diff --git a/src/arch/arm/v456/instruction.c b/src/arch/arm/v456/instruction.c deleted file mode 100644 index 4fc78a2..0000000 --- a/src/arch/arm/v456/instruction.c +++ /dev/null @@ -1,683 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * instruction.c - gestion des instructions ARM v4/v5/v6 - * - * Copyright (C) 2013 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 <http://www.gnu.org/licenses/>. - */ - - -#include "instruction.h" - - -#include "encoding.h" - - -#include "../instruction-int.h" - - - -//////// -#include <malloc.h> -///////// - - - -typedef unsigned char bin_t; - -typedef unsigned int arch_version_t; - - - -/* -------------------------- INSTRUCTIONS POUR ARM v4/5/6 -------------------------- */ - - -/* Définition d'une instruction d'architecture ARM v4/5/6 (instance) */ -struct _GArmV456Instruction -{ - GArchInstruction parent; /* A laisser en premier */ - - ArmV456Opcodes type; /* Type d'instruction en place */ - -}; - -/* Définition d'une instruction d'architecture ARM v4/5/6 (classe) */ -struct _GArmV456InstructionClass -{ - GArchInstructionClass parent; /* A laisser en premier */ - -}; - - -/* Initialise la classe des instructions pour ARM v4/5/6. */ -static void g_armv456_instruction_class_init(GArmV456InstructionClass *); - -/* Initialise une instance d'opérande d'architecture ARM v4/5/6. */ -static void g_armv456_instruction_init(GArmV456Instruction *); - -/* Traduit une instruction en version humainement lisible. */ -static const char *g_armv456_get_instruction_text(const GArmV456Instruction *, const GExeFormat *, AsmSyntax); - - - - -/* --------------------- AIDE A LA MISE EN PLACE D'INSTRUCTIONS --------------------- */ - - -/* Répertoire de toutes les instructions ARM v4/5/6 */ -typedef struct _arm_v456_instruction -{ - bin_t opcode; /* Opcode de l'instruction */ - const char *keyword; /* Mot clef de la commande */ - - arch_version_t version; /* Version de l'architecture */ - - //decomp_instr_fc decomp; /* Procédure de décompilation */ - -} arm_v456_instruction; - - -/* Liste de toutes les instructions */ -static arm_v456_instruction _instructions[AOP_COUNT] = { - - [AOP_AND] = { 0x00, "and", ARM_VERSION_ALL_456 }, - [AOP_EOR] = { 0x01, "eor", ARM_VERSION_ALL_456 }, - [AOP_SUB] = { 0x02, "sub", ARM_VERSION_ALL_456 }, - [AOP_RSB] = { 0x03, "rsb", ARM_VERSION_ALL_456 }, - [AOP_ADD] = { 0x04, "add", ARM_VERSION_ALL_456 }, - [AOP_ADC] = { 0x05, "adc", ARM_VERSION_ALL_456 }, - [AOP_SBC] = { 0x06, "sbc", ARM_VERSION_ALL_456 }, - [AOP_RSC] = { 0x07, "rsc", ARM_VERSION_ALL_456 }, - [AOP_TST] = { 0x08, "tst", ARM_VERSION_ALL_456 }, - [AOP_TEQ] = { 0x09, "teq", ARM_VERSION_ALL_456 }, - [AOP_CMP] = { 0x0a, "cmp", ARM_VERSION_ALL_456 }, - [AOP_CMN] = { 0x0b, "cmn", ARM_VERSION_ALL_456 }, - [AOP_ORR] = { 0x0c, "orr", ARM_VERSION_ALL_456 }, - [AOP_MOV] = { 0x0d, "mov", ARM_VERSION_ALL_456 }, - [AOP_BIC] = { 0x0e, "bic", ARM_VERSION_ALL_456 }, - [AOP_MVN] = { 0x0f, "mov", ARM_VERSION_ALL_456 }, - - [AOP_LDR] = { 0xff, "ldr", ARM_VERSION_ALL_456 }, - [AOP_STR] = { 0xff, "ldr", ARM_VERSION_ALL_456 } - - - -}; - - -/* Constitution d'un groupe */ -static arm_v456_instruction *_data_processing_instrs[17] = { - - &_instructions[AOP_AND], &_instructions[AOP_EOR], &_instructions[AOP_SUB], - &_instructions[AOP_RSB], &_instructions[AOP_ADD], &_instructions[AOP_ADC], - &_instructions[AOP_SBC], &_instructions[AOP_RSC], &_instructions[AOP_TST], - &_instructions[AOP_TEQ], &_instructions[AOP_CMP], &_instructions[AOP_CMN], - &_instructions[AOP_ORR], &_instructions[AOP_MOV], &_instructions[AOP_BIC], - &_instructions[AOP_MVN], NULL - -}; - - - - -/* ---------------------------------------------------------------------------------- */ -/* INSTRUCTIONS POUR ARM v4/5/6 */ -/* ---------------------------------------------------------------------------------- */ - - -/* Indique le type défini pour une instruction d'architecture Dalvik. */ -G_DEFINE_TYPE(GArmV456Instruction, g_armv456_instruction, G_TYPE_ARCH_INSTRUCTION); - - - -/****************************************************************************** -* * -* Paramètres : klass = classe à initialiser. * -* * -* Description : Initialise la classe des instructions pour Dalvik. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_armv456_instruction_class_init(GArmV456InstructionClass *klass) -{ - -} - - -/****************************************************************************** -* * -* Paramètres : instr = instance à initialiser. * -* * -* Description : Initialise une instance d'instruction d'architecture Dalvik. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_armv456_instruction_init(GArmV456Instruction *instr) -{ - GArchInstruction *parent; /* Instance parente */ - - parent = G_ARCH_INSTRUCTION(instr); - - //parent->get_text = (get_instruction_text_fc)g_armv456_get_instruction_text; - - /* - parent->get_rw_regs = (get_instruction_rw_regs_fc)g_armv456_instruction_get_rw_registers; - parent->get_text = (get_instruction_text_fc)dalvik_get_instruction_text; - parent->get_link = (get_instruction_link_fc)dalvik_get_instruction_link; - parent->is_return = (is_instruction_return_fc)dalvik_instruction_is_return; - parent->decomp = (decomp_instr_fc)dalvik_instruction_decompile; - */ - -} - - -/****************************************************************************** -* * -* Paramètres : type = type d'instruction à représenter. * -* * -* Description : Crée une instruction pour l'architecture Dalvik. * -* * -* Retour : Architecture mise en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchInstruction *g_armv456_instruction_new(ArmV456Opcodes type) -{ - GArchInstruction *result; /* Structure à retourner */ - - result = g_object_new(G_TYPE_ARMV456_INSTRUCTION, NULL); - - G_ARMV456_INSTRUCTION(result)->type = type; - - return result; - -} - - - -/****************************************************************************** -* * -* Paramètres : instr = instruction à traiter. * -* format = format du binaire manipulé. * -* syntax = type de représentation demandée. * -* * -* Description : Traduit une instruction en version humainement lisible. * -* * -* Retour : Chaîne de caractères à libérer de la mémoire. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static const char *g_armv456_get_instruction_text(const GArmV456Instruction *instr, const GExeFormat *format, AsmSyntax syntax) -{ - return _instructions[instr->type].keyword; - -} - - -#include "addressing.h" - - -GArchInstruction *try_to_decode_arm_v456_instr(bin_t *data) -{ - GArchInstruction *result; /* Instruction à retourner */ - uint32_t *instr; - - ArmV456InstrSets i; /* Boucle de parcours */ - - result = NULL; - - instr = (uint32_t *)data; - - //printf("instr = 0x%x\n", *instr); - - - - for (i = 0; i < ARM_V456_ISET_COUNT; i++) - if (IS_ENCODING_SET(*instr, _arm_v456_encoding_sets[i])) - break; - - switch (i) - { - case ARM_V456_ISET_COUNT: - printf("failed !\n"); - break; - - - case ARM_V456_LD_ST_IMM_OFFSET: - //printf("LOAD !! %s\n", *instr & ARM_V456_BIT_L ? "load" : "store"); - - - - result = g_armv456_instruction_new(*instr & ARM_V456_BIT_L ? AOP_LDR : AOP_STR); - - - /*bool */build_v456_operands_with_load_immediate_offset(result, *instr, NULL); - - - break; - - - default: - //printf("got it !\n"); - break; - - } - - - - - return result; - -} - - - - -#if 0 - -#include "instruction-int.h" -#include "decomp/translate.h" -#include "operands/register.h" -#include "operands/target.h" -#include "../instruction-int.h" -#include "../register-int.h" - - - -/* Initialise la classe des instructions pour Dalvik. */ -static void g_dalvik_instruction_class_init(GDalvikInstructionClass *); - -/* Initialise une instance d'opérande d'architecture Dalvik. */ -static void g_dalvik_instruction_init(GDalvikInstruction *); - -/* Liste les registres lus et écrits par l'instruction. */ -static void g_dalvik_instruction_get_rw_registers(const GDalvikInstruction *, GArchRegister ***, size_t *, GArchRegister ***, size_t *); - - - -/* --------------------- AIDE A LA MISE EN PLACE D'INSTRUCTIONS --------------------- */ - - -/* Répertoire de toutes les instructions Dalvik */ -typedef struct _dalvik_instruction -{ - bin_t opcode; /* Opcode de l'instruction */ - - const char *keyword; /* Mot clef de la commande */ - - decomp_instr_fc decomp; /* Procédure de décompilation */ - -} dalvik_instruction; - - -static dalvik_instruction _instructions[DOP_COUNT] = { - -}; - - -/* Traduit une instruction en version humainement lisible. */ -static const char *dalvik_get_instruction_text(const GDalvikInstruction *, const GExeFormat *, AsmSyntax); - -/* Informe sur une éventuelle référence à une autre instruction. */ -static InstructionLinkType dalvik_get_instruction_link(const GDalvikInstruction *, vmpa_t *); - -/* Indique si l'instruction correspond à un retour de fonction. */ -static bool dalvik_instruction_is_return(const GDalvikInstruction *); - -/* Décompile une instruction de la machine virtuelle Dalvik. */ -GDecInstruction *dalvik_instruction_decompile(const GDalvikInstruction *, GDecContext *); - - - -/* Indique le type défini pour une instruction d'architecture Dalvik. */ -G_DEFINE_TYPE(GDalvikInstruction, g_dalvik_instruction, G_TYPE_ARCH_INSTRUCTION); - - - -/****************************************************************************** -* * -* Paramètres : klass = classe à initialiser. * -* * -* Description : Initialise la classe des instructions pour Dalvik. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_dalvik_instruction_class_init(GDalvikInstructionClass *klass) -{ - -} - - -/****************************************************************************** -* * -* Paramètres : instr = instance à initialiser. * -* * -* Description : Initialise une instance d'instruction d'architecture Dalvik. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_dalvik_instruction_init(GDalvikInstruction *instr) -{ - GArchInstruction *parent; /* Instance parente */ - - parent = G_ARCH_INSTRUCTION(instr); - - parent->get_rw_regs = (get_instruction_rw_regs_fc)g_dalvik_instruction_get_rw_registers; - parent->get_text = (get_instruction_text_fc)dalvik_get_instruction_text; - parent->get_link = (get_instruction_link_fc)dalvik_get_instruction_link; - //parent->is_return = (is_instruction_return_fc)dalvik_instruction_is_return; - parent->decomp = (decomp_instr_fc)dalvik_instruction_decompile; - -} - - -/****************************************************************************** -* * -* Paramètres : type = type d'instruction à représenter. * -* * -* Description : Crée une instruction pour l'architecture Dalvik. * -* * -* Retour : Architecture mise en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchInstruction *g_dalvik_instruction_new(DalvikOpcodes type) -{ - GArchInstruction *result; /* Structure à retourner */ - - result = g_object_new(G_TYPE_DALVIK_INSTRUCTION, NULL); - - G_DALVIK_INSTRUCTION(result)->type = type; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : instr = instruction Dalvik à consulter. * -* * -* Description : Indique l'opcode associé à une instruction Dalvik. * -* * -* Retour : Identifiant de l'instruction en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -DalvikOpcodes g_dalvik_instruction_get_opcode(const GDalvikInstruction *instr) -{ - return instr->type; - -} - - -/****************************************************************************** -* * -* Paramètres : instr = instruction à consulter. * -* rregs = liste des rgistres lus. [OUT] * -* rcount = nombre de registres lus. [OUT] * -* wregs = liste des rgistres écrits. [OUT] * -* wcount = nombre de registres écrits. [OUT] * -* * -* Description : Liste les registres lus et écrits par l'instruction. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_dalvik_instruction_get_rw_registers(const GDalvikInstruction *instr, GArchRegister ***rregs, size_t *rcount, GArchRegister ***wregs, size_t *wcount) -{ - GArchInstruction *base; /* Version basique à manipuler */ - size_t i; /* Boucle de parcours */ - GArchOperand *operand; /* Operande à analyser */ - GDalvikRegister *reg; /* Registre concerné */ - - base = G_ARCH_INSTRUCTION(instr); - - for (i = 0; i < base->operands_count; i++) - { - operand = base->operands[i]; - - if (!G_IS_DALVIK_REGISTER_OPERAND(operand)) - continue; - - reg = g_dalvik_register_operand_get(G_DALVIK_REGISTER_OPERAND(operand)); - - if (g_dalvik_register_operand_is_written(G_DALVIK_REGISTER_OPERAND(operand))) - { - (*wregs) = (GArchRegister **)realloc(*wregs, ++(*wcount) * sizeof(GArchRegister *)); - (*wregs)[(*wcount) - 1] = G_ARCH_REGISTER(reg); - } - else - { - (*rregs) = (GArchRegister **)realloc(*rregs, ++(*rcount) * sizeof(GArchRegister *)); - (*rregs)[(*rcount) - 1] = G_ARCH_REGISTER(reg); - } - - } - -} - - - -/* ---------------------------------------------------------------------------------- */ -/* AIDE A LA MISE EN PLACE D'INSTRUCTIONS */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : data = flux de données à analyser. * -* pos = position courante dans ce flux. * -* end = limite des données à analyser. * -* * -* Description : Recherche l'identifiant de la prochaine instruction. * -* * -* Retour : Identifiant de la prochaine instruction à tenter de charger. * -* * -* Remarques : - * -* * -******************************************************************************/ - -DalvikOpcodes dalvik_guess_next_instruction(const bin_t *data, off_t pos, off_t end) -{ - DalvikOpcodes result; /* Identifiant à retourner */ - - result = (DalvikOpcodes)data[pos]; - - /* Si l'instruction est marquée comme non utilisée... */ - if (_instructions[result].keyword == NULL) - result = DOP_COUNT; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : instr = instruction à traiter. * -* format = format du binaire manipulé. * -* syntax = type de représentation demandée. * -* * -* Description : Traduit une instruction en version humainement lisible. * -* * -* Retour : Chaîne de caractères à libérer de la mémoire. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static const char *dalvik_get_instruction_text(const GDalvikInstruction *instr, const GExeFormat *format, AsmSyntax syntax) -{ - return _instructions[instr->type].keyword; - -} - - -/****************************************************************************** -* * -* Paramètres : instr = instruction à consulter. * -* addr = eventuelle adresse associée à faire connaître. [OUT] * -* * -* Description : Informe sur une éventuelle référence à une autre instruction.* -* * -* Retour : Type de lien trouvé ou ILT_NONE si aucun. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static InstructionLinkType dalvik_get_instruction_link(const GDalvikInstruction *instr, vmpa_t *addr) -{ - InstructionLinkType result; /* Type de lien à retourner */ - GArchOperand *operand; /* Opérande à manipuler */ - const GImmOperand *imm; /* Valeur immédiate */ - - switch (instr->type) - { - case DOP_GOTO: - case DOP_GOTO_16: - case DOP_GOTO_32: - - operand = g_arch_instruction_get_operand(G_ARCH_INSTRUCTION(instr), 0); - imm = g_dalvik_target_operand_get_value(G_DALVIK_TARGET_OPERAND(operand)); - - if (g_imm_operand_to_vmpa_t(imm, addr)) result = ILT_JUMP; - else result = ILT_NONE; - - break; - - case DOP_IF_EQ: - case DOP_IF_NE: - case DOP_IF_LT: - case DOP_IF_GE: - case DOP_IF_GT: - case DOP_IF_LE: - - operand = g_arch_instruction_get_operand(G_ARCH_INSTRUCTION(instr), 2); - imm = g_dalvik_target_operand_get_value(G_DALVIK_TARGET_OPERAND(operand)); - - if (g_imm_operand_to_vmpa_t(imm, addr)) result = ILT_JUMP_IF_TRUE; - else result = ILT_NONE; - - break; - - case DOP_IF_EQZ: - case DOP_IF_NEZ: - case DOP_IF_LTZ: - case DOP_IF_GEZ: - case DOP_IF_GTZ: - case DOP_IF_LEZ: - - operand = g_arch_instruction_get_operand(G_ARCH_INSTRUCTION(instr), 1); - imm = g_dalvik_target_operand_get_value(G_DALVIK_TARGET_OPERAND(operand)); - - if (g_imm_operand_to_vmpa_t(imm, addr)) result = ILT_JUMP_IF_TRUE; - else result = ILT_NONE; - - break; - - default: - result = ILT_NONE; - break; - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : instr = instruction à consulter. * -* * -* Description : Indique si l'instruction correspond à un retour de fonction. * -* * -* Retour : true si l'instruction est un 'return' quelconque ou false. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool dalvik_instruction_is_return(const GDalvikInstruction *instr) -{ - return (instr->type == DOP_RETURN_VOID - || instr->type == DOP_RETURN - || instr->type == DOP_RETURN_WIDE - || instr->type == DOP_RETURN_OBJECT); - -} - - -/****************************************************************************** -* * -* Paramètres : instr = instruction d'origine à convertir. * -* ctx = contexte de la phase de décompilation. * -* * -* Description : Décompile une instruction de la machine virtuelle Dalvik. * -* * -* Retour : Instruction mise en place ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GDecInstruction *dalvik_instruction_decompile(const GDalvikInstruction *instr, GDecContext *ctx) -{ - GDecInstruction *result; /* Instruction à retourner */ - - if (_instructions[instr->type].decomp != NULL) - result = _instructions[instr->type].decomp(G_ARCH_INSTRUCTION(instr), ctx); - - else - result = NULL; - - return result; - -} - - - -#endif |