diff options
Diffstat (limited to 'src/format')
| -rw-r--r-- | src/format/Makefile.am | 2 | ||||
| -rw-r--r-- | src/format/dex/class.c | 291 | ||||
| -rw-r--r-- | src/format/dex/class.h | 14 | ||||
| -rw-r--r-- | src/format/dex/dex-int.c | 370 | ||||
| -rwxr-xr-x | src/format/dex/dex-int.h | 51 | ||||
| -rwxr-xr-x | src/format/dex/dex.c | 364 | ||||
| -rwxr-xr-x | src/format/dex/dex.h | 6 | ||||
| -rwxr-xr-x | src/format/dex/dex_def.h | 2 | ||||
| -rw-r--r-- | src/format/dex/method.c | 156 | ||||
| -rw-r--r-- | src/format/dex/method.h | 9 | ||||
| -rw-r--r-- | src/format/dex/pool.c | 472 | ||||
| -rw-r--r-- | src/format/dex/pool.h | 31 | ||||
| -rw-r--r-- | src/format/elf/elf.c | 19 | ||||
| -rw-r--r-- | src/format/executable-int.c | 69 | ||||
| -rw-r--r-- | src/format/executable-int.h | 26 | ||||
| -rw-r--r-- | src/format/executable.c | 5 | ||||
| -rwxr-xr-x | src/format/java/java.c | 124 | ||||
| -rw-r--r-- | src/format/pe/pe.c | 63 | 
18 files changed, 1157 insertions, 917 deletions
| diff --git a/src/format/Makefile.am b/src/format/Makefile.am index a3402ee..3f18b88 100644 --- a/src/format/Makefile.am +++ b/src/format/Makefile.am @@ -4,7 +4,7 @@ noinst_LTLIBRARIES = libformat.la  libformat_la_SOURCES =					\  	debuggable-int.h					\  	debuggable.h debuggable.c			\ -	executable-int.h					\ +	executable-int.h executable-int.c	\  	executable.h executable.c			\  	format-int.h						\  	format.h format.c					\ diff --git a/src/format/dex/class.c b/src/format/dex/class.c index b866cd7..657461f 100644 --- a/src/format/dex/class.c +++ b/src/format/dex/class.c @@ -33,11 +33,6 @@ - - - - -  /* Classe issue du code source (instance) */  struct _GDexClass  { @@ -66,17 +61,14 @@ static void g_dex_class_class_init(GDexClassClass *);  /* Procède à l'initialisation d'une classe issue du code source. */  static void g_dex_class_init(GDexClass *); -/* Crée une nouvelle représentation de classe issue de code. */ -static GDexClass *g_dex_class_new(const GDexFormat *, off_t); - -/* Inscrit les méthodes d'une classe en tant que routines. */ -static void g_dex_class_register_method(const GDexClass *, GBinFormat *); - - - - +/* Supprime toutes les références externes. */ +static void g_dex_class_dispose(GDexClass *); +/* Procède à la libération totale de la mémoire. */ +static void g_dex_class_finalize(GDexClass *); +/* Inscrit les méthodes d'une classe en tant que routines. */ +//static void g_dex_class_register_method(const GDexClass *, GBinFormat *); @@ -84,7 +76,6 @@ static void g_dex_class_register_method(const GDexClass *, GBinFormat *);  G_DEFINE_TYPE(GDexClass, g_dex_class, G_TYPE_OBJECT); -  /******************************************************************************  *                                                                             *  *  Paramètres  : class = classe de composant GLib à initialiser.              * @@ -99,6 +90,12 @@ G_DEFINE_TYPE(GDexClass, g_dex_class, G_TYPE_OBJECT);  static void g_dex_class_class_init(GDexClassClass *class)  { +    GObjectClass *object;                   /* Autre version de la classe  */ + +    object = G_OBJECT_CLASS(class); + +    object->dispose = (GObjectFinalizeFunc/* ! */)g_dex_class_dispose; +    object->finalize = (GObjectFinalizeFunc)g_dex_class_finalize;  } @@ -123,8 +120,64 @@ static void g_dex_class_init(GDexClass *class)  /******************************************************************************  *                                                                             * +*  Paramètres  : class = instance d'objet GLib à traiter.                     * +*                                                                             * +*  Description : Supprime toutes les références externes.                     * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_dex_class_dispose(GDexClass *class) +{ +    size_t i;                               /* Boucle de parcours          */ + +    if (class->direct_methods != NULL) +        for (i = 0; i < class->dmethods_count; i++) +            if (class->direct_methods[i] != NULL) +                g_object_unref(G_OBJECT(class->direct_methods[i])); + +    if (class->virtual_methods != NULL) +        for (i = 0; i < class->vmethods_count; i++) +            if (class->virtual_methods[i] != NULL) +                g_object_unref(G_OBJECT(class->virtual_methods[i])); + +    G_OBJECT_CLASS(g_dex_class_parent_class)->dispose(G_OBJECT(class)); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : class = instance d'objet GLib à traiter.                     * +*                                                                             * +*  Description : Procède à la libération totale de la mémoire.                * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_dex_class_finalize(GDexClass *class) +{ +    if (class->direct_methods != NULL) +        free(class->direct_methods); + +    if (class->virtual_methods != NULL) +        free(class->virtual_methods); + +    G_OBJECT_CLASS(g_dex_class_parent_class)->finalize(G_OBJECT(class)); + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : format = représentation interne du format DEX à consulter.   * -*                offset = tête de lecture des données initiale.               * +*                def    = définitions générales associées à la classe.        *  *                                                                             *  *  Description : Crée une nouvelle représentation de classe issue de code.    *  *                                                                             * @@ -134,120 +187,66 @@ static void g_dex_class_init(GDexClass *class)  *                                                                             *  ******************************************************************************/ -static GDexClass *g_dex_class_new(const GDexFormat *format, off_t offset) +GDexClass *g_dex_class_new(GDexFormat *format, const class_def_item *def)  {      GDexClass *result;                      /* Composant à retourner       */ -    class_def_item def;                     /* Définition de la classe     */ +    vmpa2t addr;                            /* Tête de lecture générique   */      class_data_item data;                   /* Contenu de la classe        */      uleb128_t index;                        /* Conservation du dernier id  */      uleb128_t i;                            /* Boucle de parcours          */      GDexMethod *method;                     /* Méthode chargée             */ -    if (!read_dex_class_def_item(format, &offset, &def)) -        return NULL; +    init_vmpa(&addr, def->class_data_off, VMPA_NO_VIRTUAL); -    offset = def.class_data_off; - -    if (!read_dex_class_data_item(format, &offset, &data)) +    if (!read_dex_class_data_item(format, &addr, &data))          return NULL; - - -    //printf(" Classe :: d meth count == 0x%lld\n", data.direct_methods_size); -    //printf(" Classe :: v meth count == 0x%lld\n", data.virtual_methods_size); - - -      result = g_object_new(G_TYPE_DEX_CLASS, NULL); -    result->definition = def; +    result->definition = *def; + +    /** +     * On évite ici les méthodes (virtuelles) non définies. +     */ +    if (def->access_flags & ACC_ANNOTATION) goto gdcn_done;      index = 0; +    result->dmethods_count = data.direct_methods_size; +    result->direct_methods = (GDexMethod **)calloc(result->dmethods_count, sizeof(GDexMethod *)); +      for (i = 0; i < data.direct_methods_size; i++)      {          method = g_dex_method_new(format, &data.direct_methods[i], &index); +        if (method == NULL) goto gdcn_bad_method; -        if (method != NULL) -        { -            result->dmethods_count++; -            result->direct_methods = (GDexMethod **)realloc(result->direct_methods, -                                                            result->dmethods_count * sizeof(GDexMethod *)); - -            result->direct_methods[result->dmethods_count - 1] = method; - -        } +        result->direct_methods[i] = method;      }      index = 0; +    result->vmethods_count = data.virtual_methods_size; +    result->virtual_methods = (GDexMethod **)calloc(result->vmethods_count, sizeof(GDexMethod *)); +      for (i = 0; i < data.virtual_methods_size; i++)      {          method = g_dex_method_new(format, &data.virtual_methods[i], &index); +        if (method == NULL) goto gdcn_bad_method; -        if (method != NULL) -        { -            result->vmethods_count++; -            result->virtual_methods = (GDexMethod **)realloc(result->virtual_methods, -                                                             result->vmethods_count * sizeof(GDexMethod *)); - -            result->virtual_methods[result->vmethods_count - 1] = method; - -        } +        result->virtual_methods[i] = method;      } - + gdcn_done:      return result; -} + gdcn_bad_method: +    g_object_unref(G_OBJECT(result)); -/****************************************************************************** -*                                                                             * -*  Paramètres  : class  = informations chargées à consulter.                  * -*                format = format binaire à compléter.                         * -*                                                                             * -*  Description : Inscrit les méthodes d'une classe en tant que routines.      * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static void g_dex_class_register_method(const GDexClass *class, GBinFormat *format) -{ -    size_t i;                               /* Boucle de parcours          */ -    GBinRoutine *routine;                   /* Routine à inscrire          */ - -    for (i = 0; i < class->dmethods_count; i++) -    { -        routine = g_dex_method_get_routine(class->direct_methods[i]); -        g_binary_format_add_routine(format, routine); - -        /* -        printf("routine @ 0x%08llx :: '%s'\n", -               g_binary_routine_get_address(routine), -               g_binary_routine_get_name(routine)); -        */ - -    } - -    for (i = 0; i < class->vmethods_count; i++) -    { -        routine = g_dex_method_get_routine(class->virtual_methods[i]); -        g_binary_format_add_routine(format, routine); - -        /* -        printf("routine @ 0x%08llx :: '%s'\n", -               g_binary_routine_get_address(routine), -               g_binary_routine_get_name(routine)); -        */ - -    } +    return NULL;  } @@ -310,47 +309,27 @@ GDexMethod *g_dex_class_get_method(const GDexClass *class, bool virtual, size_t  /******************************************************************************  *                                                                             *  *  Paramètres  : class = informations chargées à consulter.                   * -*                parts = liste à venir compléter.                             * -*                count = quantité de zones listées. [OUT]                     * +*                raw   = portion de binaire brut à raffiner.                  *  *                                                                             * -*  Description : Fournit les références aux zones binaires à analyser.        * +*  Description : Intègre la méthode en tant que portion de code.              *  *                                                                             * -*  Retour      : Zones binaires à analyser.                                   * +*  Retour      : -                                                            *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -#if 0 -GBinPart **g_dex_class_get_parts(const GDexClass *class, GBinPart **parts, size_t *count) + +void g_dex_class_include_as_portion(const GDexClass *class, GBinPortion *raw)  {      size_t i;                               /* Boucle de parcours          */ -    GBinPart *part;                         /* Partie à intégrer à la liste*/      for (i = 0; i < class->dmethods_count; i++) -    { -        part = g_dex_method_as_part(class->direct_methods[i]); - -        parts = (GBinPart **)realloc(parts, ++(*count) * sizeof(GBinPart *)); -        parts[*count - 1] = part; - -    } +        g_dex_method_include_as_portion(class->direct_methods[i], raw);      for (i = 0; i < class->vmethods_count; i++) -    { -        part = g_dex_method_as_part(class->virtual_methods[i]); - -        parts = (GBinPart **)realloc(parts, ++(*count) * sizeof(GBinPart *)); -        parts[*count - 1] = part; - -    } - -    return parts; +        g_dex_method_include_as_portion(class->virtual_methods[i], raw);  } -#endif - - -  /****************************************************************************** @@ -428,7 +407,7 @@ const char *g_dex_class_get_source_file(const GDexClass *class, const GDexFormat  void g_dex_class_decompile(const GDexClass *class, GLangOutput *lang, GCodeBuffer *buffer, const GDexFormat *format)  { - +#if 0      GDataType *type; @@ -482,7 +461,7 @@ GBufferLine *line, GLangOutput *output) - +#endif  } @@ -500,69 +479,3 @@ GBufferLine *line, GLangOutput *output) - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : format = représentation interne du format DEX à compléter.   * -*                                                                             * -*  Description : Charge toutes les classes listées dans le contenu binaire.   * -*                                                                             * -*  Retour      : Bilan de l'opération.                                        * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -bool load_all_dex_classes(GDexFormat *format) -{ -    const dex_header *header;               /* Raccourci d'usage           */ -    uint32_t i;                             /* Boucle de parcours          */ -    GDexClass *class;                       /* Représentation chargée      */ - -    header = &format->header; - -    for (i = 0; i < header->class_defs_size; i++) -    { -        class = g_dex_class_new(format, header->class_defs_off + i * sizeof(class_def_item)); - -        if (class != NULL) -        { -            format->classes_count++; -            format->classes = (GDexClass **)realloc(format->classes, -                                                    format->classes_count * sizeof(GDexClass *)); - -            format->classes[format->classes_count - 1] = class; - -        } - -    } - -    return true; - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : format = représentation interne du format DEX à compléter.   * -*                                                                             * -*  Description : Enregistre toutes les méthodes des classes listées.          * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -void register_all_dex_class_methods(GDexFormat *format) -{ -    size_t i;                               /* Boucle de parcours          */ -    GBinFormat *bformat;                    /* Autre version du format     */ - -    bformat = G_BIN_FORMAT(format); - -    for (i = 0; i < format->classes_count; i++) -        g_dex_class_register_method(format->classes[i], bformat); - -} diff --git a/src/format/dex/class.h b/src/format/dex/class.h index 8125b91..77fa6ba 100644 --- a/src/format/dex/class.h +++ b/src/format/dex/class.h @@ -54,14 +54,17 @@ typedef struct _GDexClassClass GDexClassClass;  /* Détermine le type d'une classe issue du code source. */  GType g_dex_class_get_type(void); +/* Crée une nouvelle représentation de classe issue de code. */ +GDexClass *g_dex_class_new(GDexFormat *, const class_def_item *); +  /* Dénombre les méthodes chargées d'un type donné. */  size_t g_dex_class_count_methods(const GDexClass *, bool);  /* Fournit une méthode chargée correspondant à un type donné. */  GDexMethod *g_dex_class_get_method(const GDexClass *, bool, size_t); -/*  Fournit les références aux zones binaires à analyser. */ -//GBinPart **g_dex_class_get_parts(const GDexClass *, GBinPart **, size_t *); +/* Intègre la méthode en tant que portion de code. */ +void g_dex_class_include_as_portion(const GDexClass *, GBinPortion *);  /* Retrouve si possible la méthode associée à une adresse. */  GDexMethod *g_dex_class_find_method_by_address(const GDexClass *, vmpa_t); @@ -76,13 +79,6 @@ void g_dex_class_decompile(const GDexClass *, GLangOutput *, GCodeBuffer *, cons -/* Charge toutes les classes listées dans le contenu binaire. */ -bool load_all_dex_classes(GDexFormat *); - -/* Enregistre toutes les méthodes des classes listées. */ -void register_all_dex_class_methods(GDexFormat *); - -  #endif  /* _FORMAT_DEX_CLASS_H */ diff --git a/src/format/dex/dex-int.c b/src/format/dex/dex-int.c index 5ce0675..79cdc57 100644 --- a/src/format/dex/dex-int.c +++ b/src/format/dex/dex-int.c @@ -51,48 +51,46 @@  *                                                                             *  ******************************************************************************/ -bool read_dex_header(const GDexFormat *format, off_t *pos, dex_header *header) +bool read_dex_header(const GDexFormat *format, vmpa2t *pos, dex_header *header)  {      bool result;                            /* Bilan à retourner           */ -    const bin_t *content;                   /* Contenu binaire à lire      */ -    off_t length;                           /* Taille totale du contenu    */ +    GBinContent *content;                   /* Contenu binaire à lire      */      size_t i;                               /* Boucle de parcours          */      result = true; -    content = NULL; //G_BIN_FORMAT(format)->content; -    length = 0; //G_BIN_FORMAT(format)->length; +    content = G_BIN_FORMAT(format)->content;      for (i = 0; i < DEX_FILE_MAGIC_LEN && result; i++) -        result = read_u8(&header->magic[i], content, pos, length); +        result = g_binary_content_read_u8(content, pos, &header->magic[i]); -    result &= read_u32(&header->checksum, content, pos, length, SRE_LITTLE); +    result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &header->checksum);      for (i = 0; i < 20 && result; i++) -        result = read_u8(&header->signature[i], content, pos, length); - -    result &= read_u32(&header->file_size, content, pos, length, SRE_LITTLE); -    result &= read_u32(&header->header_size, content, pos, length, SRE_LITTLE); - -    result &= read_u32(&header->endian_tag, content, pos, length, SRE_LITTLE); - -    result &= read_u32(&header->link_size, content, pos, length, SRE_LITTLE); -    result &= read_u32(&header->link_off, content, pos, length, SRE_LITTLE); -    result &= read_u32(&header->map_off, content, pos, length, SRE_LITTLE); -    result &= read_u32(&header->string_ids_size, content, pos, length, SRE_LITTLE); -    result &= read_u32(&header->string_ids_off, content, pos, length, SRE_LITTLE); -    result &= read_u32(&header->type_ids_size, content, pos, length, SRE_LITTLE); -    result &= read_u32(&header->type_ids_off, content, pos, length, SRE_LITTLE); -    result &= read_u32(&header->proto_ids_size, content, pos, length, SRE_LITTLE); -    result &= read_u32(&header->proto_ids_off, content, pos, length, SRE_LITTLE); -    result &= read_u32(&header->field_ids_size, content, pos, length, SRE_LITTLE); -    result &= read_u32(&header->field_ids_off, content, pos, length, SRE_LITTLE); -    result &= read_u32(&header->method_ids_size, content, pos, length, SRE_LITTLE); -    result &= read_u32(&header->method_ids_off, content, pos, length, SRE_LITTLE); -    result &= read_u32(&header->class_defs_size, content, pos, length, SRE_LITTLE); -    result &= read_u32(&header->class_defs_off, content, pos, length, SRE_LITTLE); -    result &= read_u32(&header->data_size, content, pos, length, SRE_LITTLE); -    result &= read_u32(&header->data_off, content, pos, length, SRE_LITTLE); +        result = g_binary_content_read_u8(content, pos, &header->signature[i]); + +    result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &header->file_size); +    result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &header->header_size); + +    result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &header->endian_tag); + +    result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &header->link_size); +    result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &header->link_off); +    result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &header->map_off); +    result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &header->string_ids_size); +    result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &header->string_ids_off); +    result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &header->type_ids_size); +    result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &header->type_ids_off); +    result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &header->proto_ids_size); +    result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &header->proto_ids_off); +    result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &header->field_ids_size); +    result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &header->field_ids_off); +    result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &header->method_ids_size); +    result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &header->method_ids_off); +    result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &header->class_defs_size); +    result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &header->class_defs_off); +    result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &header->data_size); +    result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &header->data_off);      return result; @@ -119,18 +117,14 @@ bool read_dex_header(const GDexFormat *format, off_t *pos, dex_header *header)  *                                                                             *  ******************************************************************************/ -bool read_dex_string_id_item(const GDexFormat *format, off_t *pos, string_id_item *str_id) +bool read_dex_string_id_item(const GDexFormat *format, vmpa2t *pos, string_id_item *str_id)  {      bool result;                            /* Bilan à retourner           */ -    const bin_t *content;                   /* Contenu binaire à lire      */ -    off_t length;                           /* Taille totale du contenu    */ +    GBinContent *content;                   /* Contenu binaire à lire      */ -    result = true; - -    content = NULL; //G_BIN_FORMAT(format)->content; -    length = 0; //G_BIN_FORMAT(format)->length; +    content = G_BIN_FORMAT(format)->content; -    result &= read_u32(&str_id->string_data_off, content, pos, length, SRE_LITTLE); +    result = g_binary_content_read_u32(content, pos, SRE_LITTLE, &str_id->string_data_off);      return result; @@ -151,20 +145,17 @@ bool read_dex_string_id_item(const GDexFormat *format, off_t *pos, string_id_ite  *                                                                             *  ******************************************************************************/ -bool read_dex_string_data_item(const GDexFormat *format, off_t *pos, string_data_item *str_data) +bool read_dex_string_data_item(const GDexFormat *format, vmpa2t *pos, string_data_item *str_data)  {      bool result;                            /* Bilan à retourner           */ -    const bin_t *content;                   /* Contenu binaire à lire      */ -    off_t length;                           /* Taille totale du contenu    */ - -    result = true; +    GBinContent *content;                   /* Contenu binaire à lire      */ -    content = NULL; //G_BIN_FORMAT(format)->content; -    length = 0; //G_BIN_FORMAT(format)->length; +    content = G_BIN_FORMAT(format)->content; -    result &= read_uleb128(&str_data->utf16_size, content, pos, length); +    result = g_binary_content_read_uleb128(content, pos, &str_data->utf16_size); -    str_data->data = &content[*pos]; +    if (result) +        str_data->data = g_binary_content_get_raw_access(content, pos, str_data->utf16_size);      return result; @@ -185,18 +176,14 @@ bool read_dex_string_data_item(const GDexFormat *format, off_t *pos, string_data  *                                                                             *  ******************************************************************************/ -bool read_dex_type_id_item(const GDexFormat *format, off_t *pos, type_id_item *item) +bool read_dex_type_id_item(const GDexFormat *format, vmpa2t *pos, type_id_item *item)  {      bool result;                            /* Bilan à retourner           */ -    const bin_t *content;                   /* Contenu binaire à lire      */ -    off_t length;                           /* Taille totale du contenu    */ - -    result = true; +    GBinContent *content;                   /* Contenu binaire à lire      */ -    content = NULL; //G_BIN_FORMAT(format)->content; -    length = 0; //G_BIN_FORMAT(format)->length; +    content = G_BIN_FORMAT(format)->content; -    result &= read_u32(&item->descriptor_idx, content, pos, length, SRE_LITTLE); +    result = g_binary_content_read_u32(content, pos, SRE_LITTLE, &item->descriptor_idx);      return result; @@ -217,20 +204,16 @@ bool read_dex_type_id_item(const GDexFormat *format, off_t *pos, type_id_item *i  *                                                                             *  ******************************************************************************/ -bool read_dex_proto_id_item(const GDexFormat *format, off_t *pos, proto_id_item *proto_id) +bool read_dex_proto_id_item(const GDexFormat *format, vmpa2t *pos, proto_id_item *proto_id)  {      bool result;                            /* Bilan à retourner           */ -    const bin_t *content;                   /* Contenu binaire à lire      */ -    off_t length;                           /* Taille totale du contenu    */ - -    result = true; +    GBinContent *content;                   /* Contenu binaire à lire      */ -    content = NULL; //G_BIN_FORMAT(format)->content; -    length = 0; //G_BIN_FORMAT(format)->length; +    content = G_BIN_FORMAT(format)->content; -    result &= read_u32(&proto_id->shorty_idx, content, pos, length, SRE_LITTLE); -    result &= read_u32(&proto_id->return_type_idx, content, pos, length, SRE_LITTLE); -    result &= read_u32(&proto_id->parameters_off, content, pos, length, SRE_LITTLE); +    result = g_binary_content_read_u32(content, pos, SRE_LITTLE, &proto_id->shorty_idx); +    result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &proto_id->return_type_idx); +    result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &proto_id->parameters_off);      return result; @@ -251,20 +234,16 @@ bool read_dex_proto_id_item(const GDexFormat *format, off_t *pos, proto_id_item  *                                                                             *  ******************************************************************************/ -bool read_dex_field_id_item(const GDexFormat *format, off_t *pos, field_id_item *field_id) +bool read_dex_field_id_item(const GDexFormat *format, vmpa2t *pos, field_id_item *field_id)  {      bool result;                            /* Bilan à retourner           */ -    const bin_t *content;                   /* Contenu binaire à lire      */ -    off_t length;                           /* Taille totale du contenu    */ +    GBinContent *content;                   /* Contenu binaire à lire      */ -    result = true; - -    content = NULL; //G_BIN_FORMAT(format)->content; -    length = 0; //G_BIN_FORMAT(format)->length; +    content = G_BIN_FORMAT(format)->content; -    result &= read_u16(&field_id->class_idx, content, pos, length, SRE_LITTLE); -    result &= read_u16(&field_id->type_idx, content, pos, length, SRE_LITTLE); -    result &= read_u32(&field_id->name_idx, content, pos, length, SRE_LITTLE); +    result = g_binary_content_read_u16(content, pos, SRE_LITTLE, &field_id->class_idx); +    result &= g_binary_content_read_u16(content, pos, SRE_LITTLE, &field_id->type_idx); +    result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &field_id->name_idx);      return result; @@ -285,20 +264,16 @@ bool read_dex_field_id_item(const GDexFormat *format, off_t *pos, field_id_item  *                                                                             *  ******************************************************************************/ -bool read_dex_method_id_item(const GDexFormat *format, off_t *pos, method_id_item *meth_id) +bool read_dex_method_id_item(const GDexFormat *format, vmpa2t *pos, method_id_item *meth_id)  {      bool result;                            /* Bilan à retourner           */ -    const bin_t *content;                   /* Contenu binaire à lire      */ -    off_t length;                           /* Taille totale du contenu    */ - -    result = true; +    GBinContent *content;                   /* Contenu binaire à lire      */ -    content = NULL; //G_BIN_FORMAT(format)->content; -    length = 0; //G_BIN_FORMAT(format)->length; +    content = G_BIN_FORMAT(format)->content; -    result &= read_u16(&meth_id->class_idx, content, pos, length, SRE_LITTLE); -    result &= read_u16(&meth_id->proto_idx, content, pos, length, SRE_LITTLE); -    result &= read_u32(&meth_id->name_idx, content, pos, length, SRE_LITTLE); +    result = g_binary_content_read_u16(content, pos, SRE_LITTLE, &meth_id->class_idx); +    result &= g_binary_content_read_u16(content, pos, SRE_LITTLE, &meth_id->proto_idx); +    result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &meth_id->name_idx);      return result; @@ -319,25 +294,21 @@ bool read_dex_method_id_item(const GDexFormat *format, off_t *pos, method_id_ite  *                                                                             *  ******************************************************************************/ -bool read_dex_class_def_item(const GDexFormat *format, off_t *pos, class_def_item *class_def) +bool read_dex_class_def_item(const GDexFormat *format, vmpa2t *pos, class_def_item *class_def)  {      bool result;                            /* Bilan à retourner           */ -    const bin_t *content;                   /* Contenu binaire à lire      */ -    off_t length;                           /* Taille totale du contenu    */ - -    result = true; +    GBinContent *content;                   /* Contenu binaire à lire      */ -    content = NULL; //G_BIN_FORMAT(format)->content; -    length = 0; //G_BIN_FORMAT(format)->length; +    content = G_BIN_FORMAT(format)->content; -    result &= read_u32(&class_def->class_idx, content, pos, length, SRE_LITTLE); -    result &= read_u32(&class_def->access_flags, content, pos, length, SRE_LITTLE); -    result &= read_u32(&class_def->superclass_idx, content, pos, length, SRE_LITTLE); -    result &= read_u32(&class_def->interfaces_off, content, pos, length, SRE_LITTLE); -    result &= read_u32(&class_def->source_file_idx, content, pos, length, SRE_LITTLE); -    result &= read_u32(&class_def->annotations_off, content, pos, length, SRE_LITTLE); -    result &= read_u32(&class_def->class_data_off, content, pos, length, SRE_LITTLE); -    result &= read_u32(&class_def->static_values_off, content, pos, length, SRE_LITTLE); +    result = g_binary_content_read_u32(content, pos, SRE_LITTLE, &class_def->class_idx); +    result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &class_def->access_flags); +    result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &class_def->superclass_idx); +    result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &class_def->interfaces_off); +    result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &class_def->source_file_idx); +    result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &class_def->annotations_off); +    result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &class_def->class_data_off); +    result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &class_def->static_values_off);      return result; @@ -364,19 +335,17 @@ bool read_dex_class_def_item(const GDexFormat *format, off_t *pos, class_def_ite  *                                                                             *  ******************************************************************************/ -bool read_dex_encoded_field(const GDexFormat *format, off_t *pos, encoded_field *field) +bool read_dex_encoded_field(const GDexFormat *format, vmpa2t *pos, encoded_field *field)  {      bool result;                            /* Bilan à retourner           */ -    const bin_t *content;                   /* Contenu binaire à lire      */ -    off_t length;                           /* Taille totale du contenu    */ +    GBinContent *content;                   /* Contenu binaire à lire      */      result = true; -    content = NULL; //G_BIN_FORMAT(format)->content; -    length = 0; //G_BIN_FORMAT(format)->length; +    content = G_BIN_FORMAT(format)->content; -    result &= read_uleb128(&field->field_idx_diff, content, pos, length); -    result &= read_uleb128(&field->access_flags, content, pos, length); +    result &= g_binary_content_read_uleb128(content, pos, &field->field_idx_diff); +    result &= g_binary_content_read_uleb128(content, pos, &field->access_flags);      return result; @@ -397,20 +366,18 @@ bool read_dex_encoded_field(const GDexFormat *format, off_t *pos, encoded_field  *                                                                             *  ******************************************************************************/ -bool read_dex_encoded_method(const GDexFormat *format, off_t *pos, encoded_method *method) +bool read_dex_encoded_method(const GDexFormat *format, vmpa2t *pos, encoded_method *method)  {      bool result;                            /* Bilan à retourner           */ -    const bin_t *content;                   /* Contenu binaire à lire      */ -    off_t length;                           /* Taille totale du contenu    */ +    GBinContent *content;                   /* Contenu binaire à lire      */      result = true; -    content = NULL; //G_BIN_FORMAT(format)->content; -    length = 0; //G_BIN_FORMAT(format)->length; +    content = G_BIN_FORMAT(format)->content; -    result &= read_uleb128(&method->method_idx_diff, content, pos, length); -    result &= read_uleb128(&method->access_flags, content, pos, length); -    result &= read_uleb128(&method->code_off, content, pos, length); +    result &= g_binary_content_read_uleb128(content, pos, &method->method_idx_diff); +    result &= g_binary_content_read_uleb128(content, pos, &method->access_flags); +    result &= g_binary_content_read_uleb128(content, pos, &method->code_off);      return result; @@ -431,18 +398,14 @@ bool read_dex_encoded_method(const GDexFormat *format, off_t *pos, encoded_metho  *                                                                             *  ******************************************************************************/ -bool read_dex_type_item(const GDexFormat *format, off_t *pos, type_item *item) +bool read_dex_type_item(const GDexFormat *format, vmpa2t *pos, type_item *item)  {      bool result;                            /* Bilan à retourner           */ -    const bin_t *content;                   /* Contenu binaire à lire      */ -    off_t length;                           /* Taille totale du contenu    */ +    GBinContent *content;                   /* Contenu binaire à lire      */ -    result = true; - -    content = NULL; //G_BIN_FORMAT(format)->content; -    length = 0; //G_BIN_FORMAT(format)->length; +    content = G_BIN_FORMAT(format)->content; -    result &= read_u16(&item->type_idx, content, pos, length, SRE_LITTLE); +    result = g_binary_content_read_u16(content, pos, SRE_LITTLE, &item->type_idx);      return result; @@ -463,21 +426,19 @@ bool read_dex_type_item(const GDexFormat *format, off_t *pos, type_item *item)  *                                                                             *  ******************************************************************************/ -bool read_dex_type_list(const GDexFormat *format, off_t *pos, type_list *list) +bool read_dex_type_list(const GDexFormat *format, vmpa2t *pos, type_list *list)  {      bool result;                            /* Bilan à retourner           */ -    const bin_t *content;                   /* Contenu binaire à lire      */ -    off_t length;                           /* Taille totale du contenu    */ +    GBinContent *content;                   /* Contenu binaire à lire      */      result = true; -    content = NULL; //G_BIN_FORMAT(format)->content; -    length = 0; //G_BIN_FORMAT(format)->length; +    content = G_BIN_FORMAT(format)->content; -    result &= read_u32(&list->size, content, pos, length, SRE_LITTLE); +    result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &list->size); -    list->list = (type_item *)&content[*pos]; -    result &= ((*pos + list->size * sizeof(type_item)) <= length); +    list->list = (type_item *)g_binary_content_get_raw_access(content, pos, list->size * sizeof(type_item)); +    result &= (list->list != NULL);      return result; @@ -498,27 +459,25 @@ bool read_dex_type_list(const GDexFormat *format, off_t *pos, type_list *list)  *                                                                             *  ******************************************************************************/ -bool read_dex_class_data_item(const GDexFormat *format, off_t *pos, class_data_item *item) +bool read_dex_class_data_item(const GDexFormat *format, vmpa2t *pos, class_data_item *item)  {      bool result;                            /* Bilan à retourner           */ -    const bin_t *content;                   /* Contenu binaire à lire      */ -    off_t length;                           /* Taille totale du contenu    */ +    GBinContent *content;                   /* Contenu binaire à lire      */      uleb128_t i;                            /* Boucle de parcours          */      result = true; -    content = NULL; //G_BIN_FORMAT(format)->content; -    length = 0; //G_BIN_FORMAT(format)->length; -      item->static_fields = NULL;      item->instance_fields = NULL;      item->direct_methods = NULL;      item->virtual_methods = NULL; -    result &= read_uleb128(&item->static_fields_size, content, pos, length); -    result &= read_uleb128(&item->instance_fields_size, content, pos, length); -    result &= read_uleb128(&item->direct_methods_size, content, pos, length); -    result &= read_uleb128(&item->virtual_methods_size, content, pos, length); +    content = G_BIN_FORMAT(format)->content; + +    result &= g_binary_content_read_uleb128(content, pos, &item->static_fields_size); +    result &= g_binary_content_read_uleb128(content, pos, &item->instance_fields_size); +    result &= g_binary_content_read_uleb128(content, pos, &item->direct_methods_size); +    result &= g_binary_content_read_uleb128(content, pos, &item->virtual_methods_size);      if (result && item->static_fields_size > 0)      { @@ -617,19 +576,17 @@ void reset_dex_class_data_item(class_data_item *item)  *                                                                             *  ******************************************************************************/ -bool read_dex_encoded_type_addr_pair(const GDexFormat *format, off_t *pos, encoded_type_addr_pair *pair) +bool read_dex_encoded_type_addr_pair(const GDexFormat *format, vmpa2t *pos, encoded_type_addr_pair *pair)  {      bool result;                            /* Bilan à retourner           */ -    const bin_t *content;                   /* Contenu binaire à lire      */ -    off_t length;                           /* Taille totale du contenu    */ +    GBinContent *content;                   /* Contenu binaire à lire      */      result = true; -    content = NULL; //G_BIN_FORMAT(format)->content; -    length = 0; //G_BIN_FORMAT(format)->length; +    content = G_BIN_FORMAT(format)->content; -    result &= read_uleb128(&pair->type_idx, content, pos, length); -    result &= read_uleb128(&pair->addr, content, pos, length); +    result &= g_binary_content_read_uleb128(content, pos, &pair->type_idx); +    result &= g_binary_content_read_uleb128(content, pos, &pair->addr);      return result; @@ -650,22 +607,20 @@ bool read_dex_encoded_type_addr_pair(const GDexFormat *format, off_t *pos, encod  *                                                                             *  ******************************************************************************/ -bool read_dex_encoded_catch_handler(const GDexFormat *format, off_t *pos, encoded_catch_handler *handler) +bool read_dex_encoded_catch_handler(const GDexFormat *format, vmpa2t *pos, encoded_catch_handler *handler)  {      bool result;                            /* Bilan à retourner           */ -    const bin_t *content;                   /* Contenu binaire à lire      */ -    off_t length;                           /* Taille totale du contenu    */ +    GBinContent *content;                   /* Contenu binaire à lire      */      leb128_t count;                         /* Nombre de gestionnaires     */      leb128_t i;                             /* Boucle de parcours          */      result = true; -    content = NULL; //G_BIN_FORMAT(format)->content; -    length = 0; //G_BIN_FORMAT(format)->length; +    content = G_BIN_FORMAT(format)->content; -    handler->offset = *pos; +    handler->offset = get_phy_addr(pos); -    result &= read_leb128(&handler->size, content, pos, length); +    result &= g_binary_content_read_leb128(content, pos, &handler->size);      count = leb128_abs(handler->size); @@ -680,7 +635,8 @@ bool read_dex_encoded_catch_handler(const GDexFormat *format, off_t *pos, encode      else handler->handlers = NULL;      if (handler->size < 0) -        result &= read_uleb128(&handler->catch_all_addr, content, pos, length); +        result &= g_binary_content_read_uleb128(content, pos, &handler->catch_all_addr); +      else          handler->catch_all_addr = ULEB128_MAX; @@ -723,22 +679,20 @@ void reset_dex_encoded_catch_handler(encoded_catch_handler *handler)  *                                                                             *  ******************************************************************************/ -bool read_dex_encoded_catch_handler_list(const GDexFormat *format, off_t *pos, encoded_catch_handler_list *list) +bool read_dex_encoded_catch_handler_list(const GDexFormat *format, vmpa2t *pos, encoded_catch_handler_list *list)  {      bool result;                            /* Bilan à retourner           */ -    const bin_t *content;                   /* Contenu binaire à lire      */ -    off_t length;                           /* Taille totale du contenu    */      off_t saved_off;                        /* Sauvegarde de position      */ +    GBinContent *content;                   /* Contenu binaire à lire      */      uleb128_t i;                            /* Boucle de parcours          */      result = true; -    content = NULL; //G_BIN_FORMAT(format)->content; -    length = 0; //G_BIN_FORMAT(format)->length; +    saved_off = get_phy_addr(pos); -    saved_off = *pos; +    content = G_BIN_FORMAT(format)->content; -    result &= read_uleb128(&list->size, content, pos, length); +    result &= g_binary_content_read_uleb128(content, pos, &list->size);      if (list->size > 0 && result)      { @@ -800,20 +754,18 @@ void reset_dex_encoded_catch_handler_list(encoded_catch_handler_list *list)  *                                                                             *  ******************************************************************************/ -bool read_dex_try_item(const GDexFormat *format, off_t *pos, try_item *item) +bool read_dex_try_item(const GDexFormat *format, vmpa2t *pos, try_item *item)  {      bool result;                            /* Bilan à retourner           */ -    const bin_t *content;                   /* Contenu binaire à lire      */ -    off_t length;                           /* Taille totale du contenu    */ +    GBinContent *content;                   /* Contenu binaire à lire      */      result = true; -    content = NULL; //G_BIN_FORMAT(format)->content; -    length = 0; //G_BIN_FORMAT(format)->length; +    content = G_BIN_FORMAT(format)->content; -    result &= read_u32(&item->start_addr, content, pos, length, SRE_LITTLE); -    result &= read_u16(&item->insn_count, content, pos, length, SRE_LITTLE); -    result &= read_u16(&item->handler_off, content, pos, length, SRE_LITTLE); +    result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &item->start_addr); +    result &= g_binary_content_read_u16(content, pos, SRE_LITTLE, &item->insn_count); +    result &= g_binary_content_read_u16(content, pos, SRE_LITTLE, &item->handler_off);      return result; @@ -834,33 +786,29 @@ bool read_dex_try_item(const GDexFormat *format, off_t *pos, try_item *item)  *                                                                             *  ******************************************************************************/ -bool read_dex_code_item(const GDexFormat *format, off_t *pos, code_item *item) +bool read_dex_code_item(const GDexFormat *format, vmpa2t *pos, code_item *item)  {      bool result;                            /* Bilan à retourner           */ -    const bin_t *content;                   /* Contenu binaire à lire      */ -    off_t length;                           /* Taille totale du contenu    */ +    GBinContent *content;                   /* Contenu binaire à lire      */      uint16_t padding;                       /* Eventuel alignement         */      uint16_t i;                             /* Boucle de parcours          */      result = true; -    content = NULL; //G_BIN_FORMAT(format)->content; -    length = 0; //G_BIN_FORMAT(format)->length; - -    result &= read_u16(&item->registers_size, content, pos, length, SRE_LITTLE); -    result &= read_u16(&item->ins_size, content, pos, length, SRE_LITTLE); -    result &= read_u16(&item->outs_size, content, pos, length, SRE_LITTLE); -    result &= read_u16(&item->tries_size, content, pos, length, SRE_LITTLE); -    result &= read_u32(&item->debug_info_off, content, pos, length, SRE_LITTLE); -    result &= read_u32(&item->insns_size, content, pos, length, SRE_LITTLE); +    content = G_BIN_FORMAT(format)->content; -    item->insns = (uint16_t *)pos; +    result &= g_binary_content_read_u16(content, pos, SRE_LITTLE, &item->registers_size); +    result &= g_binary_content_read_u16(content, pos, SRE_LITTLE, &item->ins_size); +    result &= g_binary_content_read_u16(content, pos, SRE_LITTLE, &item->outs_size); +    result &= g_binary_content_read_u16(content, pos, SRE_LITTLE, &item->tries_size); +    result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &item->debug_info_off); +    result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &item->insns_size); -    *pos += item->insns_size * sizeof(uint16_t); +    item->insns = (uint16_t *)g_binary_content_get_raw_access(content, pos, item->insns_size * sizeof(uint16_t));      /* Padding ? */      if (item->tries_size > 0 && item->insns_size % 2 == 1) -        result &= read_u16(&padding, content, pos, length, SRE_LITTLE); +        result &= g_binary_content_read_u16(content, pos, SRE_LITTLE, &padding);      if (item->tries_size > 0 && result)      { @@ -928,30 +876,28 @@ void reset_dex_code_item(code_item *item)  *                                                                             *  ******************************************************************************/ -bool read_dex_packed_switch(const GDexFormat *format, off_t *pos, packed_switch *packed) +bool read_dex_packed_switch(const GDexFormat *format, vmpa2t *pos, packed_switch *packed)  {      bool result;                            /* Bilan à retourner           */ -    const bin_t *content;                   /* Contenu binaire à lire      */ -    off_t length;                           /* Taille totale du contenu    */ +    GBinContent *content;                   /* Contenu binaire à lire      */      uint16_t i;                             /* Boucle de parcours          */      result = true; -    content = NULL; //G_BIN_FORMAT(format)->content; -    length = 0; //G_BIN_FORMAT(format)->length; -      packed->targets = NULL; -    result &= read_u16(&packed->ident, content, pos, length, SRE_LITTLE); -    result &= read_u16(&packed->size, content, pos, length, SRE_LITTLE); -    result &= read_u32(&packed->first_key, content, pos, length, SRE_LITTLE); +    content = G_BIN_FORMAT(format)->content; + +    result &= g_binary_content_read_u16(content, pos, SRE_LITTLE, &packed->ident); +    result &= g_binary_content_read_u16(content, pos, SRE_LITTLE, &packed->size); +    result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &packed->first_key);      if (result && packed->size > 0)      {          packed->targets = (uint32_t *)calloc(packed->size, sizeof(uint32_t));          for (i = 0; i < packed->size && result; i++) -            result &= read_u32(&packed->targets[i], content, pos, length, SRE_LITTLE); +            result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &packed->targets[i]);      } @@ -997,23 +943,21 @@ void reset_dex_packed_switch(packed_switch *packed)  *                                                                             *  ******************************************************************************/ -bool read_dex_sparse_switch(const GDexFormat *format, off_t *pos, sparse_switch *sparse) +bool read_dex_sparse_switch(const GDexFormat *format, vmpa2t *pos, sparse_switch *sparse)  {      bool result;                            /* Bilan à retourner           */ -    const bin_t *content;                   /* Contenu binaire à lire      */ -    off_t length;                           /* Taille totale du contenu    */ +    GBinContent *content;                   /* Contenu binaire à lire      */      uint16_t i;                             /* Boucle de parcours          */      result = true; -    content = NULL; //G_BIN_FORMAT(format)->content; -    length = 0; //G_BIN_FORMAT(format)->length; +    content = G_BIN_FORMAT(format)->content;      sparse->keys = NULL;      sparse->targets = NULL; -    result &= read_u16(&sparse->ident, content, pos, length, SRE_LITTLE); -    result &= read_u16(&sparse->size, content, pos, length, SRE_LITTLE); +    result &= g_binary_content_read_u16(content, pos, SRE_LITTLE, &sparse->ident); +    result &= g_binary_content_read_u16(content, pos, SRE_LITTLE, &sparse->size);      if (result && sparse->size > 0)      { @@ -1021,10 +965,10 @@ bool read_dex_sparse_switch(const GDexFormat *format, off_t *pos, sparse_switch          sparse->targets = (uint32_t *)calloc(sparse->size, sizeof(uint32_t));          for (i = 0; i < sparse->size && result; i++) -            result &= read_u32(&sparse->keys[i], content, pos, length, SRE_LITTLE); +            result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &sparse->keys[i]);          for (i = 0; i < sparse->size && result; i++) -            result &= read_u32(&sparse->targets[i], content, pos, length, SRE_LITTLE); +            result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &sparse->targets[i]);      } @@ -1073,19 +1017,21 @@ void reset_dex_sparse_switch(sparse_switch *sparse)  *                                                                             *  ******************************************************************************/ -bool read_dex_switch(const GDexFormat *format, off_t *pos, dex_switch *dswitch) +bool read_dex_switch(const GDexFormat *format, vmpa2t *pos, dex_switch *dswitch)  {      bool result;                            /* Bilan à retourner           */ -    const bin_t *content;                   /* Contenu binaire à lire      */ -    off_t length;                           /* Taille totale du contenu    */ +    GBinContent *content;                   /* Contenu binaire à lire      */      uint16_t ident;                         /* Pseudo-code d'identification*/      result = true; -    content = NULL; //G_BIN_FORMAT(format)->content; -    length = 0; //G_BIN_FORMAT(format)->length; +    content = G_BIN_FORMAT(format)->content; + +    result &= g_binary_content_read_u16(content, pos, SRE_LITTLE, &ident); -    result &= read_u16(&ident, content, (off_t []) { *pos }, length, SRE_LITTLE); +    /** +     * La tête de lecture n'est pas mise à jour volontairement ! +     */      if (result)      { diff --git a/src/format/dex/dex-int.h b/src/format/dex/dex-int.h index 1803e05..28aadd5 100755 --- a/src/format/dex/dex-int.h +++ b/src/format/dex/dex-int.h @@ -41,12 +41,11 @@ struct _GDexFormat      dex_header header;                      /* En-tête du programme        */ - - +    GDataType **types;                      /* Types partagés pour Dalvik  */ +    GBinVariable **fields;                  /* Champs de données partagés  */ +    GBinRoutine **prototypes;               /* Routines vierges à décorer  */ +    GDexMethod **methods;                   /* Méthodes retrouvées         */      GDexClass **classes;                    /* Classes retrouvées          */ -    size_t classes_count;                   /* Nombre de ces classes       */ - -  }; @@ -72,7 +71,7 @@ GDexClass *g_dex_format_get_class(const GDexFormat *, size_t);  /* Procède à la lecture d'une en-tête de programme DEX. */ -bool read_dex_header(const GDexFormat *, off_t *, dex_header *); +bool read_dex_header(const GDexFormat *, vmpa2t *, dex_header *); @@ -80,25 +79,25 @@ bool read_dex_header(const GDexFormat *, off_t *, dex_header *);  /* Procède à la lecture d'un identifiant de chaîne DEX. */ -bool read_dex_string_id_item(const GDexFormat *, off_t *, string_id_item *); +bool read_dex_string_id_item(const GDexFormat *, vmpa2t *, string_id_item *);  /* Procède à la lecture de proriétés de chaîne DEX. */ -bool read_dex_string_data_item(const GDexFormat *, off_t *, string_data_item *); +bool read_dex_string_data_item(const GDexFormat *, vmpa2t *, string_data_item *);  /* Procède à la lecture d'un identifiant de type DEX. */ -bool read_dex_type_id_item(const GDexFormat *, off_t *, type_id_item *); +bool read_dex_type_id_item(const GDexFormat *, vmpa2t *, type_id_item *);  /* Procède à la lecture d'une description de prototype. */ -bool read_dex_proto_id_item(const GDexFormat *, off_t *, proto_id_item *); +bool read_dex_proto_id_item(const GDexFormat *, vmpa2t *, proto_id_item *);  /* Procède à la lecture d'une description de champ. */ -bool read_dex_field_id_item(const GDexFormat *, off_t *, field_id_item *); +bool read_dex_field_id_item(const GDexFormat *, vmpa2t *, field_id_item *);  /* Procède à la lecture d'une description de méthode. */ -bool read_dex_method_id_item(const GDexFormat *, off_t *, method_id_item *); +bool read_dex_method_id_item(const GDexFormat *, vmpa2t *, method_id_item *);  /* Procède à la lecture des propriétés d'une classe DEX. */ -bool read_dex_class_def_item(const GDexFormat *, off_t *, class_def_item *); +bool read_dex_class_def_item(const GDexFormat *, vmpa2t *, class_def_item *); @@ -106,19 +105,19 @@ bool read_dex_class_def_item(const GDexFormat *, off_t *, class_def_item *);  /* Procède à la lecture d'un champ quelconque DEX. */ -bool read_dex_encoded_field(const GDexFormat *, off_t *, encoded_field *); +bool read_dex_encoded_field(const GDexFormat *, vmpa2t *, encoded_field *);  /* Procède à la lecture d'une méthode quelconque DEX. */ -bool read_dex_encoded_method(const GDexFormat *, off_t *, encoded_method *); +bool read_dex_encoded_method(const GDexFormat *, vmpa2t *, encoded_method *);  /* Procède à la lecture d'un type DEX. */ -bool read_dex_type_item(const GDexFormat *, off_t *, type_item *); +bool read_dex_type_item(const GDexFormat *, vmpa2t *, type_item *);  /* Procède à la lecture d'une liste de types DEX. */ -bool read_dex_type_list(const GDexFormat *, off_t *, type_list *); +bool read_dex_type_list(const GDexFormat *, vmpa2t *, type_list *);  /* Procède à la lecture d'un contenu de classe DEX. */ -bool read_dex_class_data_item(const GDexFormat *, off_t *, class_data_item *); +bool read_dex_class_data_item(const GDexFormat *, vmpa2t *, class_data_item *);  /* Supprime tous les éléments chargés en mémoire à la lecture. */  void reset_dex_class_data_item(class_data_item *); @@ -129,25 +128,25 @@ void reset_dex_class_data_item(class_data_item *);  /* Procède à la lecture d'une association exception <-> code. */ -bool read_dex_encoded_type_addr_pair(const GDexFormat *, off_t *, encoded_type_addr_pair *); +bool read_dex_encoded_type_addr_pair(const GDexFormat *, vmpa2t *, encoded_type_addr_pair *);  /* Procède à la lecture d'une association exception <-> code. */ -bool read_dex_encoded_catch_handler(const GDexFormat *, off_t *, encoded_catch_handler *); +bool read_dex_encoded_catch_handler(const GDexFormat *, vmpa2t *, encoded_catch_handler *);  /* Supprime tous les éléments chargés en mémoire à la lecture. */  void reset_dex_encoded_catch_handler(encoded_catch_handler *);  /* Procède à la lecture d'une association exception <-> code. */ -bool read_dex_encoded_catch_handler_list(const GDexFormat *, off_t *, encoded_catch_handler_list *); +bool read_dex_encoded_catch_handler_list(const GDexFormat *, vmpa2t *, encoded_catch_handler_list *);  /* Supprime tous les éléments chargés en mémoire à la lecture. */  void reset_dex_encoded_catch_handler_list(encoded_catch_handler_list *);  /* Procède à la lecture d'une association exception <-> code. */ -bool read_dex_try_item(const GDexFormat *, off_t *, try_item *); +bool read_dex_try_item(const GDexFormat *, vmpa2t *, try_item *);  /* Procède à la lecture d'une portion de code DEX. */ -bool read_dex_code_item(const GDexFormat *, off_t *, code_item *); +bool read_dex_code_item(const GDexFormat *, vmpa2t *, code_item *);  /* Supprime tous les éléments chargés en mémoire à la lecture. */  void reset_dex_code_item(code_item *); @@ -158,19 +157,19 @@ void reset_dex_code_item(code_item *);  /* Procède à la lecture d'un contenu d'aiguillage compact. */ -bool read_dex_packed_switch(const GDexFormat *, off_t *, packed_switch *); +bool read_dex_packed_switch(const GDexFormat *, vmpa2t *, packed_switch *);  /* Supprime tous les éléments chargés en mémoire à la lecture. */  void reset_dex_packed_switch(packed_switch *);  /* Procède à la lecture d'un contenu d'aiguillage dispersé. */ -bool read_dex_sparse_switch(const GDexFormat *, off_t *, sparse_switch *); +bool read_dex_sparse_switch(const GDexFormat *, vmpa2t *, sparse_switch *);  /* Supprime tous les éléments chargés en mémoire à la lecture. */  void reset_dex_sparse_switch(sparse_switch *);  /* Procède à la lecture d'un contenu d'aiguillage Dex interne. */ -bool read_dex_switch(const GDexFormat *, off_t *, dex_switch *); +bool read_dex_switch(const GDexFormat *, vmpa2t *, dex_switch *);  /* Supprime tous les éléments chargés en mémoire à la lecture. */  void reset_dex_switch(dex_switch *); diff --git a/src/format/dex/dex.c b/src/format/dex/dex.c index 0015357..35ffe47 100755 --- a/src/format/dex/dex.c +++ b/src/format/dex/dex.c @@ -45,49 +45,81 @@ static void g_dex_format_class_init(GDexFormatClass *);  /* Initialise une instance de format d'exécutable DEX. */  static void g_dex_format_init(GDexFormat *); -/* Détermine tous les fichiers source indiqués. */ -static void g_dex_format_find_all_sources(GDexFormat *); +/* Supprime toutes les références externes. */ +static void g_dex_format_dispose(GDexFormat *); -/* Procède à la décompilation complète du format. */ -static void g_dex_format_decompile(const GDexFormat *, GCodeBuffer *, const char *); +/* Procède à la libération totale de la mémoire. */ +static void g_dex_format_finalize(GDexFormat *);  /* Indique le type d'architecture visée par le format. */  static const char *g_dex_format_get_target_machine(const GDexFormat *); -/* Fournit les références aux zones binaires à analyser. */ -//static GBinPart **g_dex_format_get_parts(const GDexFormat *, size_t *); +/* Etend la définition des portions au sein d'un binaire. */ +static void g_dex_format_refine_portions(const GDexFormat *, GBinPortion *); + +/* Fournit l'emplacement d'une section donnée. */ +static bool g_dex_format_get_section_range_by_name(const GDexFormat *, const char *, mrange_t *); + + + + + + + + + + + -/* Fournit la position correspondant à une adresse virtuelle. */ -static bool g_dex_format_translate_address_into_offset(const GDexFormat *, vmpa_t, off_t *); -/* Fournit l'adresse virtuelle correspondant à une position. */ -static bool g_dex_format_translate_offset_into_address(const GDexFormat *, off_t, vmpa_t *); +/* Détermine tous les fichiers source indiqués. */ +//static void g_dex_format_find_all_sources(GDexFormat *); + +/* Procède à la décompilation complète du format. */ +static void g_dex_format_decompile(const GDexFormat *, GCodeBuffer *, const char *);  /******************************************************************************  *                                                                             *  *  Paramètres  : content = contenu binaire à parcourir.                       * +*                parent  = éventuel format exécutable déjà chargé.            * +*                unused  = adresse non utilisée ici.                          * +*                key     = identifiant de format trouvé ou NULL. [OUT]        *  *                                                                             *  *  Description : Indique si le format peut être pris en charge ici.           *  *                                                                             * -*  Retour      : true si la réponse est positive, false sinon.                * +*  Retour      : Conclusion de haut niveau sur la reconnaissance effectuée.   *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -bool dex_is_matching(GBinContent *content) +FormatMatchStatus dex_is_matching(GBinContent *content, GExeFormat *parent, void *unused, char **key)  { -    bool result;                            /* Bilan à faire connaître     */ +    FormatMatchStatus result;               /* Bilan à renvoyer            */      vmpa2t addr;                            /* Tête de lecture initiale    */ +    bool status;                            /* Bilan des accès mémoire     */      char magic[DEX_FILE_MAGIC_LEN];         /* Idenfiant standard          */ + +    /* REMME */ +    if (parent != NULL) return FMS_UNKNOWN; + +      init_vmpa(&addr, 0, VMPA_NO_VIRTUAL); -    result = g_binary_content_read_raw(content, &addr, DEX_FILE_MAGIC_LEN, (bin_t *)magic); +    status = g_binary_content_read_raw(content, &addr, DEX_FILE_MAGIC_LEN, (bin_t *)magic); -    result &= (memcmp(magic, DEX_FILE_MAGIC, DEX_FILE_MAGIC_LEN) == 0); +    status &= (memcmp(magic, DEX_FILE_MAGIC, DEX_FILE_MAGIC_LEN) == 0); + +    if (status) +    { +        result = FMS_MATCHED; +        *key = strdup(parent == NULL ? "dex" : "dexdbg"); +    } +    else +        result = FMS_UNKNOWN;      return result; @@ -112,6 +144,23 @@ G_DEFINE_TYPE(GDexFormat, g_dex_format, G_TYPE_EXE_FORMAT);  static void g_dex_format_class_init(GDexFormatClass *klass)  { +    GObjectClass *object;                   /* Autre version de la classe  */ +    GExeFormatClass *exe;                   /* Version en exécutable       */ + +    object = G_OBJECT_CLASS(klass); + +    object->dispose = (GObjectFinalizeFunc/* ! */)g_dex_format_dispose; +    object->finalize = (GObjectFinalizeFunc)g_dex_format_finalize; + +    exe = G_EXE_FORMAT_CLASS(klass); + +    exe->get_machine = (get_target_machine_fc)g_dex_format_get_target_machine; +    exe->refine_portions = (refine_portions_fc)g_dex_format_refine_portions; + +    exe->translate_phys = (translate_phys_fc)g_exe_format_without_virt_translate_offset_into_vmpa; +    exe->translate_virt = (translate_virt_fc)g_exe_format_without_virt_translate_address_into_vmpa; + +    exe->get_range_by_name = (get_range_by_name_fc)g_dex_format_get_section_range_by_name;  } @@ -130,19 +179,49 @@ static void g_dex_format_class_init(GDexFormatClass *klass)  static void g_dex_format_init(GDexFormat *format)  { -    GExeFormat *exe_format;                 /* Format parent à compléter #1*/ -    GBinFormat *bin_format;                 /* Format parent à compléter #2*/ +    GBinFormat *bin_format;                 /* Format parent à compléter #1*/      bin_format = G_BIN_FORMAT(format);      bin_format->decompile = (format_decompile_fc)g_dex_format_decompile; -    exe_format = G_EXE_FORMAT(format); +} -    exe_format->get_machine = (get_target_machine_fc)g_dex_format_get_target_machine; -    exe_format->translate_addr = (translate_addr_fc)g_dex_format_translate_address_into_offset; -    exe_format->translate_off = (translate_off_fc)g_dex_format_translate_offset_into_address; +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = instance d'objet GLib à traiter.                    * +*                                                                             * +*  Description : Supprime toutes les références externes.                     * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_dex_format_dispose(GDexFormat *format) +{ +    G_OBJECT_CLASS(g_dex_format_parent_class)->dispose(G_OBJECT(format)); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = instance d'objet GLib à traiter.                    * +*                                                                             * +*  Description : Procède à la libération totale de la mémoire.                * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_dex_format_finalize(GDexFormat *format) +{ +    G_OBJECT_CLASS(g_dex_format_parent_class)->finalize(G_OBJECT(format));  } @@ -150,9 +229,9 @@ static void g_dex_format_init(GDexFormat *format)  /******************************************************************************  *                                                                             *  *  Paramètres  : content = contenu binaire à parcourir.                       * -*                length  = taille du contenu en question.                     * +*                parent  = éventuel format exécutable déjà chargé.            *  *                                                                             * -*  Description : Prend en charge un nouveau format DEX.                       * +*  Description : Prend en charge un nouveau format Dex.                       *  *                                                                             *  *  Retour      : Adresse de la structure mise en place ou NULL en cas d'échec.*  *                                                                             * @@ -160,54 +239,127 @@ static void g_dex_format_init(GDexFormat *format)  *                                                                             *  ******************************************************************************/ -GBinFormat *g_dex_format_new(const bin_t *content, off_t length) +GBinFormat *g_dex_format_new(GBinContent *content, GExeFormat *parent)  {      GDexFormat *result;                     /* Structure à retourner       */ -    off_t offset;                           /* Tête de lecture             */ +    vmpa2t pos;                             /* Position de tête de lecture */      result = g_object_new(G_TYPE_DEX_FORMAT, NULL); -    //g_binary_format_set_content(G_BIN_FORMAT(result), content, length); +    g_binary_format_set_content(G_BIN_FORMAT(result), content); +    init_vmpa(&pos, 0, VMPA_NO_VIRTUAL); -    offset = 0; +    if (!read_dex_header(result, &pos, &result->header)) +        goto gdfn_error; -    if (!read_dex_header(result, &offset, &result->header)) -    { -        /* TODO */ -        return NULL; -    } +    if (!load_all_dex_types(result)) +        goto gdfn_error; -    /* TODO : vérifier l'en-tête ! */ +    if (!load_all_dex_fields(result)) +        goto gdfn_error; +    if (!load_all_dex_prototypes(result)) +        goto gdfn_error; +    if (!load_all_dex_methods(result)) +        goto gdfn_error;      if (!load_all_dex_classes(result)) -    { -        g_object_unref(G_OBJECT(result)); -        return NULL; -    } +        goto gdfn_error; -    register_all_dex_class_methods(result); +    return G_BIN_FORMAT(result); -    g_dex_format_find_all_sources(result); + gdfn_error: +    g_object_unref(G_OBJECT(result)); +    exit(0); -    if (!find_all_dex_strings(result)) -    { -        g_object_unref(G_OBJECT(result)); -        return NULL; -    } +    return NULL; +} -    return G_BIN_FORMAT(result); + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = informations chargées à consulter.                  * +*                                                                             * +*  Description : Indique le type d'architecture visée par le format.          * +*                                                                             * +*  Retour      : Identifiant de l'architecture ciblée par le format.          * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static const char *g_dex_format_get_target_machine(const GDexFormat *format) +{ +    return "dalvik"; + +} + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = informations chargées à consulter.                  * +*                raw    = portion de binaire brut à raffiner.                 * +*                                                                             * +*  Description : Etend la définition des portions au sein d'un binaire.       * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_dex_format_refine_portions(const GDexFormat *format, GBinPortion *raw) +{ +    size_t max;                             /* Nombre d'itérations prévues */ +    size_t i;                               /* Boucle de parcours          */ + +    max = g_dex_format_count_classes(format); + +    for (i = 0; i < max; i++) +        g_dex_class_include_as_portion(format->classes[i], raw);  }  /******************************************************************************  *                                                                             * +*  Paramètres  : format = description de l'exécutable à consulter.            * +*                name   = nom de la section recherchée.                       * +*                range  = emplacement en mémoire à renseigner. [OUT]          * +*                                                                             * +*  Description : Fournit l'emplacement d'une section donnée.                  * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool g_dex_format_get_section_range_by_name(const GDexFormat *format, const char *name, mrange_t *range) +{ +    bool result;                            /* Bilan à retourner           */ + +    result = false; + +    return result; + +} + + + + + + + + + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : format = informations chargées à consulter.                  *  *                addr   = adresse de la routine à retrouver.                  *  *                                                                             * @@ -221,6 +373,11 @@ GBinFormat *g_dex_format_new(const bin_t *content, off_t length)  GDexMethod *g_dex_format_find_method_by_address(const GDexFormat *format, vmpa_t addr)  { + +    return NULL; + + +#if 0      GDexMethod *result;                     /* Trouvaille à retourner      */      size_t i;                               /* Boucle de parcours          */ @@ -230,6 +387,7 @@ GDexMethod *g_dex_format_find_method_by_address(const GDexFormat *format, vmpa_t          result = g_dex_class_find_method_by_address(format->classes[i], addr);      return result; +#endif  } @@ -245,9 +403,12 @@ GDexMethod *g_dex_format_find_method_by_address(const GDexFormat *format, vmpa_t  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ - +#if 0  static void g_dex_format_find_all_sources(GDexFormat *format)  { + +#if 0 +      GBinFormat *bf;                         /* Instance parente            */      size_t i;                               /* Boucle de parcours #1       */      const char *source;                     /* Fichier source trouvé       */ @@ -275,8 +436,10 @@ static void g_dex_format_find_all_sources(GDexFormat *format)      } -} +#endif +} +#endif  /******************************************************************************  *                                                                             * @@ -294,6 +457,9 @@ static void g_dex_format_find_all_sources(GDexFormat *format)  static void g_dex_format_decompile(const GDexFormat *format, GCodeBuffer *buffer, const char *filename)  { + +#if 0 +      GLangOutput *lang;                      /* Langage de sortie           */      size_t i;                               /* Boucle de parcours          */      const char *source;                     /* Fichier source trouvé       */ @@ -328,106 +494,11 @@ char *_g_data_type_to_string(const GDataType *type, bool simple)      } -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : format = informations chargées à consulter.                  * -*                                                                             * -*  Description : Indique le type d'architecture visée par le format.          * -*                                                                             * -*  Retour      : Identifiant de l'architecture ciblée par le format.          * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static const char *g_dex_format_get_target_machine(const GDexFormat *format) -{ -    return "dalvik"; - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : format = informations chargées à consulter.                  * -*                count  = quantité de zones listées. [OUT]                    * -*                                                                             * -*  Description : Fournit les références aux zones binaires à analyser.        * -*                                                                             * -*  Retour      : Zones binaires à analyser.                                   * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ -#if 0 -static GBinPart **g_dex_format_get_parts(const GDexFormat *format, size_t *count) -{ -    GBinPart **result;                      /* Tableau à retourner         */ -    size_t i;                               /* Boucle de parcours          */ - -    result = NULL; -    *count = 0; - -    for (i = 0; i < format->classes_count; i++) -        result = g_dex_class_get_parts(format->classes[i], result, count); - -    return result; - -}  #endif -/****************************************************************************** -*                                                                             * -*  Paramètres  : format = description de l'exécutable à consulter.            * -*                addr   = adresse virtuelle à retrouver.                      * -*                pos    = position correspondante. [OUT]                      * -*                                                                             * -*  Description : Fournit la position correspondant à une adresse virtuelle.   * -*                                                                             * -*  Retour      : Bilan de l'opération.                                        * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static bool g_dex_format_translate_address_into_offset(const GDexFormat *format, vmpa_t addr, off_t *pos) -{ -    bool result;                            /* Bilan à retourner           */ - -    result = false; - -    return result; -  } -/****************************************************************************** -*                                                                             * -*  Paramètres  : format = description de l'exécutable à consulter.            * -*                pos    = position dans le flux binaire à retrouver.          * -*                addr   = adresse virtuelle correspondante. [OUT]             * -*                                                                             * -*  Description : Fournit l'adresse virtuelle correspondant à une position.    * -*                                                                             * -*  Retour      : Bilan de l'opération.                                        * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static bool g_dex_format_translate_offset_into_address(const GDexFormat *format, off_t pos, vmpa_t *addr) -{ -    bool result;                            /* Bilan à retourner           */ - -    result = false; - -    return result; - -} -  /******************************************************************************  *                                                                             * @@ -443,7 +514,11 @@ static bool g_dex_format_translate_offset_into_address(const GDexFormat *format,  size_t g_dex_format_count_classes(const GDexFormat *format)  { +    return 0; + +#if 0      return format->classes_count; +#endif  } @@ -466,3 +541,8 @@ GDexClass *g_dex_format_get_class(const GDexFormat *format, size_t index)      return format->classes[index];  } + + + + + diff --git a/src/format/dex/dex.h b/src/format/dex/dex.h index 7f427a3..1ff3809 100755 --- a/src/format/dex/dex.h +++ b/src/format/dex/dex.h @@ -30,7 +30,7 @@  #include <sys/types.h> -#include "../format.h" +#include "../../core/formats.h" @@ -49,13 +49,13 @@ typedef struct _GDexFormatClass GDexFormatClass;  /* Indique si le format peut être pris en charge ici. */ -bool dex_is_matching(GBinContent *); +FormatMatchStatus dex_is_matching(GBinContent *, GExeFormat *, void *, char **);  /* Indique le type défini pour un format d'exécutable DEX. */  GType g_dex_format_get_type(void);  /* Prend en charge un nouveau format DEX. */ -GBinFormat *g_dex_format_new(const bin_t *, off_t); +GBinFormat *g_dex_format_new(GBinContent *, GExeFormat *);  /* Redéfinition : classe issue du code source (instance) */  typedef struct _GDexClass GDexClass; diff --git a/src/format/dex/dex_def.h b/src/format/dex/dex_def.h index 09496b6..ea2cd60 100755 --- a/src/format/dex/dex_def.h +++ b/src/format/dex/dex_def.h @@ -250,7 +250,7 @@ typedef struct _encoded_catch_handler       * structure efface la représentation physique, on conserve en mémoire       * le décalage rencontré à la lecture dans un champ artificiel.       */ -    off_t offset;                           /* Position dans le binaire    */ +    phys_t offset;                          /* Position dans le binaire    */  } encoded_catch_handler; diff --git a/src/format/dex/method.c b/src/format/dex/method.c index c721cea..c68e9e1 100644 --- a/src/format/dex/method.c +++ b/src/format/dex/method.c @@ -24,13 +24,15 @@  #include "method.h" +#include <i18n.h> + +  #include "dex-int.h"  #include "pool.h" -  /* Methode issue du code source (instance) */  struct _GDexMethod  { @@ -58,12 +60,11 @@ static void g_dex_method_class_init(GDexMethodClass *);  /* Procède à l'initialisation d'une methode issue du code. */  static void g_dex_method_init(GDexMethod *); +/* Supprime toutes les références externes. */ +static void g_dex_method_dispose(GDexMethod *); - - - - - +/* Procède à la libération totale de la mémoire. */ +static void g_dex_method_finalize(GDexMethod *); @@ -86,6 +87,12 @@ G_DEFINE_TYPE(GDexMethod, g_dex_method, G_TYPE_OBJECT);  static void g_dex_method_class_init(GDexMethodClass *class)  { +    GObjectClass *object;                   /* Autre version de la classe  */ + +    object = G_OBJECT_CLASS(class); + +    object->dispose = (GObjectFinalizeFunc/* ! */)g_dex_method_dispose; +    object->finalize = (GObjectFinalizeFunc)g_dex_method_finalize;  } @@ -110,6 +117,47 @@ static void g_dex_method_init(GDexMethod *method)  /******************************************************************************  *                                                                             * +*  Paramètres  : format = instance d'objet GLib à traiter.                    * +*                                                                             * +*  Description : Supprime toutes les références externes.                     * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_dex_method_dispose(GDexMethod *method) +{ +    if (method->routine != NULL) +        g_object_unref(G_OBJECT(method->routine)); + +    G_OBJECT_CLASS(g_dex_method_parent_class)->dispose(G_OBJECT(method)); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : method = instance d'objet GLib à traiter.                    * +*                                                                             * +*  Description : Procède à la libération totale de la mémoire.                * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_dex_method_finalize(GDexMethod *method) +{ +    G_OBJECT_CLASS(g_dex_method_parent_class)->finalize(G_OBJECT(method)); + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : format = représentation interne du format DEX à consulter.   *  *                seed   = graine des informations à extraire.                 *  *                last   = dernier indice utilisé (à mettre à jour). [OUT]     * @@ -122,63 +170,63 @@ static void g_dex_method_init(GDexMethod *method)  *                                                                             *  ******************************************************************************/ -GDexMethod *g_dex_method_new(const GDexFormat *format, const encoded_method *seed, uleb128_t *last) +GDexMethod *g_dex_method_new(GDexFormat *format, const encoded_method *seed, uleb128_t *last)  {      GDexMethod *result;                     /* Composant à retourner       */ -    off_t offset;                           /* Tête de lecture             */ +    vmpa2t addr;                            /* Tête de lecture générique   */      code_item item;                         /* Corps de la méthode         */ +    GBinRoutine *routine;                   /* Routine représentée         */ +    mrange_t range;                         /* Emplacement du code associé */ +    init_vmpa(&addr, seed->code_off, VMPA_NO_VIRTUAL); -    GBinRoutine *routine; - -    vmpa2t addr; -    mrange_t range; - - -    offset = seed->code_off; - -    if (!read_dex_code_item(format, &offset, &item)) +    if (!read_dex_code_item(format, &addr, &item))          return NULL;      *last += seed->method_idx_diff; -    routine = get_routine_from_dex_pool(format, *last); +    routine = get_prototype_from_dex_pool(format, *last);      if (routine == NULL) return NULL; -      result = g_object_new(G_TYPE_DEX_METHOD, NULL);      result->info = *seed;      result->body = item; -    //printf(" ==== (%p) %s ====\n", routine, g_binary_routine_to_string(routine)); - -    //printf(" try ? %d\n", item.tries_size); +    result->offset = seed->code_off + 4 * sizeof(uint16_t) + 2 *sizeof(uint32_t);/* TODO : faire plus propre ! */ -    //printf(" method idx :: %d\n", seed->method_idx_diff); -    //printf(" code size  :: %d\n", item.insns_size); +    init_vmpa(&addr, result->offset, VMPA_NO_VIRTUAL); +    init_mrange(&range, &addr, item.insns_size * sizeof(uint16_t)); -    /* -    printf(" code regs  :: %d\n", item.registers_size); -    printf(" code ins   :: %d\n", item.ins_size); -    printf(" code outs  :: %d\n", item.outs_size); -    */ +    g_binary_routine_set_range(routine, &range); -    //printf(" method idx :: %lld\n", *last); +    result->routine = routine; +    return result; -    result->offset = seed->code_off + 4 * sizeof(uint16_t) + 2 *sizeof(uint32_t);/* TODO : faire plus propre ! */ +} -    //printf(" method off :: 0x%08x\n", result->offset); +/****************************************************************************** +*                                                                             * +*  Paramètres  : format    = représentation interne du format DEX à consulter.* +*                method_id = informations de base quant à la méthode.         * +*                                                                             * +*  Description : Crée une nouvelle représentation de methode vide.            * +*                                                                             * +*  Retour      : Composant GLib créé.                                         * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ -    init_vmpa(&addr, result->offset, VMPA_NO_VIRTUAL); -    init_mrange(&range, &addr, item.insns_size * sizeof(uint16_t)); +GDexMethod *g_dex_method_new_empty(const GDexFormat *format, const method_id_item *method_id) +{ +    GDexMethod *result;                     /* Composant à retourner       */ -    g_binary_routine_set_range(routine, &range); -    result->routine = routine; +    result = g_object_new(G_TYPE_DEX_METHOD, NULL);      return result; @@ -246,33 +294,43 @@ GBinRoutine *g_dex_method_get_routine(const GDexMethod *method)  /******************************************************************************  *                                                                             *  *  Paramètres  : method = représentation interne du format DEX à consulter.   * +*                raw    = portion de binaire brut à raffiner.                 *  *                                                                             * -*  Description : Fournit la zone binaire correspondant à la méthode.          * +*  Description : Intègre la méthode en tant que portion de code.              *  *                                                                             * -*  Retour      : Zone binaire à analyser.                                     * +*  Retour      : -                                                            *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -#if 0 -GBinPart *g_dex_method_as_part(const GDexMethod *method) + +void g_dex_method_include_as_portion(const GDexMethod *method, GBinPortion *raw)  { -    GBinPart *result;                       /* Instance à retourner        */ -    off_t size;                             /* Taille du code associé      */ +    GBinPortion *new;                       /* Nouvelle portion définie    */ +    char *desc;                             /* Description d'une portion   */ +    vmpa2t addr;                            /* Emplacement dans le binaire */ -    result = g_binary_part_new(); +    /* Si la taille est nulle, on ne fait rien */ +    if (method->info.access_flags & ACC_NATIVE) +        return; -    g_binary_part_set_name(result, "name"); +    new = g_binary_portion_new(BPC_CODE); -    if (method->info.access_flags & ACC_NATIVE) size = 0; -    else size = method->body.insns_size * sizeof(uint16_t); +    asprintf(&desc, _("Dalvik code")); -    g_binary_part_set_values(result, method->offset, size, method->offset); +    g_binary_portion_set_desc(new, desc); -    return result; +    free(desc); + +    init_vmpa(&addr, method->offset, VMPA_NO_VIRTUAL); +    g_binary_portion_set_values(new, &addr, method->body.insns_size * sizeof(uint16_t)); + +    g_binary_portion_set_rights(new, PAC_READ | PAC_EXEC); + +    g_binary_portion_include(raw, new);  } -#endif +  /******************************************************************************  *                                                                             * diff --git a/src/format/dex/method.h b/src/format/dex/method.h index 79e3077..dee33cb 100644 --- a/src/format/dex/method.h +++ b/src/format/dex/method.h @@ -67,7 +67,10 @@ typedef enum _DexVariableIndex  GType g_dex_method_get_type(void);  /* Crée une nouvelle représentation de methode issue de code. */ -GDexMethod *g_dex_method_new(const GDexFormat *, const encoded_method *, uleb128_t *); +GDexMethod *g_dex_method_new(GDexFormat *, const encoded_method *, uleb128_t *); + +/* Crée une nouvelle représentation de methode vide. */ +GDexMethod *g_dex_method_new_empty(const GDexFormat *, const method_id_item *);  /* Fournit les indications Dex concernant la méthode. */  const encoded_method *g_dex_method_get_dex_info(const GDexMethod *); @@ -78,8 +81,8 @@ const code_item *g_dex_method_get_dex_body(const GDexMethod *);  /* Fournit la routine OpenIDA correspondant à la méthode. */  GBinRoutine *g_dex_method_get_routine(const GDexMethod *); -/* Fournit la zone binaire correspondant à la méthode. */ -//GBinPart *g_dex_method_as_part(const GDexMethod *); +/* Intègre la méthode en tant que portion de code. */ +void g_dex_method_include_as_portion(const GDexMethod *, GBinPortion *);  /* Indique la position de la méthode au sein du binaire. */  off_t g_dex_method_get_offset(const GDexMethod *); diff --git a/src/format/dex/pool.c b/src/format/dex/pool.c index a869873..904ab76 100644 --- a/src/format/dex/pool.c +++ b/src/format/dex/pool.c @@ -24,11 +24,13 @@  #include "pool.h" +#include <malloc.h>  #include <string.h>  #include "dex-int.h"  #include "../mangling/demangler.h" +#include "../mangling/dex/context.h" @@ -83,6 +85,7 @@ bool find_all_dex_strings(GDexFormat *format)  const char *get_string_from_dex_pool(const GDexFormat *format, uint32_t index)  {      off_t pos;                              /* Tête de lecture             */ +    vmpa2t addr;                            /* Tête de lecture générique   */      string_id_item str_id;                  /* Identifiant de chaîne       */      string_data_item str_data;              /* Description de chaîne       */ @@ -90,13 +93,15 @@ const char *get_string_from_dex_pool(const GDexFormat *format, uint32_t index)          return NULL;      pos = format->header.string_ids_off + index * sizeof(string_id_item); +    init_vmpa(&addr, pos, VMPA_NO_VIRTUAL); -    if (!read_dex_string_id_item(format, &pos, &str_id)) +    if (!read_dex_string_id_item(format, &addr, &str_id))          return NULL;      pos = str_id.string_data_off; +    init_vmpa(&addr, pos, VMPA_NO_VIRTUAL); -    if (!read_dex_string_data_item(format, &pos, &str_data)) +    if (!read_dex_string_data_item(format, &addr, &str_data))          return NULL;      return (const char *)str_data.data; @@ -109,6 +114,49 @@ const char *get_string_from_dex_pool(const GDexFormat *format, uint32_t index) + + + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = description de l'exécutable à compléter.            * +*                                                                             * +*  Description : Charge en mémoire l'ensemble des types du format DEX.        * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool load_all_dex_types(GDexFormat *format) +{ +    bool result;                            /* Bilan à retourner           */ +    uint32_t i;                             /* Boucle de parcours          */ +    GDataType *type;                        /* Type récupéré               */ + +    result = true; + +    format->types = (GDataType **)calloc(format->header.type_ids_size, sizeof(GDataType *)); + +    for (i = 0; i < format->header.type_ids_size && result; i++) +    { +        type = get_type_from_dex_pool(format, i); + +        if (type != NULL) +            g_object_unref(G_OBJECT(type)); +        else +            result = false; + +    } + +    return result; + +} + +  /******************************************************************************  *                                                                             *  *  Paramètres  : format = représentation interne du format DEX à consulter.   * @@ -122,89 +170,94 @@ const char *get_string_from_dex_pool(const GDexFormat *format, uint32_t index)  *                                                                             *  ******************************************************************************/ -GDataType *get_type_from_dex_pool(const GDexFormat *format, uint16_t index) +GDataType *get_type_from_dex_pool(GDexFormat *format, uint32_t index)  { -    off_t pos;                              /* Tête de lecture             */ +    GDataType *result;                      /* Instance à retourner        */ +    phys_t pos;                             /* Tête de lecture             */ +    vmpa2t addr;                            /* Tête de lecture générique   */      type_id_item type_id;                   /* Définition de la classe     */      string_id_item str_id;                  /* Identifiant de chaîne       */      string_data_item str_data;              /* Description de chaîne       */ - -    //printf("Tp Index :: %hd / %d\n", index, format->header.type_ids_size); - +    result = NULL;      if (index >= format->header.type_ids_size) -        return NULL; - -    pos = format->header.type_ids_off + index * sizeof(type_id_item); +        goto gtfdp_error; -    if (!read_dex_type_id_item(format, &pos, &type_id)) -        return NULL; +    if (format->types[index] == NULL) +    { +        pos = format->header.type_ids_off + index * sizeof(type_id_item); +        init_vmpa(&addr, pos, VMPA_NO_VIRTUAL); +        if (!read_dex_type_id_item(format, &addr, &type_id)) +            goto gtfdp_error; +        pos = format->header.string_ids_off + type_id.descriptor_idx * sizeof(string_id_item); +        init_vmpa(&addr, pos, VMPA_NO_VIRTUAL); +        if (!read_dex_string_id_item(format, &addr, &str_id)) +            goto gtfdp_error; -    pos = format->header.string_ids_off + type_id.descriptor_idx * sizeof(string_id_item); +        pos = str_id.string_data_off; +        init_vmpa(&addr, pos, VMPA_NO_VIRTUAL); -    if (!read_dex_string_id_item(format, &pos, &str_id)) -        return NULL; +        if (!read_dex_string_data_item(format, &addr, &str_data)) +            goto gtfdp_error; -    pos = str_id.string_data_off; +        format->types[index] = demangle_type(G_TYPE_DEX_DEMANGLER, (char *)str_data.data); -    if (!read_dex_string_data_item(format, &pos, &str_data)) -        return NULL; +    } +    result = format->types[index]; -    //printf(">> String :: '%s'\n", str_data.data); +    if (result != NULL) +        g_object_ref(G_OBJECT(result)); + gtfdp_error: -    return demangle_type(DGT_JAVA, (char *)str_data.data); +    return result;  } - - -  /******************************************************************************  *                                                                             * -*  Paramètres  : format = représentation interne du format DEX à consulter.   * -*                index  = index de la classe recherchée.                      * +*  Paramètres  : format = description de l'exécutable à compléter.            *  *                                                                             * -*  Description : Extrait une représentation de classe d'une table DEX.        * +*  Description : Charge en mémoire l'ensemble des champs du format DEX.       *  *                                                                             * -*  Retour      : Composant GLib créé.                                         * +*  Retour      : Bilan de l'opération.                                        *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -GDataType *get_class_from_dex_pool(const GDexFormat *format, uint32_t index) +bool load_all_dex_fields(GDexFormat *format)  { -    GDataType *result;                      /* Instance à retourner        */ -    off_t pos;                              /* Tête de lecture             */ -    class_def_item class_def;               /* Définition de la classe     */ - -    if (index >= format->header.class_defs_size) -        return NULL; +    bool result;                            /* Bilan à retourner           */ +    uint32_t i;                             /* Boucle de parcours          */ +    GBinVariable *field;                    /* Champ récupéré              */ -    pos = format->header.class_defs_off + index * sizeof(class_def_item); - -    if (!read_dex_class_def_item(format, &pos, &class_def)) -        return NULL; +    result = true; +    format->fields = (GBinVariable **)calloc(format->header.field_ids_size, sizeof(GBinVariable *)); +    for (i = 0; i < format->header.field_ids_size && result; i++) +    { +        field = get_field_from_dex_pool(format, i); -    result = NULL; +        if (field != NULL) +            g_object_unref(G_OBJECT(field)); +        else +            result = false; +    }      return result;  } - -  /******************************************************************************  *                                                                             *  *  Paramètres  : format = représentation interne du format DEX à consulter.   * @@ -218,48 +271,67 @@ GDataType *get_class_from_dex_pool(const GDexFormat *format, uint32_t index)  *                                                                             *  ******************************************************************************/ -GBinVariable *get_field_from_dex_pool(const GDexFormat *format, uint32_t index) +GBinVariable *get_field_from_dex_pool(GDexFormat *format, uint32_t index)  {      GBinVariable *result;                   /* Instance à retourner        */ -    off_t pos;                              /* Tête de lecture             */ +    phys_t pos;                             /* Tête de lecture             */ +    vmpa2t addr;                            /* Tête de lecture générique   */      field_id_item field_id;                 /* Description du champ        */      GDataType *type;                        /* Type du champ               */      const char *name;                       /* Désignation humaine         */ +    GBinVariable *field;                    /* Instance nouvelle à définir */      GDataType *owner;                       /* Propriétaire du champ       */ +    result = NULL; +      if (index >= format->header.field_ids_size) -        return NULL; +        goto gffdp_error; -    pos = format->header.field_ids_off + index * sizeof(field_id_item); +    if (format->fields[index] == NULL) +    { +        pos = format->header.field_ids_off + index * sizeof(field_id_item); +        init_vmpa(&addr, pos, VMPA_NO_VIRTUAL); -    if (!read_dex_field_id_item(format, &pos, &field_id)) -        return NULL; +        if (!read_dex_field_id_item(format, &addr, &field_id)) +            goto gffdp_error; -    type = get_type_from_dex_pool(format, field_id.type_idx); +        type = get_type_from_dex_pool(format, field_id.type_idx); +        if (type == NULL) goto gffdp_error; -    name = get_string_from_dex_pool(format, field_id.name_idx); -    if (name == NULL) goto bad_name; +        name = get_string_from_dex_pool(format, field_id.name_idx); +        if (name == NULL) goto gffdp_bad_name; -    result = g_binary_variable_new(type); -    g_binary_variable_set_name(result, name); +        field = g_binary_variable_new(type); +        g_binary_variable_set_name(field, name); -    if (field_id.class_idx != NO_INDEX) -    { -        owner = get_type_from_dex_pool(format, field_id.class_idx); -        if (owner == NULL) goto bad_owner; +        if (field_id.class_idx != NO_INDEX) +        { +            owner = get_type_from_dex_pool(format, field_id.class_idx); +            if (owner == NULL) goto gffdp_bad_owner; + +            g_binary_variable_set_owner(field, owner); + +        } -        g_binary_variable_set_owner(result, owner); +        format->fields[index] = field;      } +    result = format->fields[index]; + +    if (result != NULL) +        g_object_ref(G_OBJECT(result)); + + gffdp_error: +      return result; - bad_owner: + gffdp_bad_owner:      g_object_ref(G_OBJECT(type));      g_object_unref(G_OBJECT(result)); - bad_name: + gffdp_bad_name:      g_object_unref(G_OBJECT(type)); @@ -270,6 +342,44 @@ GBinVariable *get_field_from_dex_pool(const GDexFormat *format, uint32_t index)  /******************************************************************************  *                                                                             * +*  Paramètres  : format = représentation interne du format DEX à compléter.   * +*                                                                             * +*  Description : Charge tous les prototypes listés dans le contenu binaire.   * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool load_all_dex_prototypes(GDexFormat *format) +{ +    bool result;                            /* Bilan à retourner           */ +    uint32_t i;                             /* Boucle de parcours          */ +    GBinRoutine *proto;                     /* Prototype récupéré          */ + +    result = true; + +    format->prototypes = (GBinRoutine **)calloc(format->header.proto_ids_size, sizeof(GBinRoutine *)); + +    for (i = 0; i < format->header.proto_ids_size && result; i++) +    { +        proto = get_prototype_from_dex_pool(format, i); + +        if (proto != NULL) +            g_object_unref(G_OBJECT(proto)); +        else +            result = false; + +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : format = représentation interne du format DEX à consulter.   *  *                index  = index de la routine recherchée.                     *  *                                                                             * @@ -281,114 +391,244 @@ GBinVariable *get_field_from_dex_pool(const GDexFormat *format, uint32_t index)  *                                                                             *  ******************************************************************************/ -GBinRoutine *get_routine_from_dex_pool(const GDexFormat *format, uint32_t index) +GBinRoutine *get_prototype_from_dex_pool(GDexFormat *format, uint32_t index)  {      GBinRoutine *result;                    /* Instance à retourner        */ -    off_t pos;                              /* Tête de lecture             */ -    method_id_item meth_id;                 /* Description de la méthode   */ +    phys_t pos;                             /* Tête de lecture             */ +    vmpa2t addr;                            /* Tête de lecture générique   */ +    proto_id_item proto_id;                 /* Prototype de routine        */ +    GDataType *type;                        /* Type de retour              */ +    const char *name;                       /* Description compressée      */ +    type_list args;                         /* Liste des arguments         */ +    uint32_t i;                             /* Boucle de parcours          */ +    GBinVariable *arg;                      /* Argument reconstitué        */ +    if (index >= format->header.method_ids_size) +        goto grfdp_error; -    GDataType *type; +    if (format->prototypes[index] == NULL) +    { +        pos = format->header.proto_ids_off + index * sizeof(proto_id_item); +        init_vmpa(&addr, pos, VMPA_NO_VIRTUAL); -    string_id_item str_id;                  /* Identifiant de chaîne       */ -    string_data_item str_data;              /* Description de chaîne       */ +        if (!read_dex_proto_id_item(format, &addr, &proto_id)) +            goto grfdp_error; +        /* Type de retour */ -    proto_id_item proto_id;                 /* Information de prototypage  */ -    type_list args;                         /* Liste des arguments         */ +        type = get_type_from_dex_pool(format, proto_id.return_type_idx); + +        /* Nom de la méthode */ + +        name = get_string_from_dex_pool(format, proto_id.shorty_idx); + +        /* Liste des arguments */ + +        pos = proto_id.parameters_off; +        init_vmpa(&addr, pos, VMPA_NO_VIRTUAL); + +        if (read_dex_type_list(format, &addr, &args)) +            for (i = 0; i < args.size; i++) +            { +                type = get_type_from_dex_pool(format, args.list[i].type_idx); +                if (type == NULL) continue; + +                arg = g_binary_variable_new(type); +                //g_binary_routine_add_arg(result, arg); + +            } + +        /* Mise en place finale */ + +        format->prototypes[index] = demangle_routine(G_TYPE_DEX_DEMANGLER, name); + +#if 0 +        if (format->prototypes[index] != NULL) +            g_binary_routine_set_return_type(format->prototypes[index], type); +#endif + +    } + +    result = format->prototypes[index]; + +    if (result != NULL) +        g_object_ref(G_OBJECT(result)); + + grfdp_error: + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = représentation interne du format DEX à compléter.   * +*                                                                             * +*  Description : Charge toutes les méthodes listées dans le contenu binaire.  * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool load_all_dex_methods(GDexFormat *format) +{ +    bool result;                            /* Bilan à retourner           */      uint32_t i;                             /* Boucle de parcours          */ -    GBinVariable *arg;                      /* Argument reconstitué        */ +    GDexMethod *method;                     /* Méthode récupérée           */ -    if (index >= format->header.method_ids_size) -        return NULL; +    result = true; -    pos = format->header.method_ids_off + index * sizeof(method_id_item); +    format->methods = (GDexMethod **)calloc(format->header.method_ids_size, sizeof(GDexMethod *)); -    if (!read_dex_method_id_item(format, &pos, &meth_id)) -        return NULL; +    for (i = 0; i < format->header.method_ids_size && result; i++) +    { +        method = get_method_from_dex_pool(format, i); +        if (method != NULL) +            g_object_unref(G_OBJECT(method)); +        else +            result = false; +    } +    return result; +} -    type = get_type_from_dex_pool(format, meth_id.class_idx); +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = représentation interne du format DEX à consulter.   * +*                index  = index de la classe recherchée.                      * +*                                                                             * +*  Description : Extrait une représentation de méthode d'une table DEX.       * +*                                                                             * +*  Retour      : Composant GLib créé.                                         * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ -    /* -    if (type == NULL) -        printf("class is nil\n"); +GDexMethod *get_method_from_dex_pool(GDexFormat *format, uint32_t index) +{ +    GDexMethod *result;                     /* Instance à retourner        */ +    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    */ -    else -        printf("class = '%s'\n", g_data_type_to_string(type)); -    */ +    result = NULL; -    /* Nom de la méthode */ +    if (index >= format->header.method_ids_size) +        goto gmfdp_error; -    pos = format->header.string_ids_off + meth_id.name_idx * sizeof(string_id_item); +    if (format->methods[index] == NULL) +    { +        pos = format->header.method_ids_off + index * sizeof(method_id_item); +        init_vmpa(&addr, pos, VMPA_NO_VIRTUAL); -    if (!read_dex_string_id_item(format, &pos, &str_id)) -        return NULL; +        if (!read_dex_method_id_item(format, &addr, &method_id)) +            goto gmfdp_error; -    pos = str_id.string_data_off; +        format->methods[index] = g_dex_method_new_empty(format, &method_id); -    if (!read_dex_string_data_item(format, &pos, &str_data)) -        return NULL; +    } +    result = format->methods[index]; -    //printf("String :: '%s'\n", str_data.data); +    if (result != NULL) +        g_object_ref(G_OBJECT(result)); + gmfdp_error: -    result = g_binary_routine_new(); +    return result; -    g_binary_routine_set_name(result, (char *)str_data.data); +} -    if (type != NULL) -        g_binary_routine_set_namespace(result, type); +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = représentation interne du format DEX à compléter.   * +*                                                                             * +*  Description : Charge toutes les classes listées dans le contenu binaire.   * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ +bool load_all_dex_classes(GDexFormat *format) +{ +    bool result;                            /* Bilan à retourner           */ +    uint32_t i;                             /* Boucle de parcours          */ +    GDexClass *class;                       /* Classe récupérée            */ -    /* -    printf("  ####\n"); -    printf("  ####  ROUTINE '%s'\n", g_binary_routine_to_string(result)); -    printf("  ####\n"); -    printf("  ####\n"); -    */ +    result = true; -    //printf("==>>> routine :: '%s'\n", g_binary_routine_to_string(result)); +    format->classes = (GDexClass **)calloc(format->header.class_defs_size, sizeof(GDexClass *)); +    for (i = 0; i < format->header.class_defs_size && result; i++) +    { +        class = get_class_from_dex_pool(format, i); +        if (class != NULL) +            g_object_unref(G_OBJECT(class)); +        else +            result = false; +    } +    return result; +} -    /* Retour de la routine */ +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = représentation interne du format DEX à consulter.   * +*                index  = index de la classe recherchée.                      * +*                                                                             * +*  Description : Extrait une représentation de classe d'une table DEX.        * +*                                                                             * +*  Retour      : Composant GLib créé.                                         * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ -    pos = format->header.proto_ids_off + meth_id.proto_idx * sizeof(proto_id_item); +GDexClass *get_class_from_dex_pool(GDexFormat *format, uint32_t index) +{ +    GDexClass *result;                      /* Instance à retourner        */ +    phys_t pos;                             /* Tête de lecture             */ +    vmpa2t addr;                            /* Tête de lecture générique   */ +    class_def_item class_def;               /* Définition de la classe     */ -    if (!read_dex_proto_id_item(format, &pos, &proto_id)) -        goto no_more_info; +    result = NULL; -    type = get_type_from_dex_pool(format, proto_id.return_type_idx); +    if (index >= format->header.class_defs_size) +        goto gcfdp_error; -    g_binary_routine_set_return_type(result, type); +    if (format->classes[index] == NULL) +    { +        pos = format->header.class_defs_off + index * sizeof(class_def_item); +        init_vmpa(&addr, pos, VMPA_NO_VIRTUAL); -    /* Arguments de la routine */ +        if (!read_dex_class_def_item(format, &addr, &class_def)) +            goto gcfdp_error; -    pos = proto_id.parameters_off; +        format->classes[index] = g_dex_class_new(format, &class_def); -    if (read_dex_type_list(format, &pos, &args)) -        for (i = 0; i < args.size; i++) -        { -            type = get_type_from_dex_pool(format, args.list[i].type_idx); -            if (type == NULL) continue; +    } -            arg = g_binary_variable_new(type); -            g_binary_routine_add_arg(result, arg); +    result = format->classes[index]; -        } +    if (result != NULL) +        g_object_ref(G_OBJECT(result)); - no_more_info: + gcfdp_error:      return result; diff --git a/src/format/dex/pool.h b/src/format/dex/pool.h index e947465..df02ed8 100644 --- a/src/format/dex/pool.h +++ b/src/format/dex/pool.h @@ -25,7 +25,9 @@  #define _FORMAT_DEX_POOL_H +#include "class.h"  #include "dex.h" +#include "method.h"  #include "../../analysis/routine.h" @@ -36,22 +38,39 @@ bool find_all_dex_strings(GDexFormat *);  /* Extrait une chaîne de caractères d'une table DEX. */  const char *get_string_from_dex_pool(const GDexFormat *, uint32_t); -/* Extrait une représentation de type d'une table DEX. */ -GDataType *get_type_from_dex_pool(const GDexFormat *, uint16_t); -/* Extrait une représentation de classe d'une table DEX. */ -GDataType *get_class_from_dex_pool(const GDexFormat *, uint32_t); +/* Charge en mémoire l'ensemble des types du format DEX. */ +bool load_all_dex_types(GDexFormat *); +/* Extrait une représentation de type d'une table DEX. */ +GDataType *get_type_from_dex_pool(GDexFormat *, uint32_t); +/* Charge en mémoire l'ensemble des champs du format DEX. */ +bool load_all_dex_fields(GDexFormat *);  /* Extrait une représentation de champ d'une table DEX. */ -GBinVariable *get_field_from_dex_pool(const GDexFormat *, uint32_t); +GBinVariable *get_field_from_dex_pool(GDexFormat *, uint32_t); + +/* Charge tous les prototypes listés dans le contenu binaire. */ +bool load_all_dex_prototypes(GDexFormat *);  /* Extrait une représentation de routine d'une table DEX. */ -GBinRoutine *get_routine_from_dex_pool(const GDexFormat *, uint32_t); +GBinRoutine *get_prototype_from_dex_pool(GDexFormat *, uint32_t); + +/* Charge toutes les méthodes listées dans le contenu binaire. */ +bool load_all_dex_methods(GDexFormat *); + +/* Extrait une représentation de méthode d'une table DEX. */ +GDexMethod *get_method_from_dex_pool(GDexFormat *, uint32_t); + +/* Charge toutes les classes listées dans le contenu binaire. */ +bool load_all_dex_classes(GDexFormat *); + +/* Extrait une représentation de classe d'une table DEX. */ +GDexClass *get_class_from_dex_pool(GDexFormat *, uint32_t); diff --git a/src/format/elf/elf.c b/src/format/elf/elf.c index 50df077..ea1f1ff 100644 --- a/src/format/elf/elf.c +++ b/src/format/elf/elf.c @@ -76,7 +76,7 @@ static bool g_elf_format_translate_offset_into_vmpa(const GElfFormat *, phys_t,  static bool g_elf_format_translate_address_into_vmpa(const GElfFormat *, virt_t, vmpa2t *);  /* Fournit l'emplacement d'une section donnée. */ -bool g_elf_format_get_section_range_by_name(const GElfFormat *, const char *, mrange_t *); +static bool g_elf_format_get_section_range_by_name(const GElfFormat *, const char *, mrange_t *); @@ -149,6 +149,9 @@ static void g_elf_format_class_init(GElfFormatClass *klass)      exe = G_EXE_FORMAT_CLASS(klass); +    exe->get_machine = (get_target_machine_fc)g_elf_format_get_target_machine; +    exe->refine_portions = (refine_portions_fc)g_elf_format_refine_portions; +      exe->translate_phys = (translate_phys_fc)g_elf_format_translate_offset_into_vmpa;      exe->translate_virt = (translate_virt_fc)g_elf_format_translate_address_into_vmpa; @@ -171,12 +174,6 @@ static void g_elf_format_class_init(GElfFormatClass *klass)  static void g_elf_format_init(GElfFormat *format)  { -    GExeFormat *exe_format;                 /* Format parent à constituer  */ - -    exe_format = G_EXE_FORMAT(format); - -    exe_format->get_machine = (get_target_machine_fc)g_elf_format_get_target_machine; -    exe_format->refine_portions = (refine_portions_fc)g_elf_format_refine_portions;  } @@ -393,9 +390,9 @@ static void g_elf_format_refine_portions(const GElfFormat *format, GBinPortion *          new = g_binary_portion_new(background); -        sprintf(desc, "%s \"%s\"", -                _("Segment"), -                get_elf_program_type_desc(ELF_PHDR(format, phdr, p_type))); +        snprintf(desc, MAX_PORTION_DESC, "%s \"%s\"", +                 _("Segment"), +                 get_elf_program_type_desc(ELF_PHDR(format, phdr, p_type)));          g_binary_portion_set_desc(new, desc); @@ -532,7 +529,7 @@ static bool g_elf_format_translate_address_into_vmpa(const GElfFormat *format, v  *                                                                             *  ******************************************************************************/ -bool g_elf_format_get_section_range_by_name(const GElfFormat *format, const char *name, mrange_t *range) +static bool g_elf_format_get_section_range_by_name(const GElfFormat *format, const char *name, mrange_t *range)  {      bool result;                            /* Bilan à retourner           */      phys_t offset;                          /* Position physique de section*/ diff --git a/src/format/executable-int.c b/src/format/executable-int.c new file mode 100644 index 0000000..c4b8e6e --- /dev/null +++ b/src/format/executable-int.c @@ -0,0 +1,69 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * executable-int.c - code utile aux formats d'exécutables + * + * Copyright (C) 2015 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  OpenIDA is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  OpenIDA is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "executable-int.h" + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = description de l'exécutable à consulter.            * +*                off    = position physique à retrouver.                      * +*                pos    = position correspondante. [OUT]                      * +*                                                                             * +*  Description : Fournit l'emplacement correspondant à une position physique. * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool g_exe_format_without_virt_translate_offset_into_vmpa(const GExeFormat *format, phys_t off, vmpa2t *pos) +{ +    init_vmpa(pos, off, VMPA_NO_VIRTUAL); + +    return true; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = description de l'exécutable à consulter.            * +*                addr   = adresse virtuelle à retrouver.                      * +*                pos    = position correspondante. [OUT]                      * +*                                                                             * +*  Description : Fournit l'emplacement correspondant à une adresse virtuelle. * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool g_exe_format_without_virt_translate_address_into_vmpa(const GExeFormat *format, virt_t addr, vmpa2t *pos) +{ +    return false; + +} diff --git a/src/format/executable-int.h b/src/format/executable-int.h index f5a25b5..4b86092 100644 --- a/src/format/executable-int.h +++ b/src/format/executable-int.h @@ -1,6 +1,6 @@  /* Chrysalide - Outil d'analyse de fichiers binaires - * executable-int.h - prototypes utiles aux formats d'exécutables + * executable-int.h - prototypes de code utile aux formats d'exécutables   *   * Copyright (C) 2009-2013 Cyrille Bagard   * @@ -38,14 +38,6 @@ typedef const char * (* get_target_machine_fc) (const GExeFormat *);  /* Etend la définition des portions au sein d'un binaire. */  typedef void (* refine_portions_fc) (const GExeFormat *, GBinPortion *); -/* Fournit la position correspondant à une adresse virtuelle. */ -typedef bool (* translate_addr_fc) (const GExeFormat *, vmpa_t, off_t *); - -/* Fournit l'adresse virtuelle correspondant à une position. */ -typedef bool (* translate_off_fc) (const GExeFormat *, off_t, vmpa_t *); - - -  /* Fournit l'emplacement correspondant à une position physique. */  typedef bool (* translate_phys_fc) (const GExeFormat *, phys_t, vmpa2t *); @@ -65,12 +57,6 @@ struct _GExeFormat      GDbgFormat **debugs;                    /* Informations de débogage    */      size_t debugs_count;                    /* Nombre de ces informations  */ -    get_target_machine_fc get_machine;      /* Architecture ciblée         */ -    refine_portions_fc refine_portions;     /* Décrit les portions binaires*/ - -    translate_addr_fc translate_addr;       /* Correspondance addr -> pos  */ -    translate_off_fc translate_off;         /* Correspondance pos -> addr  */ -      GBinPortion *portions;                  /* Morceaux binaires distincts */  }; @@ -80,6 +66,9 @@ struct _GExeFormatClass  {      GBinFormatClass parent;                 /* A laisser en premier        */ +    get_target_machine_fc get_machine;      /* Architecture ciblée         */ +    refine_portions_fc refine_portions;     /* Décrit les portions binaires*/ +      translate_phys_fc translate_phys;       /* Correspondance phys -> vmpa */      translate_virt_fc translate_virt;       /* Correspondance virt -> vmpa */ @@ -88,5 +77,12 @@ struct _GExeFormatClass  }; +/* Fournit l'emplacement correspondant à une position physique. */ +bool g_exe_format_without_virt_translate_offset_into_vmpa(const GExeFormat *, phys_t, vmpa2t *); + +/* Fournit l'emplacement correspondant à une adresse virtuelle. */ +bool g_exe_format_without_virt_translate_address_into_vmpa(const GExeFormat *, virt_t, vmpa2t *); + +  #endif  /* _FORMAT_EXECUTABLE_INT_H */ diff --git a/src/format/executable.c b/src/format/executable.c index 5ff773c..325dc8b 100644 --- a/src/format/executable.c +++ b/src/format/executable.c @@ -182,7 +182,7 @@ GDbgFormat *g_exe_format_get_debug_info(const GExeFormat *format, size_t index)  const char *g_exe_format_get_target_machine(const GExeFormat *format)  { -    return format->get_machine(format); +    return G_EXE_FORMAT_GET_CLASS(format)->get_machine(format);  } @@ -213,8 +213,7 @@ GBinPortion *g_exe_format_get_portions(GExeFormat *format)          g_binary_portion_set_values(format->portions, &addr, length); -        if (format->refine_portions != NULL) -            format->refine_portions(format, format->portions); +        G_EXE_FORMAT_GET_CLASS(format)->refine_portions(format, format->portions);      } diff --git a/src/format/java/java.c b/src/format/java/java.c index 39403c4..4fcecd9 100755 --- a/src/format/java/java.c +++ b/src/format/java/java.c @@ -45,14 +45,14 @@ static void g_java_format_class_init(GJavaFormatClass *);  /* Initialise une instance de format d'exécutable Java. */  static void g_java_format_init(GJavaFormat *); -/* Indique le type d'architecture visée par le format. */ -static const char *g_java_format_get_target_machine(const GJavaFormat *); +/* Supprime toutes les références externes. */ +static void g_java_format_dispose(GJavaFormat *); -/* Fournit la position correspondant à une adresse virtuelle. */ -static bool g_java_format_translate_address_into_offset(const GJavaFormat *, vmpa_t, off_t *); +/* Procède à la libération totale de la mémoire. */ +static void g_java_format_finalize(GJavaFormat *); -/* Fournit l'adresse virtuelle correspondant à une position. */ -static bool g_java_format_translate_offset_into_address(const GJavaFormat *, off_t, vmpa_t *); +/* Indique le type d'architecture visée par le format. */ +static const char *g_java_format_get_target_machine(const GJavaFormat *); @@ -103,6 +103,21 @@ G_DEFINE_TYPE(GJavaFormat, g_java_format, G_TYPE_EXE_FORMAT);  static void g_java_format_class_init(GJavaFormatClass *klass)  { +    GObjectClass *object;                   /* Autre version de la classe  */ +    GExeFormatClass *exe;                   /* Version en exécutable       */ + +    object = G_OBJECT_CLASS(klass); + +    object->dispose = (GObjectFinalizeFunc/* ! */)g_java_format_dispose; +    object->finalize = (GObjectFinalizeFunc)g_java_format_finalize; + +    exe = G_EXE_FORMAT_CLASS(klass); + +    exe->get_machine = (get_target_machine_fc)g_java_format_get_target_machine; +    //exe->refine_portions = (refine_portions_fc)g_java_format_refine_portions; + +    exe->translate_phys = (translate_phys_fc)g_exe_format_without_virt_translate_offset_into_vmpa; +    exe->translate_virt = (translate_virt_fc)g_exe_format_without_virt_translate_address_into_vmpa;  } @@ -121,14 +136,44 @@ static void g_java_format_class_init(GJavaFormatClass *klass)  static void g_java_format_init(GJavaFormat *format)  { -    GExeFormat *exe_format;                 /* Format parent à constituer  */ -    exe_format = G_EXE_FORMAT(format); +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = instance d'objet GLib à traiter.                    * +*                                                                             * +*  Description : Supprime toutes les références externes.                     * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_java_format_dispose(GJavaFormat *format) +{ +    G_OBJECT_CLASS(g_java_format_parent_class)->dispose(G_OBJECT(format)); + +} + -    exe_format->get_machine = (get_target_machine_fc)g_java_format_get_target_machine; +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = instance d'objet GLib à traiter.                    * +*                                                                             * +*  Description : Procède à la libération totale de la mémoire.                * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ -    exe_format->translate_addr = (translate_addr_fc)g_java_format_translate_address_into_offset; -    exe_format->translate_off = (translate_off_fc)g_java_format_translate_offset_into_address; +static void g_java_format_finalize(GJavaFormat *format) +{ +    G_OBJECT_CLASS(g_java_format_parent_class)->finalize(G_OBJECT(format));  } @@ -189,63 +234,6 @@ static const char *g_java_format_get_target_machine(const GJavaFormat *format)  } -/****************************************************************************** -*                                                                             * -*  Paramètres  : format = description de l'exécutable à consulter.            * -*                addr   = adresse virtuelle à retrouver.                      * -*                pos    = position correspondante. [OUT]                      * -*                                                                             * -*  Description : Fournit la position correspondant à une adresse virtuelle.   * -*                                                                             * -*  Retour      : Bilan de l'opération.                                        * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static bool g_java_format_translate_address_into_offset(const GJavaFormat *format, vmpa_t addr, off_t *pos) -{ -    bool result;                            /* Bilan à retourner           */ - -    result = false; - -    return result; - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : format = description de l'exécutable à consulter.            * -*                pos    = position dans le flux binaire à retrouver.          * -*                addr   = adresse virtuelle correspondante. [OUT]             * -*                                                                             * -*  Description : Fournit l'adresse virtuelle correspondant à une position.    * -*                                                                             * -*  Retour      : Bilan de l'opération.                                        * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static bool g_java_format_translate_offset_into_address(const GJavaFormat *format, off_t pos, vmpa_t *addr) -{ -    bool result;                            /* Bilan à retourner           */ - -    result = false; - -    return result; - -} - - - - - - - - - diff --git a/src/format/pe/pe.c b/src/format/pe/pe.c index 39560ce..239f52a 100644 --- a/src/format/pe/pe.c +++ b/src/format/pe/pe.c @@ -45,12 +45,6 @@ static const char *g_pe_format_get_target_machine(const GPeFormat *);  /* Fournit les références aux zones binaires à analyser. */  //static GBinPart **g_pe_format_get_parts(const GPeFormat *, size_t *); -/* Fournit la position correspondant à une adresse virtuelle. */ -static bool g_pe_format_translate_address_into_offset(const GPeFormat *, vmpa_t, off_t *); - -/* Fournit l'adresse virtuelle correspondant à une position. */ -static bool g_pe_format_translate_offset_into_address(const GPeFormat *, off_t, vmpa_t *); -  /****************************************************************************** @@ -130,14 +124,6 @@ static void g_pe_format_class_init(GPeFormatClass *klass)  static void g_pe_format_init(GPeFormat *format)  { -    GExeFormat *exe_format;                 /* Format parent à constituer  */ - -    exe_format = G_EXE_FORMAT(format); - -    exe_format->get_machine = (get_target_machine_fc)g_pe_format_get_target_machine; - -    exe_format->translate_addr = (translate_addr_fc)g_pe_format_translate_address_into_offset; -    exe_format->translate_off = (translate_off_fc)g_pe_format_translate_offset_into_address;  } @@ -286,52 +272,3 @@ static GBinPart **g_pe_format_get_parts(const GPeFormat *format, size_t *count)  }  #endif - -/****************************************************************************** -*                                                                             * -*  Paramètres  : format = description de l'exécutable à consulter.            * -*                addr   = adresse virtuelle à retrouver.                      * -*                pos    = position correspondante. [OUT]                      * -*                                                                             * -*  Description : Fournit la position correspondant à une adresse virtuelle.   * -*                                                                             * -*  Retour      : Bilan de l'opération.                                        * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static bool g_pe_format_translate_address_into_offset(const GPeFormat *format, vmpa_t addr, off_t *pos) -{ -    bool result;                            /* Bilan à retourner           */ - -    result = false; - -    return result; - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : format = description de l'exécutable à consulter.            * -*                pos    = position dans le flux binaire à retrouver.          * -*                addr   = adresse virtuelle correspondante. [OUT]             * -*                                                                             * -*  Description : Fournit l'adresse virtuelle correspondant à une position.    * -*                                                                             * -*  Retour      : Bilan de l'opération.                                        * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static bool g_pe_format_translate_offset_into_address(const GPeFormat *format, off_t pos, vmpa_t *addr) -{ -    bool result;                            /* Bilan à retourner           */ - -    result = false; - -    return result; - -} | 
