Skip to content

Add AArch64 code-range blob example with UDF trapping - #1663

Draft
warsang wants to merge 6 commits into
qilingframework:devfrom
warsang:feat/aarch64-range-blob-example
Draft

warsang wants to merge 6 commits into
qilingframework:devfrom
warsang:feat/aarch64-range-blob-example

Conversation

@warsang

@warsang warsang commented Sep 10, 2026

Copy link
Copy Markdown

Adds examples/hello_arm64_range_blob.py: map a raw AArch64 blob executable with a scratch stack plus stub page, log invalid instructions as structured UDF faults (immediate recorded, never skipped), and stop at unmapped accesses instead of misexecuting. Follows the existing hello_arm_blob_raw.py conventions.

dependabot Bot and others added 4 commits July 22, 2026 14:09
Bumps [setuptools](https://github.com/pypa/setuptools) from 78.1.1 to 83.0.0.
- [Release notes](https://github.com/pypa/setuptools/releases)
- [Changelog](https://github.com/pypa/setuptools/blob/main/NEWS.rst)
- [Commits](pypa/setuptools@v78.1.1...v83.0.0)

---
updated-dependencies:
- dependency-name: setuptools
  dependency-version: 83.0.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
…ot/pip/setuptools-83.0.0

Bump setuptools from 78.1.1 to 83.0.0
Maps a raw AArch64 blob executable with scratch stack plus stub page,
logs invalid instructions as structured UDF faults and stops at
unmapped accesses instead of misexecuting.
@warsang
warsang marked this pull request as draft September 14, 2026 07:50
hello_arm64_range_blob.py printed qiling_aarch64_chpe.py in --help/usage. Align both docstring and runtime message with the actual filename per hello_arm_blob_raw.py conventions. No behavior change.
Comment thread examples/hello_arm64_range_blob.py Outdated
load_at = int(sys.argv[2], 16)
max_steps = int(sys.argv[3]) if len(sys.argv) > 3 else 4096

ql = Qiling(code=code, archtype=QL_ARCH.AARCH64, ostype=QL_OS.BLOB,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested sketch (not executed):

ql = Qiling(code=code, archtype=QL_ARCH.ARM64, ostype=QL_OS.BLOB,

i think we are using QL_ARCH.ARM64

Comment thread examples/hello_arm64_range_blob.py Outdated
events: list = []
state = {"steps": 0}

def hook_code(ql_inner):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested sketch (not executed):

def hook_code(ql_inner, address, size):
    state["steps"] += 1

Comment thread examples/hello_arm64_range_blob.py Outdated
def hook_unmapped(ql_inner, access, addr, size, value):
events.append({"type": "UNMAPPED", "pc": hex(ql_inner.arch.regs.pc),
"addr": hex(addr), "size": size})
return False

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Returning False from a memory hook does not stop emulation: Qiling's _hook_mem_cb ignores the callback return value and unconditionally returns True (qiling/core_hooks.py:238-252), which tells Unicorn the unmapped access was handled and lets execution continue. Impact: the docstring (line 8) and the PR description claim 'unmapped accesses stop at the loader-table boundary', but execution continues past the fault, so the example's central behavior is not delivered and the recorded UNMAPPED event is not a stop condition.

Fix: Stop explicitly from inside the callback (ql_inner.emu_stop(), as used for stop conditions elsewhere, e.g. qiling/extensions/idaplugin/qilingida.py's hook handlers, and in line 50 of this file) and drop or correct the false 'stop' claim if a record-only event is intended.

Source and suggested change
  53 |         events.append({"type": "UNMAPPED", "pc": hex(ql_inner.arch.regs.pc),
  54 |                        "addr": hex(addr), "size": size})
> 55 |         return False
  56 |
  57 |     ql.hook_code(hook_code)

Suggested sketch (not executed):

def hook_unmapped(ql_inner, access, addr, size, value):
    events.append({...})
    ql_inner.emu_stop()

QL_ARCH.AARCH64 does not exist, use QL_ARCH.ARM64. Code hooks receive (ql, address, size), accept all three. Qiling _hook_mem_cb ignores the unmapped-hook return value, so stop explicitly with emu_stop() and return True; track intentional stops so exactly one terminal event is recorded (no RETURNED/STOP after UNMAPPED/STEP-CAP). Verified: NOP blob returns, UDF blob logs single UDF fault, ret-to-unmapped stops with single UNMAPPED, tight loop hits STEP-CAP at cap.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants