summaryrefslogtreecommitdiff
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
parent946f5f093c7265dc5a5e00694325605b249eea43 (diff)
Improved the support of the DEX format.
-rw-r--r--ChangeLog39
-rw-r--r--src/analysis/disass/links.c19
-rw-r--r--src/arch/dalvik/instruction.c27
-rw-r--r--src/arch/dalvik/operand.c99
-rw-r--r--src/arch/dalvik/operand.h4
-rw-r--r--src/arch/dalvik/operands/target.c17
-rw-r--r--src/arch/dalvik/operands/target.h2
-rw-r--r--src/arch/processor.c3
-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
18 files changed, 330 insertions, 45 deletions
diff --git a/ChangeLog b/ChangeLog
index ddd89ea..e9f09cc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,42 @@
+16-02-10 Cyrille Bagard <nocbos@gmail.com>
+
+ * src/analysis/disass/links.c:
+ Translate immediate values into targets with mode care.
+
+ * src/arch/dalvik/instruction.c:
+ Provide the encoding of Dalvik instructions, as required.
+
+ * src/arch/dalvik/operand.c:
+ * src/arch/dalvik/operand.h:
+ Update the decoding of operands. Check the quantity of bytes consumed
+ from the binary stream.
+
+ * src/arch/dalvik/operands/target.c:
+ * src/arch/dalvik/operands/target.h:
+ Update code.
+
+ * src/arch/processor.c:
+ Check all decoded instructions have a full defined location.
+
+ * src/format/dex/class.c:
+ * src/format/dex/class.h:
+ * src/format/dex/dex.c:
+ * src/format/dex/dex.h:
+ * src/format/dex/method.c:
+ * src/format/dex/method.h:
+ Improve the support of the DEX format.
+
+ * src/format/elf/elf.c:
+ Update code.
+
+ * src/format/executable-int.c:
+ Create full defined locations for architectures without virtual
+ addresses support.
+
+ * src/format/format-int.h:
+ * src/format/format.c:
+ Implement common code to complete format loading.
+
16-02-09 Cyrille Bagard <nocbos@gmail.com>
* src/arch/raw.c:
diff --git a/src/analysis/disass/links.c b/src/analysis/disass/links.c
index 8d826c5..5e1e483 100644
--- a/src/analysis/disass/links.c
+++ b/src/analysis/disass/links.c
@@ -26,6 +26,7 @@
#include "../../arch/instruction.h"
+#include "../../arch/raw.h"
#include "../../arch/target.h"
@@ -128,6 +129,7 @@ static void establish_natural_link(GArchInstruction *instr, GArchInstruction *pr
static void convert_immediate_into_target(GArchInstruction *instr, size_t index, GBinFormat *format)
{
GArchOperand *op; /* Opérande numérique en place */
+ GImmOperand *imm; /* Version native de l'opérande*/
virt_t addr; /* Adresse visée par le saut */
MemoryDataSize msize; /* Taille de l'opérande */
GArchOperand *new; /* Instruction de ciblage */
@@ -135,9 +137,13 @@ static void convert_immediate_into_target(GArchInstruction *instr, size_t index,
op = g_arch_instruction_get_operand(instr, index);
if (!G_IS_IMM_OPERAND(op)) return;
- if (g_imm_operand_to_virt_t(G_IMM_OPERAND(op), &addr))
+ imm = G_IMM_OPERAND(op);
+
+ if (g_imm_operand_get_display(imm) != IOD_HEX) return;
+
+ if (g_imm_operand_to_virt_t(imm, &addr))
{
- msize = g_imm_operand_get_size(G_IMM_OPERAND(op));
+ msize = g_imm_operand_get_size(imm);
new = g_target_operand_new(msize, addr);
@@ -167,6 +173,7 @@ static void convert_immediate_into_target(GArchInstruction *instr, size_t index,
static void establish_links_for_instruction(GArchInstruction *instr, GArchInstruction *list, GBinFormat *format)
{
+ bool skip; /* Saut des conversions */
size_t count; /* Nombre d'opérandes présents */
size_t i; /* Boucle de parcours */
GArchOperand *op; /* Opérande numérique en place */
@@ -174,11 +181,17 @@ static void establish_links_for_instruction(GArchInstruction *instr, GArchInstru
vmpa2t addr; /* Localisation plus complète */
GArchInstruction *target; /* Instruction visée au final */
+ if (G_IS_RAW_INSTRUCTION(instr))
+ skip = g_raw_instruction_is_string(G_RAW_INSTRUCTION(instr));
+ else
+ skip = false;
+
count = g_arch_instruction_count_operands(instr);
for (i = 0; i < count; i++)
{
- convert_immediate_into_target(instr, i, format);
+ if (!skip)
+ convert_immediate_into_target(instr, i, format);
op = g_arch_instruction_get_operand(instr, i);
if (!G_IS_TARGET_OPERAND(op)) continue;
diff --git a/src/arch/dalvik/instruction.c b/src/arch/dalvik/instruction.c
index 31f02c8..4c1dee0 100644
--- a/src/arch/dalvik/instruction.c
+++ b/src/arch/dalvik/instruction.c
@@ -48,6 +48,9 @@ static void g_dalvik_instruction_dispose(GDalvikInstruction *);
/* Procède à la libération totale de la mémoire. */
static void g_dalvik_instruction_finalize(GDalvikInstruction *);
+/* Indique l'encodage d'une instruction de façon détaillée. */
+static const char *g_dalvik_instruction_get_encoding(const GDalvikInstruction *);
+
/* Liste les registres lus et écrits par l'instruction. */
static void g_dalvik_instruction_get_rw_registers(const GDalvikInstruction *, GArchRegister ***, size_t *, GArchRegister ***, size_t *);
@@ -373,6 +376,7 @@ static void g_dalvik_instruction_class_init(GDalvikInstructionClass *klass)
instr = G_ARCH_INSTRUCTION_CLASS(klass);
+ instr->get_encoding = (get_instruction_encoding_fc)g_dalvik_instruction_get_encoding;
instr->build_key = (build_instruction_keyword_fc)dalvik_build_instruction_keyword;
}
@@ -469,6 +473,29 @@ GArchInstruction *g_dalvik_instruction_new(const char *keyword)
/******************************************************************************
* *
+* Paramètres : instr = instruction quelconque à consulter. *
+* *
+* Description : Indique l'encodage d'une instruction de façon détaillée. *
+* *
+* Retour : Description humaine de l'encodage utilisé. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static const char *g_dalvik_instruction_get_encoding(const GDalvikInstruction *instr)
+{
+ const char *result; /* Description à retourner */
+
+ result = "Dalvik";
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : instr = instruction Dalvik à consulter. *
* *
* Description : Indique l'opcode associé à une instruction Dalvik. *
diff --git a/src/arch/dalvik/operand.c b/src/arch/dalvik/operand.c
index f8f7b39..83d95e5 100644
--- a/src/arch/dalvik/operand.c
+++ b/src/arch/dalvik/operand.c
@@ -24,6 +24,7 @@
#include "operand.h"
+#include <assert.h>
#include <malloc.h>
#include <stdarg.h>
@@ -56,7 +57,7 @@ typedef enum _DalvikOperandID
/* Procède à la lecture d'opérandes pour une instruction. */
-static bool dalvik_read_basic_operands(GArchInstruction *, GDexFormat *, const GBinContent *, vmpa2t *, bool *, SourceEndian, DalvikOperandType, va_list);
+static bool dalvik_read_basic_operands(GArchInstruction *, GDexFormat *, const GBinContent *, vmpa2t *, bool *, SourceEndian, DalvikOperandType, ...);
/* Procède à la lecture d'opérandes pour une instruction. */
static bool dalvik_read_fixed_operands(GArchInstruction *, GDexFormat *, const GBinContent *, vmpa2t *, bool *, SourceEndian, DalvikOperandType);
@@ -75,7 +76,7 @@ static bool dalvik_read_variatic_operands(GArchInstruction *, GDexFormat *, cons
* low = position éventuelle des 4 bits visés. [OUT] *
* endian = boutisme lié au binaire accompagnant. *
* model = type d'opérandes attendues. *
-* ap = éventuels arguments complémentaires. *
+* ... = éventuels arguments complémentaires. *
* *
* Description : Procède à la lecture d'opérandes pour une instruction. *
* *
@@ -85,7 +86,7 @@ static bool dalvik_read_variatic_operands(GArchInstruction *, GDexFormat *, cons
* *
******************************************************************************/
-static bool dalvik_read_basic_operands(GArchInstruction *instr, GDexFormat *format, const GBinContent *content, vmpa2t *pos, bool *low, SourceEndian endian, DalvikOperandType model, va_list ap)
+static bool dalvik_read_basic_operands(GArchInstruction *instr, GDexFormat *format, const GBinContent *content, vmpa2t *pos, bool *low, SourceEndian endian, DalvikOperandType model, ...)
{
bool result; /* Bilan à retourner */
DalvikOperandID *types; /* Liste des chargements */
@@ -93,6 +94,8 @@ static bool dalvik_read_basic_operands(GArchInstruction *instr, GDexFormat *form
GArchOperand *op; /* Opérande unique décodé */
uint16_t value16; /* Valeur sur 16 bits */
DalvikPoolType pool_type; /* Type de table à manipuler */
+ va_list ap; /* Arguments complémentaires */
+ const vmpa2t *base; /* Base pour les sauts de code */
result = true;
@@ -334,15 +337,24 @@ static bool dalvik_read_basic_operands(GArchInstruction *instr, GDexFormat *form
break;
case DOI_TARGET_8:
- op = g_dalvik_target_operand_new(content, pos, MDS_8_BITS_SIGNED, endian, va_arg(ap, vmpa_t));
+ va_start(ap, model);
+ base = va_arg(ap, const vmpa2t *);
+ op = g_dalvik_target_operand_new(content, pos, MDS_8_BITS_SIGNED, endian, base);
+ va_end(ap);
break;
case DOI_TARGET_16:
- op = g_dalvik_target_operand_new(content, pos, MDS_16_BITS_SIGNED, endian, va_arg(ap, vmpa_t));
+ va_start(ap, model);
+ base = va_arg(ap, const vmpa2t *);
+ op = g_dalvik_target_operand_new(content, pos, MDS_16_BITS_SIGNED, endian, base);
+ va_end(ap);
break;
case DOI_TARGET_32:
- op = g_dalvik_target_operand_new(content, pos, MDS_32_BITS_SIGNED, endian, va_arg(ap, vmpa_t));
+ va_start(ap, model);
+ base = va_arg(ap, const vmpa2t *);
+ op = g_dalvik_target_operand_new(content, pos, MDS_32_BITS_SIGNED, endian, base);
+ va_end(ap);
break;
default:
@@ -413,6 +425,12 @@ static bool dalvik_read_fixed_operands(GArchInstruction *instr, GDexFormat *form
}
+ /* Consommation pleine et entière */
+
+ for (; i < 4; i++)
+ if (!g_binary_content_read_u4(content, pos, low, (uint8_t []) { 0 }))
+ goto err_padding;
+
/* Rajout des éléments finaux déjà chargés */
if (a == 5)
@@ -428,6 +446,8 @@ static bool dalvik_read_fixed_operands(GArchInstruction *instr, GDexFormat *form
return true;
+ err_padding:
+
err_registers:
g_object_unref(G_OBJECT(target));
@@ -522,7 +542,6 @@ static bool dalvik_read_variatic_operands(GArchInstruction *instr, GDexFormat *f
* pos = position courante dans ce flux. [OUT] *
* endian = boutisme lié au binaire accompagnant. *
* model = type d'opérandes attendues. *
-* ... = éventuelles données complémentaires. *
* *
* Description : Procède à la lecture d'opérandes pour une instruction. *
* *
@@ -532,12 +551,21 @@ static bool dalvik_read_variatic_operands(GArchInstruction *instr, GDexFormat *f
* *
******************************************************************************/
-bool dalvik_read_operands(GArchInstruction *instr, GExeFormat *format, const GBinContent *content, vmpa2t *pos, SourceEndian endian, DalvikOperandType model, ...)
+bool dalvik_read_operands(GArchInstruction *instr, GExeFormat *format, const GBinContent *content, vmpa2t *pos, SourceEndian endian, DalvikOperandType model)
{
bool result; /* Bilan à retourner */
GDexFormat *dformat; /* Autre version du format */
bool low; /* Partie d'octets à lire */
+#ifndef NDEBUG
+ vmpa2t old; /* Position avant traitements */
+#endif
+ vmpa2t base; /* Base pour les sauts de code */
+ vmpa2t *extra; /* Information complémentaire */
va_list ap; /* Arguments complémentaires */
+#ifndef NDEBUG
+ phys_t expected; /* Consommation attendue */
+ phys_t consumed; /* Consommation réelle */
+#endif
result = true;
@@ -545,6 +573,42 @@ bool dalvik_read_operands(GArchInstruction *instr, GExeFormat *format, const GBi
low = true;
+#ifndef NDEBUG
+
+ copy_vmpa(&old, pos);
+
+#endif
+
+ /* Récupération de la base ? */
+
+ if (DALVIK_OP_GET_MNEMONIC(model) == 'T')
+ {
+ extra = &base;
+
+ copy_vmpa(extra, pos);
+ deminish_vmpa(extra, 1);
+
+ }
+ else extra = NULL;
+
+ /* Bourrage : ØØ|op ? */
+
+ switch (model & ~DALVIK_OP_EXTRA_MASK)
+ {
+ case DALVIK_OPT_10X:
+ case DALVIK_OPT_20T:
+ case DALVIK_OPT_30T:
+ case DALVIK_OPT_32X:
+ advance_vmpa(pos, 1);
+ break;
+
+ default:
+ break;
+
+ }
+
+ /* Décodage... */
+
switch (model & ~DALVIK_OP_EXTRA_MASK)
{
case DALVIK_OPT_10T:
@@ -568,9 +632,7 @@ bool dalvik_read_operands(GArchInstruction *instr, GExeFormat *format, const GBi
case DALVIK_OPT_31T:
case DALVIK_OPT_32X:
case DALVIK_OPT_51L:
- va_start(ap, model);
- result = dalvik_read_basic_operands(instr, dformat, content, pos, &low, endian, model, ap);
- va_end(ap);
+ result = dalvik_read_basic_operands(instr, dformat, content, pos, &low, endian, model, extra);
break;
case DALVIK_OPT_35C:
@@ -588,6 +650,21 @@ bool dalvik_read_operands(GArchInstruction *instr, GExeFormat *format, const GBi
}
+#ifndef NDEBUG
+
+ /* Vérification d'implémentation */
+
+ if (result)
+ {
+ expected = DALVIK_OP_GET_LEN(model) * 2;
+ consumed = 1 + compute_vmpa_diff(&old, pos);
+
+ assert(consumed == expected);
+
+ }
+
+#endif
+
return result;
}
diff --git a/src/arch/dalvik/operand.h b/src/arch/dalvik/operand.h
index 27901be..af15bde 100644
--- a/src/arch/dalvik/operand.h
+++ b/src/arch/dalvik/operand.h
@@ -65,6 +65,8 @@
#define DALVIK_OP_POOL(p) ((p) << DALVIK_OP_POOL_OFF)
#define DALVIK_OP_GET_POOL(v) (((v) & DALVIK_OP_POOL_MASK) >> DALVIK_OP_POOL_OFF)
+#define DALVIK_OP_GET_MNEMONIC(v) ((v) & 0xff)
+
/* Types d'opérandes supportés */
typedef enum _DalvikOperandType
@@ -112,7 +114,7 @@ typedef enum _DalvikOperandType
/* Procède à la lecture d'opérandes pour une instruction. */
-bool dalvik_read_operands(GArchInstruction *, GExeFormat *, const GBinContent *, vmpa2t *, SourceEndian, DalvikOperandType, ...);
+bool dalvik_read_operands(GArchInstruction *, GExeFormat *, const GBinContent *, vmpa2t *, SourceEndian, DalvikOperandType);
/* Procède à la lecture d'opérandes pour une instruction. */
void dalvik_mark_first_operand_as_written(GArchInstruction *);
diff --git a/src/arch/dalvik/operands/target.c b/src/arch/dalvik/operands/target.c
index 42d09cf..5e8b91a 100644
--- a/src/arch/dalvik/operands/target.c
+++ b/src/arch/dalvik/operands/target.c
@@ -169,31 +169,34 @@ static void g_dalvik_target_operand_finalize(GDalvikTargetOperand *operand)
* *
******************************************************************************/
-GArchOperand *g_dalvik_target_operand_new(const GBinContent *content, vmpa2t *pos, MemoryDataSize size, SourceEndian endian, vmpa_t base)
+GArchOperand *g_dalvik_target_operand_new(const GBinContent *content, vmpa2t *pos, MemoryDataSize size, SourceEndian endian, const vmpa2t *base)
{
GDalvikTargetOperand *result; /* Structure à retourner */
+ phys_t offset; /* Emplacement de base */
int8_t val8; /* Valeur sur 8 bits */
int16_t val16; /* Valeur sur 16 bits */
int32_t val32; /* Valeur sur 32 bits */
bool test; /* Bilan de lecture */
- vmpa_t address; /* Adresse finale visée */
+ phys_t address; /* Adresse finale visée */
+
+ offset = get_phy_addr(base);
switch (size)
{
case MDS_8_BITS_SIGNED:
test = g_binary_content_read_s8(content, pos, &val8);
- address = base + val8 * sizeof(uint16_t);
+ address = offset + val8 * sizeof(uint16_t);
break;
case MDS_16_BITS_SIGNED:
test = g_binary_content_read_s16(content, pos, endian, &val16);
- address = base + val16 * sizeof(uint16_t);
+ address = offset + val16 * sizeof(uint16_t);
break;
case MDS_32_BITS_SIGNED:
test = g_binary_content_read_s32(content, pos, endian, &val32);
- address = base + val32 * sizeof(uint16_t);
+ address = offset + val32 * sizeof(uint16_t);
break;
default:
- return NULL;
+ test = false;
break;
}
@@ -201,7 +204,7 @@ GArchOperand *g_dalvik_target_operand_new(const GBinContent *content, vmpa2t *po
return NULL;
result = g_object_new(G_TYPE_DALVIK_TARGET_OPERAND, NULL);
- result->immediate = G_IMM_OPERAND(g_imm_operand_new_from_value(MDS_32_BITS/*FIXME*/, (uint32_t)address/* FIXME */));
+ result->immediate = G_IMM_OPERAND(g_imm_operand_new_from_value(MDS_32_BITS, address));
return G_ARCH_OPERAND(result);
diff --git a/src/arch/dalvik/operands/target.h b/src/arch/dalvik/operands/target.h
index cb0e9f1..6328546 100644
--- a/src/arch/dalvik/operands/target.h
+++ b/src/arch/dalvik/operands/target.h
@@ -51,7 +51,7 @@ typedef struct _GDalvikTargetOperandClass GDalvikTargetOperandClass;
GType g_dalvik_target_operand_get_type(void);
/* Crée un opérande visant un instruction Dalvik. */
-GArchOperand *g_dalvik_target_operand_new(const GBinContent *, vmpa2t *, MemoryDataSize, SourceEndian, vmpa_t);
+GArchOperand *g_dalvik_target_operand_new(const GBinContent *, vmpa2t *, MemoryDataSize, SourceEndian, const vmpa2t *);
/* Fournit l'adresse représentée par une opérande Dalvik. */
const GImmOperand *g_dalvik_target_operand_get_value(const GDalvikTargetOperand *);
diff --git a/src/arch/processor.c b/src/arch/processor.c
index bbe506a..21db869 100644
--- a/src/arch/processor.c
+++ b/src/arch/processor.c
@@ -24,6 +24,7 @@
#include "processor.h"
+#include <assert.h>
#include <malloc.h>
#include <stdlib.h>
@@ -304,6 +305,8 @@ GArchInstruction *g_arch_processor_disassemble(const GArchProcessor *proc, GProc
GArchInstruction *result; /* Instruction à renvoyer */
vmpa2t back; /* Position sauvegardée */
+ assert(has_phys_addr(pos) && has_virt_addr(pos));
+
copy_vmpa(&back, pos);
result = G_ARCH_PROCESSOR_GET_CLASS(proc)->disassemble(proc, ctx, content, pos, format);
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 */