diff options
Diffstat (limited to 'src/analysis/content.c')
-rw-r--r-- | src/analysis/content.c | 396 |
1 files changed, 324 insertions, 72 deletions
diff --git a/src/analysis/content.c b/src/analysis/content.c index 626497e..e12237f 100644 --- a/src/analysis/content.c +++ b/src/analysis/content.c @@ -35,20 +35,94 @@ -/* Procède à l'initialisation de l'interface de rassemblement. */ -static void g_binary_content_default_init(GBinContentInterface *); +/* -------------------------- ENSEMBLE DE DONNEES BINAIRES -------------------------- */ +/* Initialise la classe des contenus binaires à parcourir. */ +static void g_binary_content_class_init(GBinContentClass *); -/* Détermine le type d'une interface pour la lecture de binaire. */ -G_DEFINE_INTERFACE(GBinContent, g_binary_content, G_TYPE_OBJECT); +/* Initialise l'instance de contenu binaire à parcourir. */ +static void g_binary_content_init(GBinContent *); + +/* Procède à l'initialisation de l'interface de sérialisation. */ +static void g_binary_content_serializable_interface_init(GSerializableObjectIface *); + +/* 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 *); + + + +/* -------------------- CONSERVATION ET RECHARGEMENT DES DONNEES -------------------- */ + + +/* Charge un contenu depuis une mémoire tampon. */ +static bool g_binary_content_load(GBinContent *, GObjectStorage *, packed_buffer_t *); + +/* Sauvegarde un contenu dans une mémoire tampon. */ +static bool g_binary_content_store(const GBinContent *, GObjectStorage *, packed_buffer_t *); + + + +/* ---------------------------------------------------------------------------------- */ +/* ENSEMBLE DE DONNEES BINAIRES */ +/* ---------------------------------------------------------------------------------- */ + + +/* Détermine le type d'un contenu binaire à parcourir. */ +G_DEFINE_TYPE_WITH_CODE(GBinContent, g_binary_content, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE(G_TYPE_SERIALIZABLE_OBJECT, g_binary_content_serializable_interface_init)); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des contenus binaires à parcourir. * +* * +* 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 l'instance de contenu binaire à parcourir. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_binary_content_init(GBinContent *content) +{ + +} /****************************************************************************** * * * Paramètres : iface = interface GLib à initialiser. * * * -* Description : Procède à l'initialisation de l'interface de rassemblement. * +* Description : Procède à l'initialisation de l'interface de sérialisation. * * * * Retour : - * * * @@ -56,8 +130,48 @@ G_DEFINE_INTERFACE(GBinContent, g_binary_content, G_TYPE_OBJECT); * * ******************************************************************************/ -static void g_binary_content_default_init(GBinContentInterface *iface) +static void g_binary_content_serializable_interface_init(GSerializableObjectIface *iface) { + iface->load = (load_serializable_object_cb)g_binary_content_load; + iface->store = (store_serializable_object_cb)g_binary_content_store; + +} + + +/****************************************************************************** +* * +* 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) +{ + G_OBJECT_CLASS(g_binary_content_parent_class)->finalize(G_OBJECT(content)); } @@ -77,19 +191,11 @@ static void g_binary_content_default_init(GBinContentInterface *iface) void g_binary_content_set_attributes(GBinContent *content, GContentAttributes *attribs) { - GContentAttributes *old; /* Ancien jeu d'attributs */ - GBinContentIface *iface; /* Interface utilisée */ - - iface = G_BIN_CONTENT_GET_IFACE(content); - - old = iface->get_attribs(content); + GBinContentClass *class; /* Classe de l'instance */ - if (old != NULL) - g_object_unref(G_OBJECT(old)); + class = G_BIN_CONTENT_GET_CLASS(content); - iface->set_attribs(content, attribs); - - g_object_ref_sink(G_OBJECT(attribs)); + class->set_attribs(content, attribs); } @@ -109,13 +215,11 @@ void g_binary_content_set_attributes(GBinContent *content, GContentAttributes *a GContentAttributes *g_binary_content_get_attributes(const GBinContent *content) { GContentAttributes *result; /* Instance à retourner */ - GBinContentIface *iface; /* Interface utilisée */ - - iface = G_BIN_CONTENT_GET_IFACE(content); + GBinContentClass *class; /* Classe de l'instance */ - result = iface->get_attribs(content); + class = G_BIN_CONTENT_GET_CLASS(content); - g_object_ref(G_OBJECT(result)); + result = class->get_attribs(content); return result; @@ -137,13 +241,11 @@ GContentAttributes *g_binary_content_get_attributes(const GBinContent *content) GBinContent *g_binary_content_get_root(GBinContent *content) { GBinContent *result; /* Contenu en place à renvoyer */ - GBinContentIface *iface; /* Interface utilisée */ - - iface = G_BIN_CONTENT_GET_IFACE(content); + GBinContentClass *class; /* Classe de l'instance */ - result = iface->get_root(content); + class = G_BIN_CONTENT_GET_CLASS(content); - g_object_ref(G_OBJECT(result)); + result = class->get_root(content); return result; @@ -166,11 +268,11 @@ GBinContent *g_binary_content_get_root(GBinContent *content) char *g_binary_content_describe(const GBinContent *content, bool full) { char *result; /* Description à retourner */ - GBinContentIface *iface; /* Interface utilisée */ + GBinContentClass *class; /* Classe de l'instance */ - iface = G_BIN_CONTENT_GET_IFACE(content); + class = G_BIN_CONTENT_GET_CLASS(content); - result = iface->describe(content, full); + result = class->describe(content, full); return result; @@ -193,7 +295,7 @@ const gchar *g_binary_content_get_checksum(GBinContent *content) { const gchar *result; /* Empreinte à retourner */ GChecksum *checksum; /* Calcul de l'empreinte */ - GBinContentIface *iface; /* Interface utilisée */ + GBinContentClass *class; /* Classe de l'instance */ checksum = g_object_get_data(G_OBJECT(content), "checksum"); @@ -204,9 +306,9 @@ const gchar *g_binary_content_get_checksum(GBinContent *content) g_checksum_reset(checksum); - iface = G_BIN_CONTENT_GET_IFACE(content); + class = G_BIN_CONTENT_GET_CLASS(content); - iface->compute_checksum(content, checksum); + class->compute_checksum(content, checksum); g_object_set_data_full(G_OBJECT(content), "checksum", checksum, (GDestroyNotify)g_checksum_free); @@ -233,11 +335,11 @@ const gchar *g_binary_content_get_checksum(GBinContent *content) phys_t g_binary_content_compute_size(const GBinContent *content) { - GBinContentIface *iface; /* Interface utilisée */ + GBinContentClass *class; /* Classe de l'instance */ - iface = G_BIN_CONTENT_GET_IFACE(content); + class = G_BIN_CONTENT_GET_CLASS(content); - return iface->compute_size(content); + return class->compute_size(content); } @@ -257,11 +359,11 @@ phys_t g_binary_content_compute_size(const GBinContent *content) void g_binary_content_compute_start_pos(const GBinContent *content, vmpa2t *pos) { - GBinContentIface *iface; /* Interface utilisée */ + GBinContentClass *class; /* Classe de l'instance */ - iface = G_BIN_CONTENT_GET_IFACE(content); + class = G_BIN_CONTENT_GET_CLASS(content); - return iface->compute_start_pos(content, pos); + return class->compute_start_pos(content, pos); } @@ -281,11 +383,11 @@ void g_binary_content_compute_start_pos(const GBinContent *content, vmpa2t *pos) void g_binary_content_compute_end_pos(const GBinContent *content, vmpa2t *pos) { - GBinContentIface *iface; /* Interface utilisée */ + GBinContentClass *class; /* Classe de l'instance */ - iface = G_BIN_CONTENT_GET_IFACE(content); + class = G_BIN_CONTENT_GET_CLASS(content); - return iface->compute_end_pos(content, pos); + return class->compute_end_pos(content, pos); } @@ -306,11 +408,11 @@ void g_binary_content_compute_end_pos(const GBinContent *content, vmpa2t *pos) bool g_binary_content_seek(const GBinContent *content, vmpa2t *addr, phys_t length) { - GBinContentIface *iface; /* Interface utilisée */ + GBinContentClass *class; /* Classe de l'instance */ - iface = G_BIN_CONTENT_GET_IFACE(content); + class = G_BIN_CONTENT_GET_CLASS(content); - return iface->seek(content, addr, length); + return class->seek(content, addr, length); } @@ -331,11 +433,11 @@ bool g_binary_content_seek(const GBinContent *content, vmpa2t *addr, phys_t leng const bin_t *g_binary_content_get_raw_access(const GBinContent *content, vmpa2t *addr, phys_t length) { - GBinContentIface *iface; /* Interface utilisée */ + GBinContentClass *class; /* Classe de l'instance */ - iface = G_BIN_CONTENT_GET_IFACE(content); + class = G_BIN_CONTENT_GET_CLASS(content); - return iface->get_raw_access(content, addr, length); + return class->get_raw_access(content, addr, length); } @@ -358,11 +460,99 @@ const bin_t *g_binary_content_get_raw_access(const GBinContent *content, vmpa2t bool g_binary_content_read_raw(const GBinContent *content, vmpa2t *addr, phys_t length, bin_t *out) { bool result; /* Bilan à remonter */ - GBinContentIface *iface; /* Interface utilisée */ + GBinContentClass *class; /* Classe de l'instance */ + + class = G_BIN_CONTENT_GET_CLASS(content); + + result = class->read_raw(content, addr, length, out); - iface = G_BIN_CONTENT_GET_IFACE(content); + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : content = contenu binaire à venir lire. * +* addr = position de la tête de lecture complète. * +* size = quantité de bits à lire. * +* 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_bits(const GBinContent *content, ext_vmpa_t *addr, uint8_t size, SourceEndian endian, uint64_t *val) +{ + bool result; /* Bilan de lecture à renvoyer */ + vmpa2t pos; /* Tête de lecture courante */ + uint8_t data; /* Données à parcourir */ + uint8_t i; /* Boucle de parcours */ + uint8_t remaining; /* Nombre de bits disponibles */ + uint64_t bit; /* Nouveau bit à intégrer */ + + assert(addr->consumed_extra_bits < 8); + assert(size <= 64); + + if (addr->consumed_extra_bits >= 8 || size > 64) + return false; + + copy_vmpa(&pos, &addr->base); + + result = g_binary_content_read_u8(content, &pos, &data); + if (!result) goto exit; + + remaining = 8 - addr->consumed_extra_bits; + + *val = 0; + + for (i = 0; i < size; i++) + { + if (remaining == 0) + { + result = g_binary_content_read_u8(content, &pos, &data); + if (!result) goto exit; + + remaining = 8; + + } + + bit = (data >> (remaining - 1)) & 0x1; + + remaining--; + + switch (endian) + { + case SRE_LITTLE: + *val |= (bit << i); + break; + + case SRE_BIG: + *val |= (bit << (size - i - 1)); + break; + + default: + assert(false); + result = false; + break; + + } + + } + + if (result) + { + advance_vmpa(&addr->base, get_phy_addr(&pos) - get_phy_addr(&addr->base) - 1); + addr->consumed_extra_bits = 8 - remaining; + + } - result = iface->read_raw(content, addr, length, out); + exit: return result; @@ -387,11 +577,11 @@ bool g_binary_content_read_raw(const GBinContent *content, vmpa2t *addr, phys_t bool g_binary_content_read_u4(const GBinContent *content, vmpa2t *addr, bool *low, uint8_t *val) { bool result; /* Bilan à remonter */ - GBinContentIface *iface; /* Interface utilisée */ + GBinContentClass *class; /* Classe de l'instance */ - iface = G_BIN_CONTENT_GET_IFACE(content); + class = G_BIN_CONTENT_GET_CLASS(content); - result = iface->read_u4(content, addr, low, val); + result = class->read_u4(content, addr, low, val); return result; @@ -416,11 +606,11 @@ bool g_binary_content_read_u4(const GBinContent *content, vmpa2t *addr, bool *lo bool g_binary_content_read_u8(const GBinContent *content, vmpa2t *addr, uint8_t *val) { bool result; /* Bilan à remonter */ - GBinContentIface *iface; /* Interface utilisée */ + GBinContentClass *class; /* Classe de l'instance */ - iface = G_BIN_CONTENT_GET_IFACE(content); + class = G_BIN_CONTENT_GET_CLASS(content); - result = iface->read_u8(content, addr, val); + result = class->read_u8(content, addr, val); return result; @@ -445,11 +635,11 @@ bool g_binary_content_read_u8(const GBinContent *content, vmpa2t *addr, uint8_t bool g_binary_content_read_u16(const GBinContent *content, vmpa2t *addr, SourceEndian endian, uint16_t *val) { bool result; /* Bilan à remonter */ - GBinContentIface *iface; /* Interface utilisée */ + GBinContentClass *class; /* Classe de l'instance */ - iface = G_BIN_CONTENT_GET_IFACE(content); + class = G_BIN_CONTENT_GET_CLASS(content); - result = iface->read_u16(content, addr, endian, val); + result = class->read_u16(content, addr, endian, val); return result; @@ -474,11 +664,11 @@ bool g_binary_content_read_u16(const GBinContent *content, vmpa2t *addr, SourceE bool g_binary_content_read_u32(const GBinContent *content, vmpa2t *addr, SourceEndian endian, uint32_t *val) { bool result; /* Bilan à remonter */ - GBinContentIface *iface; /* Interface utilisée */ + GBinContentClass *class; /* Classe de l'instance */ - iface = G_BIN_CONTENT_GET_IFACE(content); + class = G_BIN_CONTENT_GET_CLASS(content); - result = iface->read_u32(content, addr, endian, val); + result = class->read_u32(content, addr, endian, val); return result; @@ -503,11 +693,11 @@ bool g_binary_content_read_u32(const GBinContent *content, vmpa2t *addr, SourceE bool g_binary_content_read_u64(const GBinContent *content, vmpa2t *addr, SourceEndian endian, uint64_t *val) { bool result; /* Bilan à remonter */ - GBinContentIface *iface; /* Interface utilisée */ + GBinContentClass *class; /* Classe de l'instance */ - iface = G_BIN_CONTENT_GET_IFACE(content); + class = G_BIN_CONTENT_GET_CLASS(content); - result = iface->read_u64(content, addr, endian, val); + result = class->read_u64(content, addr, endian, val); return result; @@ -531,11 +721,11 @@ bool g_binary_content_read_u64(const GBinContent *content, vmpa2t *addr, SourceE bool g_binary_content_read_uleb128(const GBinContent *content, vmpa2t *addr, uleb128_t *val) { bool result; /* Bilan à remonter */ - GBinContentIface *iface; /* Interface utilisée */ + GBinContentClass *class; /* Classe de l'instance */ - iface = G_BIN_CONTENT_GET_IFACE(content); + class = G_BIN_CONTENT_GET_CLASS(content); - result = iface->read_uleb128(content, addr, val); + result = class->read_uleb128(content, addr, val); return result; @@ -559,11 +749,73 @@ bool g_binary_content_read_uleb128(const GBinContent *content, vmpa2t *addr, ule bool g_binary_content_read_leb128(const GBinContent *content, vmpa2t *addr, leb128_t *val) { bool result; /* Bilan à remonter */ - GBinContentIface *iface; /* Interface utilisée */ + GBinContentClass *class; /* Classe de l'instance */ + + class = G_BIN_CONTENT_GET_CLASS(content); + + result = class->read_leb128(content, addr, val); + + return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* CONSERVATION ET RECHARGEMENT DES DONNEES */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : content = élément GLib à constuire. * +* storage = conservateur de données à manipuler ou NULL. * +* pbuf = zone tampon à lire. * +* * +* Description : Charge un contenu depuis une mémoire tampon. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_binary_content_load(GBinContent *content, GObjectStorage *storage, packed_buffer_t *pbuf) +{ + bool result; /* Bilan à retourner */ + GBinContentClass *class; /* Classe de l'instance */ + + class = G_BIN_CONTENT_GET_CLASS(content); + + result = class->load(content, storage, pbuf); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : content = élément GLib à consulter. * +* storage = conservateur de données à manipuler ou NULL. * +* pbuf = zone tampon à remplir. * +* * +* Description : Sauvegarde un contenu dans une mémoire tampon. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_binary_content_store(const GBinContent *content, GObjectStorage *storage, packed_buffer_t *pbuf) +{ + bool result; /* Bilan à retourner */ + GBinContentClass *class; /* Classe de l'instance */ - iface = G_BIN_CONTENT_GET_IFACE(content); + class = G_BIN_CONTENT_GET_CLASS(content); - result = iface->read_leb128(content, addr, val); + result = class->store(content, storage, pbuf); return result; |