about summary refs log tree commit diff stats
path: root/src/miasm/analysis/disasm_cb.py
diff options
context:
space:
mode:
authorTheofilos Augoustis <theofilos.augoustis@gmail.com>2025-10-14 09:09:29 +0000
committerTheofilos Augoustis <theofilos.augoustis@gmail.com>2025-10-14 09:09:29 +0000
commit579cf1d03fb932083e6317967d1613d5c2587fb6 (patch)
tree629f039935382a2a7391bce9253f6c9968159049 /src/miasm/analysis/disasm_cb.py
parent51c15d3ea2e16d4fc5f0f01a3b9befc66b1f982e (diff)
downloadfocaccia-miasm-ta/nix.tar.gz
focaccia-miasm-ta/nix.zip
Convert to src-layout ta/nix
Diffstat (limited to 'src/miasm/analysis/disasm_cb.py')
-rw-r--r--src/miasm/analysis/disasm_cb.py127
1 files changed, 127 insertions, 0 deletions
diff --git a/src/miasm/analysis/disasm_cb.py b/src/miasm/analysis/disasm_cb.py
new file mode 100644
index 00000000..f180f0a2
--- /dev/null
+++ b/src/miasm/analysis/disasm_cb.py
@@ -0,0 +1,127 @@
+#-*- coding:utf-8 -*-
+
+from __future__ import print_function
+
+from future.utils import viewvalues
+
+from miasm.expression.expression import ExprInt, ExprId, ExprMem, match_expr
+from miasm.expression.simplifications import expr_simp
+from miasm.core.asmblock import AsmConstraintNext, AsmConstraintTo
+from miasm.core.locationdb import LocationDB
+from miasm.core.utils import upck32
+
+
+def get_lifter_model_call(arch, attrib):
+    arch = arch.name, attrib
+    if arch == ("arm", "arm"):
+        from miasm.arch.arm.lifter_model_call import LifterModelCallArmlBase as lifter_model_call
+    elif arch == ("x86", 32):
+        from miasm.arch.x86.lifter_model_call import LifterModelCall_x86_32 as lifter_model_call
+    elif arch == ("x86", 64):
+        from miasm.arch.x86.lifter_model_call import LifterModelCall_x86_64 as lifter_model_call
+    else:
+        raise ValueError('unknown architecture: %s' % arch.name)
+    return lifter_model_call
+
+
+def arm_guess_subcall(dis_engine, cur_block, offsets_to_dis):
+    arch = dis_engine.arch
+    loc_db = dis_engine.loc_db
+    lifter_model_call = get_lifter_model_call(arch, dis_engine.attrib)
+
+    lifter = lifter_model_call(loc_db)
+    ircfg = lifter_model_call.new_ircfg()
+    print('###')
+    print(cur_block)
+    lifter.add_asmblock_to_ircfg(cur_block, ircfg)
+
+    to_add = set()
+    for irblock in viewvalues(ircfg.blocks):
+        pc_val = None
+        lr_val = None
+        for exprs in irblock:
+            for e in exprs:
+                if e.dst == lifter.pc:
+                    pc_val = e.src
+                if e.dst == arch.regs.LR:
+                    lr_val = e.src
+        if pc_val is None or lr_val is None:
+            continue
+        if not isinstance(lr_val, ExprInt):
+            continue
+
+        l = cur_block.lines[-1]
+        if lr_val.arg != l.offset + l.l:
+            continue
+        l = loc_db.get_or_create_offset_location(int(lr_val))
+        c = AsmConstraintNext(l)
+
+        to_add.add(c)
+        offsets_to_dis.add(int(lr_val))
+
+    for c in to_add:
+        cur_block.addto(c)
+
+
+def arm_guess_jump_table(dis_engine, cur_block, offsets_to_dis):
+    arch = dis_engine.arch
+    loc_db = dis_engine.loc_db
+    lifter_model_call = get_lifter_model_call(arch, dis_engine.attrib)
+
+    jra = ExprId('jra')
+    jrb = ExprId('jrb')
+
+    lifter = lifter_model_call(loc_db)
+    ircfg = lifter_model_call.new_ircfg()
+    lifter.add_asmblock_to_ircfg(cur_block, ircfg)
+
+    for irblock in viewvalues(ircfg.blocks):
+        pc_val = None
+        for exprs in irblock:
+            for e in exprs:
+                if e.dst == lifter.pc:
+                    pc_val = e.src
+        if pc_val is None:
+            continue
+        if not isinstance(pc_val, ExprMem):
+            continue
+        assert(pc_val.size == 32)
+        print(pc_val)
+        ad = pc_val.arg
+        ad = expr_simp(ad)
+        print(ad)
+        res = match_expr(ad, jra + jrb, set([jra, jrb]))
+        if res is False:
+            raise NotImplementedError('not fully functional')
+        print(res)
+        if not isinstance(res[jrb], ExprInt):
+            raise NotImplementedError('not fully functional')
+        base_ad = int(res[jrb])
+        print(base_ad)
+        addrs = set()
+        i = -1
+        max_table_entry = 10000
+        max_diff_addr = 0x100000  # heuristic
+        while i < max_table_entry:
+            i += 1
+            try:
+                ad = upck32(dis_engine.bin_stream.getbytes(base_ad + 4 * i, 4))
+            except:
+                break
+            if abs(ad - base_ad) > max_diff_addr:
+                break
+            addrs.add(ad)
+        print([hex(x) for x in addrs])
+
+        for ad in addrs:
+            offsets_to_dis.add(ad)
+            l = loc_db.get_or_create_offset_location(ad)
+            c = AsmConstraintTo(l)
+            cur_block.addto(c)
+
+guess_funcs = []
+
+
+def guess_multi_cb(dis_engine, cur_block, offsets_to_dis):
+    for f in guess_funcs:
+        f(dis_engine, cur_block, offsets_to_dis)