mediatek_optical/receiver/entry/application/
registration.rs1#[derive(Debug, Clone, Copy, PartialEq, Eq)]
6pub struct Registration {
7 pub record: u32,
9 pub callback: u32,
11}
12
13pub 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}