195 lines · python
1import os, struct, signal2 3from typing import Any, Dict4 5import lldb6from lldb.plugins.scripted_process import ScriptedProcess7from lldb.plugins.scripted_process import ScriptedThread8from lldb.plugins.scripted_process import ScriptedFrame9 10 11class DummyStopHook:12 def __init__(self, target, args):13 self.target = target14 self.args = args15 16 def handle_stop(self, exe_ctx, stream):17 print("My DummyStopHook triggered. Printing args: \n%s" % self.args)18 sp = exe_ctx.process.GetScriptedImplementation()19 sp.handled_stop = True20 21class DummyScriptedProcess(ScriptedProcess):22 memory = None23 24 def __init__(self, exe_ctx: lldb.SBExecutionContext, args: lldb.SBStructuredData):25 super().__init__(exe_ctx, args)26 self.threads[0] = DummyScriptedThread(self, args)27 self.memory = {}28 addr = 0x50000000029 debugger = self.target.GetDebugger()30 index = debugger.GetIndexOfTarget(self.target)31 self.memory[addr] = "Hello, target " + str(index)32 self.handled_stop = False33 34 def read_memory_at_address(35 self, addr: int, size: int, error: lldb.SBError36 ) -> lldb.SBData:37 data = lldb.SBData().CreateDataFromCString(38 self.target.GetByteOrder(), self.target.GetCodeByteSize(), self.memory[addr]39 )40 41 return data42 43 def write_memory_at_address(self, addr, data, error):44 self.memory[addr] = data.GetString(error, 0)45 return len(self.memory[addr]) + 146 47 def get_loaded_images(self):48 return self.loaded_images49 50 def get_process_id(self) -> int:51 return 4252 53 def should_stop(self) -> bool:54 return True55 56 def is_alive(self) -> bool:57 return True58 59 def get_scripted_thread_plugin(self):60 return DummyScriptedThread.__module__ + "." + DummyScriptedThread.__name__61 62 def my_super_secret_method(self):63 if hasattr(self, "my_super_secret_member"):64 return self.my_super_secret_member65 else:66 return None67 68 69class DummyScriptedThread(ScriptedThread):70 def __init__(self, process, args):71 super().__init__(process, args)72 self.frames.append({"pc": 0x0100001B00})73 self.frames.append(DummyScriptedFrame(self, args, len(self.frames), "baz123"))74 self.frames.append(DummyScriptedFrame(self, args, len(self.frames), "bar"))75 self.frames.append(DummyScriptedFrame(self, args, len(self.frames), "foo"))76 77 def get_thread_id(self) -> int:78 return 0x1979 80 def get_name(self) -> str:81 return DummyScriptedThread.__name__ + ".thread-1"82 83 def get_state(self) -> int:84 return lldb.eStateStopped85 86 def get_stop_reason(self) -> Dict[str, Any]:87 return {"type": lldb.eStopReasonTrace, "data": {}}88 89 def get_register_context(self) -> str:90 return struct.pack(91 "21Q",92 1,93 2,94 3,95 4,96 5,97 6,98 7,99 8,100 9,101 10,102 11,103 12,104 13,105 14,106 15,107 16,108 17,109 18,110 19,111 20,112 21,113 )114 115 116class DummyScriptedFrame(ScriptedFrame):117 def __init__(self, thread, args, id, name, sym_ctx=None):118 super().__init__(thread, args)119 self.id = id120 self.name = name121 self.sym_ctx = sym_ctx122 123 def get_id(self):124 return self.id125 126 def get_function_name(self):127 return self.name128 129 def get_register_context(self) -> str:130 return struct.pack(131 "21Q",132 0x10001,133 0x10002,134 0x10003,135 0x10004,136 0x10005,137 0x10006,138 0x10007,139 0x10008,140 0x10009,141 0x100010,142 0x100011,143 0x100012,144 0x100013,145 0x100014,146 0x100015,147 0x100016,148 0x100017,149 0x100018,150 0x100019,151 0x100020,152 0x100021,153 )154 155 def get_symbol_context(self):156 def get_symbol_context_for_function(func_name):157 module = self.target.FindModule(self.target.GetExecutable())158 if not module.IsValid():159 return None160 161 sym_ctx_list = module.FindFunctions(func_name)162 if not sym_ctx_list.IsValid() or sym_ctx_list.GetSize() == 0:163 return None164 165 return sym_ctx_list.GetContextAtIndex(0)166 167 return (168 self.sym_ctx if self.sym_ctx else get_symbol_context_for_function(self.name)169 )170 171 def get_scripted_frame_plugin(self):172 return DummyScriptedFrame.__module__ + "." + DummyScriptedFrame.__name__173 174 175def __lldb_init_module(debugger, dict):176 # This is used when loading the script in an interactive debug session to177 # automatically, register the stop-hook and launch the scripted process.178 if not "SKIP_SCRIPTED_PROCESS_LAUNCH" in os.environ:179 debugger.HandleCommand(180 "target stop-hook add -k first -v 1 -k second -v 2 -P %s.%s"181 % (__name__, DummyStopHook.__name__)182 )183 debugger.HandleCommand(184 "process launch -C %s.%s" % (__name__, DummyScriptedProcess.__name__)185 )186 else:187 print(188 "Name of the class that will manage the scripted process: '%s.%s'"189 % (__name__, DummyScriptedProcess.__name__)190 )191 print(192 "Name of the class that will manage the stop-hook: '%s.%s'"193 % (__name__, DummyStopHook.__name__)194 )195