From bde67ccf58fc858d5d0db4929db149ea12f50f96 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sun, 13 Mar 2016 15:22:15 +0100 Subject: Created a readelf-like information provider for Dex files. --- ChangeLog | 25 +++ configure.ac | 1 + plugins/Makefile.am | 4 +- plugins/readdex/Makefile.am | 16 ++ plugins/readdex/class.c | 469 +++++++++++++++++++++++++++++++++++++++++ plugins/readdex/class.h | 37 ++++ plugins/readdex/code.c | 496 ++++++++++++++++++++++++++++++++++++++++++++ plugins/readdex/code.h | 37 ++++ plugins/readdex/header.c | 287 +++++++++++++++++++++++++ plugins/readdex/header.h | 37 ++++ plugins/readdex/ids.c | 440 +++++++++++++++++++++++++++++++++++++++ plugins/readdex/ids.h | 49 +++++ plugins/readdex/reader.c | 85 ++++++++ plugins/readdex/reader.h | 39 ++++ src/arch/immediate.c | 40 ++++ src/arch/immediate.h | 6 + 16 files changed, 2066 insertions(+), 2 deletions(-) create mode 100644 plugins/readdex/Makefile.am create mode 100644 plugins/readdex/class.c create mode 100644 plugins/readdex/class.h create mode 100644 plugins/readdex/code.c create mode 100644 plugins/readdex/code.h create mode 100644 plugins/readdex/header.c create mode 100644 plugins/readdex/header.h create mode 100644 plugins/readdex/ids.c create mode 100644 plugins/readdex/ids.h create mode 100644 plugins/readdex/reader.c create mode 100644 plugins/readdex/reader.h diff --git a/ChangeLog b/ChangeLog index 8d2d068..d3628c4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,28 @@ +16-03-13 Cyrille Bagard + + * configure.ac: + Add the new Makefile from the 'plugins/readdex' directory. + + * plugins/Makefile.am: + Add 'readdex' to SUBDIRS. + + * plugins/readdex/Makefile.am: + * plugins/readdex/class.c: + * plugins/readdex/class.h: + * plugins/readdex/code.c: + * plugins/readdex/code.h: + * plugins/readdex/header.c: + * plugins/readdex/header.h: + * plugins/readdex/ids.c: + * plugins/readdex/ids.h: + * plugins/readdex/reader.c: + * plugins/readdex/reader.h: + New entries: create a readelf-like information provider for Dex files. + + * src/arch/immediate.c: + * src/arch/immediate.h: + Give signed and unsigned leb128 values from generic immediate values. + 16-03-12 Cyrille Bagard * src/core/params.c: diff --git a/configure.ac b/configure.ac index bbd7cba..6c7a62e 100644 --- a/configure.ac +++ b/configure.ac @@ -309,6 +309,7 @@ AC_CONFIG_FILES([Makefile plugins/python/exectracer/Makefile plugins/python/samples/Makefile plugins/python/welcome/Makefile + plugins/readdex/Makefile plugins/readelf/Makefile plugins/ropgadgets/Makefile plugins/stackvars/Makefile diff --git a/plugins/Makefile.am b/plugins/Makefile.am index 22ef693..e3692c8 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -1,6 +1,6 @@ if HAVE_PYTHON3_CONFIG - PYTHON3_SUBDIRS = pychrysa python + PYTHON3_SUBDIRS = pychrysa python endif -SUBDIRS = androhelpers devdbg libcsem mobicore $(PYTHON3_SUBDIRS) readelf ropgadgets stackvars +SUBDIRS = androhelpers devdbg libcsem mobicore $(PYTHON3_SUBDIRS) readdex readelf ropgadgets stackvars diff --git a/plugins/readdex/Makefile.am b/plugins/readdex/Makefile.am new file mode 100644 index 0000000..ce98d4a --- /dev/null +++ b/plugins/readdex/Makefile.am @@ -0,0 +1,16 @@ + +lib_LTLIBRARIES = libreaddex.la + +libreaddex_la_SOURCES = \ + class.h class.c \ + code.h code.c \ + header.h header.c \ + ids.h ids.c \ + reader.h reader.c + +libreaddex_la_CFLAGS = $(AM_CFLAGS) + + +AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) -I../../src + +AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) diff --git a/plugins/readdex/class.c b/plugins/readdex/class.c new file mode 100644 index 0000000..3f0608a --- /dev/null +++ b/plugins/readdex/class.c @@ -0,0 +1,469 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * class.c - annotation des définitions de classes + * + * 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 . + */ + + +#include "class.h" + + +#include +#include +#include + + +#include +#include +#include +#include +#include + + +#include "code.h" + + + +/* Commente les définitions des classes pour la VM Dalvik. */ +static bool annotate_dex_class_data(const GDexFormat *, const GDexClass *, uint32_t ); + +/* Commente les définitions des champs encodés. */ +static bool annotate_dex_encoded_field(const GDexFormat *, vmpa2t *); + +/* Commente les définitions des méthodes encodées. */ +static bool annotate_dex_encoded_method(const GDexFormat *, const encoded_method *, vmpa2t *); + + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* * +* Description : Commente les définitions des classes pour la VM Dalvik. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool annotate_dex_class_defs(const GDexFormat *format) +{ + bool result; /* Bilan à retourner */ + GBinContent *content; /* Contenu binaire à lire */ + const dex_header *header; /* En-tête principale */ + SourceEndian endian; /* Boutisme utilisé */ + vmpa2t pos; /* Tête de lecture des symboles*/ + uint32_t i; /* Boucle de parcours */ + 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 */ + GDexClass *class; /* Classe chargée à manipuler */ + const class_def_item *def; /* Définition brute à lire */ + + result = true; + + content = g_binary_format_get_content(G_BIN_FORMAT(format)); + + header = g_dex_format_get_header(format); + endian = SRE_LITTLE;//g_dex_format_get_endianness(format); + + if (!g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), header->class_defs_off, &pos)) + return false; + + for (i = 0; i < header->class_defs_size && result; i++) + { + /* class_idx */ + + 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, _("Index into the type_ids list for this class")); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, text); + + free(text); + + /* access_flags */ + + 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, _("Access flags for the class")); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, text); + + free(text); + + /* superclass_idx */ + + 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, _("Index for the superclass or NO_INDEX if this class has no superclass")); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, text); + + free(text); + + /* interfaces_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 list of interfaces")); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, text); + + free(text); + + /* source_file_idx */ + + 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, _("Index for the name of the file containing the original source or NO_INDEX")); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, text); + + free(text); + + /* annotations_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 annotations structure for this class")); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, text); + + free(text); + + /* class_data_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 associated class data for this item")); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, text); + + free(text); + + /* static_values_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 list of initial values for static fields")); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, text); + + free(text); + + /* Annotations supplémentaires */ + + class = g_dex_format_get_class(format, i); + + def = g_dex_class_get_definition(class); + + result = annotate_dex_class_data(format, class, def->class_data_off); + + /* TODO : g_object_unref(G_OBJECT(class));*/ + + } + + g_object_unref(G_OBJECT(content)); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* class = classe Dex dont les données sont à commenter. * +* offset = tête de lecture physique des symboles. * +* * +* Description : Commente les définitions des classes pour la VM Dalvik. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool annotate_dex_class_data(const GDexFormat *format, const GDexClass *class, uint32_t offset) +{ + bool result; /* Bilan à retourner */ + GBinContent *content; /* Contenu binaire à lire */ + 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 */ + const class_data_item *data; /* Données chargées à lire */ + uleb128_t i; /* Boucle de parcours */ + + content = g_binary_format_get_content(G_BIN_FORMAT(format)); + + if (!g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), offset, &pos)) + return false; + + /* 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, _("Number of static fields defined in this item")); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, text); + + free(text); + + /* instance_fields_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 instance fields defined in this item")); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, text); + + free(text); + + /* direct_methods_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 direct methods defined in this item")); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, text); + + free(text); + + /* virtual_methods_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 virtual methods defined in this item")); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, text); + + free(text); + + /* Chargements complémentaires */ + + result = true; + + data = g_dex_class_get_data(class); + + for (i = 0; i < data->static_fields_size && result; i++) + result = annotate_dex_encoded_field(format, &pos); + + for (i = 0; i < data->instance_fields_size && result; i++) + result = annotate_dex_encoded_field(format, &pos); + + for (i = 0; i < data->direct_methods_size && result; i++) + result = annotate_dex_encoded_method(format, &data->direct_methods[i], &pos); + + for (i = 0; i < data->virtual_methods_size && result; i++) + result = annotate_dex_encoded_method(format, &data->virtual_methods[i], &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 à faire progresser. [OUT] * +* * +* Description : Commente les définitions des champs encodés. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool annotate_dex_encoded_field(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)); + + /* field_idx_diff */ + + copy_vmpa(&start, pos); + instr = g_raw_instruction_new_uleb128(content, pos); + + SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); + + asprintf(&text, _("Index into the field_ids list for the identity of this field")); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, text); + + free(text); + + /* access_flags */ + + copy_vmpa(&start, pos); + instr = g_raw_instruction_new_uleb128(content, pos); + + SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX); + + asprintf(&text, _("Access flags for the field")); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, text); + + free(text); + + /* Nettoyage final */ + + g_object_unref(G_OBJECT(content)); + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* method = méthode à décrire. * +* pos = tête de lecture à faire progresser. [OUT] * +* * +* Description : Commente les définitions des méthodes encodées. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool annotate_dex_encoded_method(const GDexFormat *format, const encoded_method *method, 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 */ + + content = g_binary_format_get_content(G_BIN_FORMAT(format)); + + /* method_idx_diff */ + + copy_vmpa(&start, pos); + instr = g_raw_instruction_new_uleb128(content, pos); + + SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); + + asprintf(&text, _("Index into the method_ids list for the identity of this method")); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, text); + + free(text); + + /* access_flags */ + + copy_vmpa(&start, pos); + instr = g_raw_instruction_new_uleb128(content, pos); + + SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX); + + asprintf(&text, _("Access flags for the method")); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, text); + + free(text); + + /* code_off */ + + copy_vmpa(&start, pos); + instr = g_raw_instruction_new_uleb128(content, pos); + + SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX); + + asprintf(&text, _("Offset to the code structure for this method")); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, text); + + free(text); + + /* Chargements complémentaires, si non abstraite ni native */ + + if (method->code_off > 0) + result = annotate_dex_code_item(format, method->code_off); + else + result = true; + + /* Nettoyage final */ + + g_object_unref(G_OBJECT(content)); + + return result; + +} diff --git a/plugins/readdex/class.h b/plugins/readdex/class.h new file mode 100644 index 0000000..c2508e3 --- /dev/null +++ b/plugins/readdex/class.h @@ -0,0 +1,37 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * class.h - prototypes pour l'annotation des définitions de classes + * + * 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 . + */ + + +#ifndef _PLUGINS_READDEX_CLASS_H +#define _PLUGINS_READDEX_CLASS_H + + +#include + + + +/* Commente les définitions des classes pour la VM Dalvik. */ +bool annotate_dex_class_defs(const GDexFormat *); + + + +#endif /* _PLUGINS_READDEX_CLASS_H */ 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 . + */ + + +#include "code.h" + + +#include +#include +#include + + +#include +#include +#include +#include + + + +/* 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; + +} diff --git a/plugins/readdex/code.h b/plugins/readdex/code.h new file mode 100644 index 0000000..f8276c3 --- /dev/null +++ b/plugins/readdex/code.h @@ -0,0 +1,37 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * code.h - prototypes pour l'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 . + */ + + +#ifndef _PLUGINS_READDEX_CODE_H +#define _PLUGINS_READDEX_CODE_H + + +#include + + + +/* Commente les définitions d'un corps de méthode. */ +bool annotate_dex_code_item(const GDexFormat *, uleb128_t); + + + +#endif /* _PLUGINS_READDEX_CODE_H */ diff --git a/plugins/readdex/header.c b/plugins/readdex/header.c new file mode 100644 index 0000000..183ca82 --- /dev/null +++ b/plugins/readdex/header.c @@ -0,0 +1,287 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * header.c - annotation des en-têtes de binaires DEX + * + * 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 . + */ + + +#include "header.h" + + +#include +#include +#include +#include + + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* * +* Description : Charge tous les symboles de l'en-tête DEX. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool annotate_dex_header(GDexFormat *format) +{ + 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 */ + + 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), 0, &pos)) + return false; + + /* magic */ + + copy_vmpa(&start, &pos); + instr = g_raw_instruction_new_array(content, MDS_8_BITS, DEX_FILE_MAGIC_LEN, &pos, endian); + + g_raw_instruction_mark_as_string(G_RAW_INSTRUCTION(instr), true); + + SET_IMM_DISPLAY(instr, operand, 0, IOD_CHAR); + SET_IMM_DISPLAY(instr, operand, 1, IOD_CHAR); + SET_IMM_DISPLAY(instr, operand, 2, IOD_CHAR); + + SET_IMM_DISPLAY(instr, operand, 3, IOD_HEX); + + SET_IMM_DISPLAY(instr, operand, 4, IOD_CHAR); + SET_IMM_DISPLAY(instr, operand, 5, IOD_CHAR); + SET_IMM_DISPLAY(instr, operand, 6, IOD_CHAR); + + SET_IMM_DISPLAY(instr, operand, 7, IOD_HEX); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, _("DEX magic number")); + + /* checksum */ + + 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); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, _("adler32 checksum used to detect file corruption")); + + /* signature */ + + copy_vmpa(&start, &pos); + instr = g_raw_instruction_new_array(content, MDS_32_BITS, 5, &pos, endian); + + SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, _("SHA-1 signature used to uniquely identify files")); + + /* file_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); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, _("Size of the entire file in bytes")); + + /* header_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); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, _("Size of the header in bytes")); + + /* endian_tag */ + + 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); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, _("Endianness tag ; 0x12345678 for little-endian")); + + /* link_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); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, _("Size of the link section")); + + /* link_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); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, _("Offset to the link section")); + + /* map_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); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, _("Offset to the map item")); + + /* string_ids_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); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, _("Count of strings in the string identifiers list")); + + /* string_ids_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); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, _("Offset to the string identifiers list")); + + /* type_ids_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); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, _("Count of elements in the type identifiers list")); + + /* type_ids_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); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, _("Offset to the type identifiers list")); + + /* proto_ids_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); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, _("Count of elements in the prototype identifiers list")); + + /* proto_ids_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); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, _("Offset to the prototype identifiers list")); + + /* field_ids_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); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, _("Count of elements in the field identifiers list")); + + /* field_ids_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); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, _("Offset to the field identifiers list")); + + /* method_ids_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); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, _("Count of elements in the method identifiers list")); + + /* method_ids_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); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, _("Offset to the method identifiers list")); + + /* class_defs_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); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, _("Count of elements in the class definitions list")); + + /* class_defs_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); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, _("Offset to the class definitions list")); + + /* data_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); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, _("Size of data section in bytes")); + + /* data_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); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, _("Offset to the start of the data section")); + + g_object_unref(G_OBJECT(content)); + + return true; + +} diff --git a/plugins/readdex/header.h b/plugins/readdex/header.h new file mode 100644 index 0000000..7688284 --- /dev/null +++ b/plugins/readdex/header.h @@ -0,0 +1,37 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * header.h - prototypes pour l'annotation des en-têtes de binaires DEX + * + * 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 . + */ + + +#ifndef _PLUGINS_READDEX_HEADER_H +#define _PLUGINS_READDEX_HEADER_H + + +#include + + + +/* Charge tous les symboles de l'en-tête DEX. */ +bool annotate_dex_header(GDexFormat *); + + + +#endif /* _PLUGINS_READDEX_HEADER_H */ diff --git a/plugins/readdex/ids.c b/plugins/readdex/ids.c new file mode 100644 index 0000000..54d0bd7 --- /dev/null +++ b/plugins/readdex/ids.c @@ -0,0 +1,440 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ids.c - annotation des références aux chaînes de caractères et identifiants + * + * 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 . + */ + + +#include "ids.h" + + +#include +#include +#include + + +#include +#include +#include +#include + + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* * +* Description : Commente les définitions des chaînes de caractères. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool annotate_dex_string_ids(const GDexFormat *format) +{ + GBinContent *content; /* Contenu binaire à lire */ + const dex_header *header; /* En-tête principale */ + SourceEndian endian; /* Boutisme utilisé */ + vmpa2t pos; /* Tête de lecture des symboles*/ + uint32_t i; /* Boucle de parcours */ + 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 */ + phys_t loc; /* Localisation physique */ + vmpa2t item_pos; /* Position d'un élément */ + uleb128_t length; /* Taille de la chaîne en cours*/ + MemoryDataSize leb_size; /* Taille de la taille */ + + content = g_binary_format_get_content(G_BIN_FORMAT(format)); + + header = g_dex_format_get_header(format); + endian = SRE_LITTLE;//g_dex_format_get_endianness(format); + + if (!g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), header->string_ids_off, &pos)) + return false; + + for (i = 0; i < header->string_ids_size; i++) + { + /* Saut vers la définition */ + + 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 for string item #%u/%u"), i, header->string_ids_size - 1); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, text); + + free(text); + + /* Description de la chaîne : taille */ + + operand = g_arch_instruction_get_operand(instr, 0); + + if (!g_imm_operand_to_phys_t(G_IMM_OPERAND(operand), &loc)) + continue; + + if (!g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), loc, &item_pos)) + continue; + + copy_vmpa(&start, &item_pos); + + if (!g_binary_content_read_uleb128(content, &item_pos, &length)) + continue; + + leb_size = MDS_FROM_BYTES(compute_vmpa_diff(&start, &item_pos)); + assert(leb_size != MDS_UNDEFINED); + + instr = g_raw_instruction_new_from_value(&start, leb_size, (uint64_t)length); + + SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, _("String length")); + + /* Description de la chaîne : contenu */ + + copy_vmpa(&start, &item_pos); + instr = g_raw_instruction_new_array(content, MDS_8_BITS, leb_size, &item_pos, endian); + + g_raw_instruction_mark_as_string(G_RAW_INSTRUCTION(instr), true); + + ADD_STR_AS_SYM(format, symbol, instr); + + } + + g_object_unref(G_OBJECT(content)); + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* * +* Description : Commente les définitions des identifiants de types. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool annotate_dex_type_ids(const GDexFormat *format) +{ + GBinContent *content; /* Contenu binaire à lire */ + const dex_header *header; /* En-tête principale */ + SourceEndian endian; /* Boutisme utilisé */ + vmpa2t pos; /* Tête de lecture des symboles*/ + uint32_t i; /* Boucle de parcours */ + 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)); + + header = g_dex_format_get_header(format); + endian = SRE_LITTLE;//g_dex_format_get_endianness(format); + + if (!g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), header->type_ids_off, &pos)) + return false; + + for (i = 0; i < header->type_ids_size; i++) + { + 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, _("Index for the descriptor string of this type")); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, text); + + free(text); + + } + + g_object_unref(G_OBJECT(content)); + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* * +* Description : Commente les définitions des identifiants de prototypes. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool annotate_dex_proto_ids(const GDexFormat *format) +{ + GBinContent *content; /* Contenu binaire à lire */ + const dex_header *header; /* En-tête principale */ + SourceEndian endian; /* Boutisme utilisé */ + vmpa2t pos; /* Tête de lecture des symboles*/ + uint32_t i; /* Boucle de parcours */ + 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)); + + header = g_dex_format_get_header(format); + endian = SRE_LITTLE;//g_dex_format_get_endianness(format); + + if (!g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), header->proto_ids_off, &pos)) + return false; + + for (i = 0; i < header->proto_ids_size; i++) + { + /* shorty_idx */ + + 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, _("Index for the short-form descriptor string of this prototype")); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, text); + + free(text); + + /* return_type_idx */ + + 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, _("Index for the return type of this prototype")); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, text); + + free(text); + + /* parameters_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_DEC); + + asprintf(&text, _("Offset to the list of parameter types for this prototype")); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, text); + + free(text); + + } + + g_object_unref(G_OBJECT(content)); + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* * +* Description : Commente les définitions des identifiants de champs. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool annotate_dex_field_ids(const GDexFormat *format) +{ + GBinContent *content; /* Contenu binaire à lire */ + const dex_header *header; /* En-tête principale */ + SourceEndian endian; /* Boutisme utilisé */ + vmpa2t pos; /* Tête de lecture des symboles*/ + uint32_t i; /* Boucle de parcours */ + 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)); + + header = g_dex_format_get_header(format); + endian = SRE_LITTLE;//g_dex_format_get_endianness(format); + + if (!g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), header->field_ids_off, &pos)) + return false; + + for (i = 0; i < header->field_ids_size; i++) + { + /* class_idx */ + + 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, _("Index for the definer of this field")); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, text); + + free(text); + + /* type_idx */ + + 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, _("Index for the type of this field")); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, text); + + free(text); + + /* name_idx */ + + 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, _("Index for the name of this field")); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, text); + + free(text); + + } + + g_object_unref(G_OBJECT(content)); + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* * +* Description : Commente les définitions des identifiants de méthodes. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool annotate_dex_method_ids(const GDexFormat *format) +{ + GBinContent *content; /* Contenu binaire à lire */ + const dex_header *header; /* En-tête principale */ + SourceEndian endian; /* Boutisme utilisé */ + vmpa2t pos; /* Tête de lecture des symboles*/ + uint32_t i; /* Boucle de parcours */ + 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)); + + header = g_dex_format_get_header(format); + endian = SRE_LITTLE;//g_dex_format_get_endianness(format); + + if (!g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), header->method_ids_off, &pos)) + return false; + + for (i = 0; i < header->method_ids_size; i++) + { + /* class_idx */ + + 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, _("Index for the definer of this field")); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, text); + + free(text); + + /* proto_idx */ + + 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, _("Index for the prototype of this method")); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, text); + + free(text); + + /* name_idx */ + + 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, _("Index for the name of this method")); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, text); + + free(text); + + } + + g_object_unref(G_OBJECT(content)); + + return true; + +} + diff --git a/plugins/readdex/ids.h b/plugins/readdex/ids.h new file mode 100644 index 0000000..bcbf6de --- /dev/null +++ b/plugins/readdex/ids.h @@ -0,0 +1,49 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ids.h - prototypes pour l'annotation des références aux chaînes de caractères et identifiants + * + * 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 . + */ + + +#ifndef _PLUGINS_READDEX_IDS_H +#define _PLUGINS_READDEX_IDS_H + + +#include + + + +/* Charge tous les symboles de l'en-tête DEX. */ +bool annotate_dex_string_ids(const GDexFormat *); + +/* Commente les définitions des identifiants de types. */ +bool annotate_dex_type_ids(const GDexFormat *); + +/* Commente les définitions des identifiants de prototypes. */ +bool annotate_dex_proto_ids(const GDexFormat *); + +/* Commente les définitions des identifiants de champs. */ +bool annotate_dex_field_ids(const GDexFormat *); + +/* Commente les définitions des identifiants de méthodes. */ +bool annotate_dex_method_ids(const GDexFormat *); + + + +#endif /* _PLUGINS_READDEX_IDS_H */ diff --git a/plugins/readdex/reader.c b/plugins/readdex/reader.c new file mode 100644 index 0000000..8df489e --- /dev/null +++ b/plugins/readdex/reader.c @@ -0,0 +1,85 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * reader.c - interprétation des informations secondaires contenues dans un fichier DEX + * + * 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 . + */ + + +#include "reader.h" + + +#include + + +#include "class.h" +#include "header.h" +#include "ids.h" + + + +DEFINE_CHRYSALIDE_ACTIVE_PLUGIN("readdex", "Displays information about DEX files", "0.1.0", + PGA_FORMAT_LOADER_LAST); + + +/****************************************************************************** +* * +* Paramètres : plugin = greffon à manipuler. * +* action = type d'action attendue. * +* format = description de l'exécutable à compléter. * +* * +* Description : Etablit des symboles complémentaires dans un format DEX. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +G_MODULE_EXPORT bool handle_binary_format(const GPluginModule *plugin, PluginAction action, GBinFormat *format) +{ + bool result; /* Bilan à retourner */ + GDexFormat *dex_fmt; /* Version DEX */ + + if (!G_IS_DEX_FORMAT(format)) + { + result = true; + goto hbf_exit; + } + + dex_fmt = G_DEX_FORMAT(format); + + result = annotate_dex_header(dex_fmt); + + result &= annotate_dex_string_ids(dex_fmt); + + result &= annotate_dex_type_ids(dex_fmt); + + result &= annotate_dex_proto_ids(dex_fmt); + + result &= annotate_dex_field_ids(dex_fmt); + + result &= annotate_dex_method_ids(dex_fmt); + + result &= annotate_dex_class_defs(dex_fmt); + + hbf_exit: + + return result; + +} diff --git a/plugins/readdex/reader.h b/plugins/readdex/reader.h new file mode 100644 index 0000000..8cccced --- /dev/null +++ b/plugins/readdex/reader.h @@ -0,0 +1,39 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * reader.h - prototypes pour l'interprétation des informations secondaires contenues dans un fichier DEX + * + * 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 . + */ + + +#ifndef _PLUGINS_READDEX_READER_H +#define _PLUGINS_READDEX_READER_H + + +#include +#include +#include + + + +/* Etablit des symboles complémentaires dans un format DEX. */ +G_MODULE_EXPORT bool handle_binary_format(const GPluginModule *, PluginAction, GBinFormat *); + + + +#endif /* _PLUGINS_READDEX_READER_H */ diff --git a/src/arch/immediate.c b/src/arch/immediate.c index 40533ae..2be7879 100644 --- a/src/arch/immediate.c +++ b/src/arch/immediate.c @@ -941,6 +941,46 @@ bool g_imm_operand_to_virt_t(const GImmOperand *operand, virt_t *addr) /****************************************************************************** * * * Paramètres : operand = opérande à traiter. * +* val = valeur résultante. [OUT] * +* * +* Description : Convertit une valeur immédiate en valeur de type leb128_t. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_imm_operand_as_leb128(const GImmOperand *operand, leb128_t *val) +{ + *val = operand->raw; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à traiter. * +* val = valeur résultante. [OUT] * +* * +* Description : Convertit une valeur immédiate en valeur de type uleb128_t. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_imm_operand_as_uleb128(const GImmOperand *operand, uleb128_t *val) +{ + *val = operand->raw; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à traiter. * * addr = valeur résultante. [OUT] * * * * Description : Convertit une valeur immédiate en adresse de type vmpa_t. * diff --git a/src/arch/immediate.h b/src/arch/immediate.h index e6da2f4..acc4ed5 100644 --- a/src/arch/immediate.h +++ b/src/arch/immediate.h @@ -125,6 +125,12 @@ bool g_imm_operand_to_phys_t(const GImmOperand *, phys_t *); /* Convertit une valeur immédiate en adresse de type virt_t. */ bool g_imm_operand_to_virt_t(const GImmOperand *, virt_t *); +/* Convertit une valeur immédiate en valeur de type leb128_t. */ +void g_imm_operand_as_leb128(const GImmOperand *, leb128_t *); + +/* Convertit une valeur immédiate en valeur de type uleb128_t. */ +void g_imm_operand_as_uleb128(const GImmOperand *, uleb128_t *); + /* Convertit une valeur immédiate en adresse de type vmpa_t. */ bool g_imm_operand_to_vmpa_t(const GImmOperand *, vmpa_t *) __attribute__ ((deprecated)); -- cgit v0.11.2-87-g4458