summaryrefslogtreecommitdiff
path: root/src/format/dex
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2012-12-10 23:41:09 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2012-12-10 23:41:09 (GMT)
commit79ec14ee5c1cea5c4ad345a7047b47b9205fc29e (patch)
tree0596bb4b7910964ef96c3705c80ec5dba677eeb0 /src/format/dex
parent42420cfa1f406a5f0a9f062b258ece72098635b5 (diff)
Took care of Dalvik switch cases.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@299 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/format/dex')
-rw-r--r--src/format/dex/dex-int.c273
-rwxr-xr-xsrc/format/dex/dex-int.h23
-rwxr-xr-xsrc/format/dex/dex_def.h109
3 files changed, 336 insertions, 69 deletions
diff --git a/src/format/dex/dex-int.c b/src/format/dex/dex-int.c
index 200b01f..58211e5 100644
--- a/src/format/dex/dex-int.c
+++ b/src/format/dex/dex-int.c
@@ -27,11 +27,80 @@
#include <malloc.h>
+#include "../../arch/dalvik/instruction-def.h"
#include "../../common/endianness.h"
/* ---------------------------------------------------------------------------------- */
+/* DESCRIPTION DU FORMAT DALVIK */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : format = informations chargées à consulter. *
+* pos = position de début de lecture. [OUT] *
+* header = structure lue à retourner. [OUT] *
+* *
+* Description : Procède à la lecture d'une en-tête de programme DEX. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool read_dex_header(const GDexFormat *format, off_t *pos, dex_header *header)
+{
+ bool result; /* Bilan à retourner */
+ const bin_t *content; /* Contenu binaire à lire */
+ off_t length; /* Taille totale du contenu */
+ size_t i; /* Boucle de parcours */
+
+ result = true;
+
+ content = G_BIN_FORMAT(format)->content;
+ length = G_BIN_FORMAT(format)->length;
+
+ for (i = 0; i < DEX_FILE_MAGIC_LEN && result; i++)
+ result = read_u8(&header->magic[i], content, pos, length, SRE_LITTLE);
+
+ result &= read_u32(&header->checksum, content, pos, length, SRE_LITTLE);
+
+ for (i = 0; i < 20 && result; i++)
+ result = read_u8(&header->signature[i], content, pos, length, SRE_LITTLE);
+
+ 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);
+
+ return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
/* ELEMENTS DE TABLE DES CONSTANTES */
/* ---------------------------------------------------------------------------------- */
@@ -840,18 +909,87 @@ void reset_dex_code_item(code_item *item)
+/* ---------------------------------------------------------------------------------- */
+/* AIGUILLAGES DIVERS */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : format = informations chargées à consulter. *
+* pos = position de début de lecture. [OUT] *
+* packed = structure lue à retourner. [OUT] *
+* *
+* Description : Procède à la lecture d'un contenu d'aiguillage compact. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool read_dex_packed_switch(const GDexFormat *format, off_t *pos, packed_switch *packed)
+{
+ bool result; /* Bilan à retourner */
+ const bin_t *content; /* Contenu binaire à lire */
+ off_t length; /* Taille totale du contenu */
+ uint16_t i; /* Boucle de parcours */
+
+ result = true;
+
+ content = G_BIN_FORMAT(format)->content;
+ length = 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);
+ 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);
+
+ }
+
+ if (!result)
+ reset_dex_packed_switch(packed);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : packed = structure à nettoyer. *
+* *
+* Description : Supprime tous les éléments chargés en mémoire à la lecture. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+void reset_dex_packed_switch(packed_switch *packed)
+{
+ if (packed->targets != NULL)
+ free(packed->targets);
+}
/******************************************************************************
* *
* Paramètres : format = informations chargées à consulter. *
* pos = position de début de lecture. [OUT] *
-* header = structure lue à retourner. [OUT] *
+* sparse = structure lue à retourner. [OUT] *
* *
-* Description : Procède à la lecture d'une en-tête de programme DEX. *
+* Description : Procède à la lecture d'un contenu d'aiguillage dispersé. *
* *
* Retour : Bilan de l'opération. *
* *
@@ -859,54 +997,131 @@ void reset_dex_code_item(code_item *item)
* *
******************************************************************************/
-bool read_dex_header(const GDexFormat *format, off_t *pos, dex_header *header)
+bool read_dex_sparse_switch(const GDexFormat *format, off_t *pos, sparse_switch *sparse)
{
bool result; /* Bilan à retourner */
const bin_t *content; /* Contenu binaire à lire */
off_t length; /* Taille totale du contenu */
- size_t i; /* Boucle de parcours */
+ uint16_t i; /* Boucle de parcours */
result = true;
content = G_BIN_FORMAT(format)->content;
length = G_BIN_FORMAT(format)->length;
- for (i = 0; i < DEX_FILE_MAGIC_LEN && result; i++)
- result = read_u8(&header->magic[i], content, pos, length, SRE_LITTLE);
+ sparse->keys = NULL;
+ sparse->targets = NULL;
- result &= read_u32(&header->checksum, content, pos, length, SRE_LITTLE);
+ result &= read_u16(&sparse->ident, content, pos, length, SRE_LITTLE);
+ result &= read_u16(&sparse->size, content, pos, length, SRE_LITTLE);
- for (i = 0; i < 20 && result; i++)
- result = read_u8(&header->signature[i], content, pos, length, SRE_LITTLE);
+ if (result && sparse->size > 0)
+ {
+ sparse->keys = (uint32_t *)calloc(sparse->size, sizeof(uint32_t));
+ sparse->targets = (uint32_t *)calloc(sparse->size, sizeof(uint32_t));
- result &= read_u32(&header->file_size, content, pos, length, SRE_LITTLE);
- result &= read_u32(&header->header_size, content, pos, length, SRE_LITTLE);
+ for (i = 0; i < sparse->size && result; i++)
+ result &= read_u32(&sparse->keys[i], content, pos, length, SRE_LITTLE);
- result &= read_u32(&header->endian_tag, content, pos, length, SRE_LITTLE);
+ for (i = 0; i < sparse->size && result; i++)
+ result &= read_u32(&sparse->targets[i], 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);
+ }
+
+ if (!result)
+ reset_dex_sparse_switch(sparse);
return result;
}
+/******************************************************************************
+* *
+* Paramètres : sparse = structure à nettoyer. *
+* *
+* Description : Supprime tous les éléments chargés en mémoire à la lecture. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void reset_dex_sparse_switch(sparse_switch *sparse)
+{
+ if (sparse->keys != NULL)
+ free(sparse->keys);
+
+ if (sparse->targets != NULL)
+ free(sparse->targets);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = informations chargées à consulter. *
+* pos = position de début de lecture. [OUT] *
+* dsxitch = structure lue à retourner. [OUT] *
+* *
+* Description : Procède à la lecture d'un contenu d'aiguillage Dex interne. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool read_dex_switch(const GDexFormat *format, off_t *pos, dex_switch *dswitch)
+{
+ bool result; /* Bilan à retourner */
+ const bin_t *content; /* Contenu binaire à lire */
+ off_t length; /* Taille totale du contenu */
+ uint16_t ident; /* Pseudo-code d'identification*/
+
+ result = true;
+
+ content = G_BIN_FORMAT(format)->content;
+ length = G_BIN_FORMAT(format)->length;
+
+ result &= read_u16(&ident, content, (off_t []) { *pos }, length, SRE_LITTLE);
+
+ if (result)
+ {
+ if (ident == DPO_PACKED_SWITCH)
+ result = read_dex_packed_switch(format, pos, (packed_switch *)dswitch);
+
+ else if (ident == DPO_SPARSE_SWITCH)
+ result = read_dex_sparse_switch(format, pos, (sparse_switch *)dswitch);
+
+ else
+ result = false;
+ }
+
+ return result;
+}
+
+/******************************************************************************
+* *
+* Paramètres : dswitch = structure à nettoyer. *
+* *
+* Description : Supprime tous les éléments chargés en mémoire à la lecture. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void reset_dex_switch(dex_switch *dswitch)
+{
+ if (dswitch->packed.ident == DPO_PACKED_SWITCH)
+ reset_dex_packed_switch((packed_switch *)dswitch);
+ else
+ reset_dex_sparse_switch((sparse_switch *)dswitch);
+
+}
diff --git a/src/format/dex/dex-int.h b/src/format/dex/dex-int.h
index 6a153c1..55a48b5 100755
--- a/src/format/dex/dex-int.h
+++ b/src/format/dex/dex-int.h
@@ -68,6 +68,13 @@ size_t g_dex_format_count_classes(const GDexFormat *);
GDexClass *g_dex_format_get_class(const GDexFormat *, size_t);
+/* -------------------------- DESCRIPTION DU FORMAT DALVIK -------------------------- */
+
+
+/* Procède à la lecture d'une en-tête de programme DEX. */
+bool read_dex_header(const GDexFormat *, off_t *, dex_header *);
+
+
/* ------------------------ ELEMENTS DE TABLE DES CONSTANTES ------------------------ */
@@ -147,14 +154,26 @@ void reset_dex_code_item(code_item *);
+/* ------------------------------- AIGUILLAGES DIVERS ------------------------------- */
-/* Procède à la lecture d'une en-tête de programme DEX. */
-bool read_dex_header(const GDexFormat *, off_t *, dex_header *);
+/* Procède à la lecture d'un contenu d'aiguillage compact. */
+bool read_dex_packed_switch(const GDexFormat *, off_t *, 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 *);
+/* 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 *);
+/* 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_def.h b/src/format/dex/dex_def.h
index d21ac15..eee3574 100755
--- a/src/format/dex/dex_def.h
+++ b/src/format/dex/dex_def.h
@@ -29,6 +29,55 @@
+/* -------------------------- DESCRIPTION DU FORMAT DALVIK -------------------------- */
+
+
+/* Identifiant magique "dex\n035\0" */
+#define DEX_FILE_MAGIC "\x64\x65\x78\x0a\x30\x33\x35\x00"
+#define DEX_FILE_MAGIC_LEN 8
+
+/* Types de boutisme */
+#define ENDIAN_CONSTANT 0x12345678
+#define REVERSE_ENDIAN_CONSTANT 0x78563412
+
+/* Indice non valide */
+#define NO_INDEX 0xffffffff
+
+
+/* En-tête de tout programe Dex */
+typedef struct _dex_header
+{
+ uint8_t magic[DEX_FILE_MAGIC_LEN]; /* Valeur magique du format */
+
+ uint32_t checksum; /* Somme de contrôle adler32 */
+ uint8_t signature[20]; /* Emprunte SHA-1 du reste */
+ uint32_t file_size; /* Taille du fichier */
+ uint32_t header_size; /* Taille de cette en-tête */
+
+ uint32_t endian_tag; /* Boutisme du fichier */
+
+ uint32_t link_size; /* Taille de section 'liaisons'*/
+ uint32_t link_off; /* Position de ladite section */
+ uint32_t map_off; /* Position de la cartographie */
+ uint32_t string_ids_size; /* Nombre de chaînes de carac. */
+ uint32_t string_ids_off; /* Position de cette liste */
+ uint32_t type_ids_size; /* Nom d'identifiant de type */
+ uint32_t type_ids_off; /* Position de la liste */
+ uint32_t proto_ids_size; /* Nombre de prototypes */
+ uint32_t proto_ids_off; /* Position de la liste */
+ uint32_t field_ids_size; /* Nombre de champs */
+ uint32_t field_ids_off; /* Position de la liste */
+ uint32_t method_ids_size; /* Nombre de méthodes */
+ uint32_t method_ids_off; /* Position de la liste */
+ uint32_t class_defs_size; /* Nombre de classes déclarées */
+ uint32_t class_defs_off; /* Position de la liste */
+ uint32_t data_size; /* Taille des données */
+ uint32_t data_off; /* Début des données */
+
+} dex_header;
+
+
+
/* -------------------------- CONSTANTES POUR DEX DIVERSES -------------------------- */
@@ -240,52 +289,36 @@ typedef struct _code_item
-/* -------------------------- DESCRIPTION DU FORMAT DALVIK -------------------------- */
-
+/* ------------------------------- AIGUILLAGES DIVERS ------------------------------- */
-/* Identifiant magique "dex\n035\0" */
-#define DEX_FILE_MAGIC "\x64\x65\x78\x0a\x30\x33\x35\x00"
-#define DEX_FILE_MAGIC_LEN 8
-
-/* Types de boutisme */
-#define ENDIAN_CONSTANT 0x12345678
-#define REVERSE_ENDIAN_CONSTANT 0x78563412
-/* Indice non valide */
-#define NO_INDEX 0xffffffff
+/* Aiguillage compressé */
+typedef struct _packed_switch
+{
+ uint16_t ident; /* Pseudo-code d'identification*/
+ uint16_t size; /* Nombre d'entrées */
+ uint32_t first_key; /* Première et plus petite clef*/
+ uint32_t *targets; /* Cibles relatives */
+} packed_switch;
-/* En-tête de tout programe Dex */
-typedef struct _dex_header
+/* Aiguillage dispersé */
+typedef struct _sparse_switch
{
- uint8_t magic[DEX_FILE_MAGIC_LEN]; /* Valeur magique du format */
-
- uint32_t checksum; /* Somme de contrôle adler32 */
- uint8_t signature[20]; /* Emprunte SHA-1 du reste */
- uint32_t file_size; /* Taille du fichier */
- uint32_t header_size; /* Taille de cette en-tête */
+ uint16_t ident; /* Pseudo-code d'identification*/
+ uint16_t size; /* Nombre d'entrées */
+ uint32_t *keys; /* Clefs valeureuses */
+ uint32_t *targets; /* Cibles relatives */
- uint32_t endian_tag; /* Boutisme du fichier */
+} sparse_switch;
- uint32_t link_size; /* Taille de section 'liaisons'*/
- uint32_t link_off; /* Position de ladite section */
- uint32_t map_off; /* Position de la cartographie */
- uint32_t string_ids_size; /* Nombre de chaînes de carac. */
- uint32_t string_ids_off; /* Position de cette liste */
- uint32_t type_ids_size; /* Nom d'identifiant de type */
- uint32_t type_ids_off; /* Position de la liste */
- uint32_t proto_ids_size; /* Nombre de prototypes */
- uint32_t proto_ids_off; /* Position de la liste */
- uint32_t field_ids_size; /* Nombre de champs */
- uint32_t field_ids_off; /* Position de la liste */
- uint32_t method_ids_size; /* Nombre de méthodes */
- uint32_t method_ids_off; /* Position de la liste */
- uint32_t class_defs_size; /* Nombre de classes déclarées */
- uint32_t class_defs_off; /* Position de la liste */
- uint32_t data_size; /* Taille des données */
- uint32_t data_off; /* Début des données */
+/* Manipulation interne */
+typedef union _dex_switch
+{
+ packed_switch packed; /* Modèle compact */
+ sparse_switch sparse; /* Modèle dispersé */
-} dex_header;
+} dex_switch;