Skip to main content

mediatek_optical/receiver/entry/application/
registration.rs

1//! Static opcode/callback records, separate from executable lookup evidence.
2
3/// Unique static WRITE BUFFER/type-one registration for a Thumb handler.
4/// This alone does not prove registration initialization or dispatcher use.
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
6pub struct Registration {
7    /// Address of the eight-byte descriptor/function-pointer record.
8    pub record: u32,
9    /// Even address of the Thumb callback.
10    pub callback: u32,
11}
12
13/// Find exactly one aligned record containing opcode 0x3B/type 1 and the
14/// supplied Thumb callback. Unknown types, non-Thumb pointers, duplicates,
15/// truncated records and address overflow never supply a registration.
16pub fn inspect_registration(bytes: &[u8], address: u32, callback: u32) -> Option<Registration> {
17    if callback & 1 != 0 {
18        return None;
19    }
20    let pointer = callback.checked_add(1)?.to_le_bytes();
21    let mut found = None;
22    for offset in 0..bytes.len().saturating_sub(7) {
23        let at = address.checked_add(u32::try_from(offset).ok()?)?;
24        if at & 3 != 0 {
25            continue;
26        }
27        at.checked_add(8)?;
28        if bytes[offset..offset + 4] == [0x3b, 1, 0, 0] && bytes[offset + 4..offset + 8] == pointer
29        {
30            if found.is_some() {
31                return None;
32            }
33            found = Some(Registration {
34                record: at,
35                callback,
36            });
37        }
38    }
39    found
40}
41
42#[cfg(test)]
43mod tests {
44    use super::*;
45
46    #[test]
47    fn real_v1_record_binds_opcode_type_and_thumb_pointer_uniquely() {
48        let record = [0x3b, 1, 0, 0, 3, 0xca, 9, 0];
49        assert_eq!(
50            inspect_registration(&record, 0x155ba8, 0x9ca02),
51            Some(Registration {
52                record: 0x155ba8,
53                callback: 0x9ca02
54            })
55        );
56        for i in 0..8 {
57            let mut bad = record;
58            bad[i] ^= 1;
59            assert!(inspect_registration(&bad, 0x155ba8, 0x9ca02).is_none());
60            assert!(inspect_registration(&record[..i], 0x155ba8, 0x9ca02).is_none());
61        }
62        let mut duplicate = record.to_vec();
63        duplicate.extend_from_slice(&record);
64        assert!(inspect_registration(&duplicate, 0x155ba8, 0x9ca02).is_none());
65        assert!(inspect_registration(&record, 0x155ba9, 0x9ca02).is_none());
66        assert!(inspect_registration(&record, u32::MAX - 3, 0x9ca02).is_none());
67        assert!(inspect_registration(&record, 0x155ba8, 0x9ca03).is_none());
68    }
69}