Skip to content

Instantly share code, notes, and snippets.

@tahaconfiant
Created December 10, 2019 08:40
Show Gist options
  • Save tahaconfiant/e2b8a51ae73c1e8b88e8cc2aa3b4a462 to your computer and use it in GitHub Desktop.
Save tahaconfiant/e2b8a51ae73c1e8b88e8cc2aa3b4a462 to your computer and use it in GitHub Desktop.
bundlore_python_dump
# by [email protected]
# LLDB custom command to dump OSX/Bundlore Loader python payload
# tested on $lldb --version
# lldb-1100.0.30.6
# Apple Swift version 5.1.2 (swiftlang-1100.0.278 clang-1100.0.33.9)
# (lldb) script
# Python Interactive Interpreter. To exit, type 'quit()', 'exit()' or Ctrl-D.
# >>> import sys
# >>> print(sys.version)
# 3.7.3 (default, Sep 5 2019, 17:14:41)
# [Clang 11.0.0 (clang-1100.0.33.8)]
# Can be run via :
# (lldb) command import script /path/to/bundlore_python_dump.py
# (lldb) bundlore_python_dump
# (lldb) r
import lldb
import time
def custom_breakpoints(debugger, command, result, internal_dict):
target = debugger.GetSelectedTarget()
breakpoint = target.BreakpointCreateByName("write", "libsystem_kernel.dylib")
breakpoint.SetScriptCallbackFunction('bundlore_python_dump.write_callback')
breakpoint = target.BreakpointCreateByName("waitpid")
breakpoint.SetScriptCallbackFunction('bundlore_python_dump.waitpid_callback')
def write_callback(frame, bp_loc, dict):
print ("write() detected!")
print ("dumping python code from $rsi register")
memory_address = 0
registerSet = frame.GetRegisters() # Returns an SBValueList.
for regs in registerSet:
if 'general purpose registers' in regs.name.lower():
GPRs = regs
break
print('%s (number of children = %d):' % (GPRs.name, GPRs.num_children))
for reg in GPRs:
if reg.name == "rsi":
memory_address = int(reg.value, 0)
bytes_count = 0
if memory_address:
error = lldb.SBError()
while frame.thread.process.ReadUnsignedFromMemory(memory_address, 1, error):
c = frame.thread.process.ReadUnsignedFromMemory(memory_address, 1, error)
open('/tmp/dumped.py', 'ab').write(bytes([c]))
memory_address += 1
bytes_count +=1
if error.Success():
print("sucessfully written %i bytes" % bytes_count)
else:
print('error: %s\n' % error)
else:
print ('error getting memory address')
frame.thread.process.Continue()
def waitpid_callback(frame, bp_loc, dict):
print ("waitpid() detected!")
print ("bundlore_python_dump has finished, dumped python code is here: /tmp/dumped.py")
frame.thread.process.Stop()
frame.thread.process.Kill()
def __lldb_init_module(debugger, internal_dict):
debugger.HandleCommand('command script add -f bundlore_python_dump.custom_breakpoints bundlore_python_dump')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment