Skip to content

Instantly share code, notes, and snippets.

@paavohuhtala
Created November 10, 2016 20:57
Show Gist options
  • Save paavohuhtala/c21231c9672a3b2713483e2b9cd7990c to your computer and use it in GitHub Desktop.
Save paavohuhtala/c21231c9672a3b2713483e2b9cd7990c to your computer and use it in GitHub Desktop.
PE parsing with rust
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