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)