diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/analysis/binaries/file.c | 59 | ||||
-rwxr-xr-x | src/core/Makefile.am | 1 | ||||
-rw-r--r-- | src/core/core.c | 5 | ||||
-rw-r--r-- | src/core/formats.c | 292 | ||||
-rw-r--r-- | src/core/formats.h | 62 | ||||
-rwxr-xr-x | src/format/dex/dex.c | 17 | ||||
-rwxr-xr-x | src/format/dex/dex.h | 2 | ||||
-rw-r--r-- | src/format/dwarf/dwarf.c | 2 | ||||
-rw-r--r-- | src/format/dwarf/dwarf.h | 2 | ||||
-rw-r--r-- | src/format/elf/elf.c | 23 | ||||
-rw-r--r-- | src/format/elf/elf.h | 4 | ||||
-rw-r--r-- | src/format/format-int.h | 2 | ||||
-rw-r--r-- | src/format/format.c | 154 | ||||
-rw-r--r-- | src/format/format.h | 44 | ||||
-rwxr-xr-x | src/format/java/java.c | 17 | ||||
-rwxr-xr-x | src/format/java/java.h | 2 | ||||
-rw-r--r-- | src/format/pe/pe.c | 12 | ||||
-rw-r--r-- | src/format/pe/pe.h | 2 | ||||
-rw-r--r-- | src/glibext/Makefile.am | 1 | ||||
-rw-r--r-- | src/glibext/gbincontent.c | 288 | ||||
-rw-r--r-- | src/glibext/gbincontent.h | 73 | ||||
-rw-r--r-- | src/main.c | 5 | ||||
-rw-r--r-- | src/plugins/pglist.h | 11 | ||||
-rw-r--r-- | src/plugins/plugin-int.h | 10 |
24 files changed, 805 insertions, 285 deletions
diff --git a/src/analysis/binaries/file.c b/src/analysis/binaries/file.c index a724cb7..d49ecb4 100644 --- a/src/analysis/binaries/file.c +++ b/src/analysis/binaries/file.c @@ -24,16 +24,14 @@ #include "file.h" -#include <fcntl.h> #include <string.h> -#include <unistd.h> -#include <sys/mman.h> -#include <sys/stat.h> #include "../binary-int.h" #include "../../common/extstr.h" +#include "../../core/formats.h" #include "../../core/processors.h" +#include "../../glibext/gbincontent.h" #include "../../gui/panels/log.h" @@ -161,11 +159,8 @@ GLoadedBinary *g_file_binary_new_from_file(const char *filename) { GFileBinary *result; /* Adresse à retourner */ GLoadedBinary *loaded; /* Version parente */ - int fd; /* Descripteur du fichier */ - struct stat info; /* Informations sur le fichier */ - int ret; /* Bilan d'un appel */ - void *content; /* Contenu brut du fichier */ - const char *target; /* Architecture requise */ + GBinContent *content; /* Contenu binaire chargé */ + const char *target; /* Sous-traitance requise */ const char *desc; /* Description humaine associée*/ result = g_object_new(G_TYPE_FILE_BINARY, NULL); @@ -175,47 +170,31 @@ GLoadedBinary *g_file_binary_new_from_file(const char *filename) result->filename = strdup(filename); - /* Récupération des données */ + content = g_binary_content_new_from_file(filename); + if (content == NULL) goto lbf_error; - fd = open(filename, O_RDONLY); - if (fd == -1) - { - perror("open"); - goto lbf_error; - } + ///// + loaded->bin_data = g_binary_content_get(content, &loaded->bin_length); + /////// - ret = fstat(fd, &info); - if (ret == -1) - { - close(fd); - perror("fstat"); - goto lbf_error; - } - content = mmap(NULL, info.st_size, PROT_READ, MAP_PRIVATE, fd, 0); - if (content == MAP_FAILED) + target = find_matching_format(content); + desc = get_binary_format_name(target); + + if (desc == NULL) { - close(fd); - perror("mmap"); + g_object_unref(G_OBJECT(content)); + log_simple_message(LMT_INFO, _("Unknown binary format")); goto lbf_error; } + else + log_variadic_message(LMT_INFO, _("Detected format: %s"), desc); - loaded->bin_length = info.st_size; - loaded->bin_data = (bin_t *)malloc(info.st_size); - - memcpy(loaded->bin_data, content, info.st_size); - - munmap(content, info.st_size); - close(fd); - - /* Chargement du binaire */ - - loaded->format = G_EXE_FORMAT(load_new_format(FMT_EXEC, filename, - &loaded->bin_data, &loaded->bin_length)); + loaded->format = G_EXE_FORMAT(load_new_named_format(target, content)); if (loaded->format == NULL) { - log_simple_message(LMT_INFO, _("Unknown binary format")); + log_simple_message(LMT_ERROR, _("Error while loading the binary")); goto lbf_error; } diff --git a/src/core/Makefile.am b/src/core/Makefile.am index 0d6d754..f76f520 100755 --- a/src/core/Makefile.am +++ b/src/core/Makefile.am @@ -4,6 +4,7 @@ noinst_LTLIBRARIES = libcore.la libcore_la_SOURCES = \ collections.h collections.c \ core.h core.c \ + formats.h formats.c \ params.h params.c \ processors.h processors.c diff --git a/src/core/core.c b/src/core/core.c index 36428d7..accb3da 100644 --- a/src/core/core.c +++ b/src/core/core.c @@ -25,6 +25,7 @@ #include "collections.h" +#include "formats.h" #include "params.h" #include "processors.h" @@ -59,6 +60,8 @@ bool load_all_basic_components(void) result &= load_hard_coded_processors_definitions(); + result &= load_hard_coded_formats_definitions(); + result &= load_hard_coded_collection_definitions(); } @@ -84,6 +87,8 @@ void unload_all_basic_components(void) { unload_collection_definitions(); + unload_formats_definitions(); + unload_processors_definitions(); g_generic_config_write(get_main_configuration()); diff --git a/src/core/formats.c b/src/core/formats.c new file mode 100644 index 0000000..b528e62 --- /dev/null +++ b/src/core/formats.c @@ -0,0 +1,292 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * formats.c - enregistrement et fourniture des formats de binaires supportés + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "formats.h" + + +#include <malloc.h> +#include <pthread.h> +#include <string.h> + + +#include "../format/elf/elf.h" + + + +/* Caractéristiques d'un processeur */ +typedef struct _format_t +{ + char *key; /* Clef pour un accès rapide */ + char *name; /* Désignation humaine */ + + format_match_fc is_matching; /* Recherche de correspondance */ + format_load_fc load; /* Procédure de chargement */ + +} format_t; + + +/* Mémorisation des types de formats enregistrés */ +static format_t *_formats_definitions = NULL; +static size_t _formats_definitions_count = 0; + +/* Verrou pour des accès atomiques */ +/* ... */ + + +/* Retrouve l'enregistrement correspondant à une architecture. */ +static format_t *find_format_by_key(const char *); + + + +/****************************************************************************** +* * +* Paramètres : key = désignation rapide et interne d'un format. * +* name = désignation humaine au format de binaire. * +* is_matching = procédure de détection associée. * +* load = procédure de chargement associée. * +* * +* Description : Enregistre un format de contenu binaire donné. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool register_format_type(const char *key, const char *name, format_match_fc is_matching, format_load_fc load) +{ + format_t *new; /* Nouvel élément à définir */ + + /* TODO : if find()... -> unref(), ret false */ + + /* TODO : lock */ + + _formats_definitions = (format_t *)realloc(_formats_definitions, + ++_formats_definitions_count * sizeof(format_t)); + + new = &_formats_definitions[_formats_definitions_count - 1]; + + new->key = strdup(key); + new->name = strdup(name); + + new->is_matching = is_matching; + new->load = load; + + /* TODO : unlock */ + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Charge les définitions de formats "natifs". * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool load_hard_coded_formats_definitions(void) +{ + bool result; /* Bilan à retourner */ + + result = true; + + result &= register_format_type("elf", "Executable and Linkable Format", elf_is_matching, g_elf_format_new); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Décharge toutes les définitions de formats. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void unload_formats_definitions(void) +{ + size_t i; /* Boucle de parcours */ + + for (i = 0; i < _formats_definitions_count; i++) + { + free(_formats_definitions[i].key); + free(_formats_definitions[i].name); + } + + if (_formats_definitions != NULL) + free(_formats_definitions); + + _formats_definitions = NULL; + _formats_definitions_count = 0; + +} + + +/****************************************************************************** +* * +* Paramètres : key = nom technique du processeur recherché. * +* * +* Description : Retrouve l'enregistrement correspondant à une architecture. * +* * +* Retour : Définition trouvée ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static format_t *find_format_by_key(const char *key) +{ + format_t *result; /* Trouvaille à retourner */ + size_t i; /* Boucle de parcours */ + + /** + * Le verrou d'accès global doit être posé ! + */ + + result = NULL; + + for (i = 0; i < _formats_definitions_count; i++) + if (strcmp(_formats_definitions[i].key, key) == 0) + result = &_formats_definitions[i]; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : key = nom technique du format recherché. * +* * +* Description : Fournit le nom humain du format binaire visé. * +* * +* Retour : Désignation humaine trouvée ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const char *get_binary_format_name(const char *key) +{ + const char *result; /* Description à retourner */ + format_t *def; /* Définition d'architecture */ + + /* TODO : lock */ + + def = find_format_by_key(key); + + if (def == NULL) + result = NULL; + else + result = def->name; + + /* TODO : unlock */ + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : content = contenu binaire à parcourir. * +* * +* Description : Identifie un format binaire par son contenu. * +* * +* Retour : Identifiant du format binaire trouvé ou NULL si échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const char *find_matching_format(GBinContent *content) +{ + const char *result; /* Identifiant à retourner */ + size_t i; /* Boucle de parcours */ + format_t *def; /* Définition d'architecture */ + + result = NULL; + + /* TODO : lock */ + + for (i = 0; i < _formats_definitions_count && result == NULL; i++) + { + def = &_formats_definitions[i]; + + if (def->is_matching(content)) + result = def->key; + + } + + /* TODO : unlock */ + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : key = nom technique du processeur recherché. * +* content = contenu binaire pré-chargé à traiter. * +* * +* Description : Charge le format binaire correspondant à un type. * +* * +* Retour : Format binaire instancié. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GBinFormat *load_new_named_format(const char *key, GBinContent *content) +{ + GBinFormat *result; /* Instance à retourner */ + format_t *def; /* Définition d'architecture */ + + /* TODO : lock */ + + def = find_format_by_key(key); + + if (def == NULL) + result = NULL; + else + result = def->load(content); + + /* TODO : unlock */ + + return result; + +} diff --git a/src/core/formats.h b/src/core/formats.h new file mode 100644 index 0000000..bc16f01 --- /dev/null +++ b/src/core/formats.h @@ -0,0 +1,62 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * formats.h - prototypes pour l'enregistrement et la fourniture des formats de binaires supportés + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _CORE_FORMATS_H +#define _CORE_FORMATS_H + + +#include <glib-object.h> +#include <stdbool.h> + + +#include "../format/format.h" + + +/* Indication à propos du support d'un format */ +typedef bool (* format_match_fc) (GBinContent *); + +/* Méthode de chargement d'un format */ +typedef GBinFormat * (* format_load_fc) (GBinContent *); + + +/* Enregistre un format de contenu binaire donné. */ +bool register_format_type(const char *, const char *, format_match_fc, format_load_fc); + +/* Charge les définitions de formats "natifs". */ +bool load_hard_coded_formats_definitions(void); + +/* Décharge toutes les définitions de formats. */ +void unload_formats_definitions(void); + +/* Fournit le nom humain du format binaire visé. */ +const char *get_binary_format_name(const char *); + +/* Identifie un format binaire par son contenu. */ +const char *find_matching_format(GBinContent *); + +/* Charge le format binaire correspondant à un type. */ +GBinFormat *load_new_named_format(const char *, GBinContent *); + + + +#endif /* _ANALYSIS_DB_COLLECTION_H */ diff --git a/src/format/dex/dex.c b/src/format/dex/dex.c index c5271e0..476e6f5 100755 --- a/src/format/dex/dex.c +++ b/src/format/dex/dex.c @@ -67,9 +67,7 @@ static bool g_dex_format_translate_offset_into_address(const GDexFormat *, off_t /****************************************************************************** * * -* Paramètres : type = type de format recherché. * -* content = contenu binaire à parcourir. * -* length = taille du contenu en question. * +* Paramètres : content = contenu binaire à parcourir. * * * * Description : Indique si le format peut être pris en charge ici. * * * @@ -79,14 +77,17 @@ static bool g_dex_format_translate_offset_into_address(const GDexFormat *, off_t * * ******************************************************************************/ -bool dex_is_matching(FormatType type, const uint8_t *content, off_t length) +bool dex_is_matching(GBinContent *content) { bool result; /* Bilan à faire connaître */ + vmpa2t addr; /* Tête de lecture initiale */ + char magic[DEX_FILE_MAGIC_LEN]; /* Idenfiant standard */ - result = false; + init_vmpa(&addr, 0, VMPA_NO_VIRTUAL); + + result = g_binary_content_get_raw(content, &addr, DEX_FILE_MAGIC_LEN, (bin_t *)magic); - if (length >= DEX_FILE_MAGIC_LEN) - result = (memcmp(content, DEX_FILE_MAGIC, DEX_FILE_MAGIC_LEN) == 0); + result &= (memcmp(magic, DEX_FILE_MAGIC, DEX_FILE_MAGIC_LEN) == 0); return result; @@ -166,7 +167,7 @@ GBinFormat *g_dex_format_new(const bin_t *content, off_t length) result = g_object_new(G_TYPE_DEX_FORMAT, NULL); - g_binary_format_set_content(G_BIN_FORMAT(result), content, length); + //g_binary_format_set_content(G_BIN_FORMAT(result), content, length); offset = 0; diff --git a/src/format/dex/dex.h b/src/format/dex/dex.h index 18f0980..aca6cef 100755 --- a/src/format/dex/dex.h +++ b/src/format/dex/dex.h @@ -49,7 +49,7 @@ typedef struct _GDexFormatClass GDexFormatClass; /* Indique si le format peut être pris en charge ici. */ -bool dex_is_matching(FormatType, const bin_t *, off_t); +bool dex_is_matching(GBinContent *); /* Indique le type défini pour un format d'exécutable DEX. */ GType g_dex_format_get_type(void); diff --git a/src/format/dwarf/dwarf.c b/src/format/dwarf/dwarf.c index 0292d60..c7b1c23 100644 --- a/src/format/dwarf/dwarf.c +++ b/src/format/dwarf/dwarf.c @@ -50,7 +50,7 @@ * * ******************************************************************************/ -bool dwarf_is_matching(FormatType type, const uint8_t *content, off_t length) +bool dwarf_is_matching(GBinContent *) { bool result; /* Bilan à faire connaître */ diff --git a/src/format/dwarf/dwarf.h b/src/format/dwarf/dwarf.h index e6d573c..2e32c8e 100644 --- a/src/format/dwarf/dwarf.h +++ b/src/format/dwarf/dwarf.h @@ -30,7 +30,7 @@ /* Indique si le format peut être pris en charge ici. */ -bool dwarf_is_matching(FormatType, const uint8_t *, off_t); +bool dwarf_is_matching(GBinContent *); /* Prend en charge un nouveau format Dwarf. */ GBinFormat *g_dwarf_format_new(const bin_t *, off_t); diff --git a/src/format/elf/elf.c b/src/format/elf/elf.c index cc84335..f0c361e 100644 --- a/src/format/elf/elf.c +++ b/src/format/elf/elf.c @@ -72,9 +72,7 @@ static bool g_elf_format_translate_offset_into_address(const GElfFormat *, off_t /****************************************************************************** * * -* Paramètres : type = type de format recherché. * -* content = contenu binaire à parcourir. * -* length = taille du contenu en question. * +* Paramètres : content = contenu binaire à parcourir. * * * * Description : Indique si le format peut être pris en charge ici. * * * @@ -84,14 +82,17 @@ static bool g_elf_format_translate_offset_into_address(const GElfFormat *, off_t * * ******************************************************************************/ -bool elf_is_matching(FormatType type, const bin_t *content, off_t length) +bool elf_is_matching(GBinContent *content) { bool result; /* Bilan à faire connaître */ + vmpa2t addr; /* Tête de lecture initiale */ + char magic[4]; /* Idenfiant standard */ + + init_vmpa(&addr, 0, VMPA_NO_VIRTUAL); - result = false; + result = g_binary_content_get_raw(content, &addr, 4, (bin_t *)magic); - if (length >= 4) - result = (memcmp(content, "\x7f\x45\x4c\x46" /* .ELF */, 4) == 0); + result &= (memcmp(magic, "\x7f\x45\x4c\x46" /* .ELF */, 4) == 0); return result; @@ -150,7 +151,6 @@ static void g_elf_format_init(GElfFormat *format) /****************************************************************************** * * * Paramètres : content = contenu binaire à parcourir. * -* length = taille du contenu en question. * * * * Description : Prend en charge un nouveau format ELF. * * * @@ -160,13 +160,13 @@ static void g_elf_format_init(GElfFormat *format) * * ******************************************************************************/ -GBinFormat *g_elf_format_new(const bin_t *content, off_t length) +GBinFormat *g_elf_format_new(GBinContent *content) { GElfFormat *result; /* Structure à retourner */ result = g_object_new(G_TYPE_ELF_FORMAT, NULL); - g_binary_format_set_content(G_BIN_FORMAT(result), content, length); + g_binary_format_set_content(G_BIN_FORMAT(result), content); if (!read_elf_header(result, &result->header, &result->is_32b, &result->endian)) { @@ -196,6 +196,7 @@ GBinFormat *g_elf_format_new(const bin_t *content, off_t length) } /* FIXME : à améliorer */ + /* if ((ELF_HDR(result, result->header, e_shnum) * ELF_HDR(result, result->header, e_shentsize)) >= length) { log_variadic_message(LMT_BAD_BINARY, ("Suspicious section table (bigger than the binary !) ; reset ! -- replacing 0x%04hx by 0x%04hx at offset 0x%x"), @@ -203,7 +204,7 @@ GBinFormat *g_elf_format_new(const bin_t *content, off_t length) 0, ELF_HDR_OFFSET_OF(result, e_shnum)); ELF_HDR_SET(result, result->header, e_shnum, 0); } - + */ diff --git a/src/format/elf/elf.h b/src/format/elf/elf.h index 5ea90fd..f18670c 100644 --- a/src/format/elf/elf.h +++ b/src/format/elf/elf.h @@ -49,13 +49,13 @@ typedef struct _GElfFormatClass GElfFormatClass; /* Indique si le format peut être pris en charge ici. */ -bool elf_is_matching(FormatType, const bin_t *, off_t); +bool elf_is_matching(GBinContent *); /* Indique le type défini pour un format d'exécutable ELF. */ GType g_elf_format_get_type(void); /* Prend en charge un nouveau format ELF. */ -GBinFormat *g_elf_format_new(const bin_t *, off_t); +GBinFormat *g_elf_format_new(GBinContent *); diff --git a/src/format/format-int.h b/src/format/format-int.h index 85244b6..22b0c0f 100644 --- a/src/format/format-int.h +++ b/src/format/format-int.h @@ -69,7 +69,7 @@ struct _GBinFormatClass /* Définit le contenu binaire à analyser. */ -void g_binary_format_set_content(GBinFormat *, const bin_t *, off_t); +void g_binary_format_set_content(GBinFormat *, GBinContent *) __attribute__ ((deprecated)); diff --git a/src/format/format.c b/src/format/format.c index b44d8ed..c779947 100644 --- a/src/format/format.c +++ b/src/format/format.c @@ -40,16 +40,6 @@ -#ifndef _ -# define _(str) str -#endif - - - - -/* ------------------------ TRAITEMENT INDIVIDUEL DE FORMATS ------------------------ */ - - /* Initialise la classe des formats binaires génériques. */ static void g_binary_format_class_init(GBinFormatClass *); @@ -58,43 +48,6 @@ static void g_binary_format_init(GBinFormat *); -/* ----------------------- MANIPULATION D'ENSEMBLE DE FORMATS ----------------------- */ - - -/* Format d'exécutables enregistré */ -typedef struct _registered_format -{ - const char *name; /* Désignation du format */ - - FormatType type; /* Type de format */ - - format_match_fc match; /* Procédure de reconnaissance */ - format_load_fc load; /* Fonction de chargement */ - -} registered_format; - - -/* Liste des formats d'exécutables enregistrés */ -static registered_format _formats[FID_COUNT]; - - -#define register_format(id, n, t, m, l) \ - do \ - { \ - _formats[id].name = n; \ - _formats[id].type = t; \ - _formats[id].match = m; \ - _formats[id].load = l; \ - } \ - while (0) - - - -/* ---------------------------------------------------------------------------------- */ -/* TRAITEMENT INDIVIDUEL DE FORMATS */ -/* ---------------------------------------------------------------------------------- */ - - /* Indique le type défini pour un format binaire générique. */ G_DEFINE_TYPE(GBinFormat, g_binary_format, G_TYPE_OBJECT); @@ -149,10 +102,11 @@ static void g_binary_format_init(GBinFormat *format) * * ******************************************************************************/ -void g_binary_format_set_content(GBinFormat *format, const bin_t *content, off_t length) +void g_binary_format_set_content(GBinFormat *format, GBinContent *content) { - format->content = content; - format->length = length; + + + format->content = g_binary_content_get(content, &format->length); } @@ -507,103 +461,3 @@ bool g_binary_format_resolve_relative_routine(const GBinFormat *format, const ch return result; } - - - -/* ---------------------------------------------------------------------------------- */ -/* MANIPULATION D'ENSEMBLE DE FORMATS */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : - * -* * -* Description : Procède au chargement des formats binaires reconnus. * -* * -* Retour : true pour indiquer un chargement réussi, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool init_all_formats(void) -{ - register_format(FID_DEX, _("Dalvik Executable"), FMT_EXEC, dex_is_matching, g_dex_format_new); - //register_format(FID_DWARF, _("Dwarf"), FMT_DEBUG, dwarf_is_matching, g_dwarf_format_new); - register_format(FID_ELF, _("ELF"), FMT_EXEC, elf_is_matching, g_elf_format_new); - register_format(FID_JAVA, _("Java"), FMT_EXEC, java_is_matching, g_java_format_new); - register_format(FID_PE, _("PE"), FMT_EXEC, pe_is_matching, g_pe_format_new); - - return true; - -} - - -/****************************************************************************** -* * -* Paramètres : type = type de format recherché. * -* filename = fichier d'origine des données initiales. * -* content = contenu binaire à parcourir. [OUT] * -* length = taille du contenu en question. [OUT] * -* * -* Description : Charge si possible un nouveau format binaire. * -* * -* Retour : Adresse du nouveau gestionnaire de format ou NULL si erreur. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GBinFormat *load_new_format(FormatType type, const char *filename, bin_t **content, off_t *length) -{ - GBinFormat *result; /* Adresse à retourner */ - char *tmp; /* Nom de fichier modifiable */ - GPluginModule **pglist; /* Liste de greffons */ - size_t pgcount; /* Taille de cette liste */ - size_t i; /* Boucle de parcours */ - - result = NULL; - - tmp = strdup(filename); - - pgcount = 0; - pglist = NULL;//get_all_plugins_for_action(PGA_FORMAT_MATCHER, &pgcount); - - if (pgcount > 0) - { - lnf_rescan: - - for (i = 0; i < pgcount; i++) - switch (0/*g_plugin_module_is_matching(pglist[i], &tmp, content, length)*/) - { - case MFA_MATCHED: - /* FIXME */ - break; - - case MFA_RELOAD: - //goto lnf_rescan; - break; - - default: - break; - - } - - free(pglist); - - } - - if (tmp == NULL) - free(tmp); - - for (i = 0; i < FID_COUNT && result == NULL; i++) - if (_formats[i].type == type && _formats[i].match(type, *content, *length)) - { - log_variadic_message(LMT_INFO, _("%s is matching..."), _formats[i].name); - result = _formats[i].load(*content, *length); - } - - return result; - -} diff --git a/src/format/format.h b/src/format/format.h index 0ac658b..b01a9d5 100644 --- a/src/format/format.h +++ b/src/format/format.h @@ -33,12 +33,10 @@ #include "symbol.h" #include "../analysis/routine.h" #include "../arch/context.h" +#include "../glibext/gbincontent.h" -/* ------------------------ TRAITEMENT INDIVIDUEL DE FORMATS ------------------------ */ - - #define G_TYPE_BIN_FORMAT g_binary_format_get_type() #define G_BIN_FORMAT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_binary_format_get_type(), GBinFormat)) #define G_IS_BIN_FORMAT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_binary_format_get_type())) @@ -91,44 +89,4 @@ bool g_binary_format_resolve_relative_routine(const GBinFormat *, const char **, -/* ----------------------- MANIPULATION D'ENSEMBLE DE FORMATS ----------------------- */ - - -/* Identifiants pour les différents formats */ -typedef enum _FormatIdentifier -{ - FID_DEX, /* Format DEX */ - //FID_DWARF, /* Format Dwarf */ - FID_ELF, /* Format ELF */ - FID_JAVA, /* Format Java */ - FID_PE, /* Format PE */ - - FID_COUNT - -} FormatIdentifier; - -/* Spécialité des formats */ -typedef enum _FormatType -{ - FMT_EXEC = (1 << 0), /* Format d'exécutable */ - FMT_DEBUG = (1 << 1) /* Format de débogage */ - -} FormatType; - - -/* Indication à propos du support d'un format */ -typedef bool (* format_match_fc) (FormatType, const bin_t *, off_t); - -/* Méthode de chargement d'un format */ -typedef GBinFormat * (* format_load_fc) (const bin_t *, off_t); - - -/* Procède au chargement des formats binaires reconnus. */ -bool init_all_formats(void); - -/* Charge si possible un nouveau format binaire. */ -GBinFormat *load_new_format(FormatType, const char *filename, bin_t **, off_t *); - - - #endif /* _FORMAT_FORMAT_H */ diff --git a/src/format/java/java.c b/src/format/java/java.c index e477b82..4929b52 100755 --- a/src/format/java/java.c +++ b/src/format/java/java.c @@ -58,9 +58,7 @@ static bool g_java_format_translate_offset_into_address(const GJavaFormat *, off /****************************************************************************** * * -* Paramètres : type = type de format recherché. * -* content = contenu binaire à parcourir. * -* length = taille du contenu en question. * +* Paramètres : content = contenu binaire à parcourir. * * * * Description : Indique si le format peut être pris en charge ici. * * * @@ -70,14 +68,17 @@ static bool g_java_format_translate_offset_into_address(const GJavaFormat *, off * * ******************************************************************************/ -bool java_is_matching(FormatType type, const uint8_t *content, off_t length) +bool java_is_matching(GBinContent *content) { bool result; /* Bilan à faire connaître */ + vmpa2t addr; /* Tête de lecture initiale */ + char magic[4]; /* Idenfiant standard */ - result = false; + init_vmpa(&addr, 0, VMPA_NO_VIRTUAL); - if (length >= 4) - result = (strncmp((const char *)content, "\xca\xfe\xba\xbe", 4) == 0); + result = g_binary_content_get_raw(content, &addr, 4, (bin_t *)magic); + + result &= (memcmp(magic, "\xca\xfe\xba\xbe", 4) == 0); return result; @@ -152,7 +153,7 @@ GBinFormat *g_java_format_new(const bin_t *content, off_t length) result = g_object_new(G_TYPE_JAVA_FORMAT, NULL); - g_binary_format_set_content(G_BIN_FORMAT(result), content, length); + //g_binary_format_set_content(G_BIN_FORMAT(result), content, length); offset = 0; diff --git a/src/format/java/java.h b/src/format/java/java.h index e19b03a..2ce8dba 100755 --- a/src/format/java/java.h +++ b/src/format/java/java.h @@ -49,7 +49,7 @@ typedef struct _GJavaFormatClass GJavaFormatClass; /* Indique si le format peut être pris en charge ici. */ -bool java_is_matching(FormatType, const bin_t *, off_t); +bool java_is_matching(GBinContent *); /* Indique le type défini pour un format d'exécutable Java. */ GType g_java_format_get_type(void); diff --git a/src/format/pe/pe.c b/src/format/pe/pe.c index 88756dd..39560ce 100644 --- a/src/format/pe/pe.c +++ b/src/format/pe/pe.c @@ -55,9 +55,7 @@ static bool g_pe_format_translate_offset_into_address(const GPeFormat *, off_t, /****************************************************************************** * * -* Paramètres : type = type de format recherché. * -* content = contenu binaire à parcourir. * -* length = taille du contenu en question. * +* Paramètres : content = contenu binaire à parcourir. * * * * Description : Indique si le format peut être pris en charge ici. * * * @@ -67,13 +65,13 @@ static bool g_pe_format_translate_offset_into_address(const GPeFormat *, off_t, * * ******************************************************************************/ -bool pe_is_matching(FormatType type, const uint8_t *content, off_t length) +bool pe_is_matching(GBinContent *content) { bool result; /* Bilan à faire connaître */ image_dos_header dos_header; /* En-tête DOS */ result = false; - +#if 0 if (length >= 2) { result = (strncmp((const char *)content, "\x4d\x5a" /* MZ */, 2) == 0); @@ -90,7 +88,7 @@ bool pe_is_matching(FormatType type, const uint8_t *content, off_t length) "\x50\x45\x00\x00" /* PE00 */, 4) == 0); } - +#endif return result; } @@ -168,7 +166,7 @@ GBinFormat *g_pe_format_new(const bin_t *content, off_t length) result = g_object_new(G_TYPE_PE_FORMAT, NULL); - g_binary_format_set_content(G_BIN_FORMAT(result), content, length); + //g_binary_format_set_content(G_BIN_FORMAT(result), content, length); offset = 0; diff --git a/src/format/pe/pe.h b/src/format/pe/pe.h index 0315ea2..4e1141b 100644 --- a/src/format/pe/pe.h +++ b/src/format/pe/pe.h @@ -49,7 +49,7 @@ typedef struct _GPeFormatClass GPeFormatClass; /* Indique si le format peut être pris en charge ici. */ -bool pe_is_matching(FormatType, const bin_t *, off_t); +bool pe_is_matching(GBinContent *); /* Indique le type défini pour un format d'exécutable PE. */ GType g_pe_format_get_type(void); diff --git a/src/glibext/Makefile.am b/src/glibext/Makefile.am index 192587d..0d4b57c 100644 --- a/src/glibext/Makefile.am +++ b/src/glibext/Makefile.am @@ -8,6 +8,7 @@ libglibext_la_SOURCES = \ configuration.h configuration.c \ delayed-int.h \ delayed.h delayed.c \ + gbincontent.h gbincontent.c \ gbinportion.h gbinportion.c \ gbufferline.h gbufferline.c \ gbuffersegment.h gbuffersegment.c \ diff --git a/src/glibext/gbincontent.c b/src/glibext/gbincontent.c new file mode 100644 index 0000000..c72ac15 --- /dev/null +++ b/src/glibext/gbincontent.c @@ -0,0 +1,288 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * gbincontent.c - prototypes pour le chargement de données binaires en mémoire + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "gbincontent.h" + + +#include <fcntl.h> +#include <malloc.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <sys/mman.h> +#include <sys/stat.h> + + + +/* Aire de contenu binaire */ +typedef struct _binary_part +{ + bin_t *data; /* Contenu binaire représenté */ + mrange_t range; /* Couverture du binaire */ + +} binary_part; + + +/* Content de données binaires quelconques (instance) */ +struct _GBinContent +{ + GObject parent; /* A laisser en premier */ + + binary_part *parts; /* Parties prises en compte */ + size_t count; /* Nombre de ces parties */ + +}; + +/* Content de données binaires quelconques (classe) */ +struct _GBinContentClass +{ + GObjectClass parent; /* A laisser en premier */ + +}; + + +/* Initialise la classe des contenus de données binaires. */ +static void g_binary_content_class_init(GBinContentClass *); + +/* Initialise une instance de contenu de données binaires. */ +static void g_binary_content_init(GBinContent *); + +/* Supprime toutes les références externes. */ +static void g_binary_content_dispose(GBinContent *); + +/* Procède à la libération totale de la mémoire. */ +static void g_binary_content_finalize(GBinContent *); + + + +/* Indique le type défini par la GLib pour les contenus de données. */ +G_DEFINE_TYPE(GBinContent, g_binary_content, G_TYPE_OBJECT); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des contenus de données binaires. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_binary_content_class_init(GBinContentClass *klass) +{ + GObjectClass *object; /* Autre version de la classe */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_binary_content_dispose; + object->finalize = (GObjectFinalizeFunc)g_binary_content_finalize; + + +} + + +/****************************************************************************** +* * +* Paramètres : content = instance à initialiser. * +* * +* Description : Initialise une instance de contenu de données binaires. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_binary_content_init(GBinContent *content) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : content = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_binary_content_dispose(GBinContent *content) +{ + G_OBJECT_CLASS(g_binary_content_parent_class)->dispose(G_OBJECT(content)); + +} + + +/****************************************************************************** +* * +* Paramètres : content = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_binary_content_finalize(GBinContent *content) +{ + size_t i; /* Boucle de parcours */ + + for (i = 0; i < content->count; i++) + free(content->parts[i].data); + + if (content->parts != NULL) + free(content->parts); + + G_OBJECT_CLASS(g_binary_content_parent_class)->finalize(G_OBJECT(content)); + +} + + +/****************************************************************************** +* * +* Paramètres : filename = chemin d'accès au fichier à charger. * +* * +* Description : Charge en mémoire le contenu d'un fichier donné. * +* * +* Retour : Représentation de contenu à manipuler ou NULL en cas d'échec.* +* * +* Remarques : - * +* * +******************************************************************************/ + +GBinContent *g_binary_content_new_from_file(const char *filename) +{ + GBinContent *result; /* Structure à retourner */ + int fd; /* Descripteur du fichier */ + struct stat info; /* Informations sur le fichier */ + int ret; /* Bilan d'un appel */ + void *content; /* Contenu brut du fichier */ + vmpa2t base; /* Localisation des données */ + + /* Récupération des données */ + + fd = open(filename, O_RDONLY); + if (fd == -1) + { + perror("open"); + goto gbcnff_error; + } + + ret = fstat(fd, &info); + if (ret == -1) + { + close(fd); + perror("fstat"); + goto gbcnff_error; + } + + content = mmap(NULL, info.st_size, PROT_READ, MAP_PRIVATE, fd, 0); + if (content == MAP_FAILED) + { + close(fd); + perror("mmap"); + goto gbcnff_error; + } + + /* Constitution du contenu officiel */ + + result = g_object_new(G_TYPE_BIN_CONTENT, NULL); + + result->parts = (binary_part *)calloc(1, sizeof(binary_part)); + result->count = 1; + + result->parts[0].data = (bin_t *)malloc(info.st_size); + memcpy(result->parts[0].data, content, info.st_size); + + munmap(content, info.st_size); + close(fd); + + init_vmpa(&base, 0, VMPA_NO_VIRTUAL); + init_mrange(&result->parts[0].range, &base, info.st_size); + + return result; + + gbcnff_error: + + return NULL; + +} + + + + + + + + +/****************************************************************************** +* * +* Paramètres : content = contenu binaire à venir lire. * +* addr = position de la tête de lecture. * +* length = quantité d'octets à lire. * +* out = réceptacle disponible pour ces données. [OUT] * +* * +* Description : Fournit une portion des données représentées. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_binary_content_get_raw(const GBinContent *content, const vmpa2t *addr, phys_t length, bin_t *out) +{ + /* FIXME */ + + memcpy(out, &content->parts[0].data[get_phy_addr(addr)], length); + + return true; + +} + + + + + + + + +const bin_t *g_binary_content_get(GBinContent *content, off_t *length) +{ + *length = content->parts[0].range.length; + + return content->parts[0].data; + +} + + diff --git a/src/glibext/gbincontent.h b/src/glibext/gbincontent.h new file mode 100644 index 0000000..1bfcfa5 --- /dev/null +++ b/src/glibext/gbincontent.h @@ -0,0 +1,73 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * gbincontent.h - prototypes pour le chargement de données binaires en mémoire + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _GLIBEXT_GBINCONTENT_H +#define _GLIBEXT_GBINCONTENT_H + + +#include <glib-object.h> + + +#include "../arch/archbase.h" +#include "../arch/vmpa.h" +#include "../common/endianness.h" + + + +#define G_TYPE_BIN_CONTENT (g_binary_content_get_type()) +#define G_BIN_CONTENT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_BIN_CONTENT, GBinContent)) +#define G_IS_BIN_CONTENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_BIN_CONTENT)) +#define G_BIN_CONTENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_BIN_CONTENT, GBinContentClass)) +#define G_IS_BIN_CONTENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_BIN_CONTENT)) +#define G_BIN_CONTENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_BIN_CONTENT, GBinContentClass)) + + +/* Content de données binaires quelconques (instance) */ +typedef struct _GBinContent GBinContent; + +/* Content de données binaires quelconques (classe) */ +typedef struct _GBinContentClass GBinContentClass; + + + +/* Indique le type défini par la GLib pour les contenus de données. */ +GType g_binary_content_get_type(void); + +/* Charge en mémoire le contenu d'un fichier donné. */ +GBinContent *g_binary_content_new_from_file(const char *); + + + +/* Fournit une portion des données représentées. */ +bool g_binary_content_get_raw(const GBinContent *, const vmpa2t *, phys_t, bin_t *); + + + + +const bin_t *g_binary_content_get(GBinContent *content, off_t *length); + + + + + +#endif /* _GLIBEXT_GBINCONTENT_H */ @@ -32,10 +32,8 @@ #include "editor.h" #include "project.h" #include "analysis/db/server.h" -#include "arch/processor.h" #include "core/core.h" #include "core/params.h" -#include "format/format.h" #include "glibext/delayed.h" #include "glibext/gbinportion.h" #include "gtkext/support.h" @@ -132,9 +130,6 @@ int main(int argc, char **argv) add_pixmap_directory(PACKAGE_DATA_DIR); add_pixmap_directory(PACKAGE_SOURCE_DIR G_DIR_SEPARATOR_S "pixmaps"); - /* Initialisation du programme */ - init_all_formats(); - /* Création de l'interface */ //test_itanium(); diff --git a/src/plugins/pglist.h b/src/plugins/pglist.h index fec31c2..d0176aa 100644 --- a/src/plugins/pglist.h +++ b/src/plugins/pglist.h @@ -49,8 +49,7 @@ const GPluginModule **get_all_plugins_for_action(PluginAction, size_t *); * Définitions des opérations appliquables à une catégories de greffons. */ -#define process_all__plugins_for(a, f, ...) \ - do \ +#define process_all_plugins_for(a, f, ...) \ { \ size_t __count; \ const GPluginModule **__list; \ @@ -61,10 +60,16 @@ const GPluginModule **get_all_plugins_for_action(PluginAction, size_t *); } \ while (0) + +/* DPS_FORMAT / PGA_FORMAT_MATCHER */ + +#define find_matching_format() + + /* DPS_DISASSEMBLY */ #define process_disassembly_event(a, b) \ - process_all__plugins_for(a, g_plugin_module_process_disassembly_event, b) + process_all_plugins_for(a, g_plugin_module_process_disassembly_event, b) diff --git a/src/plugins/plugin-int.h b/src/plugins/plugin-int.h index 5f7eac2..7a3fb3e 100644 --- a/src/plugins/plugin-int.h +++ b/src/plugins/plugin-int.h @@ -34,6 +34,10 @@ + +/* Indique si le format peut être pris en charge ici. */ +typedef bool (* pg_format_is_matching) (const GPluginModule *, GBinContent **); + /* Exécute une action pendant un désassemblage de binaire. */ typedef void (* pg_process_disassembly) (const GPluginModule *, PluginAction, GLoadedBinary *); @@ -55,7 +59,7 @@ typedef void (* exit_plugin_fc) (GPluginModule *); typedef PluginAction (* get_plugin_action_fc) (const GPluginModule *); /* Identifie un format à associer à un contenu binaire. */ -typedef MatchingFormatAction (* is_matching_fc) (const GPluginModule *, char **, bin_t **, off_t *); +//typedef MatchingFormatAction (* is_matching_fc) (const GPluginModule *, char **, bin_t **, off_t *); /* Exécute une action définie sur un binaire chargé. */ typedef bool (* execute_action_on_binary_fc) (const GPluginModule *, GLoadedBinary *, PluginAction); @@ -84,12 +88,14 @@ struct _GPluginModule exit_plugin_fc exit; /* Procédure d'extinction */ get_plugin_action_fc get_action; /* Opération(s) menée(s) */ - is_matching_fc is_matching; /* Recherche de correspondance */ + //is_matching_fc is_matching; /* Recherche de correspondance */ execute_action_on_binary_fc exec_on_bin;/* Action sur un binaire */ //execute_on_debugger_fc handle_debugger; /* Action liée à un débogueur */ + pg_format_is_matching is_matching; /* Recherche de correspondance */ + pg_process_disassembly proc_disass; /* Catégorie 'désassemblage' */ }; |