140 lines · python
1#!/usr/bin/env python2 3# ----------------------------------------------------------------------4# Be sure to add the python path that points to the LLDB shared library.5# On MacOSX csh, tcsh:6# setenv PYTHONPATH /Developer/Library/PrivateFrameworks/LLDB.framework/Resources/Python7# On MacOSX sh, bash:8# export PYTHONPATH=/Developer/Library/PrivateFrameworks/LLDB.framework/Resources/Python9# ----------------------------------------------------------------------10 11import lldb12import os13import sys14 15 16def disassemble_instructions(insts):17 for i in insts:18 print(i)19 20 21def usage():22 print("Usage: disasm.py [-n name] executable-image")23 print(" By default, it breaks at and disassembles the 'main' function.")24 sys.exit(0)25 26 27if len(sys.argv) == 2:28 fname = "main"29 exe = sys.argv[1]30elif len(sys.argv) == 4:31 if sys.argv[1] != "-n":32 usage()33 else:34 fname = sys.argv[2]35 exe = sys.argv[3]36else:37 usage()38 39# Create a new debugger instance40debugger = lldb.SBDebugger.Create()41 42# When we step or continue, don't return from the function until the process43# stops. We do this by setting the async mode to false.44debugger.SetAsync(False)45 46# Create a target from a file and arch47print("Creating a target for '%s'" % exe)48 49target = debugger.CreateTargetWithFileAndArch(exe, lldb.LLDB_ARCH_DEFAULT)50 51if target:52 # If the target is valid set a breakpoint at main53 main_bp = target.BreakpointCreateByName(fname, target.GetExecutable().GetFilename())54 55 print(main_bp)56 57 # Launch the process. Since we specified synchronous mode, we won't return58 # from this function until we hit the breakpoint at main59 process = target.LaunchSimple(None, None, os.getcwd())60 61 # Make sure the launch went ok62 if process:63 # Print some simple process info64 state = process.GetState()65 print(process)66 if state == lldb.eStateStopped:67 # Get the first thread68 thread = process.GetThreadAtIndex(0)69 if thread:70 # Print some simple thread info71 print(thread)72 # Get the first frame73 frame = thread.GetFrameAtIndex(0)74 if frame:75 # Print some simple frame info76 print(frame)77 function = frame.GetFunction()78 # See if we have debug info (a function)79 if function:80 # We do have a function, print some info for the81 # function82 print(function)83 # Now get all instructions for this function and print84 # them85 insts = function.GetInstructions(target)86 disassemble_instructions(insts)87 else:88 # See if we have a symbol in the symbol table for where89 # we stopped90 symbol = frame.GetSymbol()91 if symbol:92 # We do have a symbol, print some info for the93 # symbol94 print(symbol)95 # Now get all instructions for this symbol and96 # print them97 insts = symbol.GetInstructions(target)98 disassemble_instructions(insts)99 100 registerList = frame.GetRegisters()101 print(102 "Frame registers (size of register set = %d):"103 % registerList.GetSize()104 )105 for value in registerList:106 # print value107 print(108 "%s (number of children = %d):"109 % (value.GetName(), value.GetNumChildren())110 )111 for child in value:112 print(113 "Name: ", child.GetName(), " Value: ", child.GetValue()114 )115 116 print(117 "Hit the breakpoint at main, enter to continue and wait for program to exit or 'Ctrl-D'/'quit' to terminate the program"118 )119 next = sys.stdin.readline()120 if not next or next.rstrip("\n") == "quit":121 print("Terminating the inferior process...")122 process.Kill()123 else:124 # Now continue to the program exit125 process.Continue()126 # When we return from the above function we will hopefully be at the127 # program exit. Print out some process info128 print(process)129 elif state == lldb.eStateExited:130 print("Didn't hit the breakpoint at main, program has exited...")131 else:132 print(133 "Unexpected process state: %s, killing process..."134 % debugger.StateAsCString(state)135 )136 process.Kill()137 138 139lldb.SBDebugger.Terminate()140