diff options
Diffstat (limited to 'src/arch/dalvik/operand.c')
-rw-r--r-- | src/arch/dalvik/operand.c | 752 |
1 files changed, 0 insertions, 752 deletions
diff --git a/src/arch/dalvik/operand.c b/src/arch/dalvik/operand.c deleted file mode 100644 index e37a0bb..0000000 --- a/src/arch/dalvik/operand.c +++ /dev/null @@ -1,752 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * operand.c - aide à la création d'opérandes Dalvik - * - * Copyright (C) 2010-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 "operand.h" - - -#include <assert.h> -#include <malloc.h> -#include <stdarg.h> - - - -/* Liste de tous les types d'opérandes */ -typedef enum _DalvikOperandID -{ - DOI_INVALID, - - DOI_REGISTER_4, - DOI_REGISTER_8, - DOI_REGISTER_16, - - DOI_IMMEDIATE_4, - DOI_IMMEDIATE_8, - DOI_IMMEDIATE_16, - DOI_IMMEDIATE_32, - DOI_IMMEDIATE_64, - DOI_IMMEDIATE_H16, - - DOI_POOL_CONST, - DOI_POOL_CONST_WIDE, - - DOI_TARGET_8, - DOI_TARGET_16, - DOI_TARGET_32 - -} DalvikOperandID; - - -/* Crée un opérande visant une instruction Dalvik. */ -static GArchOperand *dalvik_build_target_operand(const GBinContent *, vmpa2t *, MemoryDataSize , SourceEndian, const vmpa2t *); - -/* Procède à la lecture d'opérandes pour une instruction. */ -static bool dalvik_read_basic_operands(GArchInstruction *, GDexFormat *, const GBinContent *, vmpa2t *, bool *, SourceEndian, DalvikOperandType, ...); - -/* Procède à la lecture d'opérandes pour une instruction. */ -static bool dalvik_read_fixed_operands(GArchInstruction *, GDexFormat *, const GBinContent *, vmpa2t *, bool *, SourceEndian, DalvikOperandType); - -/* Procède à la lecture d'opérandes pour une instruction. */ -static bool dalvik_read_variatic_operands(GArchInstruction *, GDexFormat *, const GBinContent *, vmpa2t *, bool *, SourceEndian, DalvikOperandType); - - - -/****************************************************************************** -* * -* Paramètres : content = flux de données à analyser. * -* pos = position courante dans ce flux. [OUT] * -* size = taille de l'opérande. * -* endian = ordre des bits dans la source. * -* base = adresse de référence pour le calcul. * -* * -* Description : Crée un opérande visant une instruction Dalvik. * -* * -* Retour : Opérande mis en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static GArchOperand *dalvik_build_target_operand(const GBinContent *content, vmpa2t *pos, MemoryDataSize size, SourceEndian endian, const vmpa2t *base) -{ - GArchOperand *result; /* Structure à retourner */ - phys_t offset; /* Emplacement de base */ - int8_t val8; /* Valeur sur 8 bits */ - int16_t val16; /* Valeur sur 16 bits */ - int32_t val32; /* Valeur sur 32 bits */ - bool test; /* Bilan de lecture */ - phys_t address; /* Adresse finale visée */ - - offset = get_phy_addr(base); - - switch (size) - { - case MDS_8_BITS_SIGNED: - test = g_binary_content_read_s8(content, pos, &val8); - address = offset + val8 * sizeof(uint16_t); - break; - case MDS_16_BITS_SIGNED: - test = g_binary_content_read_s16(content, pos, endian, &val16); - address = offset + val16 * sizeof(uint16_t); - break; - case MDS_32_BITS_SIGNED: - test = g_binary_content_read_s32(content, pos, endian, &val32); - address = offset + val32 * sizeof(uint16_t); - break; - default: - test = false; - break; - } - - if (!test) - return NULL; - - result = g_imm_operand_new_from_value(MDS_32_BITS, address); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : instr = instruction dont la définition est incomplète.[OUT]* -* format = format du fichier contenant le code. * -* content = flux de données à analyser. * -* pos = position courante dans ce flux. [OUT] * -* low = position éventuelle des 4 bits visés. [OUT] * -* endian = boutisme lié au binaire accompagnant. * -* model = type d'opérandes attendues. * -* ... = éventuels arguments complémentaires. * -* * -* Description : Procède à la lecture d'opérandes pour une instruction. * -* * -* Retour : Bilan de l'opération : true en cas de succès, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool dalvik_read_basic_operands(GArchInstruction *instr, GDexFormat *format, const GBinContent *content, vmpa2t *pos, bool *low, SourceEndian endian, DalvikOperandType model, ...) -{ - bool result; /* Bilan à retourner */ - DalvikOperandID *types; /* Liste des chargements */ - DalvikOperandID *iter; /* Boucle de parcours */ - GArchOperand *op; /* Opérande unique décodé */ - uint16_t value16; /* Valeur sur 16 bits */ - DalvikPoolType pool_type; /* Type de table à manipuler */ - va_list ap; /* Arguments complémentaires */ - const vmpa2t *base; /* Base pour les sauts de code */ - - result = true; - - /* Choix des opérandes à charger */ - - switch (model & ~DALVIK_OP_EXTRA_MASK) - { - case DALVIK_OPT_10T: - types = (DalvikOperandID []) { - DOI_TARGET_8, - DOI_INVALID - }; - break; - - case DALVIK_OPT_11N: - types = (DalvikOperandID []) { - DOI_REGISTER_4, - DOI_IMMEDIATE_4, - DOI_INVALID - }; - break; - - case DALVIK_OPT_11X: - types = (DalvikOperandID []) { - DOI_REGISTER_8, - DOI_INVALID - }; - break; - - case DALVIK_OPT_12X: - types = (DalvikOperandID []) { - DOI_REGISTER_4, - DOI_REGISTER_4, - DOI_INVALID - }; - break; - - case DALVIK_OPT_20T: - types = (DalvikOperandID []) { - DOI_TARGET_16, - DOI_INVALID - }; - break; - - case DALVIK_OPT_21C: - types = (DalvikOperandID []) { - DOI_REGISTER_8, - DOI_POOL_CONST, - DOI_INVALID - }; - break; - - case DALVIK_OPT_21H: - types = (DalvikOperandID []) { - DOI_REGISTER_8, - DOI_IMMEDIATE_H16, - DOI_INVALID - }; - break; - - case DALVIK_OPT_21S: - types = (DalvikOperandID []) { - DOI_REGISTER_8, - DOI_IMMEDIATE_16, - DOI_INVALID - }; - break; - - case DALVIK_OPT_21T: - types = (DalvikOperandID []) { - DOI_REGISTER_8, - DOI_TARGET_16, - DOI_INVALID - }; - break; - - case DALVIK_OPT_22B: - types = (DalvikOperandID []) { - DOI_REGISTER_8, - DOI_REGISTER_8, - DOI_IMMEDIATE_8, - DOI_INVALID - }; - break; - - case DALVIK_OPT_22C: - types = (DalvikOperandID []) { - DOI_REGISTER_4, - DOI_REGISTER_4, - DOI_POOL_CONST, - DOI_INVALID - }; - break; - - case DALVIK_OPT_22S: - types = (DalvikOperandID []) { - DOI_REGISTER_4, - DOI_REGISTER_4, - DOI_IMMEDIATE_16, - DOI_INVALID - }; - break; - - case DALVIK_OPT_22T: - types = (DalvikOperandID []) { - DOI_REGISTER_4, - DOI_REGISTER_4, - DOI_TARGET_16, - DOI_INVALID - }; - break; - - case DALVIK_OPT_22X: - types = (DalvikOperandID []) { - DOI_REGISTER_8, - DOI_REGISTER_16, - DOI_INVALID - }; - break; - - case DALVIK_OPT_23X: - types = (DalvikOperandID []) { - DOI_REGISTER_8, - DOI_REGISTER_8, - DOI_REGISTER_8, - DOI_INVALID - }; - break; - - case DALVIK_OPT_30T: - types = (DalvikOperandID []) { - DOI_TARGET_32, - DOI_INVALID - }; - break; - - case DALVIK_OPT_31C: - types = (DalvikOperandID []) { - DOI_REGISTER_8, - DOI_POOL_CONST_WIDE, - DOI_INVALID - }; - break; - - case DALVIK_OPT_31I: - types = (DalvikOperandID []) { - DOI_REGISTER_8, - DOI_IMMEDIATE_32, - DOI_INVALID - }; - break; - - case DALVIK_OPT_31T: - types = (DalvikOperandID []) { - DOI_REGISTER_8, - DOI_TARGET_32, - DOI_INVALID - }; - break; - - case DALVIK_OPT_32X: - types = (DalvikOperandID []) { - DOI_REGISTER_16, - DOI_REGISTER_16, - DOI_INVALID - }; - break; - - case DALVIK_OPT_51L: - types = (DalvikOperandID []) { - DOI_REGISTER_8, - DOI_IMMEDIATE_64, - DOI_INVALID - }; - break; - - default: - types = (DalvikOperandID []) { - DOI_INVALID - }; - break; - - } - - /* Chargement des opérandes */ - - for (iter = types; *iter != G_TYPE_INVALID && result; iter++) - { - op = NULL; /* Nul de GCC */ - - switch (*iter) - { - case DOI_REGISTER_4: - op = g_dalvik_register_operand_new(content, pos, low, MDS_4_BITS, endian); - break; - - case DOI_REGISTER_8: - op = g_dalvik_register_operand_new(content, pos, NULL, MDS_8_BITS, endian); - break; - - case DOI_REGISTER_16: - op = g_dalvik_register_operand_new(content, pos, NULL, MDS_16_BITS, endian); - break; - - case DOI_IMMEDIATE_4: - op = _g_imm_operand_new_from_data(MDS_4_BITS, content, pos, low, endian); - break; - - case DOI_IMMEDIATE_8: - op = g_imm_operand_new_from_data(MDS_8_BITS, content, pos, endian); - break; - - case DOI_IMMEDIATE_16: - op = g_imm_operand_new_from_data(MDS_16_BITS, content, pos, endian); - break; - - case DOI_IMMEDIATE_32: - op = g_imm_operand_new_from_data(MDS_32_BITS, content, pos, endian); - break; - - case DOI_IMMEDIATE_64: - op = g_imm_operand_new_from_data(MDS_64_BITS, content, pos, endian); - break; - - case DOI_IMMEDIATE_H16: - result = g_binary_content_read_u16(content, pos, endian, &value16); - if (result) - op = g_imm_operand_new_from_value(MDS_32_BITS_SIGNED, ((uint32_t)value16) << 16); - break; - - case DOI_POOL_CONST: - pool_type = DALVIK_OP_GET_POOL(model); - op = g_dalvik_pool_operand_new(format, pool_type, content, pos, MDS_16_BITS, endian); - break; - - case DOI_POOL_CONST_WIDE: - pool_type = DALVIK_OP_GET_POOL(model); - op = g_dalvik_pool_operand_new(format, pool_type, content, pos, MDS_32_BITS, endian); - break; - - case DOI_TARGET_8: - va_start(ap, model); - base = va_arg(ap, const vmpa2t *); - op = dalvik_build_target_operand(content, pos, MDS_8_BITS_SIGNED, endian, base); - va_end(ap); - break; - - case DOI_TARGET_16: - va_start(ap, model); - base = va_arg(ap, const vmpa2t *); - op = dalvik_build_target_operand(content, pos, MDS_16_BITS_SIGNED, endian, base); - va_end(ap); - break; - - case DOI_TARGET_32: - va_start(ap, model); - base = va_arg(ap, const vmpa2t *); - op = dalvik_build_target_operand(content, pos, MDS_32_BITS_SIGNED, endian, base); - va_end(ap); - break; - - default: - op = NULL; - break; - - } - - if (op == NULL) result = false; - else g_arch_instruction_attach_extra_operand(instr, op); - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : instr = instruction dont la définition est incomplète.[OUT]* -* format = format du fichier contenant le code. * -* content = flux de données à analyser. * -* pos = position courante dans ce flux. [OUT] * -* low = position éventuelle des 4 bits visés. [OUT] * -* endian = boutisme lié au binaire accompagnant. * -* model = type d'opérandes attendues. * -* * -* Description : Procède à la lecture d'opérandes pour une instruction. * -* * -* Retour : Bilan de l'opération : true en cas de succès, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool dalvik_read_fixed_operands(GArchInstruction *instr, GDexFormat *format, const GBinContent *content, vmpa2t *pos, bool *low, SourceEndian endian, DalvikOperandType model) -{ - GArchOperand *opg; /* Opérande G décodé */ - uint8_t a; /* Nbre. de registres utilisés */ - GArchOperand *target; /* Opérande visant la table #1 */ - GArchOperand *args; /* Liste des opérandes */ - uint8_t i; /* Boucle de parcours */ - GArchOperand *op; /* Opérande unique décodé */ - - opg = g_dalvik_register_operand_new(content, pos, low, MDS_4_BITS, endian); - - if (!g_binary_content_read_u4(content, pos, low, &a)) - goto err_va; - - if (a == 5 && opg == NULL) - goto err_no_opg; - - target = g_dalvik_pool_operand_new(format, DALVIK_OP_GET_POOL(model), content, pos, MDS_16_BITS, endian); - if (target == NULL) goto err_target; - - /* Mise en place des arguments */ - - args = g_dalvik_args_operand_new(); - - for (i = 0; i < MIN(a, 4); i++) - { - op = g_dalvik_register_operand_new(content, pos, low, MDS_4_BITS, endian); - if (op == NULL) goto err_registers; - - g_dalvik_args_operand_add(G_DALVIK_ARGS_OPERAND(args), op); - - } - - /* Consommation pleine et entière */ - - for (; i < 4; i++) - if (!g_binary_content_read_u4(content, pos, low, (uint8_t []) { 0 })) - goto err_padding; - - /* Rajout des éléments finaux déjà chargés */ - - if (a == 5) - g_dalvik_args_operand_add(G_DALVIK_ARGS_OPERAND(args), opg); - - else - { - if (opg != NULL) - g_object_unref(G_OBJECT(opg)); - } - - g_arch_instruction_attach_extra_operand(instr, args); - - /* Rajout de la cible */ - - g_arch_instruction_attach_extra_operand(instr, target); - - return true; - - err_padding: - - err_registers: - - g_object_unref(G_OBJECT(target)); - - err_target: - - if (opg != NULL) - g_object_unref(G_OBJECT(opg)); - - err_no_opg: - err_va: - - return false; - -} - - -/****************************************************************************** -* * -* Paramètres : instr = instruction dont la définition est incomplète.[OUT]* -* format = format du fichier contenant le code. * -* content = flux de données à analyser. * -* pos = position courante dans ce flux. [OUT] * -* low = position éventuelle des 4 bits visés. [OUT] * -* endian = boutisme lié au binaire accompagnant. * -* model = type d'opérandes attendues. * -* * -* Description : Procède à la lecture d'opérandes pour une instruction. * -* * -* Retour : Bilan de l'opération : true en cas de succès, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool dalvik_read_variatic_operands(GArchInstruction *instr, GDexFormat *format, const GBinContent *content, vmpa2t *pos, bool *low, SourceEndian endian, DalvikOperandType model) -{ - uint8_t a; /* Nbre. de registres utilisés */ - uint16_t c; /* Indice de registre */ - GArchOperand *target; /* Opérande visant la table */ - GArchOperand *args; /* Liste des opérandes */ - uint8_t i; /* Boucle de parcours */ - GArchOperand *op; /* Opérande unique décodé */ - - if (!g_binary_content_read_u8(content, pos, &a)) - return false; - - target = g_dalvik_pool_operand_new(format, DALVIK_OP_GET_POOL(model), content, pos, MDS_16_BITS, endian); - if (target == NULL) return false; - - if (!g_binary_content_read_u16(content, pos, endian, &c)) - return false; - - /* Mise en place des arguments */ - - args = g_dalvik_args_operand_new(); - - for (i = 0; i < a; i++) - { - op = g_dalvik_register_operand_new_from_existing(g_dalvik_register_new(c + i)); - if (op == NULL) goto drvo_registers; - - g_dalvik_args_operand_add(G_DALVIK_ARGS_OPERAND(args), op); - - } - - g_arch_instruction_attach_extra_operand(instr, args); - - /* Rajout de la cible */ - - g_arch_instruction_attach_extra_operand(instr, target); - - return true; - - drvo_registers: - - g_object_unref(G_OBJECT(target)); - - return false; - -} - - -/****************************************************************************** -* * -* Paramètres : instr = instruction dont la définition est incomplète.[OUT]* -* format = format du fichier contenant le code. * -* content = flux de données à analyser. * -* pos = position courante dans ce flux. [OUT] * -* endian = boutisme lié au binaire accompagnant. * -* model = type d'opérandes attendues. * -* * -* Description : Procède à la lecture d'opérandes pour une instruction. * -* * -* Retour : Bilan de l'opération : true en cas de succès, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool dalvik_read_operands(GArchInstruction *instr, GExeFormat *format, const GBinContent *content, vmpa2t *pos, SourceEndian endian, DalvikOperandType model) -{ - bool result; /* Bilan à retourner */ - GDexFormat *dformat; /* Autre version du format */ - bool low; /* Partie d'octets à lire */ -#ifndef NDEBUG - vmpa2t old; /* Position avant traitements */ -#endif - vmpa2t base; /* Base pour les sauts de code */ - vmpa2t *extra; /* Information complémentaire */ -#ifndef NDEBUG - phys_t expected; /* Consommation attendue */ - phys_t consumed; /* Consommation réelle */ -#endif - - result = true; - - dformat = G_DEX_FORMAT(format); - - low = true; - -#ifndef NDEBUG - - copy_vmpa(&old, pos); - -#endif - - /* Récupération de la base ? */ - - if (DALVIK_OP_GET_MNEMONIC(model) == 'T') - { - extra = &base; - - copy_vmpa(extra, pos); - deminish_vmpa(extra, 1); - - } - else extra = NULL; - - /* Bourrage : ØØ|op ? */ - - switch (model & ~DALVIK_OP_EXTRA_MASK) - { - case DALVIK_OPT_10X: - case DALVIK_OPT_20T: - case DALVIK_OPT_30T: - case DALVIK_OPT_32X: - result = g_binary_content_seek(content, pos, 1); - break; - - default: - break; - - } - - /* Décodage... */ - - switch (model & ~DALVIK_OP_EXTRA_MASK) - { - case DALVIK_OPT_10T: - case DALVIK_OPT_11N: - case DALVIK_OPT_11X: - case DALVIK_OPT_12X: - case DALVIK_OPT_20T: - case DALVIK_OPT_21C: - case DALVIK_OPT_21H: - case DALVIK_OPT_21S: - case DALVIK_OPT_21T: - case DALVIK_OPT_22B: - case DALVIK_OPT_22C: - case DALVIK_OPT_22S: - case DALVIK_OPT_22T: - case DALVIK_OPT_22X: - case DALVIK_OPT_23X: - case DALVIK_OPT_30T: - case DALVIK_OPT_31C: - case DALVIK_OPT_31I: - case DALVIK_OPT_31T: - case DALVIK_OPT_32X: - case DALVIK_OPT_51L: - result = dalvik_read_basic_operands(instr, dformat, content, pos, &low, endian, model, extra); - break; - - case DALVIK_OPT_35C: - result = dalvik_read_fixed_operands(instr, dformat, content, pos, &low, endian, model); - break; - - case DALVIK_OPT_3RC: - case DALVIK_OPT_3RMS: - case DALVIK_OPT_3RFS: - result = dalvik_read_variatic_operands(instr, dformat, content, pos, &low, endian, model); - break; - - default: - break; - - } - -#ifndef NDEBUG - - /* Vérification d'implémentation */ - - if (result) - { - expected = DALVIK_OP_GET_LEN(model) * 2; - consumed = 1 + compute_vmpa_diff(&old, pos); - - assert(consumed == expected); - - } - -#endif - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : instr = instruction dont la définition est incomplète. * -* * -* Description : Procède à la lecture d'opérandes pour une instruction. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void dalvik_mark_first_operand_as_written(GArchInstruction *instr) -{ - GArchOperand *operand; /* Première opérande visé */ - - operand = g_arch_instruction_get_operand(instr, 0); - - g_dalvik_register_operand_mark_as_written(G_DALVIK_REGISTER_OPERAND(operand)); - -} |