diff options
| -rw-r--r-- | plugins/dalvik/operands/pool.c | 6 | ||||
| -rw-r--r-- | plugins/dex/dex-int.h | 1 | ||||
| -rw-r--r-- | plugins/dex/format.c | 3 | ||||
| -rw-r--r-- | plugins/dex/method.c | 18 | ||||
| -rw-r--r-- | plugins/dex/pool.c | 122 | ||||
| -rw-r--r-- | plugins/dex/pool.h | 3 | 
6 files changed, 129 insertions, 24 deletions
diff --git a/plugins/dalvik/operands/pool.c b/plugins/dalvik/operands/pool.c index 6e4229b..f4fe1fa 100644 --- a/plugins/dalvik/operands/pool.c +++ b/plugins/dalvik/operands/pool.c @@ -377,12 +377,10 @@ static void g_dalvik_pool_operand_print(const GDalvikPoolOperand *operand, GBuff              if (routine != NULL)              { -                tmp = g_binary_routine_to_string(routine, true); +                tmp = g_binary_symbol_get_label(G_BIN_SYMBOL(routine));                  g_object_unref(G_OBJECT(routine)); -                g_buffer_line_append_text(line, BLC_ASSEMBLY, "<", 1, RTT_HOOK, NULL); -                g_buffer_line_append_text(line, BLC_ASSEMBLY, tmp, strlen(tmp), RTT_VAR_NAME, G_OBJECT(operand)); -                g_buffer_line_append_text(line, BLC_ASSEMBLY, ">", 1, RTT_HOOK, NULL); +                g_buffer_line_append_text(line, BLC_ASSEMBLY, tmp, strlen(tmp), RTT_LABEL, G_OBJECT(operand));              }              else diff --git a/plugins/dex/dex-int.h b/plugins/dex/dex-int.h index 5180b58..48a920c 100644 --- a/plugins/dex/dex-int.h +++ b/plugins/dex/dex-int.h @@ -44,6 +44,7 @@ struct _GDexFormat      GBinSymbol **strings;                   /* Symboles pour les chaînes   */      GDataType **types;                      /* Types partagés pour Dalvik  */      GBinVariable **fields;                  /* Champs de données partagés  */ +    GDexMethod **methods;                   /* Méthodes déclarées          */      GDexClass **classes;                    /* Classes retrouvées          */  }; diff --git a/plugins/dex/format.c b/plugins/dex/format.c index af005e6..d354ad0 100644 --- a/plugins/dex/format.c +++ b/plugins/dex/format.c @@ -405,6 +405,9 @@ static bool g_dex_format_analyze(GDexFormat *format, wgroup_id_t gid, GtkStatusS      if (!load_all_dex_fields(format, gid, status))          goto gdfa_error; +    if (!load_all_dex_methods(format, gid, status)) +        goto gdfa_error; +      if (!load_all_dex_classes(format, gid, status))          goto gdfa_error; diff --git a/plugins/dex/method.c b/plugins/dex/method.c index 5b7b30e..e5f6273 100644 --- a/plugins/dex/method.c +++ b/plugins/dex/method.c @@ -49,6 +49,10 @@ struct _GDexMethod       * en place à partir du constructeur g_dex_method_new_defined().       */ +#ifndef NDEBUG +    bool already_defined;                   /* Vérofication d'unicité      */ +#endif +      encoded_method info;                    /* Propriétés de la méthode    */      bool has_body;                          /* Indication de présence      */      code_item body;                         /* Corps de la méthode         */ @@ -120,6 +124,9 @@ static void g_dex_method_class_init(GDexMethodClass *class)  static void g_dex_method_init(GDexMethod *method)  { +#ifndef NDEBUG +    method->already_defined = false; +#endif  } @@ -197,6 +204,11 @@ GDexMethod *g_dex_method_new_defined(GDexFormat *format, const encoded_method *s      if (result == NULL)          return NULL; +#ifndef NDEBUG +    assert(!result->already_defined); +    result->already_defined = true; +#endif +      result->info = *seed;      result->has_body = (seed->code_off > 0); @@ -253,17 +265,23 @@ GDexMethod *g_dex_method_new_defined(GDexFormat *format, const encoded_method *s  GDexMethod *g_dex_method_new_callable(GDexFormat *format, const method_id_item *method_id)  {      GDexMethod *result;                     /* Composant à retourner       */ +    GDataType *ns;                          /* Espace d'appartenance       */      const char *name;                       /* Nom de la routine finale    */      GBinRoutine *routine;                   /* Routine représentée         */      result = NULL; +    ns = get_type_from_dex_pool(format, method_id->class_idx); +      name = get_string_from_dex_pool(format, method_id->name_idx, NULL);      if (name == NULL) goto gdmne_exit;      routine = get_prototype_from_dex_pool(format, method_id->proto_idx);      if (routine == NULL) goto gdmne_exit; +    if (ns != NULL) +        g_binary_routine_set_namespace(routine, ns, strdup(".")); +      g_binary_routine_set_name(routine, strdup(name));      result = g_object_new(G_TYPE_DEX_METHOD, NULL); diff --git a/plugins/dex/pool.c b/plugins/dex/pool.c index 8a421b2..75841df 100644 --- a/plugins/dex/pool.c +++ b/plugins/dex/pool.c @@ -711,6 +711,93 @@ GBinRoutine *get_prototype_from_dex_pool(GDexFormat *format, uint32_t index)  /******************************************************************************  *                                                                             * +*  Paramètres  : format = représentation interne du format DEX à compléter.   * +*                gid    = groupe de travail impliqué.                         * +                 status = barre de statut à tenir informée.                   * +*                                                                             * +*  Description : Charge toutes les classes listées dans le contenu binaire.   * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool load_all_dex_methods(GDexFormat *format, wgroup_id_t gid, GtkStatusStack *status) +{ +    bool result;                            /* Bilan à retourner           */ +    guint runs_count;                       /* Qté d'exécutions parallèles */ +    uint32_t run_size;                      /* Volume réparti par exécution*/ +    GWorkQueue *queue;                      /* Gestionnaire de différés    */ +    activity_id_t msg;                      /* Message de progression      */ +    guint i;                                /* Boucle de parcours          */ +    uint32_t begin;                         /* Début de bloc de traitement */ +    uint32_t end;                           /* Fin d'un bloc de traitement */ +    GDexLoading *loading;                   /* Tâche de chargement à lancer*/ + +    /** +     * Il existe deux voies pour récupérer une méthode : +     * +     *    - depuis 'method_id_item', qui précise classe d'appartenance, prototype +     *      et nom. +     * +     *    - depuis 'encoded_method', qui contient une définition 'method_id_item', +     *      ainsi que des attributs propres à la méthode visée. +     * +     * Techniquement, il peut donc y avoir plusieurs variations d'un même +     * 'method_id_item' selon différents 'encoded_method'. +     * +     * Dans la pratique, c'est hautement improbable : une méthode ne peut pas +     * être privée et publique  par exemple, ou renvoyer vers différents code. +     * +     * Donc on se permet d'associer une unique méthode par 'method_id_item', +     * et de précharger le tout. +     */ + +    result = true; + +    /* Préparation du réceptacle */ + +    format->methods = (GDexMethod **)calloc(format->header.method_ids_size, sizeof(GDexMethod *)); + +    /* Lancement des chargements */ + +    runs_count = get_max_online_threads(); + +    run_size = format->header.method_ids_size / runs_count; + +    queue = get_work_queue(); + +    msg = gtk_status_stack_add_activity(status, _("Loading all methods from the Dex pool..."), +                                        format->header.method_ids_size); + +    for (i = 0; i < runs_count; i++) +    { +        begin = i * run_size; + +        if ((i + 1) == runs_count) +            end = format->header.method_ids_size; +        else +            end = begin + run_size; + +        loading = g_dex_loading_new(format, begin, end, msg, +                                    (dex_loading_cb)get_method_from_dex_pool, &result); + +        g_work_queue_schedule_work(queue, G_DELAYED_WORK(loading), gid); + +    } + +    g_work_queue_wait_for_completion(queue, gid); + +    gtk_status_stack_remove_activity(status, msg); + +    return result; + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : format = représentation interne du format DEX à consulter.   *  *                                                                             *  *  Description : Compte le nombre de méthodes dans une table DEX.             * @@ -735,7 +822,7 @@ uint32_t count_methods_in_dex_pool(const GDexFormat *format)  /******************************************************************************  *                                                                             *  *  Paramètres  : format = représentation interne du format DEX à consulter.   * -*                index  = index de la classe recherchée.                      * +*                index  = index de la méthode recherchée.                     *  *                                                                             *  *  Description : Extrait une représentation de méthode d'une table DEX.       *  *                                                                             * @@ -748,36 +835,31 @@ uint32_t count_methods_in_dex_pool(const GDexFormat *format)  GDexMethod *get_method_from_dex_pool(GDexFormat *format, uint32_t index)  {      GDexMethod *result;                     /* Instance à retourner        */ -    uint32_t count;                         /* Nombre d'éléments présents  */      phys_t pos;                             /* Tête de lecture             */      vmpa2t addr;                            /* Tête de lecture générique   */      method_id_item method_id;               /* Définition de la méthode    */      result = NULL; -    count = count_methods_in_dex_pool(format); - -    if (index >= count) +    if (index >= format->header.method_ids_size)          goto gmfdp_error; -    /** -     * On charge ici une méthode à partir de la définition de 'method_id_item'. -     * -     * C'est l'élément 'encoded_method' qui référence cette cette définition et qui -     * applique ensuite les attributs finaux de la méthode. La classe parente est -     * précisée en outre bien en amont. -     * -     * Comme une même définition peut donc servir à plusieurs instances, -     * on ne peut pas conserver un tableau d'allocations communes. -     */ +    if (format->methods[index] == NULL) +    { +        pos = format->header.method_ids_off + index * sizeof(method_id_item); +        init_vmpa(&addr, pos, VMPA_NO_VIRTUAL); -    pos = format->header.method_ids_off + index * sizeof(method_id_item); -    init_vmpa(&addr, pos, VMPA_NO_VIRTUAL); +        if (!read_dex_method_id_item(format, &addr, &method_id)) +            goto gmfdp_error; -    if (!read_dex_method_id_item(format, &addr, &method_id)) -        goto gmfdp_error; +        format->methods[index] = g_dex_method_new_callable(format, &method_id); -    result = g_dex_method_new_callable(format, &method_id); +    } + +    result = format->methods[index]; + +    if (result != NULL) +        g_object_ref(G_OBJECT(result));   gmfdp_error: diff --git a/plugins/dex/pool.h b/plugins/dex/pool.h index ac7db60..dd27f94 100644 --- a/plugins/dex/pool.h +++ b/plugins/dex/pool.h @@ -71,6 +71,9 @@ uint32_t count_prototypes_in_dex_pool(const GDexFormat *);  /* Extrait une représentation de routine d'une table DEX. */  GBinRoutine *get_prototype_from_dex_pool(GDexFormat *, uint32_t); +/* Charge toutes les classes listées dans le contenu binaire. */ +bool load_all_dex_methods(GDexFormat *, wgroup_id_t, GtkStatusStack *); +  /* Compte le nombre de méthodes dans une table DEX. */  uint32_t count_methods_in_dex_pool(const GDexFormat *);  | 
