Getting Started

Getting Started

Initializing Qiling

Binary Emulation

1ql = Qiling(argv, rootfs, **kwargs)
ParameterTypeDescription
argvSequence[str]Command line arguments; first element is the binary path
rootfsstrEmulated filesystem root; all paths accessed by the binary are relative to this
envMutableMappingEnvironment variables (optional)

Qiling auto-detects OS and architecture from the binary. Do not use the host root / as rootfs.

Shellcode Emulation

1ql = Qiling(code=shellcode, rootfs=..., ostype=QL_OS.LINUX, archtype=QL_ARCH.X8664, **kwargs)
ParameterTypeValues
codebytesRaw shellcode bytes (replaces argv)
ostypeQL_OSLINUX, FREEBSD, MACOS, WINDOWS, UEFI, DOS, QNX, MCU, BLOB
archtypeQL_ARCHX86, X8664, ARM, ARM64, MIPS, A8086, CORTEX_M, RISCV, RISCV64, PPC
endianboolEndianness (ARM and MIPS only)
thumbboolARM Thumb mode

Common Parameters

ParameterTypeDescription
cputypeQL_CPUUnderlying CPU model for feature availability
verboseQL_VERBOSELogging verbosity (default: QL_VERBOSE.DEFAULT)
profilestrPath to .ql profile file with additional settings
log_devicesCollection[IO|str]Log output targets (default: stderr)
log_overrideLoggerCustom logger instance
log_plainboolDisable color in log output
multithreadboolEnable multi-threaded emulation
libcacheboolCache library loading (Windows only)

Configuration

Filesystem Mapping

1# Map host path to virtual path
2ql.add_fs_mapper(r'/dev/random', r'/dev/zero')
3
4# Map virtual path to custom file object (must extend QlFsMappedObject)
5ql.add_fs_mapper(r'/dev/urandom', FakeUrandom())

Memory Patching

1# Overwrite bytes at a loaded address (x86 nop-sled example)
2ql.patch(0x401100, b'\x90' * 8)

Debugger

1ql.debugger = True                      # GDB server on localhost:9999
2ql.debugger = "127.0.0.1:9999"         # GDB server on specific address
3ql.debugger = "idapro:127.0.0.1:9999"  # IDA Pro remote debug
4ql.debugger = "qdb"                     # Built-in Qdb

Running Emulation

1ql.run()
2
3# With fine-grained control:
4ql.run(
5    begin=0x401000,      # first instruction address
6    end=0x401100,        # stop address (exclusive)
7    timeout=1000000,     # max time in microseconds
8    count=100            # max instruction count
9)

When using begin/end to focus on a function, manually initialize registers/stack to simulate the calling context that was skipped.

Complete Examples

Binary Emulation

1from qiling import Qiling
2from qiling.const import QL_VERBOSE
3
4argv = r'examples/rootfs/netgear_r6220/bin/mini_httpd -d /www -r NETGEAR -c **.cgi -t 300'.split()
5ql = Qiling(argv, r'examples/rootfs/netgear_r6220', verbose=QL_VERBOSE.DEBUG, profile='netgear.ql')
6ql.add_fs_mapper('/proc', '/proc')
7ql.run()

Profile file netgear.ql:

1[MIPS]
2mmap_address = 0x7f7ee000

Shellcode Emulation

 1from qiling import Qiling
 2from qiling.const import QL_ARCH, QL_OS, QL_VERBOSE
 3
 4shellcode = bytes.fromhex('fc4881e4f0ffffff...')
 5ql = Qiling(
 6    code=shellcode,
 7    rootfs=r'examples/rootfs/x8664_windows',
 8    archtype=QL_ARCH.X8664,
 9    ostype=QL_OS.WINDOWS,
10    verbose=QL_VERBOSE.DEBUG
11)
12ql.run()