-
Notifications
You must be signed in to change notification settings - Fork 755
API Reference
Comprehensive API documentation for the Qiling Framework based on complete codebase analysis.
- Core Classes
- Constants and Enums
- Hook System
- Memory Management
- Architecture Layer
- Operating System Layer
- Loader System
- Hardware Layer (MCU)
- Debugging APIs
- Extensions
- Utilities
- Error Handling
The main emulation engine class that provides the primary interface for binary emulation.
Location: qiling/core.py:35
Inheritance: QlCoreHooks
, QlCoreStructs
def __init__(self,
argv: Sequence[str] = [],
rootfs: str = r'.',
env: MutableMapping[AnyStr, AnyStr] = {},
code: Optional[bytes] = None,
ostype: Optional[QL_OS] = None,
archtype: Optional[QL_ARCH] = None,
cputype: Optional[QL_CPU] = None,
verbose: QL_VERBOSE = QL_VERBOSE.DEFAULT,
profile: Optional[Union[str, Mapping]] = None,
console: bool = True,
log_devices: Optional[Collection[Union[IO, str]]] = None,
log_override: Optional['Logger'] = None,
log_plain: bool = False,
multithread: bool = False,
filter: Optional[str] = None,
stop: QL_STOP = QL_STOP.NONE,
*,
endian: Optional[QL_ENDIAN] = None,
thumb: bool = False,
libcache: bool = False
)
Property | Type | Description |
---|---|---|
mem |
QlMemoryManager |
Memory management interface |
hw |
QlHwManager |
Hardware management (MCU only) |
arch |
QlArch |
Architecture layer |
loader |
QlLoader |
Loader layer |
os |
QlOs |
Operating system layer |
log |
Logger |
Logging interface |
uc |
Uc |
Raw Unicorn engine instance |
Execution Control:
def run(self, begin=None, end=None, timeout=0, count=0):
"""Start emulation with optional constraints
Args:
begin: Start address (None for entry point)
end: End address (None for natural termination)
timeout: Timeout in microseconds (0 for no timeout)
count: Maximum instruction count (0 for unlimited)
"""
def stop(self):
"""Graceful stop of emulation"""
def emu_start(self, begin, end, timeout=0, count=0):
"""Low-level emulation start (Unicorn interface)"""
def emu_stop(self):
"""Low-level emulation stop (Unicorn interface)"""
Memory Operations:
def patch(self, offset, data, target=None):
"""Patch binary or library
Args:
offset: Offset in binary/library
data: Patch data
target: Target binary/library (None for main binary)
"""
State Management:
def save(self, **kwargs):
"""Save complete emulation state
Returns:
Dict containing saved state
"""
def restore(self, saved_states, snapshot=None):
"""Restore emulation state
Args:
saved_states: Saved state dictionary
snapshot: Optional snapshot name
"""
Stack Operations:
def stack_push(self, data):
"""Push data to stack
Args:
data: Data to push (int or bytes)
"""
def stack_pop(self):
"""Pop data from stack
Returns:
Popped data as integer
"""
def stack_read(self, offset):
"""Read from stack at offset
Args:
offset: Offset from stack pointer
Returns:
Read data
"""
def stack_write(self, offset, data):
"""Write to stack at offset
Args:
offset: Offset from stack pointer
data: Data to write
"""
class QL_ARCH(IntEnum):
X86 = 101 # 32-bit Intel x86
X8664 = 102 # 64-bit Intel x86-64
ARM = 103 # ARM 32-bit
ARM64 = 105 # ARM 64-bit (AArch64)
MIPS = 106 # MIPS 32-bit
A8086 = 107 # Intel 8086
CORTEX_M = 109 # ARM Cortex-M
RISCV = 110 # RISC-V 32-bit
RISCV64 = 111 # RISC-V 64-bit
PPC = 112 # PowerPC
class QL_OS(IntEnum):
LINUX = 201 # Linux
FREEBSD = 202 # FreeBSD
MACOS = 203 # macOS
WINDOWS = 204 # Windows
UEFI = 205 # UEFI
DOS = 206 # MS-DOS
QNX = 208 # QNX Neutrino
MCU = 209 # Microcontroller
BLOB = 210 # Raw binary blob
class QL_VERBOSE(IntEnum):
DISABLED = -1 # Completely disabled
OFF = 0 # No output
DEFAULT = 1 # Basic output
DEBUG = 4 # Debug information
DISASM = 10 # Include disassembly
DUMP = 20 # Memory dumps
class QL_ENDIAN(IntEnum):
EL = 1 # Little endian
EB = 2 # Big endian
class QL_STOP(IntEnum):
NONE = 0 # No special stop condition
STACK_POINTER = 1 # Stop on stack pointer issues
EXIT_TRAP = 2 # Stop on exit trap
class QL_STATE(IntEnum):
NOT_SET = 0 # Not initialized
STARTED = 1 # Emulation started
STOPPED = 2 # Emulation stopped
class QL_INTERCEPT(IntEnum):
CALL = 1 # Intercept function calls
ENTER = 2 # Intercept function entry
EXIT = 3 # Intercept function exit
def hook_code(self, callback, user_data=None, begin=1, end=0):
"""Hook instruction execution
Args:
callback: Hook callback function
user_data: Optional user data
begin: Start address (1 for all)
end: End address (0 for all)
Returns:
Hook handle for removal
"""
def hook_block(self, callback, user_data=None, begin=1, end=0):
"""Hook basic block execution
Args:
callback: Hook callback function
user_data: Optional user data
begin: Start address range
end: End address range
"""
def hook_address(self, callback, address, user_data=None):
"""Hook specific address
Args:
callback: Hook callback function
address: Specific address to hook
user_data: Optional user data
"""
def hook_intno(self, callback, intno, user_data=None):
"""Hook interrupt number
Args:
callback: Hook callback function
intno: Interrupt number
user_data: Optional user data
"""
def hook_mem_read(self, callback, user_data=None, begin=1, end=0):
"""Hook memory read operations"""
def hook_mem_write(self, callback, user_data=None, begin=1, end=0):
"""Hook memory write operations"""
def hook_mem_fetch(self, callback, user_data=None, begin=1, end=0):
"""Hook memory fetch operations (instruction fetches)"""
def hook_mem_valid(self, callback, user_data=None, begin=1, end=0):
"""Hook valid memory access"""
def hook_mem_invalid(self, callback, user_data=None, begin=1, end=0):
"""Hook invalid memory access"""
def hook_mem_unmapped(self, callback, user_data=None, begin=1, end=0):
"""Hook unmapped memory access"""
def hook_del(self, hret):
"""Remove hook
Args:
hret: Hook handle returned from hook_* methods
"""
def clear_hooks(self):
"""Remove all hooks"""
# Memory hook callback
def mem_hook_callback(ql, access, address, size, value, *context):
"""Memory hook callback
Args:
ql: Qiling instance
access: Access type (UC_MEM_READ/WRITE/FETCH)
address: Memory address
size: Access size
value: Value (for writes)
*context: Additional context
"""
# Code/block hook callback
def trace_hook_callback(ql, address, size, *context):
"""Trace hook callback
Args:
ql: Qiling instance
address: Instruction/block address
size: Instruction/block size
*context: Additional context
"""
# Address-specific hook callback
def address_hook_callback(ql, *context):
"""Address hook callback
Args:
ql: Qiling instance
*context: Additional context
"""
# Interrupt hook callback
def interrupt_hook_callback(ql, intno, *context):
"""Interrupt hook callback
Args:
ql: Qiling instance
intno: Interrupt number
*context: Additional context
"""
Location: qiling/os/memory.py:23
def read(self, addr, size):
"""Read bytes from memory
Args:
addr: Memory address
size: Number of bytes to read
Returns:
bytes: Read data
"""
def write(self, addr, data):
"""Write bytes to memory
Args:
addr: Memory address
data: Data to write (bytes)
"""
def read_ptr(self, addr, size=0, signed=False):
"""Read pointer value from memory
Args:
addr: Memory address
size: Pointer size (0 for architecture default)
signed: Whether to interpret as signed
Returns:
int: Pointer value
"""
def write_ptr(self, addr, value, size=0, signed=False):
"""Write pointer value to memory
Args:
addr: Memory address
value: Pointer value to write
size: Pointer size (0 for architecture default)
signed: Whether to interpret as signed
"""
def map(self, addr, size, perms=UC_PROT_ALL, info=None):
"""Map memory region
Args:
addr: Base address
size: Region size
perms: Memory permissions
info: Optional description
"""
def map_anywhere(self, size, minaddr=None, maxaddr=None, align=None, perms=UC_PROT_ALL, info=None):
"""Map memory at any available location
Args:
size: Region size
minaddr: Minimum address
maxaddr: Maximum address
align: Alignment requirement
perms: Memory permissions
info: Optional description
Returns:
int: Allocated address
"""
def map_mmio(self, addr, size, read_cb, write_cb, info='[mmio]'):
"""Map memory-mapped I/O region
Args:
addr: Base address
size: Region size
read_cb: Read callback function
write_cb: Write callback function
info: Optional description
"""
def unmap(self, addr, size):
"""Unmap memory region
Args:
addr: Base address
size: Region size
"""
def unmap_between(self, mem_s, mem_e):
"""Unmap memory in range
Args:
mem_s: Start address
mem_e: End address
"""
def unmap_all(self):
"""Unmap all memory regions"""
def align(self, value, alignment=None):
"""Align value down to boundary
Args:
value: Value to align
alignment: Alignment boundary (page size if None)
Returns:
int: Aligned value
"""
def align_up(self, value, alignment=None):
"""Align value up to boundary
Args:
value: Value to align
alignment: Alignment boundary (page size if None)
Returns:
int: Aligned value
"""
def is_available(self, addr, size):
"""Check if memory range is available for mapping
Args:
addr: Base address
size: Range size
Returns:
bool: True if available
"""
def is_mapped(self, addr, size):
"""Check if memory range is mapped
Args:
addr: Base address
size: Range size
Returns:
bool: True if mapped
"""
def find_free_space(self, size, minaddr=None, maxaddr=None, align=None):
"""Find free memory space
Args:
size: Required size
minaddr: Minimum address
maxaddr: Maximum address
align: Alignment requirement
Returns:
int: Free space address or None
"""
def search(self, needle, begin=None, end=None):
"""Search for bytes in memory
Args:
needle: Bytes to search for
begin: Start address (None for all memory)
end: End address (None for all memory)
Returns:
Generator[int]: Addresses where needle was found
"""
def get_mapinfo(self):
"""Get memory map information
Returns:
List[Tuple]: List of (start, end, perms, label, container)
"""
def get_formatted_mapinfo(self):
"""Get formatted memory map table
Returns:
str: Formatted memory map
"""
def save(self):
"""Save memory state
Returns:
Dict: Memory state
"""
def restore(self, mem_dict):
"""Restore memory state
Args:
mem_dict: Saved memory state
"""
Location: qiling/os/memory.py:658
def alloc(self, size):
"""Allocate heap memory
Args:
size: Size to allocate
Returns:
int: Allocated address
"""
def free(self, addr):
"""Free heap memory
Args:
addr: Address to free
"""
def size(self, addr):
"""Get allocated chunk size
Args:
addr: Chunk address
Returns:
int: Chunk size
"""
def clear(self):
"""Clear all heap memory"""
Location: qiling/arch/arch.py:22
@property
def uc(self):
"""Unicorn engine instance"""
@property
def regs(self):
"""Register manager instance"""
@property
def disassembler(self):
"""Capstone disassembler instance"""
@property
def assembler(self):
"""Keystone assembler instance"""
@property
def endian(self):
"""Processor endianness"""
def stack_push(self, value):
"""Push value to stack
Args:
value: Value to push
"""
def stack_pop(self):
"""Pop value from stack
Returns:
int: Popped value
"""
def stack_read(self, offset):
"""Read from stack at offset
Args:
offset: Offset from stack pointer
Returns:
bytes: Read data
"""
def stack_write(self, offset, value):
"""Write to stack at offset
Args:
offset: Offset from stack pointer
value: Value to write
"""
def save(self):
"""Save CPU context
Returns:
Dict: CPU context
"""
def restore(self, saved_context):
"""Restore CPU context
Args:
saved_context: Saved CPU context
"""
Location: qiling/arch/register.py:11
def read(self, register):
"""Read register value
Args:
register: Register name or ID
Returns:
int: Register value
"""
def write(self, register, value):
"""Write register value
Args:
register: Register name or ID
value: Value to write
"""
def save(self):
"""Save all registers
Returns:
Dict: Register context
"""
def restore(self, context):
"""Restore all registers
Args:
context: Register context
"""
# Properties for common registers
@property
def arch_pc(self):
"""Program counter register"""
@property
def arch_sp(self):
"""Stack pointer register"""
# Common x86 registers accessible via ql.arch.regs
.eax, .ebx, .ecx, .edx # 32-bit general purpose
.esi, .edi, .esp, .ebp # 32-bit index/pointer
.eip, .eflags # 32-bit special
# x86_64 additional registers
.rax, .rbx, .rcx, .rdx # 64-bit general purpose
.rsi, .rdi, .rsp, .rbp # 64-bit index/pointer
.rip, .rflags # 64-bit special
.r8, .r9, .r10, .r11 # 64-bit extended
.r12, .r13, .r14, .r15 # 64-bit extended
# ARM registers accessible via ql.arch.regs
.r0, .r1, .r2, .r3 # General purpose
.r4, .r5, .r6, .r7 # General purpose
.r8, .r9, .r10, .r11 # General purpose
.r12, .sp, .lr, .pc # Special purpose
.cpsr # Status register
# ARM64 registers accessible via ql.arch.regs
.x0, .x1, .x2, .x3 # 64-bit general purpose
.x29, .x30, .sp, .pc # Special purpose
.w0, .w1, .w2, .w3 # 32-bit view of x registers
Location: qiling/os/os.py:24
@property
def stdin(self):
"""Standard input stream"""
@property
def stdout(self):
"""Standard output stream"""
@property
def stderr(self):
"""Standard error stream"""
@property
def root(self):
"""Root privilege indicator"""
@property
def utils(self):
"""OS utilities (QlOsUtils)"""
@property
def stats(self):
"""Statistics collector (QlOsStats)"""
@property
def fcall(self):
"""Function call interface (QlFunctionCall)"""
def set_api(self, target, handler, intercept=QL_INTERCEPT.CALL):
"""Hook or replace API function
Args:
target: Function name or address
handler: Handler function
intercept: Intercept type
"""
def call(self, pc, func, proto, onenter, onexit, passthru=False):
"""Call function with prototype
Args:
pc: Program counter
func: Function pointer
proto: Function prototype
onenter: Entry callback
onexit: Exit callback
passthru: Pass through to original
"""
def save(self):
"""Save OS state
Returns:
Dict: OS state
"""
def restore(self, saved_state):
"""Restore OS state
Args:
saved_state: Saved OS state
"""
# Process information
.pid # Process ID
.ppid # Parent process ID
.uid # User ID
.gid # Group ID
# File system
.fd # File descriptor table
.fs_mapper # File system mappings
# Signals
.signals # Signal handling
# Handle management
.handle_manager # Windows handle manager
# Registry
.registry # Registry emulation
# Threading
.thread_manager # Windows thread manager
# Process Environment Block
.peb # Process Environment Block
Base class for POSIX-compatible systems with common functionality.
Location: qiling/loader/loader.py:21
def find_containing_image(self, address):
"""Find image containing address
Args:
address: Memory address
Returns:
Image: Image object or None
"""
def get_image_by_name(self, name, casefold=False):
"""Get image by name
Args:
name: Image name
casefold: Case-insensitive search
Returns:
Image: Image object or None
"""
def save(self):
"""Save loader state
Returns:
Dict: Loader state
"""
def restore(self, saved_state):
"""Restore loader state
Args:
saved_state: Saved loader state
"""
# ELF-specific properties
.elftype # ELF type (executable, shared, etc.)
.entry_point # Entry point address
.phdr # Program headers
.shdr # Section headers
.dynamic # Dynamic section
.interp # Interpreter
# PE-specific properties
.dll_address # Base DLL address
.import_address_table # Import address table
.export_address_table # Export address table
.sections # PE sections
.resources # Resource directory
# Mach-O specific properties
.macho # Mach-O object
.segments # Mach-O segments
.dyld_info # Dynamic loader info
class Image:
@property
def base(self):
"""Image base address"""
@property
def end(self):
"""Image end address"""
@property
def path(self):
"""Image file path"""
Support for microcontroller peripherals.
# GPIO - General Purpose I/O
.gpio # GPIO controller
# Timers
.timer # Timer/counter peripherals
# Communication
.uart # UART/USART controllers
.spi # SPI controllers
.i2c # I2C controllers
# Analog
.adc # Analog-to-Digital converters
.dac # Digital-to-Analog converters
# Memory
.flash # Flash memory controller
.dma # Direct Memory Access
# Power/Clock
.rcc # Reset and Clock Control
.pwr # Power management
- STM32F1XX, STM32F4XX: STMicroelectronics ARM Cortex-M
- GD32VF1XX: GigaDevice RISC-V
- SAM3XA: Atmel ARM Cortex-M
- MK64F12: NXP Kinetis ARM Cortex-M
Location: qiling/debugger/debugger.py:13
Remote GDB debugging support:
# Enable GDB server
ql.debugger = "gdb:localhost:9999"
ql.run()
# Connect with GDB client
# gdb -ex "target remote localhost:9999"
Qiling's built-in debugger:
# Enable QDB
ql.debugger = "qdb"
ql.run()
# QDB Commands:
# run, continue, step, stepi
# info reg, info stack
# x/FMT ADDR - examine memory
# breakpoint ADDR - set breakpoint
# quit - exit debugger
Location: qiling/extensions/afl/afl.py:21
def ql_afl_fuzz(ql, input_file, place_input_callback, exits, validate_crash_callback=None):
"""AFL++ fuzzing integration
Args:
ql: Qiling instance
input_file: Input file path
place_input_callback: Callback to place fuzzing input
exits: Exit points for fuzzing
validate_crash_callback: Optional crash validation
"""
Multiple coverage formats supported:
# DRCov format (DynamoRIO)
from qiling.extensions.coverage.drcov import QlDrCov
# Coverage collection
cov = QlDrCov(ql)
ql.run()
cov.dump_coverage("coverage.drcov")
from qiling.extensions.trace import QlTrace
# Enable tracing
tracer = QlTrace(ql, output="trace.txt")
ql.run()
# Heap sanitizer
from qiling.extensions.sanitizers.heap import QlSanitizedMemoryHeap
# Enable heap sanitization
ql.os.heap = QlSanitizedMemoryHeap(ql)
Location: qiling/utils.py
def os_convert(os):
"""Convert OS string to QL_OS enum
Args:
os: OS string
Returns:
QL_OS: OS enum value
"""
def arch_convert(arch):
"""Convert architecture string to QL_ARCH enum
Args:
arch: Architecture string
Returns:
QL_ARCH: Architecture enum value
"""
def debugger_convert(debugger):
"""Convert debugger string to debugger type
Args:
debugger: Debugger string
Returns:
Debugger type
"""
def ql_get_module(module_name):
"""Load Qiling module
Args:
module_name: Module name to load
Returns:
Module object
"""
def ql_get_module_function(module_name, member_name):
"""Get module function
Args:
module_name: Module name
member_name: Function name
Returns:
Function object
"""
Location: qiling/exception.py
class QlErrorException(Exception):
"""Base Qiling exception"""
class QlMemoryMappedError(QlErrorException):
"""Memory mapping error"""
class QlOutOfMemory(QlErrorException):
"""Out of memory error"""
class QlErrorFileNotFound(QlErrorException):
"""File not found error"""
class QlErrorFileType(QlErrorException):
"""Invalid file type error"""
class QlErrorArch(QlErrorException):
"""Architecture error"""
class QlErrorOS(QlErrorException):
"""Operating system error"""
class QlErrorExecutionStop(QlErrorException):
"""Execution stopped error"""
class QlErrorTimeout(QlErrorException):
"""Execution timeout error"""
from qiling import Qiling
from qiling.exception import *
try:
ql = Qiling(['binary'], 'rootfs')
ql.run()
except QlErrorFileNotFound as e:
print(f"File not found: {e}")
except QlErrorArch as e:
print(f"Architecture error: {e}")
except QlErrorOS as e:
print(f"OS error: {e}")
except QlErrorException as e:
print(f"General Qiling error: {e}")
Location: qiling/cc/
- cdecl: Standard C calling convention
- amd64: x86-64 System V ABI
- aarch32: ARM 32-bit AAPCS
- aarch64: ARM 64-bit AAPCS
- mipso32: MIPS O32 ABI
- riscv: RISC-V calling convention
- ppc: PowerPC calling convention
from qiling import Qiling
from qiling.const import QL_VERBOSE
# Basic emulation
ql = Qiling(['rootfs/x8664_linux/bin/x8664_hello'],
'rootfs/x8664_linux',
verbose=QL_VERBOSE.DEBUG)
# Add hooks
def code_hook(ql, address, size):
print(f"Executing: 0x{address:x}")
def mem_hook(ql, access, address, size, value):
print(f"Memory access: 0x{address:x}")
ql.hook_code(code_hook)
ql.hook_mem_read(mem_hook)
# Run emulation
ql.run()
from qiling import Qiling
def hook_malloc(ql, size):
"""Custom malloc implementation"""
addr = ql.os.heap.alloc(size)
print(f"malloc({size}) = 0x{addr:x}")
return addr
def hook_free(ql, ptr):
"""Custom free implementation"""
print(f"free(0x{ptr:x})")
ql.os.heap.free(ptr)
ql = Qiling(['binary'], 'rootfs/x8664_linux')
ql.set_api('malloc', hook_malloc)
ql.set_api('free', hook_free)
ql.run()
from qiling import Qiling
ql = Qiling(['binary'], 'rootfs/x8664_linux')
# Map custom memory
ql.mem.map(0x10000000, 0x1000, info="analysis_buffer")
# Search for patterns
for addr in ql.mem.search(b"password"):
print(f"Found 'password' at 0x{addr:x}")
# Dump memory map
print(ql.mem.get_formatted_mapinfo())
ql.run()
For platform-specific APIs and advanced usage patterns, see the respective platform guides:
- Home
- Getting Started
- Core Concepts
- Usage
- Features
- Tutorials
- Development
- Resources