Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

x86&x64: add notrack (Intel CET_IBT) #94

Open
LRGH opened this issue Mar 2, 2024 · 1 comment
Open

x86&x64: add notrack (Intel CET_IBT) #94

LRGH opened this issue Mar 2, 2024 · 1 comment

Comments

@LRGH
Copy link
Contributor

LRGH commented Mar 2, 2024

Here is the patch I use

diff --git a/amoco/arch/x64/spec_ia32e.py b/amoco/arch/x64/spec_ia32e.py
index ce976ea..c84285c 100644
--- a/amoco/arch/x64/spec_ia32e.py
+++ b/amoco/arch/x64/spec_ia32e.py
@@ -36,6 +36,10 @@ def prefix_grp1(obj, _pfx):
     setpfx(obj, _pfx, 0)
 
 
+# Because of the addition of CET_IBT, the 3e prefix has now two
+# possible meanings: DS: segment override, or notrack
+# We keep the traditional "DS: segment override" but will need to
+# hack the instructions where it means notrack: call & jmp
 @ispec_ia32("8>[ {26} ]+", _pfx=("segreg", env.es))
 @ispec_ia32("8>[ {2e} ]+", _pfx=("segreg", env.cs))
 @ispec_ia32("8>[ {36} ]+", _pfx=("segreg", env.ss))
@@ -371,6 +375,14 @@ def ia32_rm64(obj, Mod, RM, data):
     obj.operands = [op1]
     obj.misc["absolute"] = True
     obj.type = type_control_flow
+    # Because of the addition of CET_IBT, the 3e prefix has now two
+    # possible meanings: DS: segment override, or notrack
+    # We keep the traditional "DS: segment override" but will need to
+    # hack the instructions where it means notrack: this one
+    if obj.misc["segreg"] is env.ds:
+        del obj.misc["segreg"]
+        obj.misc["notrack"] = True
+        obj.misc["pfx"] = ["notrack", None, None, None]
 
 
 # r/m32/48
diff --git a/amoco/arch/x86/parsers.py b/amoco/arch/x86/parsers.py
index 9bbccbe..8024347 100644
--- a/amoco/arch/x86/parsers.py
+++ b/amoco/arch/x86/parsers.py
@@ -81,6 +81,7 @@ def att_syntax_gen(env, CONDITION_CODES, cpu_addrsize, instruction):
             "repe",
             "repne",
             "repnz",
+            "notrack",
         ]
     )
 
@@ -321,13 +322,15 @@ def att_syntax_gen(env, CONDITION_CODES, cpu_addrsize, instruction):
         i = instruction(b"")
         i.mnemonic = toks[0].upper()
         # Remove prefixes
-        if i.mnemonic in ("REP", "REPZ", "REPNZ", "REPE", "REPNE", "LOCK"):
+        if i.mnemonic in ("REP", "REPZ", "REPNZ", "REPE", "REPNE", "LOCK", "NOTRACK"):
             if i.mnemonic in ("REP", "REPZ", "REPE"):
                 i.misc.update({"pfx": ["rep", None, None, None], "rep": True})
             if i.mnemonic in ("REPNZ", "REPNE"):
                 i.misc.update({"pfx": ["repne", None, None, None], "repne": True})
             if i.mnemonic in ("LOCK",):
                 i.misc.update({"pfx": ["lock", None, None, None], "lock": True})
+            if i.mnemonic in ("NOTRACK",):
+                i.misc.update({"pfx": ["notrack", None, None, None], "notrack": True})
             del toks[0]  # toks.pop(0) is broken for pyparsing 2.0.2
             # https://bugs.launchpad.net/ubuntu/+source/pyparsing/+bug/1381564
             i.mnemonic = toks[0].upper()
diff --git a/amoco/arch/x86/spec_ia32.py b/amoco/arch/x86/spec_ia32.py
index f343675..9b20c97 100644
--- a/amoco/arch/x86/spec_ia32.py
+++ b/amoco/arch/x86/spec_ia32.py
@@ -34,6 +34,10 @@ def prefix_grp1(obj, _pfx):
     setpfx(obj, _pfx, 0)
 
 
+# Because of the addition of CET_IBT, the 3e prefix has now two
+# possible meanings: DS: segment override, or notrack
+# We keep the traditional "DS: segment override" but will need to
+# hack the instructions where it means notrack: call & jmp
 @ispec_ia32("8>[ {26} ]+", _pfx=("segreg", env.es))
 @ispec_ia32("8>[ {2e} ]+", _pfx=("segreg", env.cs))
 @ispec_ia32("8>[ {36} ]+", _pfx=("segreg", env.ss))
@@ -330,6 +334,14 @@ def ia32_rm32(obj, Mod, RM, data):
     obj.operands = [op1]
     if obj.mnemonic in ("JMP", "CALL"):
         obj.misc["absolute"] = True
+        # Because of the addition of CET_IBT, the 3e prefix has now two
+        # possible meanings: DS: segment override, or notrack
+        # We keep the traditional "DS: segment override" but will need to
+        # hack the instructions where it means notrack: this one
+        if obj.misc["segreg"] is env.ds:
+            del obj.misc["segreg"]
+            obj.misc["notrack"] = True
+            obj.misc["pfx"] = ["notrack", None, None, None]
 
 
 # r/m32/48
diff --git a/tests/test_arch_x64.py b/tests/test_arch_x64.py
index 8758829..2a2c673 100644
--- a/tests/test_arch_x64.py
+++ b/tests/test_arch_x64.py
@@ -207,3 +207,8 @@ def test_decoder_029():
   i = cpu.disassemble(b'\xf3\x0f\x1e\xfa')
   assert i.mnemonic=='ENDBR64'
   assert str(i) == 'endbr64     '
+
+def test_decoder_030():
+  i = cpu.disassemble(b'\x3e\xff\xe0')
+  assert i.mnemonic=='JMP'
+  assert str(i) == 'notrack jmp         rax'
@bdcht
Copy link
Owner

bdcht commented Mar 4, 2024

Thanks, added in fa1eb9d.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants