Skip to content

API Reference

xwings edited this page Jul 6, 2025 · 5 revisions

Complete API Reference

Comprehensive API documentation for the Qiling Framework based on complete codebase analysis.

Table of Contents


Core Classes

Qiling Class

The main emulation engine class that provides the primary interface for binary emulation.

Location: qiling/core.py:35
Inheritance: QlCoreHooks, QlCoreStructs

Constructor

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
)

Core Properties

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

Core Methods

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
    """

Constants and Enums

Architecture Types (QL_ARCH)

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

Operating Systems (QL_OS)

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

Verbosity Levels (QL_VERBOSE)

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

Other Enums

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

Hook System

Hook Methods

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
    """

Memory Hook Methods

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"""

Hook Management

def hook_del(self, hret):
    """Remove hook
    
    Args:
        hret: Hook handle returned from hook_* methods
    """

def clear_hooks(self):
    """Remove all hooks"""

Hook Callback Protocols

# 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
    """

Memory Management API

QlMemoryManager Class

Location: qiling/os/memory.py:23

Core Memory Operations

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
    """

Memory Mapping

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"""

Memory Utilities

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
    """

Memory Info

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
    """

State Management

def save(self):
    """Save memory state
    
    Returns:
        Dict: Memory state
    """

def restore(self, mem_dict):
    """Restore memory state
    
    Args:
        mem_dict: Saved memory state
    """

QlMemoryHeap Class

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"""

Architecture Layer

QlArch Base Class

Location: qiling/arch/arch.py:22

Properties

@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"""

Stack Operations

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
    """

State Management

def save(self):
    """Save CPU context
    
    Returns:
        Dict: CPU context
    """

def restore(self, saved_context):
    """Restore CPU context
    
    Args:
        saved_context: Saved CPU context
    """

QlRegisterManager Class

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"""

Architecture-Specific Classes

X86/X8664 Registers

# 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

# 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

# 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

Operating System Layer

QlOs Base Class

Location: qiling/os/os.py:24

Properties

@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)"""

API Management

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
    """

State Management

def save(self):
    """Save OS state
    
    Returns:
        Dict: OS state
    """

def restore(self, saved_state):
    """Restore OS state
    
    Args:
        saved_state: Saved OS state
    """

OS-Specific Implementations

QlOsLinux

# 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

QlOsWindows

# Handle management
.handle_manager                # Windows handle manager

# Registry
.registry                      # Registry emulation

# Threading
.thread_manager               # Windows thread manager

# Process Environment Block
.peb                          # Process Environment Block

QlOsPosix

Base class for POSIX-compatible systems with common functionality.


Loader System

QlLoader Base Class

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
    """

Loader Types

QlLoaderELF (Linux/Unix)

# 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

QlLoaderPE (Windows)

# 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

QlLoaderMachO (macOS)

# Mach-O specific properties
.macho                        # Mach-O object
.segments                     # Mach-O segments
.dyld_info                    # Dynamic loader info

Image Class

class Image:
    @property
    def base(self):
        """Image base address"""
    
    @property
    def end(self):
        """Image end address"""
    
    @property
    def path(self):
        """Image file path"""

Hardware Layer (MCU)

QlHwManager Class

Support for microcontroller peripherals.

Peripheral Categories

# 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

Supported MCU Families

  • STM32F1XX, STM32F4XX: STMicroelectronics ARM Cortex-M
  • GD32VF1XX: GigaDevice RISC-V
  • SAM3XA: Atmel ARM Cortex-M
  • MK64F12: NXP Kinetis ARM Cortex-M

Debugging APIs

QlDebugger Base Class

Location: qiling/debugger/debugger.py:13

QlDebuggerGDB

Remote GDB debugging support:

# Enable GDB server
ql.debugger = "gdb:localhost:9999"
ql.run()

# Connect with GDB client
# gdb -ex "target remote localhost:9999"

QlDebuggerQDB

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

Extensions

AFL Fuzzing Extension

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
    """

Coverage Collection

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")

Tracing Extension

from qiling.extensions.trace import QlTrace

# Enable tracing
tracer = QlTrace(ql, output="trace.txt")
ql.run()

Sanitizers

# Heap sanitizer
from qiling.extensions.sanitizers.heap import QlSanitizedMemoryHeap

# Enable heap sanitization
ql.os.heap = QlSanitizedMemoryHeap(ql)

Utilities

Conversion Functions

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
    """

Module Loading

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
    """

Error Handling

Exception Classes

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"""

Error Handling Examples

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}")

Calling Conventions

Supported Calling Conventions

Location: qiling/cc/

Intel

  • cdecl: Standard C calling convention
  • amd64: x86-64 System V ABI

ARM

  • aarch32: ARM 32-bit AAPCS
  • aarch64: ARM 64-bit AAPCS

Others

  • mipso32: MIPS O32 ABI
  • riscv: RISC-V calling convention
  • ppc: PowerPC calling convention

Usage Examples

Complete Basic Example

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()

Advanced API Hooking

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()

Memory Analysis Example

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:

Clone this wiki locally