mirror of
https://codeberg.org/reverse-skill-lab/apk-reverse
synced 2026-11-15 20:34:29 +08:00
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.
This commit is contained in:
@@ -108,6 +108,10 @@ measurements.
|
||||
execution on the host, or a live function service-ified over Frida RPC.
|
||||
- Reading **instruction-level execution evidence** when a native function has been flattened into a
|
||||
state machine by OLLVM — including the two ways Stalker was measured to bite back on a real device.
|
||||
- Reaching for the **hardware layer** when every software tracer modifies what it observes: arm64
|
||||
hardware watchpoints (no code change, but an honest `TracerPid` ledger), ETE/TRBE differential
|
||||
tracing with its five gates, and kernel-armed injection templates that are labelled unverified
|
||||
until a device with the matching gate fires them.
|
||||
- Recognising when **userspace hooking cannot reach the check at all** (raw `svc` syscalls,
|
||||
`init_array`-early detection), what the next layer up and down can actually do, and when escalating
|
||||
is the wrong answer.
|
||||
@@ -269,6 +273,25 @@ references/ loaded on demand, one topic each
|
||||
userspace hooking provably cannot reach the check: raw `svc`, init_array-early
|
||||
detection, what each root scheme hides, the kernel-route map with its version
|
||||
gate, and when to stop escalating
|
||||
hardware-watchpoints.md invisible memory watchpoints on arm64: the hardware debug slots, the
|
||||
ptrace route with its honest `TracerPid` ledger, the 8-byte-window
|
||||
alignment rules, the traps (per-thread slots, signal forwarding, the
|
||||
breakpoint step-over dance), and the control run every hit is owed
|
||||
ete-diff-tracing.md hardware execution tracing (CoreSight ETE/TRBE) plus the differential
|
||||
method: the five gates and how each fails silently, per-thread `cs_etm`
|
||||
capture, and two one-bit-different runs turned into the input-dependent
|
||||
block set — with the two open flattening families' state machines
|
||||
read from source, and the xvmp IR-VM shape
|
||||
hardware-sampling-and-crash.md
|
||||
data flow without a known address (SPE: PC + data address per
|
||||
sample), crash forensics when the stack is not trustworthy (BRBE
|
||||
branch records / the ETE tail), and runtime addresses turned into
|
||||
symbols and static offsets (`trace_addr2sym.py`, PIE vaddr/file-offset
|
||||
rules)
|
||||
kernel-event-injection.md the driver as your hands inside the target: watchpoints armed from the
|
||||
kernel with no tracer relationship, register rewrites at the trap, the
|
||||
primitive map per route (KPM/LKM/eBPF/Zygisk), and the composition
|
||||
recipes that stack this layer with the other two
|
||||
on-device-tooling.md working from the phone itself: MT Manager edit/repack/sign and its APK MCP,
|
||||
LSPosed Manager, Termux+frida, on-device data inspection
|
||||
java2c-and-jni-sinking.md Java2C and JNI sinking, the two hardening shapes most easily confused
|
||||
@@ -392,6 +415,31 @@ scripts/ parameterized, path-agnostic
|
||||
kernelsu_syscall_mask.py generate a KernelSU/APatch syscall-masking scaffold: an installable
|
||||
userspace module skeleton plus KPM/LKM/eBPF kernel-side templates, each
|
||||
with its version gate and an explicit unverified label
|
||||
hw_watch.py invisible memory watchpoints / execution breakpoints on arm64: plan
|
||||
(WCR/BCR encoders with the 8-byte-window rules), emit (a self-contained
|
||||
on-device C helper — compiles clean as a static aarch64 ELF), gates,
|
||||
run (build+push+stream hits) and decode (module+offset per hit)
|
||||
trace_diff.py differential trace reduction: reduce one trace to runs+histogram, or
|
||||
diff two traces into first-divergence / divergent regions / blocks
|
||||
unique to each side — producer-agnostic (Stalker logs or any
|
||||
address-per-line stream, incl. decoded cs_etm)
|
||||
ete_capture.py CoreSight ETE capture with gates first: the five gates (kernel era,
|
||||
coresight sysfs, cs_etm PMU, perf-with-CORESIGHT, permission), the
|
||||
perf/OpenCSD build recipe, and the per-thread record wrapper whose
|
||||
`--control` validation run must pass before any real capture
|
||||
kernel_instrument_scaffold.py
|
||||
generate the kernel-side instrumentation scaffold: KPM/LKM watchpoint +
|
||||
register-rewrite templates and an honest userspace carrier, each with
|
||||
its gate and a `NOT COMPILED AND NOT LOADED` banner that `verify`
|
||||
enforces
|
||||
trace_addr2sym.py runtime addresses -> symbols + static offsets, zero-dependency
|
||||
ELF64 (PT_LOAD vaddr/file-off conversion, .dynsym/.symtab, stripped
|
||||
fallback): accepts hw_watch hits, trace mod+off keys or raw address
|
||||
lists; host-verified against a real cross-compiled aarch64 .so
|
||||
vm_handler_slice.py de-virtualize an interpreter trace: dispatcher detection, slicing
|
||||
into handler segments at dispatch entries, signature clustering, and
|
||||
the guest-opcode trajectory via an optional handler->opcode map —
|
||||
calibrated against the open xvmp IR virtualizer
|
||||
rasc_build.py build and verify rasc, the Rust ASC re-implementation:
|
||||
--check what is present, --build clone plus cargo, --verify an APK
|
||||
against droidasc and fail on any class-set difference
|
||||
@@ -513,7 +561,11 @@ targets under those routes (`tests/benchmark.md`): it added **Java2C discriminat
|
||||
misdiagnosis that sends an agent hunting a decrypted DEX that never exists), **split APK /
|
||||
App Bundle handling**, **schema-free protobuf decoding**, a **Dex-VMP differential** harness,
|
||||
and **kernel-module templates with their version gates** — and it corrected two earlier claims
|
||||
whose measurements disagreed with them. Unity/IL2CPP logic recovery,
|
||||
whose measurements disagreed with them. A **hardware pass** then added the layer under the
|
||||
software tooling: **hardware watchpoints** with their honest `TracerPid` ledger, **ETE/TRBE
|
||||
differential tracing** with its five gates, and **kernel-side injection templates** — every
|
||||
host-checkable piece measured, every device-bound piece labelled `unverified` until a gate
|
||||
opens. Unity/IL2CPP logic recovery,
|
||||
React Native/Hermes bytecode internals, and defeating a server-side authority are **not**
|
||||
covered, and the skill is written to say so and stop rather than apply the nearest
|
||||
documented procedure to a target it was not written for.
|
||||
|
||||
Reference in New Issue
Block a user