From ea19719b17ff319c6c728271907f8f2ac7d8c9df Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sat, 8 Feb 2020 11:15:55 +0100
Subject: Recognized more combinations for ELF R_ARM_JUMP_SLOT PLT entries.

---
 plugins/elf/helper_arm.c | 45 ++++++++++++++++++++++++++++++++++-----------
 1 file changed, 34 insertions(+), 11 deletions(-)

diff --git a/plugins/elf/helper_arm.c b/plugins/elf/helper_arm.c
index bb91ada..3632f54 100644
--- a/plugins/elf/helper_arm.c
+++ b/plugins/elf/helper_arm.c
@@ -118,7 +118,7 @@ bool retrieve_arm_linkage_offset(GElfFormat *format, const mrange_t *range, uint
     copy_vmpa(&pos, get_mrange_addr(range));
 
     result = g_binary_content_read_u32(content, &pos, format->endian, &raw);
-    if (!result) goto ralo_exit;
+    if (!result) goto exit;
 
     /**
      * On ne reconnaît pour l'instant que la seule combinaison suivante.
@@ -133,17 +133,19 @@ bool retrieve_arm_linkage_offset(GElfFormat *format, const mrange_t *range, uint
      *    e28fc600     add ip, pc, #0, 12
      *    e28cca08     add ip, ip, #8, 20  ; 0x8000
      *    e5bcf310     ldr pc, [ip, #784]! ; 0x310
+     *
+     *    e28fc601     add ip, pc, #1048576 ; 0x100000
+     *    e28cca03     add ip, ip, #12288   ; 0x3000
+     *    e5bcff00     ldr pc, [ip, #3840]! ; 0xf00
+     *
      */
 
-    if (raw == 0xe28fc600)
+    if ((raw & 0xfffff000) == 0xe28fc000)
     {
         *offset = get_virt_addr(get_mrange_addr(range)) + 8;
 
-        result = g_binary_content_read_u32(content, &pos, format->endian, &raw);
-        if (!result) goto ralo_exit;
-
         /**
-         * La seconde instruction répond à l'encodage spécifié dans :
+         * Les deux premières instructions répondent à l'encodage spécifié dans :
          *
          *    A8.8.5 - ADD (immediate, ARM)
          *
@@ -167,18 +169,36 @@ bool retrieve_arm_linkage_offset(GElfFormat *format, const mrange_t *range, uint
          *
          */
 
-        if ((raw & 0xfffff000) != 0xe28cc000)
+        /**
+         * Première instruction...
+         */
+
+        if ((raw & 0xfffff000) != 0xe28fc000)
         {
             result = false;
-            goto ralo_exit;
+            goto exit;
         }
 
         shift = 32 - ((raw & 0xf00) >> 8) * 2;
 
         *offset += (raw & 0xff) << shift;
 
+        /**
+         * Seconde instruction...
+         */
+
         result = g_binary_content_read_u32(content, &pos, format->endian, &raw);
-        if (!result) goto ralo_exit;
+        if (!result) goto exit;
+
+        if ((raw & 0xfffff000) != 0xe28cc000)
+        {
+            result = false;
+            goto exit;
+        }
+
+        shift = 32 - ((raw & 0xf00) >> 8) * 2;
+
+        *offset += (raw & 0xff) << shift;
 
         /**
          * La dernière instruction répond à l'encodage spéficié dans :
@@ -202,10 +222,13 @@ bool retrieve_arm_linkage_offset(GElfFormat *format, const mrange_t *range, uint
          *
          */
 
+        result = g_binary_content_read_u32(content, &pos, format->endian, &raw);
+        if (!result) goto exit;
+
         if ((raw & 0xfffff000) != 0xe5bcf000)
         {
             result = false;
-            goto ralo_exit;
+            goto exit;
         }
 
         *offset += (raw & 0xfff);
@@ -215,7 +238,7 @@ bool retrieve_arm_linkage_offset(GElfFormat *format, const mrange_t *range, uint
     else
         result = false;
 
- ralo_exit:
+ exit:
 
     return result;
 
-- 
cgit v0.11.2-87-g4458