Skip to content
xwings edited this page Jul 6, 2025 · 2 revisions

QlTool - Command Line Interface

Comprehensive guide to QlTool, the powerful command-line interface for Qiling Framework that provides rapid analysis capabilities without writing code.

Overview

QlTool is Qiling's command-line interface designed for rapid malware analysis, shellcode execution, and binary emulation. It provides a streamlined workflow for security analysts who need quick results without writing custom Python scripts.

Key Features

  • Binary Emulation: Execute PE, ELF, Mach-O files across platforms
  • Shellcode Analysis: Analyze raw shellcode with automatic architecture detection
  • Multi-format Support: Handle various file formats and architectures
  • Debugging Integration: Built-in GDB server and QDB debugger support
  • Coverage Analysis: Code coverage collection and reporting
  • Output Formats: JSON, XML, and text output for integration
  • Batch Processing: Analyze multiple samples efficiently

Installation and Setup

Standard Installation

# QlTool is included with Qiling Framework
pip install qiling

# Verify installation
qltool --help

Docker Installation

# Using official Qiling Docker image
docker pull qilingframework/qiling:latest
docker run -it qilingframework/qiling:latest qltool --help

Development Installation

# For latest features
git clone https://github.com/qilingframework/qiling.git
cd qiling
pip install -e .
./qltool --help

Command Structure

Basic Syntax

qltool [COMMAND] [OPTIONS] [ARGUMENTS]

Available Commands

Command Description Usage
run Execute binary files qltool run -f binary --rootfs path/
code Execute shellcode qltool code --os linux --arch x64 --format hex
examples Show example usage qltool examples
version Show version info qltool version

Binary Emulation

Basic Binary Execution

Linux Binary:

# Execute Linux x86_64 binary
qltool run -f examples/rootfs/x8664_linux/bin/x8664_hello \
       --rootfs examples/rootfs/x8664_linux/ \
       --verbose

# With custom arguments
qltool run -f /path/to/binary \
       --rootfs /path/to/rootfs/ \
       --args "arg1 arg2 arg3" \
       --verbose

Windows Binary:

# Execute Windows PE file
qltool run -f malware.exe \
       --rootfs examples/rootfs/x86_windows/ \
       --timeout 60 \
       --verbose

# With environment variables
qltool run -f sample.exe \
       --rootfs examples/rootfs/x86_windows/ \
       --env "TEMP=C:\Temp,PATH=C:\Windows\System32" \
       --verbose

macOS Binary:

# Execute macOS Mach-O binary
qltool run -f app.bin \
       --rootfs examples/rootfs/x8664_macos/ \
       --arch x8664 \
       --verbose

Advanced Execution Options

With Debugging:

# Enable GDB server
qltool run -f malware.exe \
       --rootfs examples/rootfs/x86_windows/ \
       --gdb localhost:9999 \
       --verbose

# Enable QDB debugger
qltool run -f binary \
       --rootfs examples/rootfs/x8664_linux/ \
       --qdb \
       --verbose

Memory and Performance:

# Custom memory layout
qltool run -f sample.exe \
       --rootfs examples/rootfs/x86_windows/ \
       --mem-map 0x10000000:0x1000000:rwx \
       --stack-size 0x100000 \
       --verbose

# Performance optimization
qltool run -f sample.exe \
       --rootfs examples/rootfs/x86_windows/ \
       --libcache \
       --multithread \
       --timeout 30 \
       --verbose

Output Control:

# JSON output for automation
qltool run -f malware.exe \
       --rootfs examples/rootfs/x86_windows/ \
       --console false \
       --json \
       --output-file analysis_result.json

# Detailed logging
qltool run -f sample.exe \
       --rootfs examples/rootfs/x86_windows/ \
       --log-level DEBUG \
       --log-file execution.log \
       --verbose

Shellcode Analysis

Basic Shellcode Execution

Linux Shellcode:

# Execute x86_64 Linux shellcode
qltool code --os linux --arch x8664 \
       --format hex \
       --input "4831c048bb2f62696e2f736800534889e74831c04831d24831f6b03b0f05"

# From file
qltool code --os linux --arch x8664 \
       --format raw \
       --input-file shellcode.bin \
       --verbose

Windows Shellcode:

# Execute Windows x86 shellcode
qltool code --os windows --arch x86 \
       --format hex \
       --input "fc4881e4f0ffffff..." \
       --rootfs examples/rootfs/x86_windows/ \
       --verbose

# With custom stack size
qltool code --os windows --arch x8664 \
       --format raw \
       --input-file payload.bin \
       --rootfs examples/rootfs/x8664_windows/ \
       --stack-size 0x200000 \
       --verbose

ARM Shellcode:

# Execute ARM shellcode
qltool code --os linux --arch arm \
       --format hex \
       --input "01108fe211ff2fe1..." \
       --rootfs examples/rootfs/arm_linux/ \
       --verbose

