diff options
Diffstat (limited to 'src/format')
-rw-r--r-- | src/format/dex/class.c | 33 | ||||
-rw-r--r-- | src/format/dex/class.h | 4 | ||||
-rwxr-xr-x | src/format/dex/dex-int.h | 4 | ||||
-rwxr-xr-x | src/format/dex/dex.c | 28 | ||||
-rw-r--r-- | src/format/dex/method.c | 63 | ||||
-rw-r--r-- | src/format/dex/method.h | 19 | ||||
-rw-r--r-- | src/format/format.c | 6 | ||||
-rw-r--r-- | src/format/format.h | 3 |
8 files changed, 156 insertions, 4 deletions
diff --git a/src/format/dex/class.c b/src/format/dex/class.c index d08c8e2..cdf6c2c 100644 --- a/src/format/dex/class.c +++ b/src/format/dex/class.c @@ -296,6 +296,39 @@ GBinPart **g_dex_class_get_parts(const GDexClass *class, GBinPart **parts, size_ /****************************************************************************** * * +* Paramètres : class = informations chargées à consulter. * +* addr = adresse de la routine à retrouver. * +* * +* Description : Retrouve si possible la méthode associée à une adresse. * +* * +* Retour : Méthde retrouvée ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GDexMethod *g_dex_class_find_method_by_address(const GDexClass *class, vmpa_t addr) +{ + GDexMethod *result; /* Trouvaille à retourner */ + size_t i; /* Boucle de parcours */ + + result = NULL; + + for (i = 0; i < class->dmethods_count && result == NULL; i++) + if (addr == (vmpa_t)g_dex_method_get_offset(class->direct_methods[i])) + result = class->direct_methods[i]; + + for (i = 0; i < class->vmethods_count && result == NULL; i++) + if (addr == (vmpa_t)g_dex_method_get_offset(class->virtual_methods[i])) + result = class->virtual_methods[i]; + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : class = informations chargées à consulter. * * format = représentation interne du format DEX à compléter. * * * diff --git a/src/format/dex/class.h b/src/format/dex/class.h index f4d5cb0..998c1b7 100644 --- a/src/format/dex/class.h +++ b/src/format/dex/class.h @@ -29,6 +29,7 @@ #include "dex.h" +#include "method.h" #include "../../decomp/output.h" @@ -56,6 +57,9 @@ GType g_dex_class_get_type(void); /* Fournit les références aux zones binaires à analyser. */ GBinPart **g_dex_class_get_parts(const GDexClass *, GBinPart **, size_t *); +/* Retrouve si possible la méthode associée à une adresse. */ +GDexMethod *g_dex_class_find_method_by_address(const GDexClass *, vmpa_t); + /* Retrouve si possible le nom du fichier source d'une classe. */ const char *g_dex_class_get_source_file(const GDexClass *, const GDexFormat *); diff --git a/src/format/dex/dex-int.h b/src/format/dex/dex-int.h index feb63a8..5feb427 100755 --- a/src/format/dex/dex-int.h +++ b/src/format/dex/dex-int.h @@ -58,6 +58,10 @@ struct _GDexFormatClass }; +/* Retrouve si possible la méthode associée à une adresse. */ +GDexMethod *g_dex_format_find_method_by_address(const GDexFormat *, vmpa_t); + + /* ------------------------ ELEMENTS DE TABLE DES CONSTANTES ------------------------ */ diff --git a/src/format/dex/dex.c b/src/format/dex/dex.c index 0d17a4d..7075929 100755 --- a/src/format/dex/dex.c +++ b/src/format/dex/dex.c @@ -204,6 +204,34 @@ GBinFormat *g_dex_format_new(const bin_t *content, off_t length) /****************************************************************************** * * +* Paramètres : format = informations chargées à consulter. * +* addr = adresse de la routine à retrouver. * +* * +* Description : Retrouve si possible la méthode associée à une adresse. * +* * +* Retour : Méthde retrouvée ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GDexMethod *g_dex_format_find_method_by_address(const GDexFormat *format, vmpa_t addr) +{ + GDexMethod *result; /* Trouvaille à retourner */ + size_t i; /* Boucle de parcours */ + + result = NULL; + + for (i = 0; i < format->classes_count && result == NULL; i++) + result = g_dex_class_find_method_by_address(format->classes[i], addr); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : format = informations chargées à mettre à jour. * * * * Description : Détermine tous les fichiers source indiqués. * diff --git a/src/format/dex/method.c b/src/format/dex/method.c index 233ecb1..c22c11f 100644 --- a/src/format/dex/method.c +++ b/src/format/dex/method.c @@ -228,6 +228,69 @@ GBinPart *g_dex_method_as_part(const GDexMethod *method) /****************************************************************************** * * +* Paramètres : method = représentation interne du format DEX à consulter. * +* * +* Description : Indique la position de la méthode au sein du binaire. * +* * +* Retour : Localisation dans le contenu binaire. * +* * +* Remarques : - * +* * +******************************************************************************/ + +off_t g_dex_method_get_offset(const GDexMethod *method) +{ + return method->offset; +} + + +/****************************************************************************** +* * +* Paramètres : method = représentation interne du format DEX à consulter. * +* index = indice de base comme seul indice. * +* * +* Description : Fournit des indications sur la nature d'une variable donnée. * +* * +* Retour : Indentifiant complet d'une variable utilisée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +DexVariableIndex g_dex_method_get_variable(const GDexMethod *method, uint32_t index) +{ + const encoded_method *info; /* Propriétés de la méthode */ + const code_item *body; /* Corps de la méthode */ + uint32_t pivot; /* Bascule pour les arguments */ + + info = &method->info; + body = &method->body; + + /* S'agit-il d'un argument ? */ + + pivot = body->registers_size - body->ins_size; + + if (!(method->info.access_flags & ACC_STATIC)) + pivot++; + + if (index >= pivot) + return (index - pivot) | DVI_ARGUMENT; + + /* S'agit-il de "this" ? */ + + if (!(method->info.access_flags & ACC_STATIC) + && index == (body->registers_size - body->ins_size)) + return DVI_THIS; + + /* Alors il s'agit d'une variable locale... */ + + return index | DVI_LOCAL; + +} + + +/****************************************************************************** +* * * Paramètres : method = informations chargées à consulter. * * lang = langage à utiliser pour la sortie humaine. * * buffer = tampon mis à disposition pour la sortie. * diff --git a/src/format/dex/method.h b/src/format/dex/method.h index 79dbd7e..c06df73 100644 --- a/src/format/dex/method.h +++ b/src/format/dex/method.h @@ -49,6 +49,19 @@ typedef struct _GDexMethod GDexMethod; typedef struct _GDexMethodClass GDexMethodClass; +/* Détermination des variables */ +typedef enum _DexVariableIndex +{ + /* Indices... */ + + DVI_LOCAL = (1 << 29), + DVI_THIS = (1 << 30), + DVI_ARGUMENT = (1 << 31) + +} DexVariableIndex; + +#define DVI_INDEX(v) (v & ~(7 << 29)) + /* Détermine le type d'une methode issue du code source. */ GType g_dex_method_get_type(void); @@ -62,6 +75,12 @@ GBinRoutine *g_dex_method_get_routine(const GDexMethod *); /* Fournit la zone binaire correspondant à la méthode. */ GBinPart *g_dex_method_as_part(const GDexMethod *); +/* Indique la position de la méthode au sein du binaire. */ +off_t g_dex_method_get_offset(const GDexMethod *); + +/* Fournit des indications sur la nature d'une variable donnée. */ +DexVariableIndex g_dex_method_get_variable(const GDexMethod *, uint32_t); + /* Procède à la décompilation complète d'une routine donnée. */ void g_dex_method_decompile(const GDexMethod *, GLangOutput *, GCodeBuffer *); diff --git a/src/format/format.c b/src/format/format.c index 930d8db..4f6df03 100644 --- a/src/format/format.c +++ b/src/format/format.c @@ -272,6 +272,7 @@ GBinRoutine **g_binary_format_get_routines(const GBinFormat *format, size_t *cou * * * Paramètres : format = informations chargées à consulter. * * routine = routine à traiter. * +* ctx = contexte de soutien à associer à l'opération. * * * * Description : Procède à la décompilation basique d'une routine donnée. * * * @@ -281,12 +282,11 @@ GBinRoutine **g_binary_format_get_routines(const GBinFormat *format, size_t *cou * * ******************************************************************************/ -GDecInstruction *g_binary_format_decompile_routine(const GBinFormat *format, GBinRoutine *routine) +GDecInstruction *g_binary_format_decompile_routine(const GBinFormat *format, GBinRoutine *routine, GDecContext *ctx) { GDecInstruction *result; /* Instructions décompilées */ GArchInstruction *instr; /* Instructions natives */ vmpa_t max; /* Première adresse à écarter */ - GDecContext *ctx; /* Contexte de décompilation */ GArchInstruction *iter; /* Boucle de parcours */ GDecInstruction *first; /* Première décompilation */ GDecInstruction *dinstr; /* Nouvelle décompilation */ @@ -297,8 +297,8 @@ GDecInstruction *g_binary_format_decompile_routine(const GBinFormat *format, GBi max = g_binary_routine_get_address(routine) + g_binary_routine_get_size(routine); - ctx = g_dec_context_new(); g_object_set_data(G_OBJECT(ctx), "format", format); + g_object_set_data(G_OBJECT(ctx), "routine", routine); g_dec_context_set_max_address(ctx, max); for (iter = instr; diff --git a/src/format/format.h b/src/format/format.h index ce49a26..ef85fbb 100644 --- a/src/format/format.h +++ b/src/format/format.h @@ -32,6 +32,7 @@ #include "symbol.h" #include "../analysis/routine.h" +#include "../decomp/context.h" #include "../decomp/instruction.h" @@ -72,7 +73,7 @@ void g_binary_format_add_routine(GBinFormat *, GBinRoutine *); GBinRoutine **g_binary_format_get_routines(const GBinFormat *, size_t *); /* Procède à la décompilation basique d'une routine donnée. */ -GDecInstruction *g_binary_format_decompile_routine(const GBinFormat *, GBinRoutine *); +GDecInstruction *g_binary_format_decompile_routine(const GBinFormat *, GBinRoutine *, GDecContext *); /* Fournit la liste des fichiers source détectés. */ const char * const *g_binary_format_get_source_files(const GBinFormat *, size_t *, size_t *); |