
Qiling's use case, blog and related work
Qiling is an advanced binary emulation framework, with the following features:
Qiling also made its way to various international conferences.
2022: - Black Hat, EU - Black Hat, MEA
2021: - Black Hat, USA - Hack In The Box, Amsterdam - Black Hat, Asia
2020: - Black Hat, Europe - Black Hat, USA - Black Hat, USA (Demigod) - Black Hat, Asia - Hack In The Box, Lockdown 001 - Hack In The Box, Lockdown 002 - Hack In The Box, Cyberweek - Nullcon
2019:
Qiling is backed by Unicorn Engine.
Visit our website for more information.
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
There are many open-source emulators, but two projects closest to Qiling are Unicorn & QEMU user mode. This section explains the main differences of Qiling against them.
Built on top of Unicorn, but Qiling & Unicorn are two different animals.
QEMU user mode does a similar thing to our emulator, that is, to emulate whole executable binaries in a cross-architecture way. However, Qiling offers some important differences against QEMU user mode:
Please see setup guide file for how to install Qiling Framework.
The example below shows how to use Qiling framework in the most straightforward way to emulate a Windows executable.
from qiling import Qiling
if __name__ == "__main__":
# initialize Qiling instance, specifying the executable to emulate and the emulated system root.
# note that the current working directory is assumed to be Qiling home
ql = Qiling([r'examples/rootfs/x86_windows/bin/x86_hello.exe'], r'examples/rootfs/x86_windows')
# start emulation
ql.run()
from qiling import Qiling
def force_call_dialog_func(ql: Qiling):
# get DialogFunc address from current stack frame
lpDialogFunc = ql.stack_read(-8)
# setup stack memory for DialogFunc
ql.stack_push(0)
ql.stack_push(1001) # IDS_APPNAME
ql.stack_push(0x111) # WM_COMMAND
ql.stack_push(0)
# push return address
ql.stack_push(0x0401018)
# resume emulation from DialogFunc address
ql.arch.regs.eip = lpDialogFunc
if __name__ == "__main__":
# initialize Qiling instance
ql = Qiling([r'rootfs/x86_windows/bin/Easy_CrackMe.exe'], r'rootfs/x86_windows')
# NOP out some code
ql.patch(0x004010B5, b'\x90\x90')
ql.patch(0x004010CD, b'\x90\x90')
ql.patch(0x0040110B, b'\x90\x90')
ql.patch(0x00401112, b'\x90\x90')
# hook at an address with a callback
ql.hook_address(force_call_dialog_func, 0x00401016)
ql.run()
The below YouTube video shows how the above example works.
Qiling Framework hot-patches and emulates an ARM router's /usr/bin/httpd on
an x86_64 Ubuntu host.
This video demonstrates how Qiling's IDA Pro plugin can make IDA Pro run with Qiling instrumentation engine.
Solving a simple CTF challenge with Qiling Framework and IDA Pro
Qiling Framework emulates MBR
Qiling also provides a friendly tool named qltool to quickly emulate shellcode & executable binaries.
With qltool, easy execution can be performed:
With shellcode:
$ ./qltool code --os linux --arch arm --format hex -f examples/shellcodes/linarm32_tcp_reverse_shell.hex
With binary file:
$ ./qltool run -f examples/rootfs/x8664_linux/bin/x8664_hello --rootfs examples/rootfs/x8664_linux/
With binary and GDB debugger enabled:
$ ./qltool run -f examples/rootfs/x8664_linux/bin/x8664_hello --gdb 127.0.0.1:9999 --rootfs examples/rootfs/x8664_linux
With code coverage collection (UEFI only for now):
$ ./qltool run -f examples/rootfs/x8664_efi/bin/TcgPlatformSetupPolicy --rootfs examples/rootfs/x8664_efi --coverage-format drcov --coverage-file TcgPlatformSetupPolicy.cov
With JSON output (Windows, mainly):
$ ./qltool run -f examples/rootfs/x86_windows/bin/x86_hello.exe --rootfs examples/rootfs/x86_windows/ --console False --json
Get the latest info from our website https://www.qiling.io
Contact us at email info@qiling.io, via Twitter @qiling_io.
Please refer to CREDITS.md.
$ claude mcp add qiling \
-- python -m otcore.mcp_server <graph>