# ARM64 shellcode
qltool code --os linux --arch arm64 \
       --format hex \
       --input "e0031f2a..." \
       --rootfs examples/rootfs/arm64_linux/ \
       --endian little \
       --verbose

Advanced Shellcode Analysis

With Debugging:

# Debug shellcode execution
qltool code --os linux --arch x8664 \
       --format hex \
       --input "shellcode_hex" \
       --gdb localhost:9999 \
       --verbose

# Step-by-step execution
qltool code --os linux --arch x8664 \
       --format hex \
       --input "shellcode_hex" \
       --qdb \
       --single-step \
       --verbose

Coverage Analysis:

# Collect code coverage
qltool code --os linux --arch x8664 \
       --format hex \
       --input "shellcode_hex" \
       --coverage-format drcov \
       --coverage-file shellcode_coverage.cov \
       --verbose

# Multiple coverage formats
qltool code --os windows --arch x86 \
       --format raw \
       --input-file payload.bin \
       --rootfs examples/rootfs/x86_windows/ \
       --coverage-format json \
       --coverage-file coverage_report.json \
       --trace-file execution_trace.txt \
       --verbose

Advanced Features

Hooking and Instrumentation

API Hooking:

# Hook specific APIs
qltool run -f malware.exe \
       --rootfs examples/rootfs/x86_windows/ \
       --hook-addr 0x401000:log_call \
       --hook-api CreateFileW:log_file_access \
       --verbose

# Custom hook script
qltool run -f sample.exe \
       --rootfs examples/rootfs/x86_windows/ \
       --hook-script hooks.py \
       --verbose

Memory Hooks:

# Hook memory access
qltool run -f binary \
       --rootfs examples/rootfs/x8664_linux/ \
       --hook-mem-read \
       --hook-mem-write \
       --hook-mem-exec \
       --mem-trace-file memory_trace.log \
       --verbose

Fuzzing Integration

AFL++ Integration:

# Prepare for AFL++ fuzzing
qltool run -f target_binary \
       --rootfs examples/rootfs/x8664_linux/ \
       --afl-input @@  \
       --afl-persistent-addr 0x401000 \
       --afl-exit-addr 0x401100 \
       --timeout 5 \
       --verbose

# Custom fuzzing harness
qltool run -f fuzz_target \
       --rootfs examples/rootfs/x8664_linux/ \
       --fuzz-input-file input.dat \
       --fuzz-iterations 1000 \
       --fuzz-output-dir crashes/ \
       --verbose

Network Simulation

Network Services:

# Emulate network service
qltool run -f httpd_binary \
       --rootfs examples/rootfs/arm_linux/ \
       --network-bind 0.0.0.0:8080 \
       --network-forward 8080:8080 \
       --timeout 300 \
       --verbose

# Custom network configuration
qltool run -f router_firmware \
       --rootfs examples/rootfs/mips32el_linux/ \
       --network-config network.json \
       --network-pcap capture.pcap \
       --verbose

Configuration and Profiles

Profile Files

Creating Profiles:

# analysis.ql profile file
[KERNEL]
heap_base_address = 0x500000000
stack_address = 0x7ffffffde000

[NETWORK]
enable_simulation = true
bind_address = 0.0.0.0
capture_traffic = true

[LOGGING]
level = DEBUG
file = analysis.log
include_disasm = true

[HOOKS]
api_logging = true
memory_tracking = true
syscall_monitoring = true

Using Profiles:

# Load profile configuration
qltool run -f malware.exe \
       --rootfs examples/rootfs/x86_windows/ \
       --profile analysis.ql \
       --verbose

# Override profile settings
qltool run -f sample.exe \
       --rootfs examples/rootfs/x86_windows/ \
       --profile base.ql \
       --set "KERNEL.heap_base_address=0x600000000" \
       --verbose

Environment Configuration

Custom Environment:

# Set environment variables
qltool run -f sample.exe \
       --rootfs examples/rootfs/x86_windows/ \
       --env-file environment.txt \
       --working-dir "C:\Analysis" \
       --verbose

# Registry presets
qltool run -f malware.exe \
       --rootfs examples/rootfs/x86_windows/ \
       --registry-preset malware_analysis \
       --registry-file custom_registry.json \
       --verbose

Automation and Scripting

Batch Analysis

Multiple Samples:

# Process sample directory
qltool batch --input-dir samples/ \
       --output-dir results/ \
       --rootfs examples/rootfs/x86_windows/ \
       --timeout 60 \
       --format json \
       --parallel 4

# With custom script
qltool batch --input-dir malware_samples/ \
       --output-dir analysis_results/ \
       --script batch_analysis.py \
       --config batch_config.json \
       --verbose

Integration Scripts:

#!/usr/bin/env python3
# qltool_automation.py

import subprocess
import json
import sys
from pathlib import Path

