PE import start (fixed header size -> sections work)

This commit is contained in:
2026-06-08 17:31:01 -04:00
parent c9add923be
commit c17122679e
9 changed files with 264 additions and 139 deletions
+49 -36
View File
@@ -1,33 +1,56 @@
use crate::backend::ByteEncoder;
use crate::backend::pe::data_dir::DataDir;
use super::ByteEncoder;
pub struct Import {
pub name: String,
pub names: Vec<String>,
}
pub fn encode(data: &mut ByteEncoder, imports: &[Import]) -> usize {
let mut names = 0;
for import in imports {
for name in &import.names {
data.extend(ImportLookupEntry::name().bytes());
names += 1;
pub fn encode(data: &mut ByteEncoder, imports: &[Import]) -> DataDir {
let start = data.pos() as u32;
let idt = data.reserve_arr::<ImportDirTable>(imports.len());
// null entry to mark end
data.pad(size_of::<ImportDirTable>());
let end = data.pos() as u32;
for (i, import) in imports.iter().enumerate() {
// name
let name_rva = data.pos() as u32;
data.extend(import.name.as_bytes());
data.push(0);
// lookup table
data.align(size_of::<ImportLookupEntry>());
let lookup_start = data.pos();
let lookup = data.reserve_arr::<ImportLookupEntry>(import.names.len());
data.pad(size_of::<ImportLookupEntry>());
let lookup_end = data.pos();
for (i, name) in import.names.iter().enumerate() {
let rva = hint_name_entry(data, 0, name);
data[lookup][i] = ImportLookupEntry::name(rva);
}
data.extend(ImportLookupEntry::NULL.bytes());
}
let table_addr = data.pos();
for import in imports {
let idt = ImportDirTable {
lookup_table_rva: todo!(),
// address table
data.align(size_of::<ImportLookupEntry>());
let addr_start = data.pos();
let len = lookup_end - lookup_start;
data.pad(len);
data.data.copy_within(lookup_start..lookup_end, addr_start);
// entry
data[idt][i] = ImportDirTable {
lookup_table_rva: lookup_start as u32,
time_date_stamp: 0,
forwarder_chain: 0,
name_rva: todo!(),
address_table_rva: todo!(),
name_rva,
address_table_rva: addr_start as u32,
};
}
for import in imports {
for name in &import.names {
hint_name_entry(data, 0, &name);
}
DataDir {
virt_addr_rva: start,
size: end - start,
}
}
@@ -40,16 +63,6 @@ pub struct ImportDirTable {
pub address_table_rva: u32,
}
impl ImportDirTable {
pub const NULL: Self = Self {
lookup_table_rva: 0,
time_date_stamp: 0,
forwarder_chain: 0,
name_rva: 0,
address_table_rva: 0,
};
}
#[repr(C)]
pub struct ImportLookupEntry(u64);
@@ -67,11 +80,11 @@ impl ImportLookupEntry {
}
}
pub fn hint_name_entry(out: &mut Vec<u8>, hint: u16, name: &str) {
out.extend(hint.to_le_bytes());
out.extend(name.as_bytes());
out.push(0);
if out.len() % 2 == 1 {
out.push(0);
}
pub fn hint_name_entry(data: &mut ByteEncoder, hint: u16, name: &str) -> u32 {
let pos = data.pos() as u32;
data.extend(hint.to_le_bytes());
data.extend(name.as_bytes());
data.push(0);
data.align(2);
pos
}