trace FIFA17 provider lifecycle
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Trace FIFA17 ACTION_ADVANCE dispatch after MATCH_CREATED delivery.
|
||||
"""Trace FIFA17 provider dispatch and ACTION_ADVANCE delivery boundaries.
|
||||
|
||||
Stage one (`match_transition_trace.py`) proves the HTTP response, deserializer,
|
||||
and FUT_CREATE_MATCH_DP delivery. This stage uses that provider callback to
|
||||
capture the screen key, then records every nested global UI dispatch for that
|
||||
same screen until the positive-control FUT_GET_MATCH_KITS_DP arrives. It also
|
||||
captures the low-level create event and final native-to-UI provider bridge.
|
||||
This probe correlates the global UI dispatch of FUT_CREATE_MATCH_DP and
|
||||
FUT_GET_MATCH_KITS_DP, the subscribed CardsDLL provider, the internal 0x7546
|
||||
create-response callback that can replay FUT_CREATE_MATCH_DP, and the final
|
||||
native-to-UI bridge. At global dispatch, r8d is the provider ID and rdx is the
|
||||
payload; neither register is a screen key.
|
||||
|
||||
The generated GDB program uses hardware-assisted execution breakpoints only.
|
||||
It never writes client memory and never drives game input.
|
||||
@@ -84,28 +84,22 @@ handle SIGUSR1 nostop noprint pass
|
||||
handle SIGUSR2 nostop noprint pass
|
||||
|
||||
attach {pid}
|
||||
set $screen_key = 0
|
||||
set $target_seen = 0
|
||||
|
||||
hbreak *0x{address['provider']:x}
|
||||
condition 1 $edx == 0x{transition.FUT_CREATE_MATCH_DP:x} || $edx == 0x{transition.FUT_GET_MATCH_KITS_DP:x}
|
||||
commands
|
||||
silent
|
||||
if $edx == 0x{transition.FUT_CREATE_MATCH_DP:x}
|
||||
set $screen_key = $r8
|
||||
set $target_seen = 1
|
||||
end
|
||||
python import time; print("ADVTRACE epoch_ns=%d mono_ns=%d PROVIDER" % (time.time_ns(), time.monotonic_ns()), end=" ")
|
||||
printf "thread=%d provider=%#x screen_key=%p controller=%p caller=%p\\n", $_thread, $edx, $r8, $rcx, *(void**)$rsp
|
||||
printf "thread=%d provider=%#x payload=%p controller=%p caller=%p\\n", $_thread, $edx, $r8, $rcx, *(void**)$rsp
|
||||
continue
|
||||
end
|
||||
|
||||
hbreak *0x{address['global_dispatch']:x}
|
||||
condition 2 $target_seen != 0 && $r8 == $screen_key
|
||||
condition 2 $r8d == 0x{transition.FUT_CREATE_MATCH_DP:x} || $r8d == 0x{transition.FUT_GET_MATCH_KITS_DP:x}
|
||||
commands
|
||||
silent
|
||||
python import time; print("ADVTRACE epoch_ns=%d mono_ns=%d GLOBAL_DISPATCH" % (time.time_ns(), time.monotonic_ns()), end=" ")
|
||||
printf "thread=%d id=%#x screen_key=%p registry=%p caller=%p\\n", $_thread, $rdx, $r8, $rcx, *(void**)$rsp
|
||||
printf "thread=%d provider=%#x payload=%p manager=%p caller=%p\\n", $_thread, $r8d, $rdx, $rcx, *(void**)$rsp
|
||||
continue
|
||||
end
|
||||
|
||||
@@ -144,7 +138,8 @@ def selftest() -> None:
|
||||
assert script.count("hbreak *") == 4
|
||||
assert f"$edx == 0x{transition.FUT_CREATE_MATCH_DP:x}" in script
|
||||
assert f"$edx == 0x{transition.FUT_GET_MATCH_KITS_DP:x}" in script
|
||||
assert "$r8 == $screen_key" in script
|
||||
assert f"$r8d == 0x{transition.FUT_CREATE_MATCH_DP:x}" in script
|
||||
assert f"$r8d == 0x{transition.FUT_GET_MATCH_KITS_DP:x}" in script
|
||||
assert "CREATE_MATCH_CONTROLLER" in script
|
||||
assert "PROVIDER_BRIDGE" in script
|
||||
assert "set *(" not in script
|
||||
|
||||
Reference in New Issue
Block a user