summaryrefslogtreecommitdiff
path: root/src/format/dex/dex-int.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/format/dex/dex-int.c')
-rw-r--r--src/format/dex/dex-int.c273
1 files changed, 244 insertions, 29 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);
+
+}