From 32f7a1126f8ac5a602f60a29de18eb7c5683dcc2 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sun, 27 Sep 2015 22:50:50 +0000 Subject: Read LEB128 values from binary contents. git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@579 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a --- ChangeLog | 8 +++++ src/analysis/content-int.h | 9 +++++ src/analysis/content.c | 50 ++++++++++++++++++++++++++ src/analysis/content.h | 8 +++++ src/analysis/contents/file.c | 83 ++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 158 insertions(+) diff --git a/ChangeLog b/ChangeLog index e48637e..3257b05 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +15-09-28 Cyrille Bagard + + * src/analysis/content.c: + * src/analysis/content.h: + * src/analysis/content-int.h: + * src/analysis/contents/file.c: + Read LEB128 values from binary contents. + 15-09-20 Cyrille Bagard * configure.ac: 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; + +} -- cgit v0.11.2-87-g4458