Skip to main content

bootc_internal_utils/
uki.rs

1/// Create a minimal valid PE file for testing UKI parsing
2pub fn create_minimal_pe() -> Vec<u8> {
3    let mut pe = Vec::new();
4    let section_data_offset = 0x200u32; // Standard section alignment
5    let section_data = b"quiet splash"; // Sample cmdline content
6
7    // DOS header (64 bytes)
8    pe.extend_from_slice(b"MZ"); // e_magic
9    pe.extend_from_slice(&[0u8; 58]); // DOS header padding
10    pe.extend_from_slice(&0x80u32.to_le_bytes()); // e_lfanew (offset to PE header)
11
12    // DOS stub padding to reach offset 0x80
13    pe.resize(0x80, 0);
14
15    // PE header (4 bytes)
16    pe.extend_from_slice(b"PE\0\0");
17
18    // COFF header (20 bytes)
19    pe.extend_from_slice(&0x8664u16.to_le_bytes()); // machine (x64)
20    pe.extend_from_slice(&1u16.to_le_bytes()); // number of sections
21    pe.extend_from_slice(&0u32.to_le_bytes()); // timestamp
22    pe.extend_from_slice(&0u32.to_le_bytes()); // pointer to symbol table
23    pe.extend_from_slice(&0u32.to_le_bytes()); // number of symbols
24    pe.extend_from_slice(&0xF0u16.to_le_bytes()); // size of optional header
25    pe.extend_from_slice(&0x2022u16.to_le_bytes()); // characteristics
26
27    // Optional header (240 bytes for PE32+)
28    pe.extend_from_slice(&0x020Bu16.to_le_bytes()); // magic (PE32+)
29    pe.extend_from_slice(&[0u8; 0xF0 - 2]); // rest of optional header filled with zeros
30
31    // Section header (40 bytes)
32    let mut section_header = [0u8; 40];
33    section_header[..8].copy_from_slice(b".cmdline"); // name
34    section_header[8..12].copy_from_slice(&(section_data.len() as u32).to_le_bytes()); // virtual_size
35    section_header[12..16].copy_from_slice(&0x1000u32.to_le_bytes()); // virtual_address
36    section_header[16..20].copy_from_slice(&(section_data.len() as u32).to_le_bytes()); // size_of_raw_data
37    section_header[20..24].copy_from_slice(&section_data_offset.to_le_bytes()); // pointer_to_raw_data
38    section_header[36..40].copy_from_slice(&0x40000040u32.to_le_bytes()); // characteristics (readable)
39    pe.extend_from_slice(&section_header);
40
41    // Pad to section data offset
42    pe.resize(section_data_offset as usize, 0);
43
44    // Section data
45    pe.extend_from_slice(section_data);
46
47    pe
48}