diff options
Diffstat (limited to 'src/analysis')
-rwxr-xr-x | src/analysis/Makefile.am | 5 | ||||
-rw-r--r-- | src/analysis/binaries/file.c | 4 | ||||
-rw-r--r-- | src/analysis/content-int.h | 86 | ||||
-rw-r--r-- | src/analysis/content.c | 282 | ||||
-rw-r--r-- | src/analysis/content.h | 91 | ||||
-rwxr-xr-x | src/analysis/contents/Makefile.am | 16 | ||||
-rw-r--r-- | src/analysis/contents/file.c | 603 | ||||
-rw-r--r-- | src/analysis/contents/file.h | 58 |
8 files changed, 1142 insertions, 3 deletions
diff --git a/src/analysis/Makefile.am b/src/analysis/Makefile.am index 26f9df6..f3f6e92 100755 --- a/src/analysis/Makefile.am +++ b/src/analysis/Makefile.am @@ -5,6 +5,8 @@ libanalysis_la_SOURCES = \ binary.h binary.c \ block-int.h \ block.h block.c \ + content-int.h \ + content.h content.c \ project.h project.c \ roptions.h roptions.c \ routine.h routine.c \ @@ -15,6 +17,7 @@ libanalysis_la_SOURCES = \ libanalysis_la_LIBADD = \ binaries/libanalysisbinaries.la \ blocks/libanalysisblocks.la \ + contents/libanalysiscontents.la \ db/libanalysisdb.la \ decomp/libanalysisdecomp.la \ disass/libanalysisdisass.la \ @@ -27,4 +30,4 @@ AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) -SUBDIRS = binaries blocks db decomp disass types +SUBDIRS = binaries blocks contents db decomp disass types diff --git a/src/analysis/binaries/file.c b/src/analysis/binaries/file.c index 75f2c18..32cd41f 100644 --- a/src/analysis/binaries/file.c +++ b/src/analysis/binaries/file.c @@ -28,10 +28,10 @@ #include "../binary-int.h" +#include "../../analysis/contents/file.h" #include "../../common/extstr.h" #include "../../core/formats.h" #include "../../core/processors.h" -#include "../../glibext/gbincontent.h" #include "../../gui/panels/log.h" @@ -170,7 +170,7 @@ GLoadedBinary *g_file_binary_new_from_file(const char *filename) result->filename = strdup(filename); - content = g_binary_content_new_from_file(filename); + content = g_file_content_new(filename); if (content == NULL) goto lbf_error; target = find_matching_format(content, NULL); diff --git a/src/analysis/content-int.h b/src/analysis/content-int.h new file mode 100644 index 0000000..7734916 --- /dev/null +++ b/src/analysis/content-int.h @@ -0,0 +1,86 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * content-int.h - définitions internes propres aux contenus binaires + * + * 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 _ANALYSIS_CONTENT_INT_H +#define _ANALYSIS_CONTENT_INT_H + + +#include "content.h" + + + +/* Fournit une empreinte unique (SHA256) pour les données. */ +typedef const gchar * (* get_checksum_fc) (GBinContent *); + +/* Détermine le nombre d'octets lisibles. */ +typedef phys_t (* compute_size_fc) (const GBinContent *); + +/* Donne accès à une portion des données représentées. */ +typedef const bin_t * (* get_raw_access_fc) (const GBinContent *, vmpa2t *, phys_t); + +/* Fournit une portion des données représentées. */ +typedef bool (* read_raw_fc) (const GBinContent *, vmpa2t *, phys_t, bin_t *); + +/* Lit un nombre non signé sur quatre bits. */ +typedef bool (* read_u4_fc) (const GBinContent *, vmpa2t *, bool *, uint8_t *); + +/* Lit un nombre non signé sur un octet. */ +typedef bool (* read_u8_fc) (const GBinContent *, vmpa2t *, uint8_t *); + +/* Lit un nombre non signé sur deux octets. */ +typedef bool (* read_u16_fc) (const GBinContent *, vmpa2t *, SourceEndian, uint16_t *); + +/* Lit un nombre non signé sur quatre octets. */ +typedef bool (* read_u32_fc) (const GBinContent *, vmpa2t *, SourceEndian, uint32_t *); + +/* Lit un nombre non signé sur huit octets. */ +typedef bool (* read_u64_fc) (const GBinContent *, vmpa2t *, SourceEndian, uint64_t *); + + +/* Accès à un contenu binaire quelconque (interface) */ +struct _GBinContentIface +{ + GTypeInterface base_iface; /* A laisser en premier */ + + get_checksum_fc get_checksum; /* Calcul de l'empreinte */ + + compute_size_fc compute_size; /* Calcul de la taille totale */ + + get_raw_access_fc get_raw_access; /* Accès brut à une position */ + + read_raw_fc read_raw; /* Lecture brute */ + read_u4_fc read_u4; /* Lecture de 4 bits */ + read_u8_fc read_u8; /* Lecture de 8 bits */ + read_u16_fc read_u16; /* Lecture de 16 bits */ + read_u32_fc read_u32; /* Lecture de 32 bits */ + read_u64_fc read_u64; /* Lecture de 64 bits */ + +}; + + +/* Redéfinition */ +typedef GBinContentIface GBinContentInterface; + + + +#endif /* _ANALYSIS_CONTENT_INT_H */ diff --git a/src/analysis/content.c b/src/analysis/content.c new file mode 100644 index 0000000..5a4c899 --- /dev/null +++ b/src/analysis/content.c @@ -0,0 +1,282 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * content.c - lecture de données binaires quelconques + * + * 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 "content.h" + + +#include "content-int.h" + + + +/* Procède à l'initialisation de l'interface de rassemblement. */ +static void g_binary_content_default_init(GBinContentInterface *); + + + +/* Détermine le type d'une interface pour la lecture de binaire. */ +G_DEFINE_INTERFACE(GBinContent, g_binary_content, G_TYPE_OBJECT) + + +/****************************************************************************** +* * +* Paramètres : iface = interface GTK à initialiser. * +* * +* Description : Procède à l'initialisation de l'interface de rassemblement. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_binary_content_default_init(GBinContentInterface *iface) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : content = contenu binaire à venir lire. * +* * +* Description : Fournit une empreinte unique (SHA256) pour les données. * +* * +* Retour : Chaîne représentant l'empreinte du contenu binaire. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const gchar *g_binary_content_get_cheksum(GBinContent *content) +{ + GBinContentIface *iface; /* Interface utilisée */ + + iface = G_BIN_CONTENT_GET_IFACE(content); + + return iface->get_checksum(content); + +} + + +/****************************************************************************** +* * +* Paramètres : content = contenu binaire à venir lire. * +* * +* Description : Détermine le nombre d'octets lisibles. * +* * +* Retour : Quantité représentée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +phys_t g_binary_content_compute_size(const GBinContent *content) +{ + GBinContentIface *iface; /* Interface utilisée */ + + iface = G_BIN_CONTENT_GET_IFACE(content); + + return iface->compute_size(content); + +} + + +/****************************************************************************** +* * +* Paramètres : content = contenu binaire à venir lire. * +* addr = position de la tête de lecture. * +* length = quantité d'octets à lire. * +* * +* Description : Donne accès à une portion des données représentées. * +* * +* Retour : Pointeur vers les données à lire ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const bin_t *g_binary_content_get_raw_access(const GBinContent *content, vmpa2t *addr, phys_t length) +{ + GBinContentIface *iface; /* Interface utilisée */ + + iface = G_BIN_CONTENT_GET_IFACE(content); + + return iface->get_raw_access(content, addr, length); + +} + + +/****************************************************************************** +* * +* 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_read_raw(const GBinContent *content, vmpa2t *addr, phys_t length, bin_t *out) +{ + GBinContentIface *iface; /* Interface utilisée */ + + iface = G_BIN_CONTENT_GET_IFACE(content); + + return iface->read_raw(content, addr, length, out); + +} + + +/****************************************************************************** +* * +* Paramètres : content = contenu binaire à venir lire. * +* addr = position de la tête de lecture. * +* low = position éventuelle des 4 bits visés. [OUT] * +* val = lieu d'enregistrement de la lecture. [OUT] * +* * +* Description : Lit un nombre non signé sur quatre bits. * +* * +* Retour : Bilan de l'opération : true en cas de succès, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_binary_content_read_u4(const GBinContent *content, vmpa2t *addr, bool *low, uint8_t *val) +{ + GBinContentIface *iface; /* Interface utilisée */ + + iface = G_BIN_CONTENT_GET_IFACE(content); + + return iface->read_u4(content, addr, low, val); + +} + + + +/****************************************************************************** +* * +* Paramètres : content = contenu binaire à venir lire. * +* addr = position de la tête de lecture. * +* val = lieu d'enregistrement de la lecture. [OUT] * +* * +* Description : Lit un nombre non signé sur un octet. * +* * +* Retour : Bilan de l'opération : true en cas de succès, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_binary_content_read_u8(const GBinContent *content, vmpa2t *addr, uint8_t *val) +{ + GBinContentIface *iface; /* Interface utilisée */ + + iface = G_BIN_CONTENT_GET_IFACE(content); + + return iface->read_u8(content, addr, val); + +} + + +/****************************************************************************** +* * +* Paramètres : content = contenu binaire à venir lire. * +* addr = position de la tête de lecture. * +* endian = ordre des bits dans la source. * +* val = lieu d'enregistrement de la lecture. [OUT] * +* * +* Description : Lit un nombre non signé sur deux octets. * +* * +* Retour : Bilan de l'opération : true en cas de succès, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_binary_content_read_u16(const GBinContent *content, vmpa2t *addr, SourceEndian endian, uint16_t *val) +{ + GBinContentIface *iface; /* Interface utilisée */ + + iface = G_BIN_CONTENT_GET_IFACE(content); + + return iface->read_u16(content, addr, endian, val); + +} + + +/****************************************************************************** +* * +* Paramètres : content = contenu binaire à venir lire. * +* addr = position de la tête de lecture. * +* endian = ordre des bits dans la source. * +* val = lieu d'enregistrement de la lecture. [OUT] * +* * +* Description : Lit un nombre non signé sur quatre octets. * +* * +* Retour : Bilan de l'opération : true en cas de succès, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_binary_content_read_u32(const GBinContent *content, vmpa2t *addr, SourceEndian endian, uint32_t *val) +{ + GBinContentIface *iface; /* Interface utilisée */ + + iface = G_BIN_CONTENT_GET_IFACE(content); + + return iface->read_u32(content, addr, endian, val); + +} + + +/****************************************************************************** +* * +* Paramètres : content = contenu binaire à venir lire. * +* addr = position de la tête de lecture. * +* endian = ordre des bits dans la source. * +* val = lieu d'enregistrement de la lecture. [OUT] * +* * +* Description : Lit un nombre non signé sur huit octets. * +* * +* Retour : Bilan de l'opération : true en cas de succès, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_binary_content_read_u64(const GBinContent *content, vmpa2t *addr, SourceEndian endian, uint64_t *val) +{ + GBinContentIface *iface; /* Interface utilisée */ + + iface = G_BIN_CONTENT_GET_IFACE(content); + + return iface->read_u64(content, addr, endian, val); + +} diff --git a/src/analysis/content.h b/src/analysis/content.h new file mode 100644 index 0000000..d422dc6 --- /dev/null +++ b/src/analysis/content.h @@ -0,0 +1,91 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * content.h - prototypes pour la lecture de données binaires quelconques + * + * 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 _ANALYSIS_CONTENT_H +#define _ANALYSIS_CONTENT_H + + +#include <stdbool.h> +#include <glib-object.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_BIN_CONTENT_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST((vtable), G_TYPE_BIN_CONTENT, GBinContentIface)) +#define GTK_IS_BIN_CONTENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_BIN_CONTENT)) +#define GTK_IS_BIN_CONTENT_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE((vtable), G_TYPE_BIN_CONTENT)) +#define G_BIN_CONTENT_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst), G_TYPE_BIN_CONTENT, GBinContentIface)) + + +/* Accès à un contenu binaire quelconque (coquille vide) */ +typedef struct _GBinContent GBinContent; + +/* Accès à un contenu binaire quelconque (interface) */ +typedef struct _GBinContentIface GBinContentIface; + + +/* Détermine le type d'une interface pour la lecture de binaire. */ +GType g_binary_content_get_type(void) G_GNUC_CONST; + +/* Fournit une empreinte unique (SHA256) pour les données. */ +const gchar *g_binary_content_get_cheksum(GBinContent *); + +/* Détermine le nombre d'octets lisibles. */ +phys_t g_binary_content_compute_size(const GBinContent *); + +/* Donne accès à une portion des données représentées. */ +const bin_t *g_binary_content_get_raw_access(const GBinContent *, vmpa2t *, phys_t); + +/* Fournit une portion des données représentées. */ +bool g_binary_content_read_raw(const GBinContent *, vmpa2t *, phys_t, bin_t *); + +/* Lit un nombre non signé sur quatre bits. */ +bool g_binary_content_read_u4(const GBinContent *, vmpa2t *, bool *, uint8_t *); + +/* Lit un nombre non signé sur un octet. */ +bool g_binary_content_read_u8(const GBinContent *, vmpa2t *, uint8_t *); + +/* Lit un nombre non signé sur deux octets. */ +bool g_binary_content_read_u16(const GBinContent *, vmpa2t *, SourceEndian, uint16_t *); + +/* Lit un nombre non signé sur quatre octets. */ +bool g_binary_content_read_u32(const GBinContent *, vmpa2t *, SourceEndian, uint32_t *); + +/* Lit un nombre non signé sur huit octets. */ +bool g_binary_content_read_u64(const GBinContent *, vmpa2t *, SourceEndian, uint64_t *); + + +#define g_binary_content_read_s4(c, a, l, v) g_binary_content_read_u4(c, a, l, (uint8_t *)v) +#define g_binary_content_read_s8(c, a, v) g_binary_content_read_u8(c, a, (uint8_t *)v) +#define g_binary_content_read_s16(c, a, e, v) g_binary_content_read_u16(c, a, e, (uint16_t *)v) +#define g_binary_content_read_s32(c, a, e, v) g_binary_content_read_u32(c, a, e, (uint32_t *)v) +#define g_binary_content_read_s64(c, a, e, v) g_binary_content_read_u64(c, a, e, (uint64_t *)v) + + + +#endif /* _ANALYSIS_CONTENT_H */ diff --git a/src/analysis/contents/Makefile.am b/src/analysis/contents/Makefile.am new file mode 100755 index 0000000..e2eec74 --- /dev/null +++ b/src/analysis/contents/Makefile.am @@ -0,0 +1,16 @@ + +noinst_LTLIBRARIES = libanalysiscontents.la + +libanalysiscontents_la_SOURCES = \ + file.h file.c + +libanalysiscontents_la_LIBADD = + +libanalysiscontents_la_LDFLAGS = + + +AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) + +AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) + +SUBDIRS = diff --git a/src/analysis/contents/file.c b/src/analysis/contents/file.c new file mode 100644 index 0000000..eb0d488 --- /dev/null +++ b/src/analysis/contents/file.c @@ -0,0 +1,603 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * file.c - chargement de données binaires à partir d'un fichier + * + * 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 "file.h" + + +#include <assert.h> +#include <fcntl.h> +#include <malloc.h> +#include <unistd.h> +#include <sys/mman.h> +#include <sys/stat.h> + + +#include "../content-int.h" + + + +/* Contenu de données binaires issues d'un fichier (instance) */ +struct _GFileContent +{ + GObject parent; /* A laisser en premier */ + + bin_t *data; /* Contenu binaire représenté */ + mrange_t range; /* Couverture du binaire */ + + GChecksum *checksum; /* Calcul de l'empreinte */ + bool cs_computed; /* Calcul effectué ? */ + +}; + +/* Contenu de données binaires issues d'un fichier (classe) */ +struct _GFileContentClass +{ + GObjectClass parent; /* A laisser en premier */ + +}; + + +/* Initialise la classe des contenus de données binaires. */ +static void g_file_content_class_init(GFileContentClass *); + +/* Initialise une instance de contenu de données binaires. */ +static void g_file_content_init(GFileContent *); + +/* Procède à l'initialisation de l'interface de lecture. */ +static void g_file_content_interface_init(GBinContentInterface *); + +/* Supprime toutes les références externes. */ +static void g_file_content_dispose(GFileContent *); + +/* Procède à la libération totale de la mémoire. */ +static void g_file_content_finalize(GFileContent *); + +/* Fournit une empreinte unique (SHA256) pour les données. */ +static const gchar *g_file_content_get_checksum(GFileContent *); + +/* Détermine le nombre d'octets lisibles. */ +static phys_t g_file_content_compute_size(const GFileContent *); + +/* Donne accès à une portion des données représentées. */ +static const bin_t *g_file_content_get_raw_access(const GFileContent *, vmpa2t *, phys_t); + +/* Fournit une portion des données représentées. */ +static bool g_file_content_read_raw(const GFileContent *, vmpa2t *, phys_t, bin_t *); + +/* Lit un nombre non signé sur quatre bits. */ +static bool g_file_content_read_u4(const GFileContent *, vmpa2t *, bool *, uint8_t *); + +/* Lit un nombre non signé sur un octet. */ +static bool g_file_content_read_u8(const GFileContent *, vmpa2t *, uint8_t *); + +/* Lit un nombre non signé sur deux octets. */ +static bool g_file_content_read_u16(const GFileContent *, vmpa2t *, SourceEndian, uint16_t *); + +/* Lit un nombre non signé sur quatre octets. */ +static bool g_file_content_read_u32(const GFileContent *, vmpa2t *, SourceEndian, uint32_t *); + +/* Lit un nombre non signé sur huit octets. */ +static bool g_file_content_read_u64(const GFileContent *, vmpa2t *, SourceEndian, uint64_t *); + + + +/* Indique le type défini par la GLib pour les contenus de données. */ +G_DEFINE_TYPE_WITH_CODE(GFileContent, g_file_content, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE(G_TYPE_BIN_CONTENT, g_file_content_interface_init)) + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des contenus de données binaires. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_file_content_class_init(GFileContentClass *klass) +{ + GObjectClass *object; /* Autre version de la classe */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_file_content_dispose; + object->finalize = (GObjectFinalizeFunc)g_file_content_finalize; + +} + + +/****************************************************************************** +* * +* Paramètres : content = instance à initialiser. * +* * +* Description : Initialise une instance de contenu de données binaires. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_file_content_init(GFileContent *content) +{ + content->checksum = g_checksum_new(G_CHECKSUM_SHA256); + assert(content->checksum != NULL); + + content->cs_computed = false; + +} + + +/****************************************************************************** +* * +* Paramètres : iface = interface GLib à initialiser. * +* * +* Description : Procède à l'initialisation de l'interface de lecture. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_file_content_interface_init(GBinContentInterface *iface) +{ + iface->get_checksum = (get_checksum_fc)g_file_content_get_checksum; + + iface->compute_size = (compute_size_fc)g_file_content_compute_size; + + iface->get_raw_access = (get_raw_access_fc)g_file_content_get_raw_access; + + iface->read_raw = (read_raw_fc)g_file_content_read_raw; + iface->read_u4 = (read_u4_fc)g_file_content_read_u4; + iface->read_u8 = (read_u8_fc)g_file_content_read_u8; + iface->read_u16 = (read_u16_fc)g_file_content_read_u16; + iface->read_u32 = (read_u32_fc)g_file_content_read_u32; + iface->read_u64 = (read_u64_fc)g_file_content_read_u64; + +} + + +/****************************************************************************** +* * +* Paramètres : content = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_file_content_dispose(GFileContent *content) +{ + g_checksum_free(content->checksum); + + G_OBJECT_CLASS(g_file_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_file_content_finalize(GFileContent *content) +{ + if (content->data != NULL) + free(content->data); + + G_OBJECT_CLASS(g_file_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_file_content_new(const char *filename) +{ + GFileContent *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_FILE_CONTENT, NULL); + + result->data = (bin_t *)malloc(info.st_size); + memcpy(result->data, content, info.st_size); + + munmap(content, info.st_size); + close(fd); + + init_vmpa(&base, 0, VMPA_NO_VIRTUAL); + init_mrange(&result->range, &base, info.st_size); + + return G_BIN_CONTENT(result); + + gbcnff_error: + + return NULL; + +} + + +/****************************************************************************** +* * +* Paramètres : content = contenu binaire à venir lire. * +* * +* Description : Fournit une empreinte unique (SHA256) pour les données. * +* * +* Retour : Chaîne représentant l'empreinte du contenu binaire. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static const gchar *g_file_content_get_checksum(GFileContent *content) +{ + if (!content->cs_computed) + { + g_checksum_reset(content->checksum); + + g_checksum_update(content->checksum, content->data, get_mrange_length(&content->range)); + + content->cs_computed = true; + + } + + return g_checksum_get_string(content->checksum); + +} + + +/****************************************************************************** +* * +* Paramètres : content = contenu binaire à venir lire. * +* * +* Description : Détermine le nombre d'octets lisibles. * +* * +* Retour : Quantité représentée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static phys_t g_file_content_compute_size(const GFileContent *content) +{ + phys_t result; /* Quantité trouvée à retourner*/ + + result = get_mrange_length(&content->range); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : content = contenu binaire à venir lire. * +* addr = position de la tête de lecture. * +* length = quantité d'octets à lire. * +* * +* Description : Donne accès à une portion des données représentées. * +* * +* Retour : Pointeur vers les données à lire ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static const bin_t *g_file_content_get_raw_access(const GFileContent *content, vmpa2t *addr, phys_t length) +{ + phys_t offset; /* Emplacement de départ */ + + offset = get_phy_addr(addr); + + if (offset == VMPA_NO_PHYSICAL) + return NULL; + + if ((offset + length) >= get_mrange_length(&content->range)) + return NULL; + + advance_vmpa(addr, length); + + return &content->data[offset]; + +} + + +/****************************************************************************** +* * +* 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 : - * +* * +******************************************************************************/ + +static bool g_file_content_read_raw(const GFileContent *content, vmpa2t *addr, phys_t length, bin_t *out) +{ + bool result; /* Bilan à remonter */ + const bin_t *data; /* Pointeur vers données utiles*/ + + data = g_file_content_get_raw_access(content, addr, length); + + if (data != NULL) + { + result = true; + memcpy(out, data, length); + } + else + result = false; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : content = contenu binaire à venir lire. * +* addr = position de la tête de lecture. * +* low = position éventuelle des 4 bits visés. [OUT] * +* val = lieu d'enregistrement de la lecture. [OUT] * +* * +* Description : Lit un nombre non signé sur quatre bits. * +* * +* Retour : Bilan de l'opération : true en cas de succès, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_file_content_read_u4(const GFileContent *content, vmpa2t *addr, bool *low, uint8_t *val) +{ + bool result; /* Bilan de lecture à renvoyer */ + phys_t pos; /* Tête de lecture courante */ + phys_t length; /* Taille de la surface dispo. */ + + pos = get_phy_addr(addr); + + if (pos == VMPA_NO_PHYSICAL) + return false; + + length = get_mrange_length(&content->range); + + result = read_u4(val, content->data, &pos, length, low); + + if (result) + advance_vmpa(addr, pos - get_phy_addr(addr)); + + return result; + +} + + + +/****************************************************************************** +* * +* Paramètres : content = contenu binaire à venir lire. * +* addr = position de la tête de lecture. * +* val = lieu d'enregistrement de la lecture. [OUT] * +* * +* Description : Lit un nombre non signé sur un octet. * +* * +* Retour : Bilan de l'opération : true en cas de succès, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_file_content_read_u8(const GFileContent *content, vmpa2t *addr, uint8_t *val) +{ + bool result; /* Bilan de lecture à renvoyer */ + phys_t pos; /* Tête de lecture courante */ + phys_t length; /* Taille de la surface dispo. */ + + pos = get_phy_addr(addr); + + if (pos == VMPA_NO_PHYSICAL) + return false; + + length = get_mrange_length(&content->range); + + result = read_u8(val, content->data, &pos, length); + + if (result) + advance_vmpa(addr, pos - get_phy_addr(addr)); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : content = contenu binaire à venir lire. * +* addr = position de la tête de lecture. * +* endian = ordre des bits dans la source. * +* val = lieu d'enregistrement de la lecture. [OUT] * +* * +* Description : Lit un nombre non signé sur deux octets. * +* * +* Retour : Bilan de l'opération : true en cas de succès, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_file_content_read_u16(const GFileContent *content, vmpa2t *addr, SourceEndian endian, uint16_t *val) +{ + bool result; /* Bilan de lecture à renvoyer */ + phys_t pos; /* Tête de lecture courante */ + phys_t length; /* Taille de la surface dispo. */ + + pos = get_phy_addr(addr); + + if (pos == VMPA_NO_PHYSICAL) + return false; + + length = get_mrange_length(&content->range); + + result = read_u16(val, content->data, &pos, length, endian); + + if (result) + advance_vmpa(addr, pos - get_phy_addr(addr)); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : content = contenu binaire à venir lire. * +* addr = position de la tête de lecture. * +* endian = ordre des bits dans la source. * +* val = lieu d'enregistrement de la lecture. [OUT] * +* * +* Description : Lit un nombre non signé sur quatre octets. * +* * +* Retour : Bilan de l'opération : true en cas de succès, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_file_content_read_u32(const GFileContent *content, vmpa2t *addr, SourceEndian endian, uint32_t *val) +{ + bool result; /* Bilan de lecture à renvoyer */ + phys_t pos; /* Tête de lecture courante */ + phys_t length; /* Taille de la surface dispo. */ + + pos = get_phy_addr(addr); + + if (pos == VMPA_NO_PHYSICAL) + return false; + + length = get_mrange_length(&content->range); + + result = read_u32(val, content->data, &pos, length, endian); + + if (result) + advance_vmpa(addr, pos - get_phy_addr(addr)); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : content = contenu binaire à venir lire. * +* addr = position de la tête de lecture. * +* endian = ordre des bits dans la source. * +* val = lieu d'enregistrement de la lecture. [OUT] * +* * +* Description : Lit un nombre non signé sur huit octets. * +* * +* Retour : Bilan de l'opération : true en cas de succès, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_file_content_read_u64(const GFileContent *content, vmpa2t *addr, SourceEndian endian, uint64_t *val) +{ + bool result; /* Bilan de lecture à renvoyer */ + phys_t pos; /* Tête de lecture courante */ + phys_t length; /* Taille de la surface dispo. */ + + pos = get_phy_addr(addr); + + if (pos == VMPA_NO_PHYSICAL) + return false; + + length = get_mrange_length(&content->range); + + result = read_u64(val, content->data, &pos, length, endian); + + if (result) + advance_vmpa(addr, pos - get_phy_addr(addr)); + + return result; + +} diff --git a/src/analysis/contents/file.h b/src/analysis/contents/file.h new file mode 100644 index 0000000..2e3cfef --- /dev/null +++ b/src/analysis/contents/file.h @@ -0,0 +1,58 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * file.h - prototypes pour le chargement de données binaires à partir d'un fichier + * + * 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 _ANALYSIS_CONTENTS_FILE_H +#define _ANALYSIS_CONTENTS_FILE_H + + +#include <glib-object.h> + + +#include "../content.h" + + + +#define G_TYPE_FILE_CONTENT (g_file_content_get_type()) +#define G_FILE_CONTENT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_FILE_CONTENT, GFileContent)) +#define G_IS_FILE_CONTENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_FILE_CONTENT)) +#define G_FILE_CONTENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_FILE_CONTENT, GFileContentClass)) +#define G_IS_FILE_CONTENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_FILE_CONTENT)) +#define G_FILE_CONTENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_FILE_CONTENT, GFileContentClass)) + + +/* Contenu de données binaires issues d'un fichier (instance) */ +typedef struct _GFileContent GFileContent; + +/* Contenu de données binaires issues d'un fichier (classe) */ +typedef struct _GFileContentClass GFileContentClass; + + +/* Indique le type défini par la GLib pour les contenus de données. */ +GType g_file_content_get_type(void); + +/* Charge en mémoire le contenu d'un fichier donné. */ +GBinContent *g_file_content_new(const char *); + + + +#endif /* _ANALYSIS_CONTENTS_FILE_H */ |