-
Notifications
You must be signed in to change notification settings - Fork 755
API Reference
xwings edited this page Jul 6, 2025
·
5 revisions
This page provides comprehensive documentation for the Qiling Framework API.
The main class for all Qiling operations.
class Qiling:
def __init__(self, argv=None, rootfs=None, env=None, code=None,
ostype=None, archtype=None, bigendian=False,
verbose=QL_VERBOSE.DEFAULT, profile=None,
console=True, log_dir=None, libcache=False,
stdin=None, stdout=None, stderr=None,
multithread=False, filter=None, **kwargs)
Parameter | Type | Description |
---|---|---|
argv |
list[str] |
Command line arguments for binary emulation |
rootfs |
str |
Root filesystem path |
env |
dict |
Environment variables |
code |
bytes |
Shellcode for shellcode emulation |
ostype |
QL_OS |
Target OS type |
archtype |
QL_ARCH |
Target architecture |
bigendian |
bool |
Big endian architecture |
verbose |
QL_VERBOSE |
Verbosity level |
profile |
str |
Profile file path |
console |
bool |
Enable console output |
libcache |
bool |
Enable library caching |
multithread |
bool |
Enable multithreading |
Execution Control:
def run(self, begin=None, end=None, timeout=0, count=0)
"""Start emulation with optional constraints"""
def stop(self)
"""Stop emulation"""
def emu_start(self, begin, end, timeout=0, count=0)
"""Low-level emulation start"""
def emu_stop(self)
"""Low-level emulation stop"""
Memory Operations:
def mem_write(self, addr, data)
"""Write data to memory at address"""
def mem_read(self, addr, size)
"""Read data from memory"""
def mem_map(self, addr, size, perms=None, ptr=None)
"""Map memory region"""
def mem_unmap(self, addr, size)
"""Unmap memory region"""
def mem_protect(self, addr, size, perms)
"""Change memory protection"""
def mem_is_mapped(self, addr, size=1)
"""Check if memory is mapped"""
Patching:
def patch(self, addr, code, file_name=None)
"""Patch memory or file"""
def unpatch(self, addr)
"""Remove patch"""
Filesystem:
def add_fs_mapper(self, fm, to)
"""Map filesystem paths"""
def remove_fs_mapper(self, fm)
"""Remove filesystem mapping"""
Hooking:
def hook_address(self, callback, address, user_data=None)
"""Hook specific address"""
def hook_code(self, callback, user_data=None)
"""Hook all instructions"""
def hook_block(self, callback, user_data=None)
"""Hook basic blocks"""
def hook_mem_read(self, callback, user_data=None)
"""Hook memory reads"""
def hook_mem_write(self, callback, user_data=None)
"""Hook memory writes"""
def hook_mem_fetch(self, callback, user_data=None)
"""Hook memory fetches"""
def hook_intr(self, callback, user_data=None)
"""Hook interrupts"""
Register Access:
# Read registers
ql.arch.regs.rax # x86_64 RAX register
ql.arch.regs.eip # x86 EIP register
ql.arch.regs.r0 # ARM R0 register
# Write registers
ql.arch.regs.rax = 0x1234
ql.arch.regs.write("rax", 0x1234)
# Get all registers
all_regs = ql.arch.regs.save()
ql.arch.regs.restore(all_regs)
Architecture Information:
ql.arch.type # Architecture type
ql.arch.bits # Architecture bits (32/64)
ql.arch.endian # Endianness
ql.arch.get_pc() # Program counter
ql.arch.set_pc(addr) # Set program counter
ql.arch.get_sp() # Stack pointer
ql.arch.set_sp(addr) # Set stack pointer
File Operations:
ql.os.fd # File descriptor table
ql.os.fs_mapper # Filesystem mappings
ql.os.stdin # Standard input
ql.os.stdout # Standard output
ql.os.stderr # Standard error
Process Information:
ql.os.pid # Process ID
ql.os.ppid # Parent process ID
ql.os.uid # User ID
ql.os.gid # Group ID
ql.os.exit_code # Exit code
Threading:
ql.os.thread_management # Thread manager
ql.os.current_thread # Current thread
ql.os.main_thread # Main thread
Memory Operations:
def read(self, addr, size)
"""Read memory"""
def write(self, addr, data)
"""Write memory"""
def string(self, addr, encoding='utf-8')
"""Read null-terminated string"""
def map(self, addr, size, perms=UC_PROT_ALL, info=None)
"""Map memory region"""
def unmap(self, addr, size)
"""Unmap memory region"""
def protect(self, addr, size, perms)
"""Change memory permissions"""
def is_mapped(self, addr, size=1)
"""Check if memory is mapped"""
def align(self, addr, alignment=0x1000)
"""Align address"""
def get_mapinfo(self)
"""Get memory map information"""
Stack Operations:
def push(self, data)
"""Push data to stack"""
def pop(self)
"""Pop data from stack"""
def read_ptr(self, addr=None)
"""Read pointer from memory"""
def write_ptr(self, addr, value)
"""Write pointer to memory"""
QL_ARCH.X86 # 32-bit x86
QL_ARCH.X8664 # 64-bit x86
QL_ARCH.ARM # 32-bit ARM
QL_ARCH.ARM64 # 64-bit ARM
QL_ARCH.MIPS # MIPS
QL_ARCH.A8086 # 8086
QL_ARCH.CORTEX_M # Cortex-M
QL_ARCH.RISCV # RISC-V 32-bit
QL_ARCH.RISCV64 # RISC-V 64-bit
QL_ARCH.PPC # PowerPC
QL_OS.LINUX # Linux
QL_OS.WINDOWS # Windows
QL_OS.MACOS # macOS
QL_OS.FREEBSD # FreeBSD
QL_OS.UEFI # UEFI
QL_OS.DOS # DOS
QL_OS.QNX # QNX
QL_OS.MCU # Microcontroller
QL_OS.BLOB # Raw binary blob
QL_VERBOSE.OFF # No output
QL_VERBOSE.DEFAULT # Basic output
QL_VERBOSE.DEBUG # Debug information
QL_VERBOSE.DISASM # Include disassembly
QL_VERBOSE.DUMP # Memory dumps
QL_HOOK.CODE # Instruction hooks
QL_HOOK.BLOCK # Basic block hooks
QL_HOOK.MEM_READ # Memory read hooks
QL_HOOK.MEM_WRITE # Memory write hooks
QL_HOOK.MEM_FETCH # Memory fetch hooks
QL_HOOK.INTR # Interrupt hooks
UC_PROT_NONE # No access
UC_PROT_READ # Read only
UC_PROT_WRITE # Write only
UC_PROT_EXEC # Execute only
UC_PROT_ALL # Read/Write/Execute
ql.debugger = "qdb"
ql.run()
QDB provides an interactive debugging interface with commands like:
-
run
- Start execution -
step
- Single step -
continue
- Continue execution -
info reg
- Show registers -
x/10x $rsp
- Examine memory -
breakpoint 0x401000
- Set breakpoint
ql.debugger = "gdb:localhost:9999"
ql.run()
Connect external GDB to the server for advanced debugging.
Different loaders for various file formats:
# PE Loader (Windows)
from qiling.loader.pe import QlLoaderPE
# ELF Loader (Linux/Unix)
from qiling.loader.elf import QlLoaderELF
# Mach-O Loader (macOS)
from qiling.loader.macho import QlLoaderMACHO
# Access loader
ql.loader.load_address # Load address
ql.loader.entry_point # Entry point
ql.loader.images # Loaded images
ql.loader.import_symbols # Import table
ql.loader.export_symbols # Export table
def afl_fuzz_custom(ql, input_data, persistent_addr, exits):
# Custom AFL++ fuzzing logic
pass
ql.afl_fuzz(input_file, persistent_addr, exits, afl_fuzz_custom)
from qiling.extensions.trace import QlTracer
tracer = QlTracer(ql)
tracer.trace_func_call = True
tracer.trace_func_ret = True
ql.run()
from qiling.extensions.coverage import QlCoverage
cov = QlCoverage(ql)
ql.run()
coverage_data = cov.get_coverage()
from qiling.utils import *
# Address calculations
def align_up(addr, alignment)
def align_down(addr, alignment)
# Data conversions
def int_to_bytes(value, size, byteorder='little')
def bytes_to_int(data, byteorder='little')
# String utilities
def read_cstring(ql, addr)
def read_wstring(ql, addr)
from qiling.arch.utils import *
# Instruction utilities
def disasm(ql, code, addr)
def asm(ql, code, addr)
# Register utilities
def reg_read(ql, reg_name)
def reg_write(ql, reg_name, value)
def code_hook(ql, address, size):
"""Called for each instruction
Args:
ql: Qiling instance
address: Instruction address
size: Instruction size
"""
pass
def mem_hook(ql, access, address, size, value):
"""Called for memory access
Args:
ql: Qiling instance
access: Access type (UC_MEM_READ/WRITE/FETCH)
address: Memory address
size: Access size
value: Value (for writes)
"""
pass
def addr_hook(ql):
"""Called at specific address
Args:
ql: Qiling instance
"""
pass
def api_hook(ql, *args, **kwargs):
"""Called for hooked API
Args:
ql: Qiling instance
*args: API arguments
**kwargs: Additional parameters
Returns:
API return value or None for original behavior
"""
pass
from qiling.exception import *
QlErrorException # General Qiling error
QlMemoryMappedError # Memory mapping error
QlOutOfMemory # Out of memory
QlErrorFileNotFound # File not found
QlErrorArch # Architecture error
QlErrorOS # OS error
QlErrorExecutionStop # Execution stopped
from qiling import Qiling
from qiling.exception import QlErrorException
try:
ql = Qiling(['binary'], 'rootfs')
ql.run()
except QlErrorException as e:
print(f"Qiling error: {e}")
except Exception as e:
print(f"General error: {e}")
- Use
libcache=True
for Windows binaries - Enable multithread for multithreaded applications
- Use appropriate verbosity levels
- Consider memory mapping for large datasets
- Always use isolated rootfs directories
- Validate input data before emulation
- Monitor memory usage for potential DoS
- Use timeouts for long-running emulations
- Start with
QL_VERBOSE.DEBUG
for troubleshooting - Use hooks to track program flow
- Examine memory layout with
ql.mem.get_mapinfo()
- Check register states at critical points
# Registry access
ql.os.registry.read(key, value)
ql.os.registry.write(key, value, data)
# Handle table
ql.os.handle_manager.get(handle_id)
ql.os.handle_manager.create(obj)
# Thread management
ql.os.thread_manager.current_thread
# Process filesystem
ql.os.proc_fd_table
ql.os.proc_pid
# Signal handling
ql.os.signals
# Hardware peripherals
ql.hw.gpio
ql.hw.uart
ql.hw.timer
# Interrupt handling
ql.hw.nvic
For more detailed examples and advanced usage patterns, see the Advanced Usage guide.
- Home
- Getting Started
- Core Concepts
- Usage
- Features
- Tutorials
- Development
- Resources