Created
November 10, 2016 20:57
-
-
Save paavohuhtala/c21231c9672a3b2713483e2b9cd7990c to your computer and use it in GitHub Desktop.
PE parsing with rust
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std; | |
use std::io::{Read, Seek, SeekFrom}; | |
use byteorder::{ReadBytesExt, LittleEndian}; | |
trait ReadableStruct { | |
fn read_from<R: Read + Seek>(reader: &mut R) -> Result<Self, std::io::Error> where Self : std::marker::Sized; | |
} | |
#[derive(Debug)] | |
pub struct DataDirectory { | |
virtual_address: u32, | |
size: u32 | |
} | |
impl ReadableStruct for DataDirectory { | |
fn read_from<R: Read + Seek>(mut reader: &mut R) -> Result<DataDirectory, std::io::Error> { | |
let virtual_address = reader.read_u32::<LittleEndian>()?; | |
let size = reader.read_u32::<LittleEndian>()?; | |
Ok (DataDirectory { virtual_address: virtual_address, size: size }) | |
} | |
} | |
#[derive(Debug)] | |
pub struct PEFile { | |
msil: Vec<u8> | |
} | |
impl PEFile { | |
pub fn read_from<R: Read + Seek>(mut reader: R) -> Result<PEFile, std::io::Error> { | |
println!("Reading PE file..."); | |
let mut dos_magic = [0 as u8; 2]; | |
reader.read_exact(&mut dos_magic)?; | |
assert_eq!(0x4D as u8, dos_magic[0]); | |
assert_eq!(0x5A as u8, dos_magic[1]); | |
println!("DOS Magic ✓"); | |
reader.seek(SeekFrom::Start(0x3C))?; | |
let pe_header_start = reader.read_u32::<LittleEndian>()?; | |
println!("PE header pointer: {}", pe_header_start); | |
reader.seek(SeekFrom::Start(pe_header_start as u64))?; | |
let mut pe_magic = [0 as u8; 4]; | |
reader.read_exact(&mut pe_magic)?; | |
assert_eq!('P' as u8, pe_magic[0]); | |
assert_eq!('E' as u8, pe_magic[1]); | |
assert_eq!(0 as u8, pe_magic[2]); | |
assert_eq!(0 as u8, pe_magic[3]); | |
println!("PE Magic ✓"); | |
let coff_header_start = pe_header_start + 4; | |
let coff_opt_header_start = coff_header_start + 20; | |
let rvas_and_sizes_offset = coff_opt_header_start + 92; | |
reader.seek(SeekFrom::Start(rvas_and_sizes_offset as u64))?; | |
let rva_count = reader.read_u32::<LittleEndian>()?; | |
println!("RVA count: {}", rva_count); | |
let mut rvas: Vec<DataDirectory> = vec![]; | |
for i in 0 .. rva_count { | |
let rva = DataDirectory::read_from(&mut reader)?; | |
println!("RVA {}: {:?}", i, rva); | |
rvas.push(rva); | |
} | |
Ok (PEFile { msil: vec![] }) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment