about summary refs log tree commit diff stats
path: root/miasm/analysis/debugging.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 /miasm/analysis/debugging.py
parent51c15d3ea2e16d4fc5f0f01a3b9befc66b1f982e (diff)
downloadfocaccia-miasm-ta/nix.tar.gz
focaccia-miasm-ta/nix.zip
Convert to src-layout ta/nix
Diffstat (limited to 'miasm/analysis/debugging.py')
-rw-r--r--miasm/analysis/debugging.py557
1 files changed, 0 insertions, 557 deletions
diff --git a/miasm/analysis/debugging.py b/miasm/analysis/debugging.py
deleted file mode 100644
index d5f59d49..00000000
--- a/miasm/analysis/debugging.py
+++ /dev/null
@@ -1,557 +0,0 @@
-from __future__ import print_function
-from builtins import map
-from builtins import range
-import cmd
-from future.utils import viewitems
-
-from miasm.core.utils import hexdump
-from miasm.core.interval import interval
-import miasm.jitter.csts as csts
-from miasm.jitter.jitload import ExceptionHandle
-
-
-class DebugBreakpoint(object):
-
-    "Debug Breakpoint parent class"
-    pass
-
-
-class DebugBreakpointSoft(DebugBreakpoint):
-
-    "Stand for software breakpoint"
-
-    def __init__(self, addr):
-        self.addr = addr
-
-    def __str__(self):
-        return "Soft BP @0x%08x" % self.addr
-
-
-class DebugBreakpointTerminate(DebugBreakpoint):
-    "Stand for an execution termination"
-
-    def __init__(self, status):
-        self.status = status
-
-    def __str__(self):
-        return "Terminate with %s" % self.status
-
-
-class DebugBreakpointMemory(DebugBreakpoint):
-
-    "Stand for memory breakpoint"
-
-    type2str = {csts.BREAKPOINT_READ: "R",
-                csts.BREAKPOINT_WRITE: "W"}
-
-    def __init__(self, addr, size, access_type):
-        self.addr = addr
-        self.access_type = access_type
-        self.size = size
-
-    def __str__(self):
-        bp_type = ""
-        for k, v in viewitems(self.type2str):
-            if k & self.access_type != 0:
-                bp_type += v
-        return "Memory BP @0x%08x, Size 0x%08x, Type %s" % (
-            self.addr,
-            self.size,
-            bp_type
-        )
-
-    @classmethod
-    def get_access_type(cls, read=False, write=False):
-        value = 0
-        for k, v in viewitems(cls.type2str):
-            if v == "R" and read is True:
-                value += k
-            if v == "W" and write is True:
-                value += k
-        return value
-
-
-class Debugguer(object):
-
-    "Debugguer linked with a Jitter instance"
-
-    def __init__(self, myjit):
-        "myjit : jitter instance"
-        self.myjit = myjit
-        self.bp_list = []     # DebugBreakpointSoft list
-        self.mem_bp_list = []  # DebugBreakpointMemory list
-        self.mem_watched = []  # Memory areas watched
-        self.init_memory_breakpoint()
-
-    def init_run(self, addr):
-        self.myjit.init_run(addr)
-
-    def add_breakpoint(self, addr):
-        "Add bp @addr"
-        bp = DebugBreakpointSoft(addr)
-        func = lambda x: bp
-        bp.func = func
-        self.bp_list.append(bp)
-        self.myjit.add_breakpoint(addr, func)
-
-    def init_memory_breakpoint(self):
-        "Set exception handler on EXCEPT_BREAKPOINT_MEMORY"
-        def exception_memory_breakpoint(jitter):
-            "Stop the execution and return an identifier"
-            return ExceptionHandle.memoryBreakpoint()
-
-        self.myjit.add_exception_handler(csts.EXCEPT_BREAKPOINT_MEMORY,
-                                         exception_memory_breakpoint)
-
-
-    def add_memory_breakpoint(self, addr, size, read=False, write=False):
-        "add mem bp @[addr, addr + size], on read/write/both"
-        access_type = DebugBreakpointMemory.get_access_type(read=read,
-                                                            write=write)
-        dbm = DebugBreakpointMemory(addr, size, access_type)
-        self.mem_bp_list.append(dbm)
-        self.myjit.vm.add_memory_breakpoint(addr, size, access_type)
-
-    def remove_breakpoint(self, dbs):
-        "remove the DebugBreakpointSoft instance"
-        self.bp_list.remove(dbs)
-        self.myjit.remove_breakpoints_by_callback(dbs.func)
-
-    def remove_breakpoint_by_addr(self, addr):
-        "remove breakpoints @ addr"
-        for bp in self.get_breakpoint_by_addr(addr):
-            self.remove_breakpoint(bp)
-
-    def remove_memory_breakpoint(self, dbm):
-        "remove the DebugBreakpointMemory instance"
-        self.mem_bp_list.remove(dbm)
-        self.myjit.vm.remove_memory_breakpoint(dbm.addr, dbm.access_type)
-
-    def remove_memory_breakpoint_by_addr_access(self, addr, read=False,
-                                                write=False):
-        "remove breakpoints @ addr"
-        access_type = DebugBreakpointMemory.get_access_type(read=read,
-                                                            write=write)
-        for bp in self.mem_bp_list:
-            if bp.addr == addr and bp.access_type == access_type:
-                self.remove_memory_breakpoint(bp)
-
-    def get_breakpoint_by_addr(self, addr):
-        ret = []
-        for dbgsoft in self.bp_list:
-            if dbgsoft.addr == addr:
-                ret.append(dbgsoft)
-        return ret
-
-    def get_breakpoints(self):
-        return self.bp_list
-
-    def active_trace(self, mn=None, regs=None, newbloc=None):
-        if mn is not None:
-            self.myjit.jit.log_mn = mn
-        if regs is not None:
-            self.myjit.jit.log_regs = regs
-        if newbloc is not None:
-            self.myjit.jit.log_newbloc = newbloc
-
-    def handle_exception(self, res):
-        if not res:
-            # A breakpoint has stopped the execution
-            return DebugBreakpointTerminate(res)
-
-        if isinstance(res, DebugBreakpointSoft):
-            print("Breakpoint reached @0x%08x" % res.addr)
-        elif isinstance(res, ExceptionHandle):
-            if res == ExceptionHandle.memoryBreakpoint():
-                print("Memory breakpoint reached @0x%08x" % self.myjit.pc)
-
-                memory_read = self.myjit.vm.get_memory_read()
-                if len(memory_read) > 0:
-                    print("Read:")
-                    for start_address, end_address in memory_read:
-                        print("- from 0x%08x to 0x%08x" % (start_address, end_address))
-                memory_write = self.myjit.vm.get_memory_write()
-                if len(memory_write) > 0:
-                    print("Write:")
-                    for start_address, end_address in memory_write:
-                        print("- from 0x%08x to 0x%08x" % (start_address, end_address))
-
-                # Remove flag
-                except_flag = self.myjit.vm.get_exception()
-                self.myjit.vm.set_exception(except_flag ^ res.except_flag)
-                # Clean memory access data
-                self.myjit.vm.reset_memory_access()
-            else:
-                raise NotImplementedError("Unknown Except")
-        else:
-            raise NotImplementedError("type res")
-
-        # Repropagate res
-        return res
-
-    def step(self):
-        "Step in jit"
-
-        self.myjit.jit.set_options(jit_maxline=1)
-        # Reset all jitted blocks
-        self.myjit.jit.clear_jitted_blocks()
-
-        res = self.myjit.continue_run(step=True)
-        self.handle_exception(res)
-
-        self.myjit.jit.set_options(jit_maxline=50)
-        self.on_step()
-
-        return res
-
-    def run(self):
-        status = self.myjit.continue_run()
-        return self.handle_exception(status)
-
-    def get_mem(self, addr, size=0xF):
-        "hexdump @addr, size"
-
-        hexdump(self.myjit.vm.get_mem(addr, size))
-
-    def get_mem_raw(self, addr, size=0xF):
-        "hexdump @addr, size"
-        return self.myjit.vm.get_mem(addr, size)
-
-    def watch_mem(self, addr, size=0xF):
-        self.mem_watched.append((addr, size))
-
-    def on_step(self):
-        for addr, size in self.mem_watched:
-            print("@0x%08x:" % addr)
-            self.get_mem(addr, size)
-
-    def get_reg_value(self, reg_name):
-        return getattr(self.myjit.cpu, reg_name)
-
-    def set_reg_value(self, reg_name, value):
-
-        # Handle PC case
-        if reg_name == self.myjit.lifter.pc.name:
-            self.init_run(value)
-
-        setattr(self.myjit.cpu, reg_name, value)
-
-    def get_gpreg_all(self):
-        "Return general purposes registers"
-        return self.myjit.cpu.get_gpreg()
-
-
-class DebugCmd(cmd.Cmd, object):
-
-    "CommandLineInterpreter for Debugguer instance"
-
-    color_g = '\033[92m'
-    color_e = '\033[0m'
-    color_b = '\033[94m'
-    color_r = '\033[91m'
-
-    intro = color_g + "=== Miasm2 Debugging shell ===\nIf you need help, "
-    intro += "type 'help' or '?'" + color_e
-    prompt = color_b + "$> " + color_e
-
-    def __init__(self, dbg):
-        "dbg : Debugguer"
-        self.dbg = dbg
-        super(DebugCmd, self).__init__()
-
-    # Debug methods
-
-    def print_breakpoints(self):
-        bp_list = self.dbg.bp_list
-        if len(bp_list) == 0:
-            print("No breakpoints.")
-        else:
-            for i, b in enumerate(bp_list):
-                print("%d\t0x%08x" % (i, b.addr))
-
-    def print_memory_breakpoints(self):
-        bp_list = self.dbg.mem_bp_list
-        if len(bp_list) == 0:
-            print("No memory breakpoints.")
-        else:
-            for _, bp in enumerate(bp_list):
-                print(str(bp))
-
-    def print_watchmems(self):
-        watch_list = self.dbg.mem_watched
-        if len(watch_list) == 0:
-            print("No memory watchpoints.")
-        else:
-            print("Num\tAddress  \tSize")
-            for i, w in enumerate(watch_list):
-                addr, size = w
-                print("%d\t0x%08x\t0x%08x" % (i, addr, size))
-
-    def print_registers(self):
-        regs = self.dbg.get_gpreg_all()
-
-        # Display settings
-        title1 = "Registers"
-        title2 = "Values"
-        max_name_len = max(map(len, list(regs) + [title1]))
-
-        # Print value table
-        s = "%s%s    |    %s" % (
-            title1, " " * (max_name_len - len(title1)), title2)
-        print(s)
-        print("-" * len(s))
-        for name, value in sorted(viewitems(regs), key=lambda x: x[0]):
-            print(
-                "%s%s    |    %s" % (
-                    name,
-                    " " * (max_name_len - len(name)),
-                    hex(value).replace("L", "")
-                )
-            )
-
-    def add_breakpoints(self, bp_addr):
-        for addr in bp_addr:
-            addr = int(addr, 0)
-
-            good = True
-            for i, dbg_obj in enumerate(self.dbg.bp_list):
-                if dbg_obj.addr == addr:
-                    good = False
-                    break
-            if good is False:
-                print("Breakpoint 0x%08x already set (%d)" % (addr, i))
-            else:
-                l = len(self.dbg.bp_list)
-                self.dbg.add_breakpoint(addr)
-                print("Breakpoint 0x%08x successfully added ! (%d)" % (addr, l))
-
-    display_mode = {
-        "mn": None,
-        "regs": None,
-        "newbloc": None
-    }
-
-    def update_display_mode(self):
-        self.display_mode = {
-            "mn": self.dbg.myjit.jit.log_mn,
-            "regs": self.dbg.myjit.jit.log_regs,
-            "newbloc": self.dbg.myjit.jit.log_newbloc
-        }
-
-    # Command line methods
-    def print_warning(self, s):
-        print(self.color_r + s + self.color_e)
-
-    def onecmd(self, line):
-        cmd_translate = {
-            "h": "help",
-            "q": "exit",
-            "e": "exit",
-            "!": "exec",
-            "r": "run",
-            "i": "info",
-            "b": "breakpoint",
-            "m": "memory_breakpoint",
-            "s": "step",
-            "d": "dump"
-        }
-
-        if len(line) >= 2 and \
-           line[1] == " " and \
-           line[:1] in cmd_translate:
-            line = cmd_translate[line[:1]] + line[1:]
-
-        if len(line) == 1 and line in cmd_translate:
-            line = cmd_translate[line]
-
-        r = super(DebugCmd, self).onecmd(line)
-        return r
-
-    def can_exit(self):
-        return True
-
-    def do_display(self, arg):
-        if arg == "":
-            self.help_display()
-            return
-
-        args = arg.split(" ")
-        if args[-1].lower() not in ["on", "off"]:
-            self.print_warning("[!] %s not in 'on' / 'off'" % args[-1])
-            return
-        mode = args[-1].lower() == "on"
-        d = {}
-        for a in args[:-1]:
-            d[a] = mode
-        self.dbg.active_trace(**d)
-        self.update_display_mode()
-
-    def help_display(self):
-        print("Enable/Disable tracing.")
-        print("Usage: display <mode1> <mode2> ... on|off")
-        print("Available modes are:")
-        for k in self.display_mode:
-            print("\t%s" % k)
-        print("Use 'info display' to get current values")
-
-    def do_watchmem(self, arg):
-        if arg == "":
-            self.help_watchmem()
-            return
-
-        args = arg.split(" ")
-        if len(args) >= 2:
-            size = int(args[1], 0)
-        else:
-            size = 0xF
-
-        addr = int(args[0], 0)
-
-        self.dbg.watch_mem(addr, size)
-
-    def help_watchmem(self):
-        print("Add a memory watcher.")
-        print("Usage: watchmem <addr> [size]")
-        print("Use 'info watchmem' to get current memory watchers")
-
-    def do_info(self, arg):
-        av_info = [
-            "registers",
-            "display",
-            "breakpoints",
-            "memory_breakpoint",
-            "watchmem"
-        ]
-
-        if arg == "":
-            print("'info' must be followed by the name of an info command.")
-            print("List of info subcommands:")
-            for k in av_info:
-                print("\t%s" % k)
-
-        if arg.startswith("b"):
-            # Breakpoint
-            self.print_breakpoints()
-
-        if arg.startswith("m"):
-            # Memory breakpoints
-            self.print_memory_breakpoints()
-
-        if arg.startswith("d"):
-            # Display
-            self.update_display_mode()
-            for k, v in viewitems(self.display_mode):
-                print("%s\t\t%s" % (k, v))
-
-        if arg.startswith("w"):
-            # Watchmem
-            self.print_watchmems()
-
-        if arg.startswith("r"):
-            # Registers
-            self.print_registers()
-
-    def help_info(self):
-        print("Generic command for showing things about the program being")
-        print("debugged. Use 'info' without arguments to get the list of")
-        print("available subcommands.")
-
-    def do_breakpoint(self, arg):
-        if arg == "":
-            self.help_breakpoint()
-        else:
-            addrs = arg.split(" ")
-            self.add_breakpoints(addrs)
-
-    def help_breakpoint(self):
-        print("Add breakpoints to argument addresses.")
-        print("Example:")
-        print("\tbreakpoint 0x11223344")
-        print("\tbreakpoint 1122 0xabcd")
-
-    def do_memory_breakpoint(self, arg):
-        if arg == "":
-            self.help_memory_breakpoint()
-            return
-        args = arg.split(" ")
-        if len(args) > 3 or len(args) <= 1:
-            self.help_memory_breakpoint()
-            return
-        address = int(args[0], 0)
-        size = int(args[1], 0)
-        if len(args) == 2:
-            self.dbg.add_memory_breakpoint(address, size, read=True, write=True)
-        else:
-            self.dbg.add_memory_breakpoint(address,
-                                           size,
-                                           read=('r' in args[2]),
-                                           write=('w' in args[2]))
-
-    def help_memory_breakpoint(self):
-        print("Add memory breakpoints to memory space defined by a starting")
-        print("address and a size on specified access type (default is 'rw').")
-        print("Example:")
-        print("\tmemory_breakpoint 0x11223344 0x100 r")
-        print("\tmemory_breakpoint 1122 10")
-
-    def do_step(self, arg):
-        if arg == "":
-            nb = 1
-        else:
-            nb = int(arg)
-        for _ in range(nb):
-            self.dbg.step()
-
-    def help_step(self):
-        print("Step program until it reaches a different source line.")
-        print("Argument N means do this N times (or till program stops")
-        print("for another reason).")
-
-    def do_dump(self, arg):
-        if arg == "":
-            self.help_dump()
-        else:
-            args = arg.split(" ")
-            if len(args) >= 2:
-                size = int(args[1], 0)
-            else:
-                size = 0xF
-            addr = int(args[0], 0)
-
-            self.dbg.get_mem(addr, size)
-
-    def help_dump(self):
-        print("Dump <addr> [size]. Dump size bytes at addr.")
-
-    def do_run(self, _):
-        self.dbg.run()
-
-    def help_run(self):
-        print("Launch or continue the current program")
-
-    def do_exit(self, _):
-        return True
-
-    def do_exec(self, line):
-        try:
-            print(eval(line))
-        except Exception as error:
-            print("*** Error: %s" % error)
-
-    def help_exec(self):
-        print("Exec a python command.")
-        print("You can also use '!' shortcut.")
-
-    def help_exit(self):
-        print("Exit the interpreter.")
-        print("You can also use the Ctrl-D shortcut.")
-
-    def help_help(self):
-        print("Print help")
-
-    def postloop(self):
-        print('\nGoodbye !')
-        super(DebugCmd, self).postloop()
-
-    do_EOF = do_exit
-    help_EOF = help_exit