1use crate::error::{HaoError, Result};
2use crate::io::DataReader;
3
4use pewter::pe::optional_header::OptionalHeader;
5use pewter::pe::sections::cor20::ImageCor20Header;
6use pewter::pe::sections::{SectionRow};
7use pewter::PEFile;
8
9pub struct PEImage<'a> {
10 pub pe: PEFile<'a>,
11}
12
13impl<'a> PEImage<'a> {
14 pub fn load_bytes(data: &'a [u8]) -> Result<Self> {
15 let pe = PEFile::parse(data).map_err(|_| HaoError::BadPeFormat)?;
16
17 Ok(Self { pe })
18 }
19
20 pub fn optional_header(&self) -> Result<&OptionalHeader> {
21 self.pe.optional_header.as_ref().ok_or(HaoError::BadPeFormat)
22 }
23
24 pub fn rva_to_section(&self, rva: u32) -> Option<&SectionRow> {
25 self.pe.sections.find_rva(rva as usize)
26 }
27
28 pub fn rva_to_file_offset_(&self, _rva: u32) -> Result<usize> {
29 todo!()
30 }
31
32 pub fn create_reader(&self, rva: u32, size: Option<usize>) -> Result<DataReader<'a>> {
33 let data = self
34 .pe
35 .sections
36 .find_rva_data(rva as usize)
37 .ok_or_else(|| HaoError::BadRva(rva))?;
38
39 let data = if let Some(size) = size {
40 &data[..size]
41 } else {
42 data
43 };
44
45 Ok(DataReader::new(data))
46 }
47
48 pub fn read_clr_rt_header(&self) -> Result<ImageCor20Header> {
49 let clr = self
50 .pe
51 .read_clr_runtime_header()
52 .map_err(|_| HaoError::BadImageFormat("Failed to read image cor20 header"))?;
53
54 let header = clr.ok_or(HaoError::NotDotNetBinary)?;
55
56 Ok(header)
57 }
58}