From 7e5540029350ab7e69ee8f75c96fc3fbc9ad5751 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Thu, 1 Oct 2015 16:24:23 +0000
Subject: Fixed the support of ELF internal arrays.

git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@583 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
---
 ChangeLog                |  5 +++++
 src/format/elf/symbols.c | 26 ++++++++++++++++++--------
 2 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index cb8407c..49c6f77 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 15-10-01  Cyrille Bagard <nocbos@gmail.com>
 
+	* src/format/elf/symbols.c:
+	Fix the support of ELF internal arrays.
+
+15-10-01  Cyrille Bagard <nocbos@gmail.com>
+
 	* src/format/dex/dex.c:
 	Provide the real number of loaded classes instead of 0.
 
diff --git a/src/format/elf/symbols.c b/src/format/elf/symbols.c
index 04c584d..57d14cd 100644
--- a/src/format/elf/symbols.c
+++ b/src/format/elf/symbols.c
@@ -291,27 +291,37 @@ static bool load_all_elf_basic_entry_points(GElfFormat *format)
 
         for (i = 0; get_phy_addr(&pos) < length; i++)
         {
+            /**
+             * Selon la libc d'Android (https://www.codeaurora.org/.../android/bionic/linker/README.TXT) :
+             *
+             *      DT_INIT_ARRAY
+             *          Points to an array of function addresses that must be
+             *          called, in-order, to perform initialization. Some of
+             *          the entries in the array can be 0 or -1, and should
+             *          be ignored.
+             *
+             * On étend le principe aux sections DT_FINI_ARRAY et DT_PREINIT_ARRAY.
+             */
+
             if (fmt->is_32b)
             {
                 status = g_binary_content_read_u32(content, &pos, fmt->endian, &virt_32);
+                status &= (virt_32 != 0x0 && virt_32 != 0xffffffff);
                 ep = virt_32;
             }
             else
             {
                 status = g_binary_content_read_u64(content, &pos, fmt->endian, &virt_64);
+                status &= (virt_64 != 0x0 && virt_64 != 0xffffffffffffffff);
                 ep = virt_64;
             }
 
             if (!status) break;
 
-            if (ep != 0x0)
-            {
-                snprintf(fullname, sizeof(fullname), "%s%u", prefix, i);
-
-                routine = try_to_demangle_routine(fullname);
-                register_elf_entry_point(fmt, ep, 0, routine);
+            snprintf(fullname, sizeof(fullname), "%s%u", prefix, i);
 
-            }
+            routine = try_to_demangle_routine(fullname);
+            register_elf_entry_point(fmt, ep, 0, routine);
 
         }
 
@@ -506,7 +516,7 @@ static bool load_elf_internal_symbols(GElfFormat *format)
         vmpa2t addr;                        /* Localisation d'une routine  */
         mrange_t range;                     /* Couverture mémoire associée */
         const char *name;                   /* Nom du symbole trouvé       */
-        char alt_name[5 + VMPA_MAX_LEN];    /* Nom abstrait de substitution*/
+        char alt_name[6 + VMPA_MAX_LEN];    /* Nom abstrait de substitution*/
         GBinRoutine *routine;               /* Nouvelle routine trouvée    */
         GBinSymbol *symbol;                 /* Nouveau symbole construit   */
 
-- 
cgit v0.11.2-87-g4458