pe_assembler/formats/exe/reader/
mod.rs1use crate::{
2 helpers::{
3 pe_reader::{read_pe_head, read_pe_program, read_pe_section_headers},
4 PeReader,
5 },
6 types::{PeHeader, PeInfo, PeProgram, SectionHeader},
7};
8use gaia_types::{GaiaDiagnostics, GaiaError};
9use std::io::{Read, Seek, SeekFrom};
10
11#[derive(Debug)]
13pub struct ExeReader<R> {
14 reader: R,
15 exe_header: Option<PeHeader>,
16 exe_info: Option<PeInfo>,
17 exe_section_headers: Option<Vec<SectionHeader>>,
18 exe_program: Option<PeProgram>,
19 errors: Vec<GaiaError>,
20}
21
22impl<R: Read> Read for ExeReader<R> {
23 fn read(&mut self, buffer: &mut [u8]) -> std::io::Result<usize> {
24 self.reader.read(buffer)
25 }
26}
27
28impl<R: Seek> Seek for ExeReader<R> {
29 fn seek(&mut self, position: SeekFrom) -> std::io::Result<u64> {
30 self.reader.seek(position)
31 }
32}
33
34impl<R> ExeReader<R> {
35 pub fn new(reader: R) -> Self {
36 Self { reader, exe_header: None, exe_section_headers: None, exe_program: None, exe_info: None, errors: vec![] }
37 }
38
39 pub fn finish(mut self) -> GaiaDiagnostics<PeProgram>
40 where
41 R: Read + Seek,
42 {
43 if self.exe_program.is_none() {
44 if let Err(e) = read_pe_program(&mut self) {
45 return GaiaDiagnostics { result: Err(e), diagnostics: self.errors };
46 }
47 }
48 unsafe {
49 let exe = self.exe_program.unwrap_unchecked();
50 GaiaDiagnostics { result: Ok(exe), diagnostics: self.errors }
51 }
52 }
53}
54
55impl<R: Read + Seek> PeReader<R> for ExeReader<R> {
56 fn get_viewer(&mut self) -> &mut R {
57 &mut self.reader
58 }
59
60 fn add_diagnostics(&mut self, error: impl Into<GaiaError>) {
61 self.errors.push(error.into());
62 }
63
64 fn get_section_headers(&mut self) -> Result<&[SectionHeader], GaiaError> {
65 if self.exe_section_headers.is_none() {
66 self.exe_section_headers = Some(read_pe_section_headers(self)?);
67 }
68 unsafe { Ok(self.exe_section_headers.as_ref().unwrap_unchecked()) }
69 }
70
71 fn get_pe_header(&mut self) -> Result<&PeHeader, GaiaError> {
72 if self.exe_header.is_none() {
73 self.exe_header = Some(read_pe_head(self)?)
74 }
75 unsafe { Ok(self.exe_header.as_ref().unwrap_unchecked()) }
76 }
77
78 fn get_program(&mut self) -> Result<&PeProgram, GaiaError> {
79 if self.exe_program.is_none() {
80 self.exe_program = Some(read_pe_program(self)?);
81 }
82 unsafe { Ok(self.exe_program.as_ref().unwrap_unchecked()) }
83 }
84}