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.c266
1 files changed, 266 insertions, 0 deletions
diff --git a/src/format/dex/dex-int.c b/src/format/dex/dex-int.c
index 5628e6b..200b01f 100644
--- a/src/format/dex/dex-int.c
+++ b/src/format/dex/dex-int.c
@@ -529,10 +529,226 @@ void reset_dex_class_data_item(class_data_item *item)
+/* ---------------------------------------------------------------------------------- */
+/* PORTION DE CODE EXECUTABLE */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : format = informations chargées à consulter. *
+* pos = position de début de lecture. [OUT] *
+* pair = structure lue à retourner. [OUT] *
+* *
+* Description : Procède à la lecture d'une association exception <-> code. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool read_dex_encoded_type_addr_pair(const GDexFormat *format, off_t *pos, encoded_type_addr_pair *pair)
+{
+ bool result; /* Bilan à retourner */
+ const bin_t *content; /* Contenu binaire à lire */
+ off_t length; /* Taille totale du contenu */
+
+ result = true;
+
+ content = G_BIN_FORMAT(format)->content;
+ length = G_BIN_FORMAT(format)->length;
+
+ result &= read_uleb128(&pair->type_idx, content, pos, length);
+ result &= read_uleb128(&pair->addr, content, pos, length);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = informations chargées à consulter. *
+* pos = position de début de lecture. [OUT] *
+* handler = structure lue à retourner. [OUT] *
+* *
+* Description : Procède à la lecture d'une association exception <-> code. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool read_dex_encoded_catch_handler(const GDexFormat *format, off_t *pos, encoded_catch_handler *handler)
+{
+ bool result; /* Bilan à retourner */
+ const bin_t *content; /* Contenu binaire à lire */
+ off_t length; /* Taille totale du contenu */
+ leb128_t count; /* Nombre de gestionnaires */
+ leb128_t i; /* Boucle de parcours */
+
+ result = true;
+
+ content = G_BIN_FORMAT(format)->content;
+ length = G_BIN_FORMAT(format)->length;
+
+ handler->offset = *pos;
+
+ result &= read_leb128(&handler->size, content, pos, length);
+
+ count = leb128_abs(handler->size);
+
+ if (count > 0 && result)
+ {
+ handler->handlers = (encoded_type_addr_pair *)calloc(count, sizeof(encoded_type_addr_pair));
+
+ for (i = 0; i < count && result; i++)
+ result &= read_dex_encoded_type_addr_pair(format, pos, &handler->handlers[i]);
+
+ }
+ else handler->handlers = NULL;
+
+ if (handler->size < 0)
+ result &= read_uleb128(&handler->catch_all_addr, content, pos, length);
+ else
+ handler->catch_all_addr = ULEB128_MAX;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : handler = structure à nettoyer. *
+* *
+* Description : Supprime tous les éléments chargés en mémoire à la lecture. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void reset_dex_encoded_catch_handler(encoded_catch_handler *handler)
+{
+ if (handler->handlers != NULL)
+ free(handler->handlers);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = informations chargées à consulter. *
+* pos = position de début de lecture. [OUT] *
+* list = structure lue à retourner. [OUT] *
+* *
+* Description : Procède à la lecture d'une association exception <-> code. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool read_dex_encoded_catch_handler_list(const GDexFormat *format, off_t *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 */
+ uleb128_t i; /* Boucle de parcours */
+ result = true;
+ content = G_BIN_FORMAT(format)->content;
+ length = G_BIN_FORMAT(format)->length;
+
+ saved_off = *pos;
+
+ result &= read_uleb128(&list->size, content, pos, length);
+ if (list->size > 0 && result)
+ {
+ list->list = (encoded_catch_handler *)calloc(list->size, sizeof(encoded_catch_handler));
+ for (i = 0; i < list->size && result; i++)
+ {
+ result &= read_dex_encoded_catch_handler(format, pos, &list->list[i]);
+ if (result) list->list[i].offset -= saved_off;
+ }
+
+ }
+ else list->list = NULL;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : list = structure à nettoyer. *
+* *
+* Description : Supprime tous les éléments chargés en mémoire à la lecture. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void reset_dex_encoded_catch_handler_list(encoded_catch_handler_list *list)
+{
+ uleb128_t i; /* Boucle de parcours */
+
+ if (list->list != NULL)
+ {
+ for (i = 0; i < list->size; i++)
+ reset_dex_encoded_catch_handler(&list->list[i]);
+
+ free(list->list);
+
+ }
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = informations chargées à consulter. *
+* pos = position de début de lecture. [OUT] *
+* item = structure lue à retourner. [OUT] *
+* *
+* Description : Procède à la lecture d'une association exception <-> code. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool read_dex_try_item(const GDexFormat *format, off_t *pos, try_item *item)
+{
+ bool result; /* Bilan à retourner */
+ const bin_t *content; /* Contenu binaire à lire */
+ off_t length; /* Taille totale du contenu */
+
+ result = true;
+
+ content = G_BIN_FORMAT(format)->content;
+ length = G_BIN_FORMAT(format)->length;
+
+ 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);
+
+ return result;
+
+}
/******************************************************************************
@@ -554,6 +770,8 @@ bool read_dex_code_item(const GDexFormat *format, off_t *pos, code_item *item)
bool result; /* Bilan à retourner */
const bin_t *content; /* Contenu binaire à lire */
off_t length; /* Taille totale du contenu */
+ uint16_t padding; /* Eventuel alignement */
+ uint16_t i; /* Boucle de parcours */
result = true;
@@ -569,11 +787,59 @@ bool read_dex_code_item(const GDexFormat *format, off_t *pos, code_item *item)
item->insns = (uint16_t *)pos;
+ *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);
+
+ if (item->tries_size > 0 && result)
+ {
+ item->tries = (try_item *)calloc(item->tries_size, sizeof(try_item));
+
+ for (i = 0; i < item->tries_size && result; i++)
+ result &= read_dex_try_item(format, pos, &item->tries[i]);
+
+ if (result)
+ {
+ item->handlers = (encoded_catch_handler_list *)calloc(1, sizeof(encoded_catch_handler_list));
+ result &= read_dex_encoded_catch_handler_list(format, pos, item->handlers);
+ }
+
+ }
+
return result;
}
+/******************************************************************************
+* *
+* Paramètres : item = structure à nettoyer. *
+* *
+* Description : Supprime tous les éléments chargés en mémoire à la lecture. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void reset_dex_code_item(code_item *item)
+{
+ if (item->tries != NULL)
+ free(item->tries);
+
+ if (item->handlers != NULL)
+ {
+ reset_dex_encoded_catch_handler_list(item->handlers);
+ free(item->handlers);
+ }
+
+}
+
+
+