diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2016-12-29 10:30:28 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2016-12-29 10:30:28 (GMT) |
commit | 9f9041e11efa71cb043425cd5e89daea0247e76c (patch) | |
tree | 84d8704c291a5efef46af1e14a2aa3544dc29455 /src/format | |
parent | 403a0519ec85a156a7f306b045d9cab619302473 (diff) |
Cut binary data into several areas using all the available CPUs and less memory.
Diffstat (limited to 'src/format')
-rw-r--r-- | src/format/dex/class.c | 9 | ||||
-rw-r--r-- | src/format/dex/class.h | 2 | ||||
-rwxr-xr-x | src/format/dex/dex.c | 16 | ||||
-rw-r--r-- | src/format/dex/method.c | 18 | ||||
-rw-r--r-- | src/format/dex/method.h | 2 | ||||
-rw-r--r-- | src/format/elf/elf.c | 155 | ||||
-rw-r--r-- | src/format/executable-int.h | 8 | ||||
-rw-r--r-- | src/format/executable.c | 167 | ||||
-rw-r--r-- | src/format/executable.h | 6 | ||||
-rw-r--r-- | src/format/format.c | 1 | ||||
-rw-r--r-- | src/format/symbol.c | 31 | ||||
-rw-r--r-- | src/format/symbol.h | 3 |
12 files changed, 197 insertions, 221 deletions
diff --git a/src/format/dex/class.c b/src/format/dex/class.c index 26907ed..c1ff62a 100644 --- a/src/format/dex/class.c +++ b/src/format/dex/class.c @@ -401,9 +401,8 @@ GDexMethod *g_dex_class_get_method(const GDexClass *class, bool virtual, size_t /****************************************************************************** * * -* Paramètres : class = informations chargées à consulter. * +* 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. * * * @@ -413,15 +412,15 @@ GDexMethod *g_dex_class_get_method(const GDexClass *class, bool virtual, size_t * * ******************************************************************************/ -void g_dex_class_include_as_portion(const GDexClass *class, const GDexFormat *format, GPortionLayer *layer) +void g_dex_class_include_as_portion(const GDexClass *class, GExeFormat *format) { size_t i; /* Boucle de parcours */ for (i = 0; i < class->dmethods_count; i++) - g_dex_method_include_as_portion(class->direct_methods[i], format, layer); + g_dex_method_include_as_portion(class->direct_methods[i], format); for (i = 0; i < class->vmethods_count; i++) - g_dex_method_include_as_portion(class->virtual_methods[i], format, layer); + g_dex_method_include_as_portion(class->virtual_methods[i], format); } diff --git a/src/format/dex/class.h b/src/format/dex/class.h index 46529c3..ec2fa24 100644 --- a/src/format/dex/class.h +++ b/src/format/dex/class.h @@ -69,7 +69,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 *, const GDexFormat *, GPortionLayer *); +void g_dex_class_include_as_portion(const GDexClass *, GExeFormat *); /* 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 c550375..df920b2 100755 --- a/src/format/dex/dex.c +++ b/src/format/dex/dex.c @@ -58,7 +58,7 @@ static void g_dex_format_finalize(GDexFormat *); static const char *g_dex_format_get_target_machine(const GDexFormat *); /* Etend la définition des portions au sein d'un binaire. */ -static void g_dex_format_refine_portions(const GDexFormat *, GPortionLayer *); +static void g_dex_format_refine_portions(GDexFormat *); /* Fournit l'emplacement d'une section donnée. */ static bool g_dex_format_get_section_range_by_name(const GDexFormat *, const char *, mrange_t *); @@ -247,12 +247,14 @@ GBinFormat *g_dex_format_new(GBinContent *content, GExeFormat *parent, GtkStatus { GDexFormat *result; /* Structure à retourner */ GBinFormat *base; /* Version basique du format */ + GExeFormat *exe_format; /* Autre version du format */ vmpa2t pos; /* Position de tête de lecture */ wgroup_id_t gid; /* Identifiant pour les tâches */ result = g_object_new(G_TYPE_DEX_FORMAT, NULL); base = G_BIN_FORMAT(result); + exe_format = G_EXE_FORMAT(result); g_binary_format_set_content(base, content); @@ -277,7 +279,7 @@ GBinFormat *g_dex_format_new(GBinContent *content, GExeFormat *parent, GtkStatus if (!load_all_dex_classes(result, gid, status)) goto gdfn_error; - if (!g_binary_format_complete_loading(base, status)) + if (!g_executable_format_complete_loading(exe_format, status)) goto gdfn_error; return base; @@ -322,20 +324,18 @@ static const char *g_dex_format_get_target_machine(const GDexFormat *format) * * ******************************************************************************/ -static void g_dex_format_refine_portions(const GDexFormat *format, GPortionLayer *main) +static void g_dex_format_refine_portions(GDexFormat *format) { - GPortionLayer *layer; /* Couche à mettre en place */ + GExeFormat *exe_format; /* Autre version du format */ size_t max; /* Nombre d'itérations prévues */ size_t i; /* Boucle de parcours */ - layer = g_portion_layer_new(NO_LENGTH_YET, _("Code")); - - g_portion_layer_attach_sub(main, layer); + exe_format = G_EXE_FORMAT(format); max = g_dex_format_count_classes(format); for (i = 0; i < max; i++) - g_dex_class_include_as_portion(format->classes[i], format, layer); + g_dex_class_include_as_portion(format->classes[i], exe_format); } diff --git a/src/format/dex/method.c b/src/format/dex/method.c index 1223eb9..8659a73 100644 --- a/src/format/dex/method.c +++ b/src/format/dex/method.c @@ -338,7 +338,6 @@ 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. * * * @@ -348,11 +347,10 @@ GBinRoutine *g_dex_method_get_routine(const GDexMethod *method) * * ******************************************************************************/ -void g_dex_method_include_as_portion(const GDexMethod *method, const GDexFormat *format, GPortionLayer *layer) +void g_dex_method_include_as_portion(const GDexMethod *method, GExeFormat *format) { vmpa2t addr; /* Emplacement dans le binaire */ GBinPortion *new; /* Nouvelle portion définie */ - char *desc; /* Description d'une portion */ /* Si la taille est nulle, on ne fait rien */ if (method->info.access_flags & ACC_NATIVE) @@ -361,22 +359,16 @@ void g_dex_method_include_as_portion(const GDexMethod *method, const GDexFormat if (!method->has_body) return; - if (!g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), method->offset, &addr)) + if (!g_exe_format_translate_offset_into_vmpa(format, method->offset, &addr)) return; - new = g_binary_portion_new(BPC_CODE); + new = g_binary_portion_new(BPC_CODE, &addr, method->body.insns_size * sizeof(uint16_t)); - asprintf(&desc, _("Dalvik code")); - - g_binary_portion_set_desc(new, desc); - - free(desc); - - g_binary_portion_set_values(new, &addr, method->body.insns_size * sizeof(uint16_t)); + g_binary_portion_set_desc(new, _("Dalvik code")); g_binary_portion_set_rights(new, PAC_READ | PAC_EXEC); - g_portion_layer_include(layer, new); + g_exe_format_include_portion(format, new); } diff --git a/src/format/dex/method.h b/src/format/dex/method.h index 41ddb4c..8836abb 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 *, const GDexFormat *, GPortionLayer *); +void g_dex_method_include_as_portion(const GDexMethod *, GExeFormat *); /* Indique la position de la méthode au sein du binaire. */ bool g_dex_method_get_offset(const GDexMethod *method, phys_t *); diff --git a/src/format/elf/elf.c b/src/format/elf/elf.c index 2dd41e1..a51fe33 100644 --- a/src/format/elf/elf.c +++ b/src/format/elf/elf.c @@ -69,7 +69,7 @@ static SourceEndian g_elf_format_get_endianness(const GElfFormat *); static const char *g_elf_format_get_target_machine(const GElfFormat *); /* Etend la définition des portions au sein d'un binaire. */ -static void g_elf_format_refine_portions(const GElfFormat *, GPortionLayer *); +static void g_elf_format_refine_portions(GElfFormat *); /* Fournit l'emplacement correspondant à une position physique. */ static bool g_elf_format_translate_offset_into_vmpa(const GElfFormat *, phys_t, vmpa2t *); @@ -244,10 +244,12 @@ GBinFormat *g_elf_format_new(GBinContent *content, GExeFormat *parent, GtkStatus { GElfFormat *result; /* Structure à retourner */ GBinFormat *base; /* Version basique du format */ + GExeFormat *exe_format; /* Autre version du format */ result = g_object_new(G_TYPE_ELF_FORMAT, NULL); base = G_BIN_FORMAT(result); + exe_format = G_EXE_FORMAT(result); g_binary_format_set_content(base, content); @@ -305,7 +307,7 @@ GBinFormat *g_elf_format_new(GBinContent *content, GExeFormat *parent, GtkStatus } - if (!g_binary_format_complete_loading(base, status)) + if (!g_executable_format_complete_loading(exe_format, status)) goto gefn_error; return base; @@ -383,7 +385,6 @@ static const char *g_elf_format_get_target_machine(const GElfFormat *format) /****************************************************************************** * * * Paramètres : format = informations chargées à consulter. * -* main = couche de portions principale à raffiner. * * * * Description : Etend la définition des portions au sein d'un binaire. * * * @@ -393,14 +394,13 @@ static const char *g_elf_format_get_target_machine(const GElfFormat *format) * * ******************************************************************************/ -static void g_elf_format_refine_portions(const GElfFormat *format, GPortionLayer *main) +static void g_elf_format_refine_portions(GElfFormat *format) { - GPortionLayer *layer; /* Couche à mettre en place */ + GExeFormat *exe_format; /* Autre version du format */ uint16_t max; /* Décompte d'éléments traités */ - elf_phdr *sorted_phdrs; /* Liste de segments triée */ uint16_t i; /* Boucle de parcours */ off_t offset; /* Début de part de programme */ - elf_phdr *phdr; /* En-tête de programme ELF */ + elf_phdr phdr; /* En-tête de programme ELF */ uint32_t p_flags; /* Droits associés à une partie*/ const char *background; /* Fond signigicatif */ GBinPortion *new; /* Nouvelle portion définie */ @@ -409,11 +409,12 @@ static void g_elf_format_refine_portions(const GElfFormat *format, GPortionLayer PortionAccessRights rights; /* Droits d'une portion */ elf_shdr strings; /* Section des descriptions */ bool has_strings; /* Section trouvée ? */ - elf_shdr *sorted_shdrs; /* Liste de sections triée */ - elf_shdr *section; /* En-tête de section ELF */ + elf_shdr shdr; /* En-tête de section ELF */ uint64_t sh_flags; /* Droits associés à une partie*/ const char *name; /* Nom trouvé ou NULL */ + exe_format = G_EXE_FORMAT(format); + /** * La copie des différents en-têtes cherche à reproduire l'inclusion native * du format : @@ -429,83 +430,35 @@ static void g_elf_format_refine_portions(const GElfFormat *format, GPortionLayer * Côté segments basiques. */ - layer = g_portion_layer_new(NO_LENGTH_YET, _("Segment")); - - g_portion_layer_attach_sub(main, layer); - - /* Constitution d'une liste de travail */ - max = ELF_HDR(format, format->header, e_phnum); - sorted_phdrs = (elf_phdr *)calloc(max, sizeof(elf_phdr)); - for (i = 0; i < max; i++) { offset = ELF_HDR(format, format->header, e_phoff) + ELF_HDR(format, format->header, e_phentsize) * i; - if (!read_elf_program_header(format, offset, &sorted_phdrs[i])) - { - if (format->is_32b) - sorted_phdrs[i].phdr32.p_type = PT_NULL; - else - sorted_phdrs[i].phdr64.p_type = PT_NULL; - } - - } - - /* Tri de cette liste */ - - int sort_phdr(elf_phdr *a, elf_phdr *b) - { - uint64_t filesz_a; /* Taille de l'en-tête 'a' */ - uint64_t filesz_b; /* Taille de l'en-tête 'b' */ - int status; /* Bilan d'une comparaison */ - - filesz_a = ELF_PHDR(format, *a, p_filesz); - filesz_b = ELF_PHDR(format, *b, p_filesz); - - if (filesz_a < filesz_b) - status = 1; - - else if (filesz_a > filesz_b) - status = -1; - - else - status = 0; - - return status; - - } - - qsort(sorted_phdrs, max, sizeof(elf_phdr), (__compar_fn_t)sort_phdr); - - /* Inclusion de ces en-têtes */ - - for (i = 0; i < max; i++) - { - phdr = &sorted_phdrs[i]; + if (!read_elf_program_header(format, offset, &phdr)) + continue; - if (ELF_PHDR(format, *phdr, p_type) == PT_NULL) + if (ELF_PHDR(format, phdr, p_type) == PT_NULL) continue; - p_flags = ELF_PHDR(format, *phdr, p_flags); + p_flags = ELF_PHDR(format, phdr, p_flags); if (p_flags & PF_X) background = BPC_CODE; else if (p_flags & PF_W) background = BPC_DATA; else background = BPC_DATA_RO; - new = g_binary_portion_new(background); + init_vmpa(&addr, ELF_PHDR(format, phdr, p_offset), ELF_PHDR(format, phdr, p_vaddr)); + + new = g_binary_portion_new(background, &addr, ELF_PHDR(format, phdr, p_filesz)); snprintf(desc, MAX_PORTION_DESC, "%s \"%s\"", _("Segment"), - get_elf_program_type_desc(ELF_PHDR(format, *phdr, p_type))); + get_elf_program_type_desc(ELF_PHDR(format, phdr, p_type))); g_binary_portion_set_desc(new, desc); - init_vmpa(&addr, ELF_PHDR(format, *phdr, p_offset), ELF_PHDR(format, *phdr, p_vaddr)); - g_binary_portion_set_values(new, &addr, ELF_PHDR(format, *phdr, p_filesz)); - rights = PAC_NONE; if (p_flags & PF_R) rights |= PAC_READ; if (p_flags & PF_W) rights |= PAC_WRITE; @@ -513,12 +466,10 @@ static void g_elf_format_refine_portions(const GElfFormat *format, GPortionLayer g_binary_portion_set_rights(new, rights); - g_portion_layer_include(layer, new); + g_exe_format_include_portion(exe_format, new); } - free(sorted_phdrs); - /** * Inclusion des sections, si possible... */ @@ -527,64 +478,17 @@ static void g_elf_format_refine_portions(const GElfFormat *format, GPortionLayer ELF_HDR(format, format->header, e_shstrndx), &strings); - layer = g_portion_layer_new(NO_LENGTH_YET, _("Section")); - - g_portion_layer_attach_sub(main, layer); - - /* Constitution d'une liste de travail */ - max = ELF_HDR(format, format->header, e_shnum); - sorted_shdrs = (elf_shdr *)calloc(max, sizeof(elf_shdr)); - - for (i = 0; i < max; i++) - { - if (!find_elf_section_by_index(format, i, &sorted_shdrs[i])) - { - if (format->is_32b) - sorted_shdrs[i].shdr32.sh_offset = 0; - else - sorted_shdrs[i].shdr64.sh_offset = 0; - } - - } - - /* Tri de cette liste */ - - int sort_shdr(elf_shdr *a, elf_shdr *b) - { - uint64_t size_a; /* Taille de l'en-tête 'a' */ - uint64_t size_b; /* Taille de l'en-tête 'b' */ - int status; /* Bilan d'une comparaison */ - - size_a = ELF_SHDR(format, *a, sh_size); - size_b = ELF_SHDR(format, *b, sh_size); - - if (size_a < size_b) - status = 1; - - else if (size_a > size_b) - status = -1; - - else - status = 0; - - return status; - - } - - qsort(sorted_shdrs, max, sizeof(elf_shdr), (__compar_fn_t)sort_shdr); - - /* Inclusion de ces en-têtes */ - for (i = 0; i < max; i++) { - section = &sorted_shdrs[i]; + if (!find_elf_section_by_index(format, i, &shdr)) + continue; - if (ELF_SHDR(format, *section, sh_offset) == 0) + if (ELF_SHDR(format, shdr, sh_offset) == 0) continue; - sh_flags = ELF_SHDR(format, *section, sh_flags); + sh_flags = ELF_SHDR(format, shdr, sh_flags); if ((sh_flags & SHF_ALLOC) == 0) continue; @@ -593,11 +497,13 @@ static void g_elf_format_refine_portions(const GElfFormat *format, GPortionLayer else if (sh_flags & SHF_WRITE) background = BPC_DATA; else background = BPC_DATA_RO; - new = g_binary_portion_new(background); + init_vmpa(&addr, ELF_SHDR(format, shdr, sh_offset), ELF_SHDR(format, shdr, sh_addr)); + + new = g_binary_portion_new(background, &addr, ELF_SHDR(format, shdr, sh_size)); if (has_strings) name = extract_name_from_elf_string_section(format, &strings, - ELF_SHDR(format, *section, sh_name)); + ELF_SHDR(format, shdr, sh_name)); else name = NULL; if (name != NULL) @@ -607,9 +513,6 @@ static void g_elf_format_refine_portions(const GElfFormat *format, GPortionLayer g_binary_portion_set_desc(new, desc); - init_vmpa(&addr, ELF_SHDR(format, *section, sh_offset), ELF_SHDR(format, *section, sh_addr)); - g_binary_portion_set_values(new, &addr, ELF_SHDR(format, *section, sh_size)); - rights = PAC_NONE; if (sh_flags & SHF_ALLOC) rights |= PAC_READ; if (sh_flags & SHF_WRITE) rights |= PAC_WRITE; @@ -617,12 +520,10 @@ static void g_elf_format_refine_portions(const GElfFormat *format, GPortionLayer g_binary_portion_set_rights(new, rights); - g_portion_layer_include(layer, new); + g_exe_format_include_portion(exe_format, new); } - free(sorted_shdrs); - } diff --git a/src/format/executable-int.h b/src/format/executable-int.h index a4d4b35..88527a5 100644 --- a/src/format/executable-int.h +++ b/src/format/executable-int.h @@ -36,7 +36,7 @@ typedef const char * (* get_target_machine_fc) (const GExeFormat *); /* Etend la définition des portions au sein d'un binaire. */ -typedef void (* refine_portions_fc) (const GExeFormat *, GPortionLayer *); +typedef void (* refine_portions_fc) (GExeFormat *); /* Fournit l'emplacement correspondant à une position physique. */ typedef bool (* translate_phys_fc) (const GExeFormat *, phys_t, vmpa2t *); @@ -57,7 +57,8 @@ struct _GExeFormat GDbgFormat **debugs; /* Informations de débogage */ size_t debugs_count; /* Nombre de ces informations */ - GPortionLayer *layers; /* Couches de morceaux binaires*/ + GBinPortion *portions; /* Couches de morceaux binaires*/ + GMutex mutex; /* Accès à l'arborescence */ }; @@ -77,6 +78,9 @@ struct _GExeFormatClass }; +/* Effectue les ultimes opérations de chargement d'un binaire. */ +bool g_executable_format_complete_loading(GExeFormat *, GtkStatusStack *); + /* Fournit l'emplacement correspondant à une position physique. */ bool g_exe_format_without_virt_translate_offset_into_vmpa(const GExeFormat *, phys_t, vmpa2t *); diff --git a/src/format/executable.c b/src/format/executable.c index c1ff940..3e902cf 100644 --- a/src/format/executable.c +++ b/src/format/executable.c @@ -24,6 +24,7 @@ #include "executable.h" +#include <assert.h> #include <malloc.h> #include <stdlib.h> @@ -39,6 +40,12 @@ static void g_executable_format_class_init(GExeFormatClass *); /* Initialise une instance de format d'exécutable générique. */ static void g_executable_format_init(GExeFormat *); +/* Supprime toutes les références externes. */ +static void g_executable_format_dispose(GExeFormat *); + +/* Procède à la libération totale de la mémoire. */ +static void g_executable_format_finalize(GExeFormat *); + /* Indique le type défini pour un format d'exécutable générique. */ @@ -59,6 +66,12 @@ G_DEFINE_TYPE(GExeFormat, g_executable_format, G_TYPE_BIN_FORMAT); static void g_executable_format_class_init(GExeFormatClass *klass) { + GObjectClass *object; /* Autre version de la classe */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_executable_format_dispose; + object->finalize = (GObjectFinalizeFunc)g_executable_format_finalize; } @@ -77,11 +90,57 @@ static void g_executable_format_class_init(GExeFormatClass *klass) static void g_executable_format_init(GExeFormat *format) { + g_mutex_init(&format->mutex); } +/****************************************************************************** +* * +* Paramètres : format = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_executable_format_dispose(GExeFormat *format) +{ + size_t i; /* Boucle de parcours */ + + for (i = 0; i < format->debugs_count; i++) + g_object_unref(G_OBJECT(format->debugs[i])); + + if (format->portions != NULL) + g_object_unref(G_OBJECT(format->portions)); + + g_mutex_clear(&format->mutex); + G_OBJECT_CLASS(g_executable_format_parent_class)->dispose(G_OBJECT(format)); + +} + + +/****************************************************************************** +* * +* Paramètres : format = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_executable_format_finalize(GExeFormat *format) +{ + G_OBJECT_CLASS(g_executable_format_parent_class)->finalize(G_OBJECT(format)); + +} /****************************************************************************** @@ -184,109 +243,95 @@ const char *g_exe_format_get_target_machine(const GExeFormat *format) /****************************************************************************** * * -* Paramètres : format = description de l'exécutable à consulter. * +* Paramètres : format = instance à traiter. * +* status = barre de statut à tenir informée. * * * -* Description : Fournit la première couche des portions composent le binaire.* +* Description : Effectue les ultimes opérations de chargement d'un binaire. * * * -* Retour : Couche brute des différentes portions. * +* Retour : Bilan de l'opération. * * * -* Remarques : Le compteur de références de l'instance renvoyée doit être * -* décrémenté après usage. * +* Remarques : - * * * ******************************************************************************/ -GPortionLayer *g_exe_format_get_main_layer(GExeFormat *format) +bool g_executable_format_complete_loading(GExeFormat *format, GtkStatusStack *status) { - GBinPortion *portion; /* Portion brute globale */ + bool result; /* Bilan à faire remonter */ + GBinFormat *base; /* Version basique du format */ vmpa2t addr; /* Emplacement vide de sens */ phys_t length; /* Taille de portion globale */ - GPortionLayer *layer; /* Couche à mettre en place */ - - if (format->layers == NULL) - { - /* Création d'une portion globale */ - - portion = g_binary_portion_new(BPC_RAW); - init_vmpa(&addr, 0, VMPA_NO_VIRTUAL); - length = g_binary_content_compute_size(G_BIN_FORMAT(format)->content); + base = G_BIN_FORMAT(format); - g_binary_portion_set_values(portion, &addr, length); + result = g_binary_format_complete_loading(base, status); - /* Création d'une couche de base brute */ - - layer = g_portion_layer_new(length, NULL); - - g_portion_layer_include(layer, portion); + if (result) + { + result = g_exe_format_translate_offset_into_vmpa(format, 0, &addr); + assert(result); - /* Remplissage */ + length = g_binary_content_compute_size(base->content); - G_EXE_FORMAT_GET_CLASS(format)->refine_portions(format, layer); + format->portions = g_binary_portion_new(BPC_RAW, &addr, length); - format->layers = layer; + G_EXE_FORMAT_GET_CLASS(format)->refine_portions(format); } - g_object_ref(G_OBJECT(format->layers)); - - return format->layers; + return result; } /****************************************************************************** * * -* Paramètres : format = informations chargées à consulter. * -* count = quantité de zones listées. [OUT] * +* Paramètres : format = description de l'exécutable à modifier. * +* portion = portion à inclure dans les définitions du format. * * * -* Description : Fournit les espaces mémoires des portions exécutables. * +* Description : Procède à l'enregistrement d'une portion dans un format. * * * -* Retour : Liste de zones binaires exécutables à libérer après usage. * +* Retour : - * * * * Remarques : - * * * ******************************************************************************/ -mrange_t *g_exe_format_get_x_ranges(GExeFormat *format, size_t *count) +void g_exe_format_include_portion(GExeFormat *format, GBinPortion *portion) { - mrange_t *result; /* Liste à retourner */ - - typedef struct _x_ranges - { - mrange_t *list; - size_t length; + g_mutex_lock(&format->mutex); - } x_ranges; + g_binary_portion_include(format->portions, portion); - x_ranges tmp; /* Sauvegarde de la liste */ - GPortionLayer *layer; /* Couche première de portions */ + g_mutex_unlock(&format->mutex); - bool visit_for_x(GBinPortion *portion, x_ranges *ranges) - { - const mrange_t *range; - - if (g_binary_portion_get_rights(portion) & PAC_EXEC) - { - range = g_binary_portion_get_range(portion); +} - ranges->list = (mrange_t *)realloc(ranges->list, ++ranges->length * sizeof(mrange_t)); - copy_mrange(&ranges->list[ranges->length - 1], range); - } +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à consulter. * +* * +* Description : Fournit la première couche des portions composent le binaire.* +* * +* Retour : Arborescence des différentes portions binaires. * +* * +* Remarques : Le compteur de références de l'instance renvoyée doit être * +* décrémenté après usage. * +* * +******************************************************************************/ - return true; +GBinPortion *g_exe_format_get_portions(GExeFormat *format) +{ + GBinPortion *result; /* Instance à retourner */ - } + g_mutex_lock(&format->mutex); - tmp.list = NULL; - tmp.length = 0; + result = format->portions; - layer = g_exe_format_get_main_layer(format); - g_portion_layer_visit(format->layers, (visit_portion_fc)visit_for_x, &tmp); - g_object_unref(G_OBJECT(layer)); + if (result != NULL) + g_object_ref(G_OBJECT(result)); - result = tmp.list; - *count = tmp.length; + g_mutex_unlock(&format->mutex); return result; diff --git a/src/format/executable.h b/src/format/executable.h index ad89948..6384851 100644 --- a/src/format/executable.h +++ b/src/format/executable.h @@ -52,7 +52,6 @@ typedef struct _GExeFormatClass GExeFormatClass; /* Indique le type défini pour un format d'exécutable générique. */ GType g_executable_format_get_type(void); - /* Rajoute des informations de débogage à un exécutable. */ void g_exe_format_add_debug_info(GExeFormat *, GDbgFormat *); @@ -65,8 +64,11 @@ GDbgFormat *g_exe_format_get_debug_info(const GExeFormat *, size_t); /* Indique le type d'architecture visée par le format. */ const char *g_exe_format_get_target_machine(const GExeFormat *); +/* Procède à l'enregistrement d'une portion dans un format. */ +void g_exe_format_include_portion(GExeFormat *, GBinPortion *); + /* Fournit la première couche des portions composent le binaire. */ -GPortionLayer *g_exe_format_get_main_layer(GExeFormat *); +GBinPortion *g_exe_format_get_portions(GExeFormat *); /* Fournit les espaces mémoires des portions exécutables. */ mrange_t *g_exe_format_get_x_ranges(GExeFormat *format, size_t *count); diff --git a/src/format/format.c b/src/format/format.c index bf4a0e1..516f882 100644 --- a/src/format/format.c +++ b/src/format/format.c @@ -137,7 +137,6 @@ bool g_binary_format_complete_loading(GBinFormat *format, GtkStatusStack *status * * * Paramètres : format = description de l'exécutable à consulter. * * content = contenu binaire à parcourir. * -* length = taille du contenu fourni. * * * * Description : Définit le contenu binaire à analyser. * * * diff --git a/src/format/symbol.c b/src/format/symbol.c index 48f3dbb..97ff114 100644 --- a/src/format/symbol.c +++ b/src/format/symbol.c @@ -226,6 +226,37 @@ int g_binary_symbol_cmp(const GBinSymbol **a, const GBinSymbol **b) /****************************************************************************** * * +* Paramètres : symbol = symbole à analyser. * +* addr = localisation à venir comparer à celle du symbole. * +* * +* Description : Compare un symbole et une localisation. * +* * +* Retour : Bilan de la comparaison : -1, 0 ou 1 (-1 par défaut). * +* * +* Remarques : - * +* * +******************************************************************************/ + +int g_binary_symbol_cmp_with_vmpa(const GBinSymbol *symbol, const vmpa2t *addr) +{ + int result; /* Bilan à retourner */ + const mrange_t *range; /* Emplacement du symbole */ + + range = g_binary_symbol_get_range(symbol); + + if (range == NULL) + result = 1; + + else + result = cmp_mrange_with_vmpa(range, addr); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : symbol = symbole à venir consulter. * * * * Description : Fournit le type du symbole. * diff --git a/src/format/symbol.h b/src/format/symbol.h index 8432d8d..78741cb 100644 --- a/src/format/symbol.h +++ b/src/format/symbol.h @@ -80,6 +80,9 @@ GBinSymbol *g_binary_symbol_new(SymbolType); /* Compare deux symboles d'exécutable selon leurs propriétés. */ int g_binary_symbol_cmp(const GBinSymbol **, const GBinSymbol **); +/* Compare un symbole et une localisation. */ +int g_binary_symbol_cmp_with_vmpa(const GBinSymbol *, const vmpa2t *); + /* Fournit le type du symbole. */ SymbolType g_binary_symbol_get_target_type(const GBinSymbol *); |