Skip to content

Basic Usage

xwings edited this page Jul 6, 2025 · 2 revisions

Basic Usage

This guide covers the fundamental operations for using Qiling Framework. It assumes you have already installed Qiling and have a basic understanding of its architecture.

The Qiling Object

The Qiling object is the cornerstone of any emulation task. It holds the entire state of the emulated machine, including the CPU, memory, filesystem, and OS.

Initialization

To start, you need to initialize the Qiling object. The constructor requires two main arguments:

  1. argv: A list of strings representing the command-line arguments for the program you want to emulate. The first element is typically the path to the executable itself.
  2. rootfs: The path to the root filesystem that the emulated program will see. Qiling needs a proper rootfs for the target OS and architecture to find necessary libraries and files.

Example:

from qiling import Qiling
from qiling.const import QL_VERBOSE

# Arguments for the emulated program: `ls -l /`
argv = ['/bin/ls', '-l', '/']
rootfs = 'path/to/your/rootfs/x8664_linux'

# Initialize Qiling
# verbose=QL_VERBOSE.OFF disables detailed instruction tracing
ql = Qiling(argv, rootfs, verbose=QL_VERBOSE.OFF)

Running the Emulation

Once the Qiling object is initialized, you can start the emulation using the run() method.

# This will start execution from the binary's entry point
ql.run()

The run() method can also take optional arguments:

  • begin: The address to start execution from. If not specified, it uses the binary's entry point.
  • end: The address to stop execution at.
  • timeout: The maximum time (in milliseconds) to run the emulation.
  • count: The maximum number of instructions to execute.

Example: Running a specific function

# Assume 'my_function' is at address 0x401122
function_addr = 0x401122

# Run until a specific address is hit (e.g., a return instruction)
end_addr = 0x401133

ql.run(begin=function_addr, end=end_addr)

Accessing Registers and Memory

During emulation, you often need to inspect or modify the machine state.

Registers (ql.reg)

The ql.reg object provides direct access to the CPU registers.

# Read the value of the RAX register
rax_val = ql.reg.rax
print(f"RAX = {rax_val:#x}")

# Modify the value of the RCX register
ql.reg.rcx = 0x1000

Memory (ql.mem)

The ql.mem object allows you to interact with the emulated memory.

# Read 16 bytes from a memory address
mem_content = ql.mem.read(0x7fffffffe100, 16)

# Write a string to a memory location
ql.mem.write(0x405000, b"Hello, Qiling memory!\n")

Simple Hooking

Hooking is a powerful feature that lets you execute Python code when certain events occur. The simplest type of hook is an address hook.

Example: Hooking the entry point

# Define a callback function
def entry_point_hook(ql):
    print("Execution has reached the entry point!")
    print(f"Initial stack pointer (RSP) is at {ql.reg.rsp:#x}")

# Get the entry point from the loader
entry_point = ql.loader.elf_entry

# Set the hook
ql.hook_address(entry_point_hook, entry_point)

# Now, when you call ql.run(), the hook will be executed
ql.run()

This covers the essential workflow of a typical Qiling script. For more complex scenarios, you will need to explore advanced hooking, OS-level interactions, and the various APIs Qiling provides, as detailed in the other sections of this wiki.

Clone this wiki locally