1import os, struct, signal 2 3from typing import Any, Dict 4 5import lldb 6from lldb.plugins.scripted_process import ScriptedProcess 7from lldb.plugins.scripted_process import ScriptedThread 8 9 10class DummyStopHook: 11 def __init__(self, target, args): 12 self.target = target 13 self.args = args 14 15 def handle_stop(self, exe_ctx, stream): 16 print("My DummyStopHook triggered. Printing args: \n%s" % self.args) 17 sp = exe_ctx.process.GetScriptedImplementation() 18 sp.handled_stop = True 19 20class DummyScriptedProcess(ScriptedProcess): 21 memory = None 22 23 def __init__(self, exe_ctx: lldb.SBExecutionContext, args: lldb.SBStructuredData): 24 super().__init__(exe_ctx, args) 25 self.threads[0] = DummyScriptedThread(self, None) 26 self.memory = {} 27 addr = 0x500000000 28 debugger = self.target.GetDebugger() 29 index = debugger.GetIndexOfTarget(self.target) 30 self.memory[addr] = "Hello, target " + str(index) 31 self.handled_stop = False 32 33 def read_memory_at_address( 34 self, addr: int, size: int, error: lldb.SBError 35 ) -> lldb.SBData: 36 data = lldb.SBData().CreateDataFromCString( 37 self.target.GetByteOrder(), self.target.GetCodeByteSize(), self.memory[addr] 38 ) 39 40 return data 41 42 def write_memory_at_address(self, addr, data, error): 43 self.memory[addr] = data.GetString(error, 0) 44 return len(self.memory[addr]) + 1 45 46 def get_loaded_images(self): 47 return self.loaded_images 48 49 def get_process_id(self) -> int: 50 return 42 51 52 def should_stop(self) -> bool: 53 return True 54 55 def is_alive(self) -> bool: 56 return True 57 58 def get_scripted_thread_plugin(self): 59 return DummyScriptedThread.__module__ + "." + DummyScriptedThread.__name__ 60 61 def my_super_secret_method(self): 62 if hasattr(self, "my_super_secret_member"): 63 return self.my_super_secret_member 64 else: 65 return None 66 67 68class DummyScriptedThread(ScriptedThread): 69 def __init__(self, process, args): 70 super().__init__(process, args) 71 self.frames.append({"pc": 0x0100001B00}) 72 73 def get_thread_id(self) -> int: 74 return 0x19 75 76 def get_name(self) -> str: 77 return DummyScriptedThread.__name__ + ".thread-1" 78 79 def get_state(self) -> int: 80 return lldb.eStateStopped 81 82 def get_stop_reason(self) -> Dict[str, Any]: 83 return {"type": lldb.eStopReasonTrace, "data": {}} 84 85 def get_register_context(self) -> str: 86 return struct.pack( 87 "21Q", 88 1, 89 2, 90 3, 91 4, 92 5, 93 6, 94 7, 95 8, 96 9, 97 10, 98 11, 99 12, 100 13, 101 14, 102 15, 103 16, 104 17, 105 18, 106 19, 107 20, 108 21, 109 ) 110 111 112def __lldb_init_module(debugger, dict): 113 # This is used when loading the script in an interactive debug session to 114 # automatically, register the stop-hook and launch the scripted process. 115 if not "SKIP_SCRIPTED_PROCESS_LAUNCH" in os.environ: 116 debugger.HandleCommand( 117 "target stop-hook add -k first -v 1 -k second -v 2 -P %s.%s" 118 % (__name__, DummyStopHook.__name__) 119 ) 120 debugger.HandleCommand( 121 "process launch -C %s.%s" % (__name__, DummyScriptedProcess.__name__) 122 ) 123 else: 124 print( 125 "Name of the class that will manage the scripted process: '%s.%s'" 126 % (__name__, DummyScriptedProcess.__name__) 127 ) 128 print( 129 "Name of the class that will manage the stop-hook: '%s.%s'" 130 % (__name__, DummyStopHook.__name__) 131 ) 132