From 8327e2edfea2417a1c08130fac6a6408903c549b Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sat, 28 Apr 2018 22:48:52 +0200
Subject: Handled corrupted Dex headers.

---
 plugins/dex/format.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 51 insertions(+)

diff --git a/plugins/dex/format.c b/plugins/dex/format.c
index d3e18da..371684f 100755
--- a/plugins/dex/format.c
+++ b/plugins/dex/format.c
@@ -31,6 +31,7 @@
 #include <i18n.h>
 #include <core/demanglers.h>
 #include <core/global.h>
+#include <core/logs.h>
 #include <plugins/pglist.h>
 
 
@@ -267,6 +268,9 @@ static bool g_dex_format_analyze(GDexFormat *format, wgroup_id_t gid, GtkStatusS
     GBinFormat *base;                       /* Version basique du format   */
     GExeFormat *exe;                        /* Autre version du format     */
     vmpa2t pos;                             /* Position de tête de lecture */
+    phys_t size;                            /* Taille du binaire           */
+    VMPA_BUFFER(size_str);                  /* Conversion en chaîne        */
+    uint32_t max;                           /* Nombre maximal d'éléments   */
 
     result = false;
 
@@ -278,6 +282,53 @@ static bool g_dex_format_analyze(GDexFormat *format, wgroup_id_t gid, GtkStatusS
     if (!read_dex_header(format, &pos, &format->header))
         goto gdfa_error;
 
+    /* Vérification des tailles fournies */
+
+    size = g_binary_content_compute_size(base->content);
+
+    if (size >= 0xffffffffllu)
+    {
+        init_vmpa(&pos, size, VMPA_NO_VIRTUAL);
+        vmpa2_phys_to_string(&pos, MDS_UNDEFINED, size_str, NULL);
+
+        log_variadic_message(LMT_BAD_BINARY, _("The binary content is too big (size=%s)"), size_str);
+        goto gdfa_error;
+
+    }
+
+
+#define CHECK_DEX_HEADER(type, cstruct, hardlim, msg)                                               \
+    do                                                                                              \
+    {                                                                                               \
+        if (format->header. type ## _off > size)                                                    \
+        {                                                                                           \
+            log_variadic_message(LMT_BAD_BINARY,                                                    \
+                                 _("Corrupted " msg " offset; fixed!  --  replacing 0x%x by 0x%x"), \
+                                 format->header. type ## _off, size);                               \
+            format->header. type ## _off = size;                                                    \
+        }                                                                                           \
+                                                                                                    \
+        max = (size - format->header. type ## _off) / sizeof(cstruct);                              \
+                                                                                                    \
+        if (hardlim && max > 65535)                                                                 \
+            max = 65535;                                                                            \
+                                                                                                    \
+        if (format->header. type ## _size > max)                                                    \
+        {                                                                                           \
+            log_variadic_message(LMT_BAD_BINARY,                                                    \
+                                 _("Corrupted " msg " size; fixed!  --  replacing 0x%x by 0x%x"),   \
+                                 format->header. type ## _size, max);                               \
+            format->header. type ## _size = max;                                                    \
+        }                                                                                           \
+    }                                                                                               \
+    while (0);
+
+    CHECK_DEX_HEADER(type_ids, type_id_item, true, "type identifiers");
+    CHECK_DEX_HEADER(proto_ids, proto_id_item, true, "prototype identifiers");
+    CHECK_DEX_HEADER(field_ids, field_id_item, true, "field identifiers");
+    CHECK_DEX_HEADER(method_ids, method_id_item, true, "method identifiers");
+    CHECK_DEX_HEADER(class_defs, class_def_item, false, "class definitions");
+
 
     /* TODO : vérifier que les *_id ne se chevauchent pas */
 
-- 
cgit v0.11.2-87-g4458