///|
pub fn PEImage::imports(self : Self) -> Array[ImportLibrary] raise PeError {
let directory = match self.directory(1) {
Some(directory) if directory.virtual_address != 0UL && directory.size > 0 =>
directory
_ => return []
}
let descriptor_offset = self.rva_to_offset(directory.virtual_address)
let directory_limit = if directory.size >= 20 {
directory.size / 20
} else {
4096
}
let descriptor_limit = if directory_limit < 4096 {
directory_limit
} else {
4096
}
let libraries = []
for index in 0.. Array[ImportSymbol] raise PeError {
if thunk_rva == 0UL {
return []
}
let entry_size = if self.is_64_bit() { 8 } else { 4 }
let symbols = []
let mut index = 0
while index < 65536 {
let entry = if self.is_64_bit() {
let offset = self.rva_to_offset(
thunk_rva + (index * entry_size).to_uint64(),
)
read_u64(self.data, offset)
} else {
let offset = self.rva_to_offset(
thunk_rva + (index * entry_size).to_uint64(),
)
read_u32(self.data, offset)
}
if entry == 0UL {
break
}
let ordinal_mask = if self.is_64_bit() {
0x8000000000000000UL
} else {
0x80000000UL
}
if entry.land(ordinal_mask) != 0UL {
symbols.push({
name: None,
ordinal: Some(entry.land(0xffffUL).to_int()),
hint: None,
})
} else {
let name_rva = if self.is_64_bit() {
entry.land(0x7fffffffffffffffUL)
} else {
entry.land(0x7fffffffUL)
}
let name_offset = self.rva_to_offset(name_rva)
let hint = read_u16(self.data, name_offset)
let name = read_ascii_z(self.data, name_offset + 2, 4096)
symbols.push({ name: Some(name), ordinal: None, hint: Some(hint), })
}
index = index + 1
}
symbols
}