4.7 KiB
eatmycode_version
| eatmycode_version |
|---|
| 1.2.0 |
CLI — qltool and qltui
Goal
Give users a no-code way to run emulations: qltool run executes a binary
against a rootfs, qltool code runs shellcode (hex/asm/bin), qltool examples prints usage samples, and qltool qltui launches an interactive
TUI that gathers the same options. Owns argument parsing and the mapping
from flags to Qiling kwargs; it must not implement emulation behavior.
No roadmap milestone applies; maturity-based status.
Status
done — tests/test_qltool.py (observed: Ran 8 tests … OK once the
package is installed) shells out to qltool for run/code subcommands,
coverage, JSON, and log filtering; InstalledQltool_Test checks the
installed console script, shellcode exit status, bundled profiles, and TUI
import outside the checkout.
Code Structure
| File | Role |
|---|---|
qltool |
Checkout launcher: from qiling.cli import run |
qiling/cli.py |
Argparse CLI; installed as the qltool console script (pyproject.toml:33-34); builds kwargs and drives Qiling |
qltui.py |
questionary/pyfx/termcolor TUI; collects options and returns them to qltool |
Language and Conventions
Python; root rules apply. Enum-valued flags use __make_enum_arg
argparse actions mapping lowercase names to QL_ARCH/QL_OS/QL_ENDIAN/
QL_VERBOSE (qiling/cli.py:59-75). Errors surface as argparse errors or
Qiling exceptions; the process exits with ql.os.exit_code
(qiling/cli.py:321). qltui.py is the only module that imports
questionary, pyfx, and termcolor (pyproject.toml:48-50).
Design and Invariants
- Subcommands:
run(-f,--rootfs,--args …),code(-f/-i,--arch,--os,--endian,--thumb,--format asm|hex|bin),examples,qltui(qiling/cli.py:196-217); common flags cover verbosity,--env(pickled dict),--gdb,--qdb,--rr,--profile,--filter,--log-file,--log-plain,--no-console,--root,--debug-stop,--multithread,--timeout,--coverage-file,--coverage-format,--json,--libcache(:225-242). handle_run/handle_codereturn the kwargs dict;Qiling(**ql_args)atqiling/cli.py:276is the single construction point, followed by optional Qdb (:279), gdbserver (:285), coverage-wrappedql.run()(:306-310), JSON report (:312), and exit (:321).code --format asmassembles with Keystone viaqiling.arch.utils.assembler(:104).- The installed script and the checkout launcher must behave identically;
InstalledQltool_Testruns with an emptyPYTHONPATHfrom a temp directory to prove profiles ship in the wheel (tests/test_qltool.py:55-72).
Key Types and Entry Points
qiling/cli.py:189-run()- argparse setup and dispatch.qiling/cli.py:129-handle_run(options)- builds{'argv': [file]+args, 'rootfs': …}.qiling/cli.py:78-handle_code(options)- reads hex/asm/bin shellcode.qiling/cli.py:59-__make_enum_arg(enum_rmap, aliases)- argparse action factory.qltui.py- TUI entry invoked by theqltuisubcommand.
Interactions
- Thin client of core.md: constructs
Qilingand callsrun(). - Attaches debugger.md via
--gdb [HOST:PORT]/--qdb [--rr]. - Uses extensions.md for coverage (
cov_utils.factory) and the JSON report. - Packaging:
pyproject.toml:33-34defines the console script; the PyPI workflow runsInstalledQltool_Testagainst the built wheel (.github/workflows/pythonpublish.yml:41-44).
How to Test
python3 -m pip install -e .
cd tests && python3 test_qltool.py # pass = "Ran 8 tests … OK", exit 0
-
Qltool_Testuses the checkout launcher../qltool;InstalledQltool_Testneeds the console script on the interpreter's scripts path (hence the install step). Without it the two installed cases error withFileNotFoundError: …/bin/qltool. -
Manual smoke test from the repository root (pass = prints
Hello, World!):./qltool run -f examples/rootfs/x8664_linux/bin/x8664_hello --rootfs examples/rootfs/x8664_linux
Review and Refactor Guide
- New flag: add it to the common or subcommand parser, thread it into
ql_argsor the post-construction block, mirror it inqltui.py, and add aQltool_Testcase. - Do not add emulation logic here; new behavior belongs to the owning module and is only surfaced by a flag.
- Keep
qltool(checkout) a two-line launcher so installed and checkout behavior cannot diverge.
Open Gaps / Roadmap
qltui.pyhas only an import smoke test; its interactive flows are not covered.- Complex setups (fs mappers, custom hooks) still require the Python API.