Files
apk-reverse/docs/tool-verification/EXTENSION-kernel-instrument.md
T
inliver233 e151d7d605 Merge PR #6 "Hardware pass (stage 1)" (dabao1955/feat/ete)
Merges the hardware-layer pass onto the dexsql commit: arm64 hardware
watchpoints, ETE differential tracing, kernel-side event injection, SPE/BRBE
sampling and crash forensics, address symbolization and interpreter-trace
de-slicing. 33 files, 6 new scripts, 6 new test modules, 4 new reference
documents.

The only conflict was in evidence/capability-matrix.json: both sides appended
to the same array tail. Resolved by keeping both -- the PR's seven entries
(44 rows total now) -- and re-validated as JSON before staging.

Verified on the merged tree, not on the PR branch alone:

  * check_repo.py, check_refs.py, check_commands.py, check_routing.py and
    check_budget.py all pass with zero problems;
  * pytest: 766 passed, 172 skipped, 25 xfailed -- the 141 tests this PR adds
    all pass alongside the 625 that were already there;
  * the PR's host-side claims were reproduced by hand, not taken on trust:
    `hw_watch.py plan --addr 0x1004 --len 4 --access w` returns
    `cr: 7701` (WCR 0x1E15) exactly as the record says, both refusals exit 2
    with the documented reason strings, and the kernel scaffold's
    generate/verify round trip returns RESULT=ok.

One documentation defect was found and fixed in the merge: EXTENSION-kernel-instrument.md
recorded `verified 3 kernel-side file(s)` while the same page's own generate
output lists four (kpm/src/kwatch.c, kpm/Makefile, lkm/kwatch.c, lkm/Makefile)
and the tool reports 4. The page now says 4.

Everything the PR ships that needs a device or a kernel toolchain stays
labelled unverified in the files themselves, which is the property that made
it mergeable.
2026-10-16 02:05:59 +08:00

4.2 KiB

Extension verification — kernel-side instrumentation scaffold (templates, gates, verify)

Covers the hardware-layer pass that added scripts/kernel_instrument_scaffold.py and references/kernel-event-injection.md. Strength labels as this directory's README defines them. This pass follows EXTENSION-kernel-weapons.md's shape deliberately: a generator whose host behaviour is measured, kernel-side templates that have never been compiled or loaded anywhere, and the gate table that says so.

Reference environment: Linux container host, Python 3.13, no aarch64-none-elf-gcc (gates reports NOT FOUND — observed), no APatch/KernelPatch boot image, no device.

Headline: gates/generate/verify are measured on the host. Every generated kernel-side file carries a NOT COMPILED AND NOT LOADED banner that verify enforces. The register-rewrite action is labelled experimental in the template itself — it was never run anywhere, by anyone in this repository.


1. Generate + verify round trip — observed

$ python skills/apk-reverse/scripts/kernel_instrument_scaffold.py generate \
    --out work/kwatch --pid 12345 --watch w:0x7b2000123450:8:w --break b:0x7b20001234c0 --set-reg x0=0x1
wrote work/kwatch
  kpm/src/kwatch.c  kpm/Makefile  lkm/kwatch.c  lkm/Makefile
  module.prop  README.md  post-fs-data.sh  config/instrument.json
RESULT=ok
$ python skills/apk-reverse/scripts/kernel_instrument_scaffold.py verify --dir work/kwatch
verified 4 kernel-side file(s), 0 problem(s)
RESULT=ok

Spec validation reuses the hardware rules and refuses at generation, before any file is written: a watch crossing its 8-byte window and a misaligned breakpoint PC both exit 2 with the reason (observed, same refusal strings as hw_watch.py plan — one rule, one copy in each tool, both unit-tested).

The generated KPM template embeds: kfunc_def(...) declarations without extern (the loader-rejection lesson recorded in EXTENSION-kernel-weapons.md, restated in the template's own header), a callback whose first statements are the cheap filter, and the watch config as generated constants with "regenerate rather than hand-edit" in the config JSON.

2. The honesty devices this pass ships

  • The primitive map is a capability table, not a wishlist. Each cell names what the route can do, and the no cells (eBPF cannot create perf breakpoint events; a userspace module cannot arm anything) are the rows that stop a reader from spending a day on a route that cannot express the need.
  • The experimental action is fenced three times: template comment, script header, and the reference's stop table ("the first run is a measurement"). Rewriting pt_regs in a perf overflow callback is mechanically what a ptrace stop does, and that is exactly as far as the claim goes.
  • The userspace carrier cannot arm watchpoints and says so in its own README — the same structural correction EXTENSION-kernel-weapons.md made for syscall masking, applied before anyone could misread this module the same way.

3. What this pass deliberately did not do

  • Nothing was compiled: no aarch64-none-elf-gcc exists here, no KernelPatch image exists on any reference device, and the LKM route has no matching kernel source. All three kernel files are unverified templates and are labelled so in the files themselves.
  • No claim about whether register_hw_breakpoint can be resolved from a KPM on any specific KernelPatch revision is made; the template says to verify symbol names against the revision's kpmodule.h, which is the same instruction the syscall-mask template gives.

4. Facts this pass pinned for the next one

  • The kernel's perf breakpoint layer owning the debug registers is a gate in its own right: if CONFIG_HW_PERF_EVENTS is out, both templates close regardless of root scheme. Probe: ls /sys/bus/event_source/devices/breakpoint on the device.
  • verify exists so the banner survives edits: someone will adapt a template on a real device, strip the banner, and the next reader must be able to tell an adapted-unverified file from a measured one. A banner replaced by a real measurement is the intended outcome, and kernel-event-injection.md's checklist says so.