Getting Started
Getting Started
Initializing Qiling
Binary Emulation
1ql = Qiling(argv, rootfs, **kwargs)
| Parameter | Type | Description |
|---|---|---|
argv | Sequence[str] | Command line arguments; first element is the binary path |
rootfs | str | Emulated filesystem root; all paths accessed by the binary are relative to this |
env | MutableMapping | Environment 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)
| Parameter | Type | Values |
|---|---|---|
code | bytes | Raw shellcode bytes (replaces argv) |
ostype | QL_OS | LINUX, FREEBSD, MACOS, WINDOWS, UEFI, DOS, QNX, MCU, BLOB |
archtype | QL_ARCH | X86, X8664, ARM, ARM64, MIPS, A8086, CORTEX_M, RISCV, RISCV64, PPC |
endian | bool | Endianness (ARM and MIPS only) |
thumb | bool | ARM Thumb mode |
Common Parameters
| Parameter | Type | Description |
|---|---|---|
cputype | QL_CPU | Underlying CPU model for feature availability |
verbose | QL_VERBOSE | Logging verbosity (default: QL_VERBOSE.DEFAULT) |
profile | str | Path to .ql profile file with additional settings |
log_devices | Collection[IO|str] | Log output targets (default: stderr) |
log_override | Logger | Custom logger instance |
log_plain | bool | Disable color in log output |
multithread | bool | Enable multi-threaded emulation |
libcache | bool | Cache 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()