def analyze_sample(sample_path, output_dir):
    """Automate QlTool analysis"""
    
    cmd = [
        'qltool', 'run',
        '-f', str(sample_path),
        '--rootfs', 'examples/rootfs/x86_windows/',
        '--timeout', '60',
        '--json',
        '--output-file', str(output_dir / f"{sample_path.stem}_analysis.json"),
        '--console', 'false'
    ]
    
    try:
        result = subprocess.run(cmd, capture_output=True, text=True, timeout=120)
        return result.returncode == 0
    except subprocess.TimeoutExpired:
        print(f"Analysis timeout for {sample_path}")
        return False

def main():
    samples_dir = Path(sys.argv[1])
    output_dir = Path(sys.argv[2])
    output_dir.mkdir(exist_ok=True)
    
    for sample in samples_dir.glob('*.exe'):
        print(f"Analyzing {sample}")
        success = analyze_sample(sample, output_dir)
        print(f"{'✓' if success else '✗'} {sample}")

if __name__ == "__main__":
    main()

CI/CD Integration

GitHub Actions:

# .github/workflows/malware_analysis.yml
name: Malware Analysis
on: [push, pull_request]

jobs:
  analyze:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    
    - name: Setup Python
      uses: actions/setup-python@v2
      with:
        python-version: '3.11'
    
    - name: Install Qiling
      run: |
        pip install qiling
        
    - name: Analyze Samples
      run: |
        qltool batch --input-dir samples/ \
                    --output-dir results/ \
                    --timeout 30 \
                    --format json
    
    - name: Upload Results
      uses: actions/upload-artifact@v2
      with:
        name: analysis-results
        path: results/

Output Formats and Reporting

JSON Output

Structured Analysis:

# Generate JSON report
qltool run -f malware.exe \
       --rootfs examples/rootfs/x86_windows/ \
       --json \
       --output-file analysis.json \
       --console false

# Example JSON structure:
{
  "sample_info": {
    "file_path": "malware.exe",
    "file_size": 102400,
    "md5": "d41d8cd98f00b204e9800998ecf8427e",
    "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
  },
  "execution_info": {
    "start_time": "2025-01-06T10:00:00Z",
    "end_time": "2025-01-06T10:01:00Z",
    "timeout": false,
    "exit_code": 0
  },
  "api_calls": [...],
  "memory_accesses": [...],
  "network_activity": [...]
}

Coverage Reports

Code Coverage:

# DrcOV format for IDA Pro/Lighthouse
qltool run -f target.exe \
       --rootfs examples/rootfs/x86_windows/ \
       --coverage-format drcov \
       --coverage-file target.cov

# JSON format for custom analysis
qltool code --os linux --arch x8664 \
       --format hex \
       --input "shellcode" \
       --coverage-format json \
       --coverage-file coverage.json

Integration with Analysis Tools

IDA Pro Integration:

# ida_qltool_import.py
import json
import idaapi

def import_qltool_coverage(coverage_file):
    """Import QlTool coverage into IDA Pro"""
    
    with open(coverage_file, 'r') as f:
        coverage_data = json.load(f)
    
    for addr in coverage_data.get('executed_addresses', []):
        # Color executed instructions
        idaapi.set_item_color(addr, 0x00FF00)  # Green
    
    print(f"Imported {len(coverage_data['executed_addresses'])} coverage points")

# Usage in IDA Pro console
import_qltool_coverage("analysis_coverage.json")

Best Practices

Performance Optimization

# Optimize for speed
qltool run -f large_binary \
       --rootfs examples/rootfs/x8664_linux/ \
       --libcache \
       --multithread \
       --timeout 30 \
       --log-level ERROR \
       --console false

# Memory optimization
qltool run -f memory_intensive_app \
       --rootfs examples/rootfs/x86_windows/ \
       --stack-size 0x50000 \
       --heap-size 0x1000000 \
       --mem-limit 2GB

Security Considerations

# Isolated analysis
qltool run -f untrusted_sample \
       --rootfs /tmp/isolated_rootfs/ \
       --network-disable \
       --filesystem-readonly \
       --timeout 60 \
       --verbose

# Sandboxed execution
docker run --rm -v $(pwd):/analysis \
       qilingframework/qiling:latest \
       qltool run -f /analysis/malware.exe \
       --rootfs /qiling/examples/rootfs/x86_windows/ \
       --timeout 30 \
       --console false \
       --json

Troubleshooting

Common Issues:

# Debug emulation issues
qltool run -f problematic_binary \
       --rootfs examples/rootfs/x8664_linux/ \
       --log-level DEBUG \
       --log-file debug.log \
       --trace-file execution_trace.txt \
       --verbose

# Memory access debugging
qltool run -f crashing_app \
       --rootfs examples/rootfs/x86_windows/ \
       --hook-mem-invalid \
       --hook-mem-unmapped \
       --gdb localhost:9999 \
       --verbose

QlTool provides a powerful command-line interface for rapid malware analysis and binary emulation. Its extensive feature set makes it suitable for both quick analysis tasks and complex automation workflows in enterprise security environments.

Clone this wiki locally