[Audit] round 9: generalize JIT-entry probe to PC-configurable cvar
Some checks failed
Orchestrator / Commit Message Validation (push) Has been skipped
Orchestrator / Lint (push) Failing after 1m18s
Orchestrator / Windows (x86-64) (push) Has been skipped
Orchestrator / Linux (x86-64) (push) Has been skipped
Orchestrator / Create Release (push) Has been skipped
Some checks failed
Orchestrator / Commit Message Validation (push) Has been skipped
Orchestrator / Lint (push) Failing after 1m18s
Orchestrator / Windows (x86-64) (push) Has been skipped
Orchestrator / Linux (x86-64) (push) Has been skipped
Orchestrator / Create Release (push) Has been skipped
Replace the round-7 hardcoded `current_guest_function_ == 0x824F7800` gate with a runtime cvar `audit_jit_prolog_pc` (uint32, 0 = disabled). The cvar names the guest entry PC at which the x64 emitter inserts a CallNative to the prolog probe; the probe now dumps the active PC in each log line so multiple instrumentation campaigns can share output. Renames `audit_log_sub824F7800_args` (cvar) and `AuditLogSub824F7800Args` (host function) — the round-7 sub_824F7800-specific cvar and function are deleted, not left dormant. The `audit_handle_lifecycle` cvar and its existing AUDIT-HLC probe sites in xboxkrnl_threading.cc / kernel_state.cc are untouched. Validated by audit-059 round 9: with `--audit_jit_prolog_pc=0x821B55D8` the silph WorkerCtx-init chain entry fires 1× in canary at tid=6 lr=0x82172D8C (call site at sub_82172BA0+0x1E8 `bctrl`, the virtual dispatch through vtable slot 6 that statically-blind xref-walkers cannot enumerate). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -41,13 +41,14 @@
|
|||||||
|
|
||||||
DEFINE_bool(debugprint_trap_log, false,
|
DEFINE_bool(debugprint_trap_log, false,
|
||||||
"Log debugprint traps to the active debugger", "CPU");
|
"Log debugprint traps to the active debugger", "CPU");
|
||||||
DEFINE_bool(audit_log_sub824F7800_args, false,
|
DEFINE_uint32(audit_jit_prolog_pc, 0,
|
||||||
"Emit one XELOGKERNEL line per JIT-compiled entry to guest function "
|
"Guest function entry PC at which to emit one XELOGKERNEL line "
|
||||||
"0x824F7800 (silph::WorkerCtx ctor's immediate caller; per audit-058 "
|
"per JIT-compiled entry. When non-zero, the x64 emitter inserts "
|
||||||
"fires exactly 1x after DiscImageDevice::ResolvePath). Dumps "
|
"a CallNative to AuditLogJitPrologArgs at the start of the JIT "
|
||||||
"r3..r10, LR, and 64 bytes at host(r3). Audit-059 round 7 probe — "
|
"body of the matching guest function. Dumps r3..r10, LR, and 64 "
|
||||||
"off by default.",
|
"bytes at host(r3). Zero (default) disables the probe. Audit-059 "
|
||||||
"Auditing");
|
"round 7+ JIT-prolog probe — generic PC-configurable variant.",
|
||||||
|
"Auditing");
|
||||||
DEFINE_bool(ignore_undefined_externs, true,
|
DEFINE_bool(ignore_undefined_externs, true,
|
||||||
"Don't exit when an undefined extern is called.", "CPU");
|
"Don't exit when an undefined extern is called.", "CPU");
|
||||||
DEFINE_bool(emit_source_annotations, false,
|
DEFINE_bool(emit_source_annotations, false,
|
||||||
@@ -277,14 +278,16 @@ bool X64Emitter::Emit(HIRBuilder* builder, EmitFunctionInfo& func_info) {
|
|||||||
count on no other code modifying it. mov(GetMembaseReg(),
|
count on no other code modifying it. mov(GetMembaseReg(),
|
||||||
qword[GetContextReg() + offsetof(ppc::PPCContext, virtual_membase)]);
|
qword[GetContextReg() + offsetof(ppc::PPCContext, virtual_membase)]);
|
||||||
*/
|
*/
|
||||||
// Audit-059 round 7: one-shot dump of r3..r10/LR at entry to sub_824F7800.
|
// Audit-059: PC-configurable JIT-prolog probe. Runtime-gated on the cvar
|
||||||
// Compile-time gated on guest function address; runtime gated on the cvar.
|
// audit_jit_prolog_pc (uint32; 0 disables). When non-zero and the current
|
||||||
|
// guest function's entry PC matches, emit a single CallNative to
|
||||||
|
// AuditLogJitPrologArgs that dumps r3..r10, LR, and 64 bytes at host(r3).
|
||||||
// Emits *before* any body instruction runs, so r3..r10 / LR in PPCContext
|
// Emits *before* any body instruction runs, so r3..r10 / LR in PPCContext
|
||||||
// still reflect the caller's args (no LOAD/STORE_CONTEXT has executed yet).
|
// still reflect the caller's args (no LOAD/STORE_CONTEXT has executed yet).
|
||||||
if (cvars::audit_log_sub824F7800_args &&
|
if (cvars::audit_jit_prolog_pc != 0u &&
|
||||||
current_guest_function_ == 0x824F7800u) {
|
current_guest_function_ == cvars::audit_jit_prolog_pc) {
|
||||||
extern uint64_t AuditLogSub824F7800Args(void* raw_context, uint64_t arg0);
|
extern uint64_t AuditLogJitPrologArgs(void* raw_context, uint64_t arg0);
|
||||||
CallNative(AuditLogSub824F7800Args, 0);
|
CallNative(AuditLogJitPrologArgs, 0);
|
||||||
}
|
}
|
||||||
// Body.
|
// Body.
|
||||||
auto block = builder->first_block();
|
auto block = builder->first_block();
|
||||||
@@ -454,12 +457,14 @@ uint64_t TrapDebugBreak(void* raw_context, uint64_t address) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Audit-059 round 7 probe: dump r3..r10, LR, and 64 bytes at host(r3) when
|
// Audit-059 JIT-prolog probe: dump r3..r10, LR, and 64 bytes at host(r3)
|
||||||
// the guest hits the JIT-compiled entry of sub_824F7800 (silph::WorkerCtx
|
// when the guest hits the JIT-compiled entry of the function whose entry PC
|
||||||
// ctor's immediate caller). Per audit-058 this fires exactly once after the
|
// matches cvars::audit_jit_prolog_pc. Generic PC-configurable variant of the
|
||||||
// DiscImageDevice::ResolvePath(\dat\movie) sequence on canary.
|
// round-7 sub_824F7800 hook. The hook logs the current guest PC so multiple
|
||||||
uint64_t AuditLogSub824F7800Args(void* raw_context, uint64_t /*unused*/) {
|
// instrumentation campaigns can share log output.
|
||||||
|
uint64_t AuditLogJitPrologArgs(void* raw_context, uint64_t /*unused*/) {
|
||||||
auto* ctx = reinterpret_cast<ppc::PPCContext_s*>(raw_context);
|
auto* ctx = reinterpret_cast<ppc::PPCContext_s*>(raw_context);
|
||||||
|
uint32_t pc = static_cast<uint32_t>(cvars::audit_jit_prolog_pc);
|
||||||
uint32_t r3 = static_cast<uint32_t>(ctx->r[3]);
|
uint32_t r3 = static_cast<uint32_t>(ctx->r[3]);
|
||||||
uint32_t r4 = static_cast<uint32_t>(ctx->r[4]);
|
uint32_t r4 = static_cast<uint32_t>(ctx->r[4]);
|
||||||
uint32_t r5 = static_cast<uint32_t>(ctx->r[5]);
|
uint32_t r5 = static_cast<uint32_t>(ctx->r[5]);
|
||||||
@@ -473,9 +478,9 @@ uint64_t AuditLogSub824F7800Args(void* raw_context, uint64_t /*unused*/) {
|
|||||||
uint32_t tid = ctx->thread_state ? ctx->thread_state->thread_id() : 0u;
|
uint32_t tid = ctx->thread_state ? ctx->thread_state->thread_id() : 0u;
|
||||||
|
|
||||||
XELOGKERNEL(
|
XELOGKERNEL(
|
||||||
"AUDIT-HLC sub_824F7800 entry tid={:08X} r3={:08X} r4={:08X} r5={:08X} "
|
"AUDIT-HLC JitProlog pc={:08X} tid={:08X} r3={:08X} r4={:08X} r5={:08X} "
|
||||||
"r6={:08X} r7={:08X} r8={:08X} r9={:08X} r10={:08X} lr={:08X}",
|
"r6={:08X} r7={:08X} r8={:08X} r9={:08X} r10={:08X} lr={:08X}",
|
||||||
tid, r3, r4, r5, r6, r7, r8, r9, r10, lr);
|
pc, tid, r3, r4, r5, r6, r7, r8, r9, r10, lr);
|
||||||
|
|
||||||
// Dump 64 bytes at host(r3) if r3 looks like a plausible guest VA.
|
// Dump 64 bytes at host(r3) if r3 looks like a plausible guest VA.
|
||||||
if (r3 >= 0x10000 && r3 < 0xE0000000) {
|
if (r3 >= 0x10000 && r3 < 0xE0000000) {
|
||||||
@@ -486,14 +491,17 @@ uint64_t AuditLogSub824F7800Args(void* raw_context, uint64_t /*unused*/) {
|
|||||||
uint32_t d1 = xe::load_and_swap<uint32_t>(host + off + 4);
|
uint32_t d1 = xe::load_and_swap<uint32_t>(host + off + 4);
|
||||||
uint32_t d2 = xe::load_and_swap<uint32_t>(host + off + 8);
|
uint32_t d2 = xe::load_and_swap<uint32_t>(host + off + 8);
|
||||||
uint32_t d3 = xe::load_and_swap<uint32_t>(host + off + 12);
|
uint32_t d3 = xe::load_and_swap<uint32_t>(host + off + 12);
|
||||||
XELOGKERNEL("AUDIT-HLC sub_824F7800 r3+{:02X}: {:08X} {:08X} {:08X} {:08X}",
|
XELOGKERNEL(
|
||||||
off, d0, d1, d2, d3);
|
"AUDIT-HLC JitProlog pc={:08X} r3+{:02X}: {:08X} {:08X} {:08X} "
|
||||||
|
"{:08X}",
|
||||||
|
pc, off, d0, d1, d2, d3);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
XELOGKERNEL("AUDIT-HLC sub_824F7800 r3 translate failed");
|
XELOGKERNEL("AUDIT-HLC JitProlog pc={:08X} r3 translate failed", pc);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
XELOGKERNEL("AUDIT-HLC sub_824F7800 r3 out of VA range, skipping dump");
|
XELOGKERNEL("AUDIT-HLC JitProlog pc={:08X} r3 out of VA range, skipping dump",
|
||||||
|
pc);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user