diff options
Diffstat (limited to 'plugins/androhelpers')
| -rw-r--r-- | plugins/androhelpers/Makefile.am | 18 | ||||
| -rw-r--r-- | plugins/androhelpers/androhelpers.c | 100 | ||||
| -rw-r--r-- | plugins/androhelpers/androhelpers.h | 43 | ||||
| -rw-r--r-- | plugins/androhelpers/try_n_catch.c | 337 | ||||
| -rw-r--r-- | plugins/androhelpers/try_n_catch.h | 37 | 
5 files changed, 535 insertions, 0 deletions
diff --git a/plugins/androhelpers/Makefile.am b/plugins/androhelpers/Makefile.am new file mode 100644 index 0000000..3562206 --- /dev/null +++ b/plugins/androhelpers/Makefile.am @@ -0,0 +1,18 @@ + +lib_LTLIBRARIES = libandrohelpers.la + +libandrohelpers_la_SOURCES =			\ +	androhelpers.h androhelpers.c		\ +	try_n_catch.h try_n_catch.c + +libandrohelpers_la_LDFLAGS = -L../../src/.libs -L../../src/gui/.libs -lchrysagui \ +	-lchrysadisass -lchrysagtkext 	\ +	-L../../src/plugins/.libs -lplugins + + +INCLUDES = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \ +	-I../../src + +AM_CPPFLAGS =  + +AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) diff --git a/plugins/androhelpers/androhelpers.c b/plugins/androhelpers/androhelpers.c new file mode 100644 index 0000000..a644868 --- /dev/null +++ b/plugins/androhelpers/androhelpers.c @@ -0,0 +1,100 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * androhelpers.c - greffon d'appoint pour les traitements Android + * + * Copyright (C) 2012 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  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 "androhelpers.h" + + +#include <string.h> + + +#include "try_n_catch.h" + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : -                                                            * +*                                                                             * +*  Description : Précise le nom associé au greffon.                           * +*                                                                             * +*  Retour      : Nom à libérer de la mémoire.                                 * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +char *get_plugin_name(void) +{ +    return strdup("AndroHelpers"); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : plugin = greffon à consulter.                                * +*                                                                             * +*  Description : Indique les opérations offertes par un greffon donné.        * +*                                                                             * +*  Retour      : Action(s) offerte(s) par le greffon.                         * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +PluginAction get_plugin_action(const GPluginModule *plugin) +{ +    PluginAction result;                    /* Combinaison à retourner     */ + +    result = PGA_DISASS_PROCESS; + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : plugin = greffon de prise en charge à utiliser.              * +*                binary = représentation binaire à traiter.                   * +*                action = action attendue.                                    * +*                                                                             * +*  Description : Exécute une action définie sur un binaire chargé.            * +*                                                                             * +*  Retour      : true si une action a été menée, false sinon.                 * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool execute_action_on_binary(GPluginModule *plugin, GLoadedBinary *binary, PluginAction action) +{ +    bool result;                            /* Bilan à retourner           */ + +    result = true; + +    result &= process_exception_handlers(binary); + +    return result; + +} diff --git a/plugins/androhelpers/androhelpers.h b/plugins/androhelpers/androhelpers.h new file mode 100644 index 0000000..b1a5084 --- /dev/null +++ b/plugins/androhelpers/androhelpers.h @@ -0,0 +1,43 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * androhelpers.h - prototypes pour le greffon d'appoint pour les traitements Android + * + * Copyright (C) 2012 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  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/>. + */ + + +#ifndef _PLUGINS_ANDROHELPERS_H +#define _PLUGINS_ANDROHELPERS_H + + +#include <plugins/plugin.h> + + + +/* Précise le nom associé au greffon. */ +char *get_plugin_name(void); + +/* Indique les opérations offertes par un greffon donné. */ +PluginAction get_plugin_action(const GPluginModule *); + +/* Exécute une action définie sur un binaire chargé. */ +bool execute_action_on_binary(GPluginModule *, GLoadedBinary *, PluginAction); + + + +#endif  /* _PLUGINS_ANDROHELPERS_H */ diff --git a/plugins/androhelpers/try_n_catch.c b/plugins/androhelpers/try_n_catch.c new file mode 100644 index 0000000..e7a3c0a --- /dev/null +++ b/plugins/androhelpers/try_n_catch.c @@ -0,0 +1,337 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * try_n_catch.c - support des exceptions chez Android + * + * Copyright (C) 2012 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  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 "try_n_catch.h" + + +#include <malloc.h> + + +#include <format/dex/dex-int.h> +#include <format/dex/pool.h> +#include <../i18n.h> + + + +/* Mémorisation d'un lien vers un gestionnaire */ +typedef struct _caught_exception +{ +    GArchInstruction *instr;                /* Première instruction visée  */ +    char *desc;                             /* Nom de l'exception          */ + +} caught_exception; + + + +/* Valide la zone couverte par le gestionnaire d'exceptions. */ +static bool check_covered_area(const try_item *, const GBinRoutine *); + +/* Construit une liste pointant sur les différentes gestions. */ +static caught_exception *build_destinations_list(GLoadedBinary *, const try_item *, const encoded_catch_handler_list *, const GBinRoutine *, size_t *); + +/* Rattache les gestionnaires d'exception à leur code couvert. */ +static void attach_caught_code(GLoadedBinary *, const try_item *, const encoded_catch_handler_list *, const GBinRoutine *); + +/* Recherche et met en avant tous les gestionnaires d'exception. */ +static void look_for_exception_handlers(GLoadedBinary *, const GDexFormat *, GDexMethod *); + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : try     = informations sur la gestion à consulter.           * +*                routine = routine associée, pour validation.                 * +*                                                                             * +*  Description : Valide la zone couverte par le gestionnaire d'exceptions.    * +*                                                                             * +*  Retour      : Validité de la zone couverte.                                * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool check_covered_area(const try_item *try, const GBinRoutine *routine) +{ +    off_t length;                           /* Taille de la zone de code   */ +    vmpa_t covered_start;                   /* Début de la zone couverte   */ +    vmpa_t covered_end;                     /* Fin de la zone couverte     */ + +    length = g_binary_routine_get_size(routine); + +    covered_start = try->start_addr * sizeof(uint16_t); +    covered_end = covered_start + try->insn_count * sizeof(uint16_t); + +    return (covered_end <= length); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : binary  = représentation binaire à traiter.                  * +*                try     = informations sur la gestion à consulter.           * +*                hlist   = liste de tous les gestionnaires en place.          * +*                routine = routine associée, pour l'accès au instructions.    * +*                count   = quantité de destinations trouvées. [OUT]           * +*                                                                             * +*  Description : Construit une liste pointant sur les différentes gestions.   * +*                                                                             * +*  Retour      : Adresse des codes à lier systématiquement.                   * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static caught_exception *build_destinations_list(GLoadedBinary *binary, const try_item *try, const encoded_catch_handler_list *hlist, const GBinRoutine *routine, size_t *count) +{ +    caught_exception *result;               /* Liste à retourner           */ +    GDexFormat *format;                     /* Format du binaire chargé    */ +    vmpa_t start;                           /* Début du code de la routine */ +    GArchInstruction *instrs;               /* Instructions Dalvik         */ +    uleb128_t index;                        /* Indice du bon gestionnaire  */ +    encoded_catch_handler *handlers;        /* Groupe de gestionnaires     */ +    leb128_t max;                           /* Quantité d'exception        */ +    leb128_t i;                             /* Boucle de parcours          */ +    vmpa_t handler_addr;                    /* Adresse du code de gestion  */ +    GDataType *type;                        /* Type de l'exception         */ + +    format = G_DEX_FORMAT(g_loaded_binary_get_format(binary)); + +    start = g_binary_routine_get_address(routine); + +    instrs = g_loaded_binary_get_instructions(binary); +    instrs = g_arch_instruction_find_by_address(instrs, start, true); + +    for (index = 0; index < hlist->size; index++) +        if (try->handler_off == hlist->list[index].offset) +            break; + +    if (index == hlist->size) +    { +        *count = 0; +        return NULL; +    } + +    handlers = &hlist->list[index]; +    max = leb128_abs(handlers->size); + +    *count = max + (handlers->size < 0 ? 1 : 0); +    result = (caught_exception *)calloc(*count, sizeof(caught_exception)); + +    *count = 0; + +    for (i = 0; i < max; i++) +    { +        handler_addr = start + handlers->handlers[i].addr * sizeof(uint16_t); +        result[*count].instr = g_arch_instruction_find_by_address(instrs, handler_addr, true); + +        if (result[*count].instr == NULL) +            continue; + +        type = get_type_from_dex_pool(format, handlers->handlers[i].type_idx); +        result[*count].desc = g_data_type_to_string(type); + +        (*count)++; + +    } + +    if (handlers->size < 0) +    { +        handler_addr = start + handlers->catch_all_addr * sizeof(uint16_t); +        result[*count].instr = g_arch_instruction_find_by_address(instrs, handler_addr, true); + +        if (result[*count].instr != NULL) +        { +            result[*count].desc = strdup(_("default")); +            (*count)++; +        } + +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : binary   = représentation binaire à traiter.                 * +*                try      = informations sur la gestion à consulter.          * +*                handlers = liste de tous les gestionnaires en place.         * +*                routine  = routine associée, pour l'accès au instructions.   * +*                                                                             * +*  Description : Rattache les gestionnaires d'exception à leur code couvert.  * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void attach_caught_code(GLoadedBinary *binary, const try_item *try, const encoded_catch_handler_list *handlers, const GBinRoutine *routine) +{ +    vmpa_t start;                           /* Début de la zone couverte   */ +    vmpa_t end;                             /* Début de la zone couverte   */ +    GArchInstruction *instrs;               /* Instructions Dalvik         */ +    GArchInstruction *first;                /* Première instruction        */ +    GArchInstruction *prev;                 /* Instruction à détacher      */ +    GArchInstruction *iter;                 /* Boucle de parcours          */ +    size_t dests_count;                     /* Nombre de points d'arrivée  */ +    caught_exception *dests;                /* Points d'arrivée            */ +    size_t i;                               /* Boucle de parcours          */ + +    start = g_binary_routine_get_address(routine); +    start += try->start_addr * sizeof(uint16_t); + +    end = start + try->insn_count * sizeof(uint16_t); + +    instrs = g_loaded_binary_get_instructions(binary); +    first = g_arch_instruction_find_by_address(instrs, start, true); + +    /* Si un détachement est nécessaire... */ +    if (!g_arch_instruction_has_sources(first)) +    { +        prev = g_arch_instruction_get_prev_iter(instrs, first); +        g_arch_instruction_link_with(prev, first, ILT_JUMP); +    } + +    /* Détermination du code des exceptions */ +    dests = build_destinations_list(binary, try, handlers, routine, &dests_count); + +    if (dests != NULL) +    { +        /* Rattachements */ +        for (iter = first; +             iter != NULL; +             iter = g_arch_instruction_get_next_iter(instrs, iter, end)) +        { +            if (!g_arch_instruction_has_destinations(iter)) +                continue; + +            for (i = 0; i < dests_count; i++) +                g_arch_instruction_link_with(iter, dests[i].instr, ILT_CATCH_EXCEPTION); + +        } + +        /* Libération de la mémoire utilisée */ + +        for (i = 0; i < dests_count; i++) +            free(dests[i].desc); + +        free(dests); + +    } + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : binary = représentation binaire à traiter.                   * +*                format = format du binaire Dex.                              * +*                method = méthode à analyser.                                 * +*                                                                             * +*  Description : Recherche et met en avant tous les gestionnaires d'exception.* +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void look_for_exception_handlers(GLoadedBinary *binary, const GDexFormat *format, GDexMethod *method) +{ +    const code_item *body;                  /* Description du corps        */ +    GBinRoutine *routine;                   /* Abstraction globale         */ +    uint16_t i;                             /* Boucle de parcours          */ + +    body = g_dex_method_get_dex_body(method); + +    if (body->tries_size == 0) +        return; + +    routine = g_dex_method_get_routine(method); + +    for (i = 0; i < body->tries_size; i++) +    { +        if (!check_covered_area(&body->tries[i], routine)) +            continue; + +        attach_caught_code(binary, &body->tries[i], body->handlers, routine); + +    } + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : binary = représentation binaire à traiter.                   * +*                                                                             * +*  Description : Traite tous les gestionnaires d'exception trouvés.           * +*                                                                             * +*  Retour      : true si une action a été menée, false sinon.                 * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool process_exception_handlers(GLoadedBinary *binary) +{ +    GDexFormat *format;                     /* Format du binaire chargé    */ +    size_t cls_count;                       /* Nombre de classes trouvées  */ +    size_t i;                               /* Boucle de parcours #1       */ +    GDexClass *class;                       /* Classe à analyser           */ +    size_t meth_count;                      /* Nombre de méthodes trouvées */ +    size_t j;                               /* Boucle de parcours #2       */ +    GDexMethod *method;                     /* Méthode à parcourir         */ + +    if (!G_IS_DEX_FORMAT(g_loaded_binary_get_format(binary))) +        return false; + +    format = G_DEX_FORMAT(g_loaded_binary_get_format(binary)); + +    cls_count = g_dex_format_count_classes(format); +    for (i = 0; i < cls_count; i++) +    { +        class = g_dex_format_get_class(format, i); + +        meth_count = g_dex_class_count_methods(class, false); +        for (j = 0; j < meth_count; j++) +        { +            method = g_dex_class_get_method(class, false, j); +            look_for_exception_handlers(binary, format, method); +        } + +        meth_count = g_dex_class_count_methods(class, true); +        for (j = 0; j < meth_count; j++) +        { +            method = g_dex_class_get_method(class, true, j); +            look_for_exception_handlers(binary, format, method); +        } + +    } + +    return true; + +} diff --git a/plugins/androhelpers/try_n_catch.h b/plugins/androhelpers/try_n_catch.h new file mode 100644 index 0000000..5ac4ad5 --- /dev/null +++ b/plugins/androhelpers/try_n_catch.h @@ -0,0 +1,37 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * try_n_catch.h - prototypes pour le support des exceptions chez Android + * + * Copyright (C) 2012 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  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/>. + */ + + +#ifndef _PLUGINS_TRY_N_CATCH_H +#define _PLUGINS_TRY_N_CATCH_H + + +#include <analysis/binary.h> + + + +/* Traite tous les gestionnaires d'exception trouvés. */ +bool process_exception_handlers(GLoadedBinary *); + + + +#endif  /* _PLUGINS_TRY_N_CATCH_H */  | 
