PE import start (fixed header size -> sections work)
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user