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:

 1class TritonVM(pyqbdl.TargetMemory):
 2    def __init__(self, ctx: TritonContext):
 3        super().__init__()
 4        self.ctx = ctx
 5
 6    def mmap(self, ptr, size):
 7        return ptr
 8
 9    def mprotect(self, ptr, size, access):
10        return True
11
12    def write(self, ptr, data):
13        self.ctx.setConcreteMemoryAreaValue(ptr, bytes(data))
14
15    def read(self, ptr, size):
16        return self.ctx.getConcreteMemoryAreaValue(ptr, size)
17
18class TritonSystem(pyqbdl.TargetSystem):
19    def __init__(self, arch, ctx):
20        super().__init__(TritonVM(ctx))
21        self.arch = arch
22        self.ctx = ctx
23
24    def symlink(self, loader, sym):
25        for name, impl, addr in externalFunctions:
26            if sym.name == name:
27                return addr
28        return 0
29
30    def supports(self, bin_):
31        return pyqbdl.Arch.from_bin(bin_) == self.arch
32
33    def base_address_hint(self, bin_ba, vsize):
34        return bin_ba
35
36x86_64_arch = pyqbdl.Arch(lief.ARCHITECTURES.X86, lief.ENDIANNESS.LITTLE, True)
37loader = pyqbdl.loaders.MachO.from_file(args.filename, x86_64_arch,
38                                        TritonSystem(x86_64_arch, ctx), pyqbdl.Loader.BIND.NOW)