| #!/usr/bin/env python |
| |
| # ---------------------------------------------------------------------- |
| # 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() |