diff options
Diffstat (limited to 'plugins/readdex/code.c')
-rw-r--r-- | plugins/readdex/code.c | 496 |
1 files changed, 496 insertions, 0 deletions
diff --git a/plugins/readdex/code.c b/plugins/readdex/code.c new file mode 100644 index 0000000..971117e --- /dev/null +++ b/plugins/readdex/code.c @@ -0,0 +1,496 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * code.c - annotation des éléments de code Dalvik + * + * 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 <http://www.gnu.org/licenses/>. + */ + + +#include "code.h" + + +#include <assert.h> +#include <malloc.h> +#include <stdio.h> + + +#include <i18n.h> +#include <arch/raw.h> +#include <format/symbol.h> +#include <format/dex/dex_def.h> + + + +/* Commente les définitions d'une protection contre exceptions. */ +static bool annotate_dex_try_item(const GDexFormat *, vmpa2t *, const vmpa2t *); + +/*Commente les définitions des listes de gestion d'exceptions. */ +static bool annotate_dex_encoded_catch_handler_list(const GDexFormat *, vmpa2t *); + +/* Commente les définitions d'une prise en compte d'exceptions. */ +static bool annotate_dex_encoded_catch_handler(const GDexFormat *, vmpa2t *); + +/* Commente les définitions des gestions d'exceptions par type. */ +static bool annotate_dex_encoded_type_addr_pair(const GDexFormat *, vmpa2t *); + + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* * +* Description : Commente les définitions d'un corps de méthode. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool annotate_dex_code_item(const GDexFormat *format, uleb128_t offset) +{ + bool result; /* Bilan à retourner */ + GBinContent *content; /* Contenu binaire à lire */ + SourceEndian endian; /* Boutisme utilisé */ + vmpa2t pos; /* Tête de lecture des symboles*/ + vmpa2t start; /* Localisation des symboles */ + GArchInstruction *instr; /* Instruction décodée */ + GArchOperand *operand; /* Opérande à venir modifier */ + GDbComment *comment; /* Définition de commentaire */ + GBinSymbol *symbol; /* Symbole à intégrer */ + char *text; /* Texte constant à insérer */ + uint16_t tries_size; /* Nombre de gestionnaires */ + uint32_t insns_size; /* Nombre d'instructions */ + vmpa2t handlers; /* Base des gestionnaires */ + uint16_t i; /* Boucle de parcours */ + + content = g_binary_format_get_content(G_BIN_FORMAT(format)); + + endian = SRE_LITTLE;//g_dex_format_get_endianness(format); + + if (!g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), offset, &pos)) + return false; + + /* registers_size */ + + copy_vmpa(&start, &pos); + instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, &pos, endian); + + SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); + + asprintf(&text, _("Number of registers used by this code")); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, text); + + free(text); + + /* ins_size */ + + copy_vmpa(&start, &pos); + instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, &pos, endian); + + SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); + + asprintf(&text, _("Number of words of incoming arguments to the method that this code is for")); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, text); + + free(text); + + /* outs_size */ + + copy_vmpa(&start, &pos); + instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, &pos, endian); + + SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); + + asprintf(&text, _("Number of words of outgoing argument space required by this code for method invocation")); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, text); + + free(text); + + /* tries_size */ + + copy_vmpa(&start, &pos); + instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, &pos, endian); + + SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); + + asprintf(&text, _("Number of try_items for this instance")); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, text); + + free(text); + + g_imm_operand_get_value(G_IMM_OPERAND(operand), MDS_16_BITS, &tries_size); + + /* debug_info_off */ + + copy_vmpa(&start, &pos); + instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian); + + SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX); + + asprintf(&text, _("Offset to the debug info sequence for this code")); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, text); + + free(text); + + /* insns_size */ + + copy_vmpa(&start, &pos); + instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian); + + SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); + + asprintf(&text, _("Size of the instructions list, in 16-bit code units")); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, text); + + free(text); + + /* insns */ + + g_imm_operand_get_value(G_IMM_OPERAND(operand), MDS_32_BITS, &insns_size); + + advance_vmpa(&pos, insns_size * 2); + + /* padding */ + + if (insns_size % 2 != 0) + { + copy_vmpa(&start, &pos); + instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, &pos, endian); + + SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX); + + asprintf(&text, _("Pading")); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, text); + + free(text); + + } + + /* tries */ + + copy_vmpa(&handlers, &pos); + advance_vmpa(&handlers, tries_size * (4 + 2 + 2)); + + result = true; + + for (i = 0; i < tries_size && result; i++) + result = annotate_dex_try_item(format, &pos, &handlers); + + /* Nettoyage final */ + + g_object_unref(G_OBJECT(content)); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* pos = tête de lecture pour les symboles. * +* handlers = position de départ pour les gestionnaires. * +* * +* Description : Commente les définitions d'une protection contre exceptions. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool annotate_dex_try_item(const GDexFormat *format, vmpa2t *pos, const vmpa2t *handlers) +{ + bool result; /* Bilan à retourner */ + GBinContent *content; /* Contenu binaire à lire */ + SourceEndian endian; /* Boutisme utilisé */ + vmpa2t start; /* Localisation des symboles */ + GArchInstruction *instr; /* Instruction décodée */ + GArchOperand *operand; /* Opérande à venir modifier */ + GDbComment *comment; /* Définition de commentaire */ + GBinSymbol *symbol; /* Symbole à intégrer */ + char *text; /* Texte constant à insérer */ + uint16_t handler_off; /* Décallage à appliquer */ + vmpa2t handler; /* Lecture à poursuivre */ + + content = g_binary_format_get_content(G_BIN_FORMAT(format)); + + endian = SRE_LITTLE;//g_dex_format_get_endianness(format); + + /* start_addr */ + + copy_vmpa(&start, pos); + instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, endian); + + SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX); + + asprintf(&text, _("Start address of the block of code covered by this entry")); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, text); + + free(text); + + /* insn_count */ + + copy_vmpa(&start, pos); + instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, pos, endian); + + SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); + + asprintf(&text, _("Number of 16-bit code units covered by this entry")); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, text); + + free(text); + + /* handler_off */ + + copy_vmpa(&start, pos); + instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, pos, endian); + + SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX); + + asprintf(&text, _("Offset to the encoded_catch_handler for this entry")); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, text); + + free(text); + + g_imm_operand_get_value(G_IMM_OPERAND(operand), MDS_16_BITS, &handler_off); + + copy_vmpa(&handler, handlers); + advance_vmpa(&handler, handler_off); + + result = annotate_dex_encoded_catch_handler_list(format, &handler); + + /* Nettoyage final */ + + g_object_unref(G_OBJECT(content)); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* pos = tête de lecture physique des symboles. * +* * +* Description : Commente les définitions des listes de gestion d'exceptions. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool annotate_dex_encoded_catch_handler_list(const GDexFormat *format, vmpa2t *pos) +{ + bool result; /* Bilan à retourner */ + GBinContent *content; /* Contenu binaire à lire */ + vmpa2t start; /* Localisation des symboles */ + GArchInstruction *instr; /* Instruction décodée */ + GArchOperand *operand; /* Opérande à venir modifier */ + GDbComment *comment; /* Définition de commentaire */ + GBinSymbol *symbol; /* Symbole à intégrer */ + char *text; /* Texte constant à insérer */ + uleb128_t size; /* Nombre d'entrées */ + uleb128_t i; /* Boucle de parcours */ + + content = g_binary_format_get_content(G_BIN_FORMAT(format)); + + /* static_fields_size */ + + copy_vmpa(&start, pos); + instr = g_raw_instruction_new_uleb128(content, pos); + + SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); + + asprintf(&text, _("Size of the list, in entries")); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, text); + + free(text); + + /* instance_fields_size */ + + g_imm_operand_as_uleb128(G_IMM_OPERAND(operand), &size); + + result = true; + + for (i = 0; i < size && result; i++) + result = annotate_dex_encoded_catch_handler(format, pos); + + /* Nettoyage final */ + + g_object_unref(G_OBJECT(content)); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* pos = tête de lecture physique des symboles. * +* * +* Description : Commente les définitions d'une prise en compte d'exceptions. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool annotate_dex_encoded_catch_handler(const GDexFormat *format, vmpa2t *pos) +{ + bool result; /* Bilan à retourner */ + GBinContent *content; /* Contenu binaire à lire */ + vmpa2t start; /* Localisation des symboles */ + GArchInstruction *instr; /* Instruction décodée */ + GArchOperand *operand; /* Opérande à venir modifier */ + GDbComment *comment; /* Définition de commentaire */ + GBinSymbol *symbol; /* Symbole à intégrer */ + char *text; /* Texte constant à insérer */ + leb128_t size; /* Nombre de gestionnaires */ + bool has_catch_all; /* Gestion par défaut ? */ + uleb128_t i; /* Boucle de parcours */ + + content = g_binary_format_get_content(G_BIN_FORMAT(format)); + + /* size */ + + copy_vmpa(&start, pos); + instr = g_raw_instruction_new_uleb128(content, pos); + + SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); + + asprintf(&text, _("Number of static fields defined in this item")); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, text); + + free(text); + + g_imm_operand_as_leb128(G_IMM_OPERAND(operand), &size); + + has_catch_all = (size <= 0); + + if (size < 0) + size *= -1; + + /* handlers */ + + result = true; + + for (i = 0; i < size && result; i++) + result = annotate_dex_encoded_type_addr_pair(format, pos); + + /* catch_all_addr */ + + if (has_catch_all) + { + copy_vmpa(&start, pos); + instr = g_raw_instruction_new_uleb128(content, pos); + + SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX); + + asprintf(&text, _("Bytecode address of the catch-all handler")); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, text); + + free(text); + + } + + /* Nettoyage final */ + + g_object_unref(G_OBJECT(content)); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* pos = tête de lecture des symboles. * +* * +* Description : Commente les définitions des gestions d'exceptions par type. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool annotate_dex_encoded_type_addr_pair(const GDexFormat *format, vmpa2t *pos) +{ + GBinContent *content; /* Contenu binaire à lire */ + vmpa2t start; /* Localisation des symboles */ + GArchInstruction *instr; /* Instruction décodée */ + GArchOperand *operand; /* Opérande à venir modifier */ + GDbComment *comment; /* Définition de commentaire */ + GBinSymbol *symbol; /* Symbole à intégrer */ + char *text; /* Texte constant à insérer */ + + content = g_binary_format_get_content(G_BIN_FORMAT(format)); + + /* type_idx */ + + copy_vmpa(&start, pos); + instr = g_raw_instruction_new_uleb128(content, pos); + + SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); + + asprintf(&text, _("Index for the type of the exception to catch")); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, text); + + free(text); + + /* addr */ + + copy_vmpa(&start, pos); + instr = g_raw_instruction_new_uleb128(content, pos); + + SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX); + + asprintf(&text, _("Bytecode address of the associated exception handler")); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, text); + + free(text); + + /* Nettoyage final */ + + g_object_unref(G_OBJECT(content)); + + return true; + +} |