about summary refs log tree commit diff stats
path: root/run.py
diff options
context:
space:
mode:
authorTheofilos Augoustis <theofilos.augoustis@gmail.com>2023-11-26 11:56:49 +0100
committerTheofilos Augoustis <theofilos.augoustis@gmail.com>2023-11-26 11:56:49 +0100
commit47894bb5d2e425f28d992aee6331b89b85b2058d (patch)
treefd08c28c447fbb95e9d8d4122514227f9a48d0ad /run.py
parenta4bf627c2440cbea392e27f138b07fa22cd9e6f1 (diff)
downloadfocaccia-47894bb5d2e425f28d992aee6331b89b85b2058d.tar.gz
focaccia-47894bb5d2e425f28d992aee6331b89b85b2058d.zip
Standardize X86 register names
Add some infrastructure for flexible register name matching (i.e. using
'PC' to look up RIP):

 - `Arch.to_regname` tries to look up a register's standard name from an
   arbitrary string.

 - `ArchX86` overrides `to_regname` to resolve alias names for
   registers. Currently just 'PC' for 'RIP'.

 - `ProgramState.read` and `ProgramState.write` use `to_regname` to make
   register access more convenient.

Add all flags with their standard abbreviations to `x86.regnames`.

Implement a full RFLAGS decomposition into its individual flags in
`x86`. Replace the hacks in `run.py` and `miasm_test.py` with this more
complete solution.

Co-authored-by: Theofilos Augoustis <theofilos.augoustis@gmail.com>
Co-authored-by: Nicola Crivellin <nicola.crivellin98@gmail.com>
Diffstat (limited to 'run.py')
-rw-r--r--run.py47
1 files changed, 9 insertions, 38 deletions
diff --git a/run.py b/run.py
index 6aca4d2..768a73d 100644
--- a/run.py
+++ b/run.py
@@ -20,46 +20,17 @@ class SnapshotBuilder:
         self.states = []
         self.regnames = set(arch.regnames)
 
-    @staticmethod
-    def parse_flags(flag_reg: int):
-        flags = {'ZF': 0,
-                 'CF': 0,
-                 'OF': 0,
-                 'SF': 0,
-                 'PF': 0,
-                 'DF': 0}
-
-        # CF (Carry flag) Bit 0
-        # PF (Parity flag) Bit 2
-        # ZF (Zero flag) Bit 6
-        # SF (Sign flag) Bit 7
-        # TF (Trap flag) Bit 8
-        # IF (Interrupt enable flag) Bit 9
-        # DF (Direction flag) Bit 10
-        # OF (Overflow flag) Bit 11
-        flags['CF'] = int(0 != flag_reg & 1)
-        flags['ZF'] = int(0 != flag_reg & (1 << 6))
-        flags['OF'] = int(0 != flag_reg & (1 << 11))
-        flags['SF'] = int(0 != flag_reg & (1 << 7))
-        flags['DF'] = int(0 != flag_reg & (1 << 10))
-        flags['PF'] = int(0 != flag_reg & (1 << 1))
-        return flags
-
-    def create_snapshot(self, frame):
+    def create_snapshot(self, frame: lldb.SBFrame):
         state = ProgramState(self.arch)
         state.set('PC', frame.GetPC())
-        for reg in frame.GetRegisters():
-            for sub_reg in reg:
-                # Set the register's value in the current snapshot
-                regname = sub_reg.GetName().upper()
-                if regname in self.regnames:
-                    regval = int(sub_reg.GetValue(), base=16)
-                    if regname == 'RFLAGS':
-                        flags = SnapshotBuilder.parse_flags(regval)
-                        for flag, val in flags.items():
-                            state.set(f'flag {flag}', val)
-                    else:
-                        state.set(regname, regval)
+        for regname in self.arch.regnames:
+            reg = frame.FindRegister(regname)
+            regval = int(reg.GetValue(), base=16)
+            state.set(regname, regval)
+            if regname == 'RFLAGS':
+                flags = x86.decompose_rflags(regval)
+                for flag_name, val in flags.items():
+                    state.set(flag_name, val)
         return state
 
     def __call__(self, frame):