Nothing to see here, move along meow
0

Configure Feed

Select the types of activity you want to include in your feed.

at main 4.8 kB View raw
1use lancer_core::elf; 2 3fn make_minimal_elf(entry: u64, machine: u16, class: u8, segments: &[(u64, u64, u64)]) -> Vec<u8> { 4 let ehdr_size = 64u16; 5 let phdr_size = 56u16; 6 let phdr_offset = ehdr_size as u64; 7 let phdr_count = segments.len() as u16; 8 9 let total_header = ehdr_size as usize + phdr_size as usize * segments.len(); 10 let mut buf = vec![0u8; total_header + 4096]; 11 12 buf[0..4].copy_from_slice(&[0x7f, b'E', b'L', b'F']); 13 buf[4] = class; 14 buf[5] = 1; 15 buf[16..18].copy_from_slice(&2u16.to_le_bytes()); 16 buf[18..20].copy_from_slice(&machine.to_le_bytes()); 17 buf[20..24].copy_from_slice(&1u32.to_le_bytes()); 18 buf[24..32].copy_from_slice(&entry.to_le_bytes()); 19 buf[32..40].copy_from_slice(&phdr_offset.to_le_bytes()); 20 buf[52..54].copy_from_slice(&ehdr_size.to_le_bytes()); 21 buf[54..56].copy_from_slice(&phdr_size.to_le_bytes()); 22 buf[56..58].copy_from_slice(&phdr_count.to_le_bytes()); 23 24 segments 25 .iter() 26 .enumerate() 27 .for_each(|(i, &(vaddr, filesz, memsz))| { 28 let off = ehdr_size as usize + phdr_size as usize * i; 29 let data_offset = total_header as u64; 30 buf[off..off + 4].copy_from_slice(&1u32.to_le_bytes()); 31 buf[off + 4..off + 8].copy_from_slice(&5u32.to_le_bytes()); 32 buf[off + 8..off + 16].copy_from_slice(&data_offset.to_le_bytes()); 33 buf[off + 16..off + 24].copy_from_slice(&vaddr.to_le_bytes()); 34 buf[off + 24..off + 32].copy_from_slice(&0u64.to_le_bytes()); 35 buf[off + 32..off + 40].copy_from_slice(&filesz.to_le_bytes()); 36 buf[off + 40..off + 48].copy_from_slice(&memsz.to_le_bytes()); 37 buf[off + 48..off + 56].copy_from_slice(&0x1000u64.to_le_bytes()); 38 }); 39 40 buf 41} 42 43#[test] 44fn parse_valid_elf() { 45 let data = make_minimal_elf(0x401000, 0x3E, 2, &[(0x401000, 256, 512)]); 46 let info = elf::parse(&data).expect("should parse valid ELF"); 47 assert_eq!(info.entry, 0x401000); 48 assert_eq!(info.segments.len(), 1); 49 let seg = info.segments.get(0).unwrap(); 50 assert_eq!(seg.vaddr, 0x401000); 51 assert_eq!(seg.filesz, 256); 52 assert_eq!(seg.memsz, 512); 53} 54 55#[test] 56fn parse_multiple_segments() { 57 let data = make_minimal_elf(0x1000, 0x3E, 2, &[(0x1000, 128, 256), (0x2000, 64, 128)]); 58 let info = elf::parse(&data).expect("should parse"); 59 assert_eq!(info.segments.len(), 2); 60} 61 62#[test] 63fn reject_truncated() { 64 let data = vec![0x7f, b'E', b'L', b'F']; 65 assert_eq!(elf::parse(&data).unwrap_err(), elf::ElfError::Truncated); 66} 67 68#[test] 69fn reject_bad_magic() { 70 let mut data = make_minimal_elf(0x1000, 0x3E, 2, &[]); 71 data[0] = 0x00; 72 assert_eq!(elf::parse(&data).unwrap_err(), elf::ElfError::BadMagic); 73} 74 75#[test] 76fn reject_wrong_machine() { 77 let data = make_minimal_elf(0x1000, 0xB7, 2, &[]); 78 assert_eq!( 79 elf::parse(&data).unwrap_err(), 80 elf::ElfError::UnsupportedFormat 81 ); 82} 83 84#[test] 85fn reject_32bit_class() { 86 let data = make_minimal_elf(0x1000, 0x3E, 1, &[]); 87 assert_eq!( 88 elf::parse(&data).unwrap_err(), 89 elf::ElfError::UnsupportedFormat 90 ); 91} 92 93#[test] 94fn random_bytes_no_panic() { 95 let data: Vec<u8> = (0..512).map(|i| ((i * 37 + 13) % 256) as u8).collect(); 96 let _ = elf::parse(&data); 97} 98 99#[test] 100fn empty_input() { 101 assert_eq!(elf::parse(&[]).unwrap_err(), elf::ElfError::Truncated); 102} 103 104#[test] 105fn header_exact_size_no_segments() { 106 let full = make_minimal_elf(0x1000, 0x3E, 2, &[]); 107 let exact = &full[..64]; 108 let info = elf::parse(exact).expect("exact-header-size ELF with 0 phdrs should parse"); 109 assert_eq!(info.entry, 0x1000); 110 assert_eq!(info.segments.len(), 0); 111} 112 113#[test] 114fn header_one_byte_short_truncates() { 115 let full = make_minimal_elf(0x1000, 0x3E, 2, &[]); 116 let short = &full[..63]; 117 assert_eq!( 118 elf::parse(short).unwrap_err(), 119 elf::ElfError::Truncated, 120 "63 bytes (one short of Elf64Header) must be Truncated" 121 ); 122} 123 124#[test] 125fn phdr_ends_at_last_byte() { 126 let segments = &[(0x40_0000, 0, 4096)]; 127 let full = make_minimal_elf(0x40_0000, 0x3E, 2, segments); 128 let header_plus_phdr = 64 + 56; 129 let exact = &full[..header_plus_phdr]; 130 let info = elf::parse(exact).expect("data ending exactly after phdr should parse"); 131 assert_eq!(info.segments.len(), 1); 132} 133 134#[test] 135fn phdr_one_byte_short_skips_segment() { 136 let segments = &[(0x40_0000, 0, 4096)]; 137 let full = make_minimal_elf(0x40_0000, 0x3E, 2, segments); 138 let header_plus_phdr = 64 + 56; 139 let short = &full[..header_plus_phdr - 1]; 140 let info = elf::parse(short).expect("truncated phdr should be skipped, not fatal"); 141 assert_eq!( 142 info.segments.len(), 143 0, 144 "phdr truncated by 1 byte should be silently skipped via filter_map" 145 ); 146}