PyQBDIPreload
PyQBDIPreload is an implementation of QBDIPreload for PyQBDI. It allows users to inject the Python runtime into a target process and execute their own script in it. The limitations are pretty much the same as those we face on QBDIPreload and PyQBDI:
Only Linux and macOS are currently supported
The executable should be injectable with
LD_PRELOAD
orDYLD_INSERT_LIBRARIES
PyQBDIPreload cannot be injected in a Python process
The Python runtime and the target must share the same architecture
An extra
VM
must not be created. An already preparedVM
is provided topyqbdipreload_on_run()
.
Note
The Python library libpython3.x.so
must be installed.
Main hook process
Unlike QBDIPreload, the hook of the main function cannot be customised so you are unable to alter the hook process. The Python interpreter is only initialised once the main function is hooked and the script is loaded. Furthermore, some modifications are made on the environment of the interpreter before the user script loading:
sys.argv
are the argument of the executableLD_PRELOAD
orDYLD_INSERT_LIBRARIES
are removed fromos.environ
pyqbdi.__preload__
is set toTrue
Instrumentation
Once the script is loaded, the pyqbdipreload_on_run()
function is called with a ready-to-run VM
.
Any user callbacks should be registered to the VM
, then the VM can be run with pyqbdi.VM.run()
.
import pyqbdi
def instCallback(vm, gpr, fpr, data):
# User code ...
return pyqbdi.CONTINUE
def pyqbdipreload_on_run(vm, start, stop):
vm.addCodeCB(pyqbdi.PREINST, instCallback, None)
vm.run(start, stop)
Exit hook
The atexit
module is triggered when the execution is finished, or when exit
or _exit
are called.
Note
Any VM
object is invalided when the atexit
module is triggered and should never be used.
Execution
A script called pyqbdipreload.py
is brought to set the environment up and run the executable.
The first parameter is the PyQBDIPreload script. Next are the binary followed by its respective arguments if any.
python3 -m pyqbdipreload <script> <executable> [<arguments> ...]
Full example
Merging everything we have learnt throughout this tutorial, we are now able to write our Python script which prints the instructions that are being executed by the target executable.
#!/usr/bin/env python3
import pyqbdi
def showInstruction(vm, gpr, fpr, data):
instAnalysis = vm.getInstAnalysis()
print("0x{:x}: {}".format(instAnalysis.address, instAnalysis.disassembly))
return pyqbdi.CONTINUE
def pyqbdipreload_on_run(vm, start, stop):
vm.addCodeCB(pyqbdi.PREINST, showInstruction, None)
vm.run(start, stop)