QBDL

June 3, 2021

QBDL (QuarkslaB Dynamic Loader) is a cross-platform library that enables to load ELF, PE and Mach-O binaries with an abstraction on the targeted system. It abstracts the memory model on which the binary is loaded and provides an enhanced API to the user to process symbols resolution. In a nutshell, it enables to load binaries on foreign systems without reinventing the wheel.

Here is an example to load a Mach-O in Triton with QBDL:

class TritonVM(pyqbdl.TargetMemory):
    def __init__(self, ctx: TritonContext):
        super().__init__()
        self.ctx = ctx

    def mmap(self, ptr, size):
        return ptr

    def mprotect(self, ptr, size, access):
        return True

    def write(self, ptr, data):
        self.ctx.setConcreteMemoryAreaValue(ptr, bytes(data))

    def read(self, ptr, size):
        return self.ctx.getConcreteMemoryAreaValue(ptr, size)

class TritonSystem(pyqbdl.TargetSystem):
    def __init__(self, arch, ctx):
        super().__init__(TritonVM(ctx))
        self.arch = arch
        self.ctx = ctx

    def symlink(self, loader, sym):
        for name, impl, addr in externalFunctions:
            if sym.name == name:
                return addr
        return 0

    def supports(self, bin_):
        return pyqbdl.Arch.from_bin(bin_) == self.arch

    def base_address_hint(self, bin_ba, vsize):
        return bin_ba

x86_64_arch = pyqbdl.Arch(lief.ARCHITECTURES.X86, lief.ENDIANNESS.LITTLE, True)
loader = pyqbdl.loaders.MachO.from_file(args.filename, x86_64_arch,
                                        TritonSystem(x86_64_arch, ctx), pyqbdl.Loader.BIND.NOW)