| #!/usr/bin/env python3 | |
| # ---------------------------------------------------------------------- | |
| # Be sure to add the python path that points to the LLDB shared library. | |
| # On MacOSX csh, tcsh: | |
| # setenv PYTHONPATH /Developer/Library/PrivateFrameworks/LLDB.framework/Resources/Python | |
| # On MacOSX sh, bash: | |
| # export PYTHONPATH=/Developer/Library/PrivateFrameworks/LLDB.framework/Resources/Python | |
| # ---------------------------------------------------------------------- | |
| import lldb | |
| import os | |
| import sys | |
| def disassemble_instructions(insts): | |
| for i in insts: | |
| print(i) | |
| def usage(): | |
| print("Usage: disasm.py [-n name] executable-image") | |
| print(" By default, it breaks at and disassembles the 'main' function.") | |
| sys.exit(0) | |
| if len(sys.argv) == 2: | |
| fname = "main" | |
| exe = sys.argv[1] | |
| elif len(sys.argv) == 4: | |
| if sys.argv[1] != "-n": | |
| usage() | |
| else: | |
| fname = sys.argv[2] | |
| exe = sys.argv[3] | |
| else: | |
| usage() | |
| # Create a new debugger instance | |
| debugger = lldb.SBDebugger.Create() | |
| # When we step or continue, don't return from the function until the process | |
| # stops. We do this by setting the async mode to false. | |
| debugger.SetAsync(False) | |
| # Create a target from a file and arch | |
| print("Creating a target for '%s'" % exe) | |
| target = debugger.CreateTargetWithFileAndArch(exe, lldb.LLDB_ARCH_DEFAULT) | |
| if target: | |
| # If the target is valid set a breakpoint at main | |
| main_bp = target.BreakpointCreateByName(fname, target.GetExecutable().GetFilename()) | |
| print(main_bp) | |
| # Launch the process. Since we specified synchronous mode, we won't return | |
| # from this function until we hit the breakpoint at main | |
| process = target.LaunchSimple(None, None, os.getcwd()) | |
| # Make sure the launch went ok | |
| if process: | |
| # Print some simple process info | |
| state = process.GetState() | |
| print(process) | |
| if state == lldb.eStateStopped: | |
| # Get the first thread | |
| thread = process.GetThreadAtIndex(0) | |
| if thread: | |
| # Print some simple thread info | |
| print(thread) | |
| # Get the first frame | |
| frame = thread.GetFrameAtIndex(0) | |
| if frame: | |
| # Print some simple frame info | |
| print(frame) | |
| function = frame.GetFunction() | |
| # See if we have debug info (a function) | |
| if function: | |
| # We do have a function, print some info for the | |
| # function | |
| print(function) | |
| # Now get all instructions for this function and print | |
| # them | |
| insts = function.GetInstructions(target) | |
| disassemble_instructions(insts) | |
| else: | |
| # See if we have a symbol in the symbol table for where | |
| # we stopped | |
| symbol = frame.GetSymbol() | |
| if symbol: | |
| # We do have a symbol, print some info for the | |
| # symbol | |
| print(symbol) | |
| # Now get all instructions for this symbol and | |
| # print them | |
| insts = symbol.GetInstructions(target) | |
| disassemble_instructions(insts) | |
| registerList = frame.GetRegisters() | |
| print( | |
| "Frame registers (size of register set = %d):" | |
| % registerList.GetSize() | |
| ) | |
| for value in registerList: | |
| # print value | |
| print( | |
| "%s (number of children = %d):" | |
| % (value.GetName(), value.GetNumChildren()) | |
| ) | |
| for child in value: | |
| print( | |
| "Name: ", child.GetName(), " Value: ", child.GetValue() | |
| ) | |
| print( | |
| "Hit the breakpoint at main, enter to continue and wait for program to exit or 'Ctrl-D'/'quit' to terminate the program" | |
| ) | |
| next = sys.stdin.readline() | |
| if not next or next.rstrip("\n") == "quit": | |
| print("Terminating the inferior process...") | |
| process.Kill() | |
| else: | |
| # Now continue to the program exit | |
| process.Continue() | |
| # When we return from the above function we will hopefully be at the | |
| # program exit. Print out some process info | |
| print(process) | |
| elif state == lldb.eStateExited: | |
| print("Didn't hit the breakpoint at main, program has exited...") | |
| else: | |
| print( | |
| "Unexpected process state: %s, killing process..." | |
| % debugger.StateAsCString(state) | |
| ) | |
| process.Kill() | |
| lldb.SBDebugger.Terminate() |