about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKonstantin Komarov <gerayee@gmail.com>2021-07-03 12:04:25 +0300
committerGitHub <noreply@github.com>2021-07-03 11:04:25 +0200
commitfcb324e04e11feb7f6f5aa51ec60f67f24b040e3 (patch)
treea5144ec3c21ecc5906618ecd529f9d13b9f37e9d
parent069440e8b4517a0ff93b94b4f89598e1695a429a (diff)
downloadmiasm-fcb324e04e11feb7f6f5aa51ec60f67f24b040e3.tar.gz
miasm-fcb324e04e11feb7f6f5aa51ec60f67f24b040e3.zip
x86_64 Fix multiple REX prefix instruction disasm (#1376)
Fix multiple rex prefixes
-rw-r--r--miasm/arch/x86/arch.py10
-rw-r--r--test/arch/x86/arch.py7
2 files changed, 14 insertions, 3 deletions
diff --git a/miasm/arch/x86/arch.py b/miasm/arch/x86/arch.py
index e0580bc0..d17577fc 100644
--- a/miasm/arch/x86/arch.py
+++ b/miasm/arch/x86/arch.py
@@ -751,14 +751,18 @@ class mn_x86(cls_mn):
                 break
             pre_dis_info['prefix'] += c
             offset += 1
-        if mode == 64 and c in b'@ABCDEFGHIJKLMNO':
-            x = ord(c)
+        rex_prefixes = b'@ABCDEFGHIJKLMNO'
+        if mode == 64 and c in rex_prefixes:
+            while c in rex_prefixes:
+                # multiple REX prefixes case - use last REX prefix
+                x = ord(c)
+                offset += 1
+                c = v.getbytes(offset)
             pre_dis_info['rex_p'] = 1
             pre_dis_info['rex_w'] = (x >> 3) & 1
             pre_dis_info['rex_r'] = (x >> 2) & 1
             pre_dis_info['rex_x'] = (x >> 1) & 1
             pre_dis_info['rex_b'] = (x >> 0) & 1
-            offset += 1
         elif pre_dis_info.get('g1', None) == 12 and c in [b'\xa6', b'\xa7', b'\xae', b'\xaf']:
             pre_dis_info['g1'] = 4
         return pre_dis_info, v, mode, offset, offset - offset_o
diff --git a/test/arch/x86/arch.py b/test/arch/x86/arch.py
index bedbc503..55694dfe 100644
--- a/test/arch/x86/arch.py
+++ b/test/arch/x86/arch.py
@@ -3125,6 +3125,8 @@ reg_tests = [
      "f30f1efa"),
     (m32, "00000000    ENDBR32",
      "f30f1efb"),
+    (m64, "00000000    MOV        QWORD PTR ES:[RAX], RDX",
+     "26488910"),
 ]
 
 
@@ -3201,3 +3203,8 @@ cProfile.run('profile_dis(o)')
 instr_bytes = b'\x65\xc7\x00\x09\x00\x00\x00'
 inst = mn_x86.dis(instr_bytes, 32, 0)
 assert(inst.b == instr_bytes)
+
+# Test multiple REX prefixes
+for i in range(1, 4):
+    mn = mn_x86.dis(b'\x26' + b'\x48' * i + b'\x89\x10', 64)
+    assert (str(mn).strip() == 'MOV        QWORD PTR ES:[RAX], RDX')