-
Notifications
You must be signed in to change notification settings - Fork 776
QlTool
Comprehensive guide to QlTool, the powerful command-line interface for Qiling Framework that provides rapid analysis capabilities without writing code.
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.
- 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
# QlTool is included with Qiling Framework
pip install qiling
# Verify installation
qltool --help# Using official Qiling Docker image
docker pull qilingframework/qiling:latest
docker run -it qilingframework/qiling:latest qltool --help# For latest features
git clone https://github.com/qilingframework/qiling.git
cd qiling
pip install -e .
./qltool --helpqltool [COMMAND] [OPTIONS] [ARGUMENTS]| 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 |
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" \
--verboseWindows 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" \
--verbosemacOS Binary:
# Execute macOS Mach-O binary
qltool run -f app.bin \
--rootfs examples/rootfs/x8664_macos/ \
--arch x8664 \
--verboseWith 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 \
--verboseMemory 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 \
--verboseOutput 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 \
--verboseLinux 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 \
--verboseWindows 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 \
--verboseARM 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 \
--verboseWith 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 \
--verboseCoverage 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 \
--verboseAPI 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 \
--verboseMemory 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 \
--verboseAFL++ 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/ \
--verboseNetwork 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 \
--verboseCreating 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 = trueUsing 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" \
--verboseCustom 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 \
--verboseMultiple 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 \
--verboseIntegration 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()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/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": [...]
}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.jsonIDA 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")# 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# 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 \
--jsonCommon 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 \
--verboseQlTool 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.
- Home
- Getting Started
- Core Concepts
- Usage
- Features
- Tutorials
- Development
- Resources