summaryrefslogtreecommitdiff
path: root/src/analysis
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2015-09-27 22:50:50 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2015-09-27 22:50:50 (GMT)
commit32f7a1126f8ac5a602f60a29de18eb7c5683dcc2 (patch)
treef92189c4d5d8f164c4b666289dd40344d71d39f9 /src/analysis
parentad4ae001fbb37bdccd99ef1e01404ae72c0a1318 (diff)
Read LEB128 values from binary contents.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@579 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/analysis')
-rw-r--r--src/analysis/content-int.h9
-rw-r--r--src/analysis/content.c50
-rw-r--r--src/analysis/content.h8
-rw-r--r--src/analysis/contents/file.c83
4 files changed, 150 insertions, 0 deletions
diff --git a/src/analysis/content-int.h b/src/analysis/content-int.h
index c5b1659..36168be 100644
--- a/src/analysis/content-int.h
+++ b/src/analysis/content-int.h
@@ -62,6 +62,12 @@ typedef bool (* read_u32_fc) (const GBinContent *, vmpa2t *, SourceEndian, uint3
/* Lit un nombre non signé sur huit octets. */
typedef bool (* read_u64_fc) (const GBinContent *, vmpa2t *, SourceEndian, uint64_t *);
+/* Lit un nombre non signé encodé au format LEB128. */
+typedef bool (* read_uleb128_fc) (const GBinContent *, vmpa2t *, uleb128_t *);
+
+/* Lit un nombre signé encodé au format LEB128. */
+typedef bool (* read_leb128_fc) (const GBinContent *, vmpa2t *, leb128_t *);
+
/* Accès à un contenu binaire quelconque (interface) */
struct _GBinContentIface
@@ -85,6 +91,9 @@ struct _GBinContentIface
read_u32_fc read_u32; /* Lecture de 32 bits */
read_u64_fc read_u64; /* Lecture de 64 bits */
+ read_uleb128_fc read_uleb128; /* Lecture d'un LEB non signé */
+ read_leb128_fc read_leb128; /* Lecture d'un LEB signé */
+
};
diff --git a/src/analysis/content.c b/src/analysis/content.c
index d314d0c..d86a351 100644
--- a/src/analysis/content.c
+++ b/src/analysis/content.c
@@ -366,3 +366,53 @@ bool g_binary_content_read_u64(const GBinContent *content, vmpa2t *addr, SourceE
return iface->read_u64(content, addr, endian, 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é encodé au format LEB128. *
+* *
+* Retour : Bilan de l'opération : true en cas de succès, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_binary_content_read_uleb128(const GBinContent *content, vmpa2t *addr, uleb128_t *val)
+{
+ GBinContentIface *iface; /* Interface utilisée */
+
+ iface = G_BIN_CONTENT_GET_IFACE(content);
+
+ return iface->read_uleb128(content, addr, 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 signé encodé au format LEB128. *
+* *
+* Retour : Bilan de l'opération : true en cas de succès, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_binary_content_read_leb128(const GBinContent *content, vmpa2t *addr, leb128_t *val)
+{
+ GBinContentIface *iface; /* Interface utilisée */
+
+ iface = G_BIN_CONTENT_GET_IFACE(content);
+
+ return iface->read_leb128(content, addr, val);
+
+}
diff --git a/src/analysis/content.h b/src/analysis/content.h
index 0d991b9..591097d 100644
--- a/src/analysis/content.h
+++ b/src/analysis/content.h
@@ -31,6 +31,7 @@
#include "../arch/vmpa.h"
#include "../common/endianness.h"
+#include "../common/leb128.h"
#include "../common/xml.h"
@@ -97,5 +98,12 @@ bool g_binary_content_read_u64(const GBinContent *, vmpa2t *, SourceEndian, uint
#define g_binary_content_read_s64(c, a, e, v) g_binary_content_read_u64(c, a, e, (uint64_t *)v)
+/* Lit un nombre non signé encodé au format LEB128. */
+bool g_binary_content_read_uleb128(const GBinContent *, vmpa2t *, uleb128_t *);
+
+/* Lit un nombre signé encodé au format LEB128. */
+bool g_binary_content_read_leb128(const GBinContent *, vmpa2t *, leb128_t *);
+
+
#endif /* _ANALYSIS_CONTENT_H */
diff --git a/src/analysis/contents/file.c b/src/analysis/contents/file.c
index 9f1c10c..f24e930 100644
--- a/src/analysis/contents/file.c
+++ b/src/analysis/contents/file.c
@@ -109,6 +109,12 @@ static bool g_file_content_read_u32(const GFileContent *, vmpa2t *, SourceEndian
/* Lit un nombre non signé sur huit octets. */
static bool g_file_content_read_u64(const GFileContent *, vmpa2t *, SourceEndian, uint64_t *);
+/* Lit un nombre non signé encodé au format LEB128. */
+static bool g_file_content_read_uleb128(const GFileContent *, vmpa2t *, uleb128_t *);
+
+/* Lit un nombre signé encodé au format LEB128. */
+static bool g_file_content_read_leb128(const GFileContent *, vmpa2t *, leb128_t *);
+
/* Indique le type défini par la GLib pour les contenus de données. */
@@ -193,6 +199,9 @@ static void g_file_content_interface_init(GBinContentInterface *iface)
iface->read_u32 = (read_u32_fc)g_file_content_read_u32;
iface->read_u64 = (read_u64_fc)g_file_content_read_u64;
+ iface->read_uleb128 = (read_uleb128_fc)g_file_content_read_uleb128;
+ iface->read_leb128 = (read_leb128_fc)g_file_content_read_leb128;
+
}
@@ -729,3 +738,77 @@ static bool g_file_content_read_u64(const GFileContent *content, vmpa2t *addr, S
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é encodé au format LEB128. *
+* *
+* Retour : Bilan de l'opération : true en cas de succès, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_file_content_read_uleb128(const GFileContent *content, vmpa2t *addr, uleb128_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_uleb128(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. *
+* val = lieu d'enregistrement de la lecture. [OUT] *
+* *
+* Description : Lit un nombre signé encodé au format LEB128. *
+* *
+* Retour : Bilan de l'opération : true en cas de succès, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_file_content_read_leb128(const GFileContent *content, vmpa2t *addr, leb128_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_leb128(val, content->data, &pos, length);
+
+ if (result)
+ advance_vmpa(addr, pos - get_phy_addr(addr));
+
+ return result;
+
+}