summaryrefslogtreecommitdiff
path: root/src/analysis
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2016-09-24 21:18:51 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2016-09-24 21:18:51 (GMT)
commit3c970a0a1b74a1991be303132221329f3eef0b91 (patch)
tree7f3c9e8969f5c5c9fe1188c762dda0668c6f9ff6 /src/analysis
parent65a4b8d9c1929fb7b171d630d336519fc4d418ef (diff)
Prevented out of bounds access when moving the reading position forwards.
Diffstat (limited to 'src/analysis')
-rw-r--r--src/analysis/content-int.h5
-rw-r--r--src/analysis/content.c25
-rw-r--r--src/analysis/content.h3
-rw-r--r--src/analysis/contents/file.c47
-rw-r--r--src/analysis/contents/restricted.c47
-rw-r--r--src/analysis/disass/area.c6
6 files changed, 122 insertions, 11 deletions
diff --git a/src/analysis/content-int.h b/src/analysis/content-int.h
index 24cea81..558e32c 100644
--- a/src/analysis/content-int.h
+++ b/src/analysis/content-int.h
@@ -41,6 +41,9 @@ typedef void (* compute_checksum_fc) (GBinContent *, GChecksum *);
/* Détermine le nombre d'octets lisibles. */
typedef phys_t (* compute_size_fc) (const GBinContent *);
+/* Avance la tête de lecture d'une certaine quantité de données. */
+typedef bool (* seek_fc) (const GBinContent *, vmpa2t *, phys_t);
+
/* Donne accès à une portion des données représentées. */
typedef const bin_t * (* get_raw_access_fc) (const GBinContent *, vmpa2t *, phys_t);
@@ -82,6 +85,8 @@ struct _GBinContentIface
compute_size_fc compute_size; /* Calcul de la taille totale */
+ seek_fc seek; /* Avancée de tête de lecture */
+
get_raw_access_fc get_raw_access; /* Accès brut à une position */
read_raw_fc read_raw; /* Lecture brute */
diff --git a/src/analysis/content.c b/src/analysis/content.c
index 4b4645f..898bf43 100644
--- a/src/analysis/content.c
+++ b/src/analysis/content.c
@@ -216,6 +216,31 @@ phys_t g_binary_content_compute_size(const GBinContent *content)
* *
* Paramètres : content = contenu binaire à venir lire. *
* addr = position de la tête de lecture. *
+* length = quantité d'octets à provisionner. *
+* *
+* Description : Avance la tête de lecture d'une certaine quantité de données.*
+* *
+* Retour : Bilan de l'opération : true en cas de succès, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_binary_content_seek(const GBinContent *content, vmpa2t *addr, phys_t length)
+{
+ GBinContentIface *iface; /* Interface utilisée */
+
+ iface = G_BIN_CONTENT_GET_IFACE(content);
+
+ return iface->seek(content, addr, length);
+
+}
+
+
+/******************************************************************************
+* *
+* 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. *
diff --git a/src/analysis/content.h b/src/analysis/content.h
index f1e5bbf..4ec4f61 100644
--- a/src/analysis/content.h
+++ b/src/analysis/content.h
@@ -69,6 +69,9 @@ const gchar *g_binary_content_get_checksum(GBinContent *);
/* Détermine le nombre d'octets lisibles. */
phys_t g_binary_content_compute_size(const GBinContent *);
+/* Avance la tête de lecture d'une certaine quantité de données. */
+bool g_binary_content_seek(const GBinContent *, vmpa2t *, phys_t);
+
/* 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);
diff --git a/src/analysis/contents/file.c b/src/analysis/contents/file.c
index 95cfd5d..e7bebd0 100644
--- a/src/analysis/contents/file.c
+++ b/src/analysis/contents/file.c
@@ -85,6 +85,9 @@ static void g_file_content_compute_checksum(GFileContent *, GChecksum *);
/* Détermine le nombre d'octets lisibles. */
static phys_t g_file_content_compute_size(const GFileContent *);
+/* Avance la tête de lecture d'une certaine quantité de données. */
+static bool g_file_content_seek(const GFileContent *, vmpa2t *, phys_t);
+
/* 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);
@@ -183,6 +186,8 @@ static void g_file_content_interface_init(GBinContentInterface *iface)
iface->compute_size = (compute_size_fc)g_file_content_compute_size;
+ iface->seek = (seek_fc)g_file_content_seek;
+
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;
@@ -479,31 +484,59 @@ static phys_t g_file_content_compute_size(const GFileContent *content)
* *
* Paramètres : content = contenu binaire à venir lire. *
* addr = position de la tête de lecture. *
-* length = quantité d'octets à lire. *
+* length = quantité d'octets à provisionner. *
* *
-* Description : Donne accès à une portion des données représentées. *
+* Description : Avance la tête de lecture d'une certaine quantité de données.*
* *
-* Retour : Pointeur vers les données à lire ou NULL en cas d'échec. *
+* Retour : Bilan de l'opération : true en cas de succès, false sinon. *
* *
* Remarques : - *
* *
******************************************************************************/
-static const bin_t *g_file_content_get_raw_access(const GFileContent *content, vmpa2t *addr, phys_t length)
+static bool g_file_content_seek(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;
+ return false;
if ((offset + length) >= get_mrange_length(&content->range))
- return NULL;
+ return false;
advance_vmpa(addr, length);
- return &content->data[offset];
+ return true;
+
+}
+
+
+/******************************************************************************
+* *
+* 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 */
+ bool allowed; /* Capacité d'avancer ? */
+
+ offset = get_phy_addr(addr);
+
+ allowed = g_file_content_seek(content, addr, length);
+
+ return (allowed ? &content->data[offset] : NULL);
}
diff --git a/src/analysis/contents/restricted.c b/src/analysis/contents/restricted.c
index e342242..1f996d1 100644
--- a/src/analysis/contents/restricted.c
+++ b/src/analysis/contents/restricted.c
@@ -69,6 +69,9 @@ static void g_restricted_content_finalize(GRestrictedContent *);
/* Calcule une empreinte unique (SHA256) pour les données. */
static void g_restricted_content_compute_checksum(GRestrictedContent *, GChecksum *);
+/* Avance la tête de lecture d'une certaine quantité de données. */
+static bool g_restricted_content_seek(const GRestrictedContent *, vmpa2t *, phys_t);
+
/* Donne accès à une portion des données représentées. */
static const bin_t *g_restricted_content_get_raw_access(const GRestrictedContent *, vmpa2t *, phys_t);
@@ -161,6 +164,8 @@ static void g_restricted_content_interface_init(GBinContentInterface *iface)
{
iface->compute_checksum = (compute_checksum_fc)g_restricted_content_compute_checksum;
+ iface->seek = (seek_fc)g_restricted_content_seek;
+
iface->get_raw_access = (get_raw_access_fc)g_restricted_content_get_raw_access;
iface->read_raw = (read_raw_fc)g_restricted_content_read_raw;
@@ -286,6 +291,48 @@ static void g_restricted_content_compute_checksum(GRestrictedContent *content, G
* *
* Paramètres : content = contenu binaire à venir lire. *
* addr = position de la tête de lecture. *
+* length = quantité d'octets à provisionner. *
+* *
+* Description : Avance la tête de lecture d'une certaine quantité de données.*
+* *
+* Retour : Bilan de l'opération : true en cas de succès, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_restricted_content_seek(const GRestrictedContent *content, vmpa2t *addr, phys_t length)
+{
+ bool result; /* Bilan de lecture à renvoyer */
+ vmpa2t old; /* Copie de sauvegarde */
+
+ if (!mrange_contains_addr(&content->range, addr))
+ {
+ result = false;
+ goto bad_range;
+ }
+
+ copy_vmpa(&old, addr);
+
+ result = g_binary_content_seek(content->internal, addr, length);
+
+ if (result && !mrange_contains_addr_inclusive(&content->range, addr))
+ {
+ copy_vmpa(addr, &old);
+ result = false;
+ }
+
+ bad_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. *
diff --git a/src/analysis/disass/area.c b/src/analysis/disass/area.c
index b1d4bb1..c9612af 100644
--- a/src/analysis/disass/area.c
+++ b/src/analysis/disass/area.c
@@ -206,11 +206,9 @@ static bool is_range_blank_in_mem_area_v2(mem_area_v2 *area, phys_t start, phys_
{
bool result; /* Résultat à renvoyer */
- if ((start + len) > get_mrange_length(&area->range))
- result = false;
+ assert((start + len) <= get_mrange_length(&area->range));
- else
- result = !test_in_bit_field(area->processed, start, len);
+ result = !test_in_bit_field(area->processed, start, len);
return result;