Binary loading
Before doing anything with a quokka file, you need to load it.
Tip
For the remaining of this tutorial, I will be using an interactive IPython shell.
To load a program, quokka needs both the export file and the original
binary. Indeed, to reduce the size of the export, information directly available
in the binary are not exported.
import quokka
from pathlib import Path
samples = Path('docs/samples')
assert samples.is_dir(), "You should run this code in Quokka main directory"
prog = quokka.Program(samples / "qb-crackme.quokka", samples / "qb-crackme")
# Let's check if it worked
print(f'Program base address is 0x{prog.base_address:x}')
# Should print: Program base address is 0x8048000.
Explore a bit the Program object
We now have in prog a complete program representation.
Using dir(prog), you can see the different possibilities.
For instance, you can list the functions found in the program using:
import quokka
prog = quokka.Program("docs/samples/qb-crackme.quokka", "docs/samples/qb-crackme")
print(f"Found {len(prog)} functions in {prog.export_file.stem}")
Using the protobuf directly
Of note, the protobuf generated by the plugin is available in prog.proto.
You should not access it directly because it's a rather compact format not
well documented.
Export and load
If a disassembler plugin is installed (IDA with the Quokka plugin, or Ghidra with the QuokkaExporter extension), you can export and load directly using the from_binary method.
import quokka
prog = quokka.Program.from_binary('docs/samples/qb-crackme')
assert prog is not None, "Unable to export qb-crackme"
Tips & tricks
When using IDA, the database (.i64) is stored next to the binary file by default.
This is not convenient when dealing with read-only filesystems.
Use the database_file and output_file options to control where files should be stored.
import quokka
prog = quokka.Program.from_binary('/bin/ls')
# May fail because /bin is not writable (IDA stores the database there by default)
prog = quokka.Program.from_binary('/bin/ls',
output_file='docs/samples/ls.quokka',
database_file='docs/samples/ls.i64')
assert prog is not None, "Unable to export ls"
The debug parameter of the same method will control the output. One of its
effect is that it will print the exporter output and the command used to launch
it.