summaryrefslogtreecommitdiff
path: root/src/analysis/content.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/analysis/content.c')
-rw-r--r--src/analysis/content.c384
1 files changed, 324 insertions, 60 deletions
diff --git a/src/analysis/content.c b/src/analysis/content.c
index 6d8075c..e12237f 100644
--- a/src/analysis/content.c
+++ b/src/analysis/content.c
@@ -35,20 +35,114 @@
-/* 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 : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+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 : - *
* *
@@ -56,8 +150,28 @@ G_DEFINE_INTERFACE(GBinContent, g_binary_content, G_TYPE_OBJECT);
* *
******************************************************************************/
-static void g_binary_content_default_init(GBinContentInterface *iface)
+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,11 +191,11 @@ static void g_binary_content_default_init(GBinContentInterface *iface)
void g_binary_content_set_attributes(GBinContent *content, GContentAttributes *attribs)
{
- 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);
- iface->set_attribs(content, attribs);
+ class->set_attribs(content, attribs);
}
@@ -101,11 +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 */
+ GBinContentClass *class; /* Classe de l'instance */
- iface = G_BIN_CONTENT_GET_IFACE(content);
+ class = G_BIN_CONTENT_GET_CLASS(content);
- result = iface->get_attribs(content);
+ result = class->get_attribs(content);
return result;
@@ -127,11 +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 */
+ GBinContentClass *class; /* Classe de l'instance */
- iface = G_BIN_CONTENT_GET_IFACE(content);
+ class = G_BIN_CONTENT_GET_CLASS(content);
- result = iface->get_root(content);
+ result = class->get_root(content);
return result;
@@ -154,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;
@@ -181,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");
@@ -192,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);
@@ -221,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);
}
@@ -245,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);
}
@@ -269,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);
}
@@ -294,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);
}
@@ -319,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);
}
@@ -346,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 */
- iface = G_BIN_CONTENT_GET_IFACE(content);
+ class = G_BIN_CONTENT_GET_CLASS(content);
- result = iface->read_raw(content, addr, length, out);
+ result = class->read_raw(content, addr, length, out);
+
+ 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;
+
+ }
+
+ exit:
return result;
@@ -375,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;
@@ -404,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;
@@ -433,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;
@@ -462,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;
@@ -491,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;
@@ -519,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;
@@ -547,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;