2010-10-06 11:53:16 +08:00
|
|
|
#!/usr/bin/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
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2010-10-06 11:53:16 +08:00
|
|
|
def disassemble_instructions(insts):
|
2011-04-29 07:26:17 +08:00
|
|
|
for i in insts:
|
2019-03-22 02:27:40 +08:00
|
|
|
print(i)
|
2010-10-06 11:53:16 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2011-05-26 06:29:23 +08:00
|
|
|
def usage():
|
2019-03-22 02:27:40 +08:00
|
|
|
print("Usage: disasm.py [-n name] executable-image")
|
|
|
|
print(" By default, it breaks at and disassembles the 'main' function.")
|
2011-05-26 06:29:23 +08:00
|
|
|
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()
|
|
|
|
|
2010-10-06 11:53:16 +08:00
|
|
|
# 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
|
2019-03-22 02:27:40 +08:00
|
|
|
print("Creating a target for '%s'" % exe)
|
2010-10-07 12:19:01 +08:00
|
|
|
|
2011-05-26 06:29:23 +08:00
|
|
|
target = debugger.CreateTargetWithFileAndArch(exe, lldb.LLDB_ARCH_DEFAULT)
|
2010-10-06 11:53:16 +08:00
|
|
|
|
2011-05-26 04:48:29 +08:00
|
|
|
if target:
|
2010-10-06 11:53:16 +08:00
|
|
|
# If the target is valid set a breakpoint at main
|
2011-05-26 06:29:23 +08:00
|
|
|
main_bp = target.BreakpointCreateByName(
|
|
|
|
fname, target.GetExecutable().GetFilename())
|
2010-10-07 12:19:01 +08:00
|
|
|
|
2019-03-22 02:27:40 +08:00
|
|
|
print(main_bp)
|
2010-10-07 12:19:01 +08:00
|
|
|
|
2010-10-06 11:53:16 +08:00
|
|
|
# Launch the process. Since we specified synchronous mode, we won't return
|
|
|
|
# from this function until we hit the breakpoint at main
|
2011-05-26 04:56:32 +08:00
|
|
|
process = target.LaunchSimple(None, None, os.getcwd())
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2010-10-06 11:53:16 +08:00
|
|
|
# Make sure the launch went ok
|
2011-05-26 04:48:29 +08:00
|
|
|
if process:
|
2010-10-06 11:53:16 +08:00
|
|
|
# Print some simple process info
|
2010-10-07 12:19:01 +08:00
|
|
|
state = process.GetState()
|
2019-03-22 02:27:40 +08:00
|
|
|
print(process)
|
2010-10-07 12:19:01 +08:00
|
|
|
if state == lldb.eStateStopped:
|
|
|
|
# Get the first thread
|
|
|
|
thread = process.GetThreadAtIndex(0)
|
2011-05-26 04:48:29 +08:00
|
|
|
if thread:
|
2010-10-07 12:19:01 +08:00
|
|
|
# Print some simple thread info
|
2019-03-22 02:27:40 +08:00
|
|
|
print(thread)
|
2010-10-07 12:19:01 +08:00
|
|
|
# Get the first frame
|
|
|
|
frame = thread.GetFrameAtIndex(0)
|
2011-05-26 04:48:29 +08:00
|
|
|
if frame:
|
2010-10-07 12:19:01 +08:00
|
|
|
# Print some simple frame info
|
2019-03-22 02:27:40 +08:00
|
|
|
print(frame)
|
2010-10-07 12:19:01 +08:00
|
|
|
function = frame.GetFunction()
|
|
|
|
# See if we have debug info (a function)
|
2011-05-26 04:48:29 +08:00
|
|
|
if function:
|
2010-10-07 12:19:01 +08:00
|
|
|
# We do have a function, print some info for the
|
|
|
|
# function
|
2019-03-22 02:27:40 +08:00
|
|
|
print(function)
|
2010-10-07 12:19:01 +08:00
|
|
|
# Now get all instructions for this function and print
|
|
|
|
# them
|
|
|
|
insts = function.GetInstructions(target)
|
2010-10-06 11:53:16 +08:00
|
|
|
disassemble_instructions(insts)
|
2010-10-07 12:19:01 +08:00
|
|
|
else:
|
|
|
|
# See if we have a symbol in the symbol table for where
|
|
|
|
# we stopped
|
|
|
|
symbol = frame.GetSymbol()
|
2011-05-26 04:48:29 +08:00
|
|
|
if symbol:
|
2010-10-07 12:19:01 +08:00
|
|
|
# We do have a symbol, print some info for the
|
|
|
|
# symbol
|
2019-03-22 02:27:40 +08:00
|
|
|
print(symbol)
|
2010-10-07 12:19:01 +08:00
|
|
|
# Now get all instructions for this symbol and
|
|
|
|
# print them
|
|
|
|
insts = symbol.GetInstructions(target)
|
|
|
|
disassemble_instructions(insts)
|
2011-03-30 09:55:23 +08:00
|
|
|
|
|
|
|
registerList = frame.GetRegisters()
|
2019-03-22 02:27:40 +08:00
|
|
|
print("Frame registers (size of register set = %d):" % registerList.GetSize())
|
2011-04-29 07:26:17 +08:00
|
|
|
for value in registerList:
|
|
|
|
# print value
|
2019-03-22 02:27:40 +08:00
|
|
|
print("%s (number of children = %d):" % (value.GetName(), value.GetNumChildren()))
|
2011-04-29 07:26:17 +08:00
|
|
|
for child in value:
|
2019-03-22 02:27:40 +08:00
|
|
|
print("Name: ", child.GetName(), " Value: ", child.GetValue())
|
2011-03-30 09:55:23 +08:00
|
|
|
|
2019-03-22 02:27:40 +08:00
|
|
|
print("Hit the breakpoint at main, enter to continue and wait for program to exit or 'Ctrl-D'/'quit' to terminate the program")
|
2011-05-26 06:01:16 +08:00
|
|
|
next = sys.stdin.readline()
|
|
|
|
if not next or next.rstrip('\n') == 'quit':
|
2019-03-22 02:27:40 +08:00
|
|
|
print("Terminating the inferior process...")
|
2011-05-26 06:01:16 +08:00
|
|
|
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
|
2019-03-22 02:27:40 +08:00
|
|
|
print(process)
|
2010-10-07 12:19:01 +08:00
|
|
|
elif state == lldb.eStateExited:
|
2019-03-22 02:27:40 +08:00
|
|
|
print("Didn't hit the breakpoint at main, program has exited...")
|
2010-10-07 12:19:01 +08:00
|
|
|
else:
|
2019-03-22 02:27:40 +08:00
|
|
|
print("Unexpected process state: %s, killing process..." % debugger.StateAsCString(state))
|
2010-10-07 12:19:01 +08:00
|
|
|
process.Kill()
|
|
|
|
|
2010-10-06 11:53:16 +08:00
|
|
|
|
|
|
|
lldb.SBDebugger.Terminate()
|