|  | #!/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() |