summaryrefslogtreecommitdiff
path: root/src/format
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2016-02-10 10:02:16 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2016-02-10 10:02:16 (GMT)
commit465488d5b231c2552116a305c48b5fcccea55a09 (patch)
treef4d072ad9cf56466f4e55d0608f7a3fe9204efaf /src/format
parent946f5f093c7265dc5a5e00694325605b249eea43 (diff)
Improved the support of the DEX format.
Diffstat (limited to 'src/format')
-rw-r--r--src/format/dex/class.c47
-rw-r--r--src/format/dex/class.h8
-rwxr-xr-xsrc/format/dex/dex.c40
-rwxr-xr-xsrc/format/dex/dex.h4
-rw-r--r--src/format/dex/method.c9
-rw-r--r--src/format/dex/method.h2
-rw-r--r--src/format/elf/elf.c12
-rw-r--r--src/format/executable-int.c8
-rw-r--r--src/format/format-int.h6
-rw-r--r--src/format/format.c29
10 files changed, 143 insertions, 22 deletions
diff --git a/src/format/dex/class.c b/src/format/dex/class.c
index 1dc3a40..a5181d2 100644
--- a/src/format/dex/class.c
+++ b/src/format/dex/class.c
@@ -39,6 +39,7 @@ struct _GDexClass
GObject parent; /* A laisser en premier */
class_def_item definition; /* Définition de la classe */
+ class_data_item data; /* Contenu de la classe */
GDexMethod **direct_methods; /* Méthodes propres */
size_t dmethods_count; /* Quantité de ces méthodes */
@@ -204,6 +205,7 @@ GDexClass *g_dex_class_new(GDexFormat *format, const class_def_item *def)
result = g_object_new(G_TYPE_DEX_CLASS, NULL);
result->definition = *def;
+ result->data = data;
/**
* On évite ici les méthodes (virtuelles) non définies.
@@ -254,6 +256,44 @@ GDexClass *g_dex_class_new(GDexFormat *format, const class_def_item *def)
/******************************************************************************
* *
* Paramètres : class = informations chargées à consulter. *
+* *
+* Description : Fournit la définition brute d'une classe. *
+* *
+* Retour : Données brutes issues du binaire chargé. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+const class_def_item *g_dex_class_get_definition(const GDexClass *class)
+{
+ return &class->definition;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : class = informations chargées à consulter. *
+* *
+* Description : Fournit la définition brute des données d'une classe. *
+* *
+* Retour : Données brutes issues du binaire chargé. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+const class_data_item *g_dex_class_get_data(const GDexClass *class)
+{
+ return &class->data;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : class = informations chargées à consulter. *
* virtual = précise la nature des méthodes ciblées. *
* *
* Description : Dénombre les méthodes chargées d'un type donné. *
@@ -309,6 +349,7 @@ GDexMethod *g_dex_class_get_method(const GDexClass *class, bool virtual, size_t
/******************************************************************************
* *
* Paramètres : class = informations chargées à consulter. *
+* format = format permettant d'obtenir une adresse complète. *
* layer = couche de portions à raffiner. *
* *
* Description : Intègre la méthode en tant que portion de code. *
@@ -319,15 +360,15 @@ GDexMethod *g_dex_class_get_method(const GDexClass *class, bool virtual, size_t
* *
******************************************************************************/
-void g_dex_class_include_as_portion(const GDexClass *class, GPortionLayer *layer)
+void g_dex_class_include_as_portion(const GDexClass *class, const GDexFormat *format, GPortionLayer *layer)
{
size_t i; /* Boucle de parcours */
for (i = 0; i < class->dmethods_count; i++)
- g_dex_method_include_as_portion(class->direct_methods[i], layer);
+ g_dex_method_include_as_portion(class->direct_methods[i], format, layer);
for (i = 0; i < class->vmethods_count; i++)
- g_dex_method_include_as_portion(class->virtual_methods[i], layer);
+ g_dex_method_include_as_portion(class->virtual_methods[i], format, layer);
}
diff --git a/src/format/dex/class.h b/src/format/dex/class.h
index fb7cada..bee9553 100644
--- a/src/format/dex/class.h
+++ b/src/format/dex/class.h
@@ -57,6 +57,12 @@ 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 *);
+/* Fournit la définition brute d'une classe. */
+const class_def_item *g_dex_class_get_definition(const GDexClass *);
+
+/* Fournit la définition brute des données d'une classe. */
+const class_data_item *g_dex_class_get_data(const GDexClass *);
+
/* Dénombre les méthodes chargées d'un type donné. */
size_t g_dex_class_count_methods(const GDexClass *, bool);
@@ -64,7 +70,7 @@ size_t g_dex_class_count_methods(const GDexClass *, bool);
GDexMethod *g_dex_class_get_method(const GDexClass *, bool, size_t);
/* Intègre la méthode en tant que portion de code. */
-void g_dex_class_include_as_portion(const GDexClass *, GPortionLayer *);
+void g_dex_class_include_as_portion(const GDexClass *, const GDexFormat *, GPortionLayer *);
/* Retrouve si possible la méthode associée à une adresse. */
GDexMethod *g_dex_class_find_method_by_address(const GDexClass *, vmpa_t);
diff --git a/src/format/dex/dex.c b/src/format/dex/dex.c
index ed2565f..764b6dc 100755
--- a/src/format/dex/dex.c
+++ b/src/format/dex/dex.c
@@ -256,6 +256,11 @@ GBinFormat *g_dex_format_new(GBinContent *content, GExeFormat *parent)
if (!read_dex_header(result, &pos, &result->header))
goto gdfn_error;
+
+
+ /* TODO : vérifier que les *_id ne se chevauchent pas */
+
+
if (!load_all_dex_types(result))
goto gdfn_error;
@@ -271,14 +276,15 @@ GBinFormat *g_dex_format_new(GBinContent *content, GExeFormat *parent)
if (!load_all_dex_classes(result))
goto gdfn_error;
+ if (!g_binary_format_complete_loading(G_BIN_FORMAT(result)))
+ goto gdfn_error;
+
return G_BIN_FORMAT(result);
gdfn_error:
g_object_unref(G_OBJECT(result));
- exit(0);
-
return NULL;
}
@@ -328,7 +334,7 @@ static void g_dex_format_refine_portions(const GDexFormat *format, GPortionLayer
max = g_dex_format_count_classes(format);
for (i = 0; i < max; i++)
- g_dex_class_include_as_portion(format->classes[i], layer);
+ g_dex_class_include_as_portion(format->classes[i], format, layer);
}
@@ -508,6 +514,32 @@ char *_g_data_type_to_string(const GDataType *type, bool simple)
+
+
+
+
+/******************************************************************************
+* *
+* Paramètres : format = informations chargées à consulter. *
+* *
+* Description : Présente l'en-tête DEX du format chargé. *
+* *
+* Retour : Pointeur vers la description principale. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+const dex_header *g_dex_format_get_header(const GDexFormat *format)
+{
+ return &format->header;
+
+}
+
+
+
+
+
/******************************************************************************
* *
* Paramètres : format = description de l'exécutable à consulter. *
@@ -542,6 +574,8 @@ size_t g_dex_format_count_classes(const GDexFormat *format)
GDexClass *g_dex_format_get_class(const GDexFormat *format, size_t index)
{
+ /* TODO : ref() */
+
return format->classes[index];
}
diff --git a/src/format/dex/dex.h b/src/format/dex/dex.h
index 1ff3809..28d2a49 100755
--- a/src/format/dex/dex.h
+++ b/src/format/dex/dex.h
@@ -30,6 +30,7 @@
#include <sys/types.h>
+#include "dex_def.h"
#include "../../core/formats.h"
@@ -57,6 +58,9 @@ GType g_dex_format_get_type(void);
/* Prend en charge un nouveau format DEX. */
GBinFormat *g_dex_format_new(GBinContent *, GExeFormat *);
+/* Présente l'en-tête DEX du format chargé. */
+const dex_header *g_dex_format_get_header(const GDexFormat *);
+
/* Redéfinition : classe issue du code source (instance) */
typedef struct _GDexClass GDexClass;
diff --git a/src/format/dex/method.c b/src/format/dex/method.c
index b74a713..316f094 100644
--- a/src/format/dex/method.c
+++ b/src/format/dex/method.c
@@ -294,6 +294,7 @@ GBinRoutine *g_dex_method_get_routine(const GDexMethod *method)
/******************************************************************************
* *
* Paramètres : method = représentation interne du format DEX à consulter. *
+* format = format permettant d'obtenir une adresse complète. *
* layer = couche de portions à raffiner. *
* *
* Description : Intègre la méthode en tant que portion de code. *
@@ -304,16 +305,19 @@ GBinRoutine *g_dex_method_get_routine(const GDexMethod *method)
* *
******************************************************************************/
-void g_dex_method_include_as_portion(const GDexMethod *method, GPortionLayer *layer)
+void g_dex_method_include_as_portion(const GDexMethod *method, const GDexFormat *format, GPortionLayer *layer)
{
+ vmpa2t addr; /* Emplacement dans le binaire */
GBinPortion *new; /* Nouvelle portion définie */
char *desc; /* Description d'une portion */
- vmpa2t addr; /* Emplacement dans le binaire */
/* Si la taille est nulle, on ne fait rien */
if (method->info.access_flags & ACC_NATIVE)
return;
+ if (!g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), method->offset, &addr))
+ return;
+
new = g_binary_portion_new(BPC_CODE);
asprintf(&desc, _("Dalvik code"));
@@ -322,7 +326,6 @@ void g_dex_method_include_as_portion(const GDexMethod *method, GPortionLayer *la
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);
diff --git a/src/format/dex/method.h b/src/format/dex/method.h
index 4d29bac..4ed3960 100644
--- a/src/format/dex/method.h
+++ b/src/format/dex/method.h
@@ -82,7 +82,7 @@ const code_item *g_dex_method_get_dex_body(const GDexMethod *);
GBinRoutine *g_dex_method_get_routine(const GDexMethod *);
/* Intègre la méthode en tant que portion de code. */
-void g_dex_method_include_as_portion(const GDexMethod *, GPortionLayer *);
+void g_dex_method_include_as_portion(const GDexMethod *, const GDexFormat *, GPortionLayer *);
/* 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/elf/elf.c b/src/format/elf/elf.c
index a48e3b3..4bc8bbf 100644
--- a/src/format/elf/elf.c
+++ b/src/format/elf/elf.c
@@ -39,7 +39,6 @@
#include "strings.h"
#include "symbols.h"
#include "../../gui/panels/log.h"
-#include "../../plugins/pglist.h"
@@ -294,15 +293,16 @@ GBinFormat *g_elf_format_new(GBinContent *content, GExeFormat *parent)
}
- /* TODO : à bouger dans un épilogue commun */
+ if (!g_binary_format_complete_loading(G_BIN_FORMAT(result)))
+ goto gefn_error;
- handle_binary_format(PGA_FORMAT_LOADER_LAST, G_BIN_FORMAT(result));
+ return G_BIN_FORMAT(result);
- g_binary_format_delete_duplicated_symbols(G_BIN_FORMAT(result));
+ gefn_error:
- /* .... */
+ g_object_unref(G_OBJECT(result));
- return G_BIN_FORMAT(result);
+ return NULL;
}
diff --git a/src/format/executable-int.c b/src/format/executable-int.c
index c4b8e6e..0189d76 100644
--- a/src/format/executable-int.c
+++ b/src/format/executable-int.c
@@ -41,7 +41,13 @@
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);
+ /**
+ * On ne peut pas initialiser la partie virtuelle à VMPA_NO_VIRTUAL
+ * car les manipulations au niveau des formats (par exemple, cf. la fonction
+ * _g_binary_format_add_symbol()) attendent des définitions complètes.
+ */
+
+ init_vmpa(pos, off, off);
return true;
diff --git a/src/format/format-int.h b/src/format/format-int.h
index f97a4ad..84f77c4 100644
--- a/src/format/format-int.h
+++ b/src/format/format-int.h
@@ -78,12 +78,12 @@ struct _GBinFormatClass
};
+/* Effectue les ultimes opérations de chargement d'un binaire. */
+bool g_binary_format_complete_loading(GBinFormat *);
+
/* Définit le contenu binaire à analyser. */
void g_binary_format_set_content(GBinFormat *, GBinContent *);
-/* Supprime les éventuels doublons au sein des symboles. */
-void g_binary_format_delete_duplicated_symbols(GBinFormat *);
-
#endif /* _FORMAT_FORMAT_INT_H */
diff --git a/src/format/format.c b/src/format/format.c
index 8395c6e..387894c 100644
--- a/src/format/format.c
+++ b/src/format/format.c
@@ -52,6 +52,9 @@ static void g_binary_format_init(GBinFormat *);
/* Retire un symbole de la collection du format binaire. */
static void _g_binary_format_remove_symbol(GBinFormat *, size_t);
+/* Supprime les éventuels doublons au sein des symboles. */
+static void g_binary_format_delete_duplicated_symbols(GBinFormat *);
+
/* Recherche le symbole associé à une adresse. */
static bool _g_binary_format_find_symbol(const GBinFormat *, const vmpa2t *, __compar_fn_t, GBinSymbol **);
@@ -101,6 +104,30 @@ static void g_binary_format_init(GBinFormat *format)
}
+/******************************************************************************
+* *
+* Paramètres : format = instance à traiter. *
+* *
+* Description : Effectue les ultimes opérations de chargement d'un binaire. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_binary_format_complete_loading(GBinFormat *format)
+{
+ handle_binary_format(PGA_FORMAT_LOADER_LAST, format);
+
+ g_binary_format_delete_duplicated_symbols(format);
+
+ return true;
+
+}
+
+
+
/* FIXME : g_rw_lock_clear(&format->syms_lock);*/
@@ -431,7 +458,7 @@ void g_binary_format_sort_symbols(GBinFormat *format)
* *
******************************************************************************/
-void g_binary_format_delete_duplicated_symbols(GBinFormat *format)
+static void g_binary_format_delete_duplicated_symbols(GBinFormat *format)
{
size_t i; /* Boucle de parcours */
const mrange_t *range; /* Emplacement à consulter */