Harden FIFA17 SBC dispatch repair

This commit is contained in:
funman300
2026-08-18 20:20:27 +00:00
parent 6cdb45e482
commit 1c7111ddbf
+17
View File
@@ -92,6 +92,7 @@ enum Rejection {
ReaderMissing,
ParseFailed,
ResponseClassMismatch,
ModelChanged,
ModelEmpty,
NotifierNotCurrent,
ControllerMismatch,
@@ -118,6 +119,7 @@ struct DecisionInput {
deserializer_thread: usize,
response_class_matches: bool,
model: usize,
live_category_count: usize,
category_count: usize,
notifier_entries: u64,
notifier_exits: u64,
@@ -175,6 +177,9 @@ fn decide(input: DecisionInput) -> Result<Decision, Rejection> {
if input.model == 0 || input.category_count == 0 || input.category_count == usize::MAX {
return Err(Rejection::ModelEmpty);
}
if input.live_category_count != input.category_count {
return Err(Rejection::ModelChanged);
}
if input.notifier_entries != generation
|| input.notifier_entries == 0
|| input.notifier_exits.checked_add(1) != Some(input.notifier_entries)
@@ -265,6 +270,12 @@ unsafe extern "system" fn completion_wrapper(
let response_vtable = crate::sbc_trace::guarded_usize(evidence.deserializer_this);
let captured_controller = SBC_CONTROLLER.load(Ordering::Acquire);
let live_category_count = evidence
.model
.checked_add(0x50)
.and_then(|address| crate::sbc_trace::guarded_u16(address))
.map(usize::from)
.unwrap_or(usize::MAX);
let (controller_matches, controller_model_matches) =
controller_identity(evidence.base, captured_controller, evidence.model);
let input = DecisionInput {
@@ -287,6 +298,7 @@ unsafe extern "system" fn completion_wrapper(
response_class_matches: response_vtable
== evidence.base.checked_add(CATEGORY_RESPONSE_VTABLE_RVA),
model: evidence.model,
live_category_count,
category_count: evidence.category_count,
notifier_entries: evidence.notifier_entries,
notifier_exits: evidence.notifier_exits,
@@ -676,6 +688,7 @@ mod tests {
deserializer_thread: 7,
response_class_matches: true,
model: 0x4000,
live_category_count: 2,
category_count: 2,
notifier_entries: generation,
notifier_exits: generation - 1,
@@ -731,6 +744,10 @@ mod tests {
let mut input = valid_input(1);
input.controller_model_matches = false;
assert_eq!(decide(input), Err(Rejection::ControllerModelMismatch));
let mut input = valid_input(1);
input.live_category_count = 0;
assert_eq!(decide(input), Err(Rejection::ModelChanged));
}
#[test]