Skip to content

Commit

Permalink
move pe parsing into separate crate
Browse files Browse the repository at this point in the history
  • Loading branch information
evmar committed Feb 19, 2025
1 parent a214d26 commit 05cccc2
Show file tree
Hide file tree
Showing 21 changed files with 98 additions and 71 deletions.
12 changes: 12 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ members = [
"exe/rust",
"exe/zip",
"minibuild",
"pe",
"web/glue",
"win32/derive",
"win32/extract",
Expand All @@ -14,6 +15,7 @@ members = [
[workspace.dependencies]
log = "0.4"
memory = { path = "memory" }
pe = { path = "pe" }
win32 = { path = "win32" }
x86 = { path = "x86" }
tsify = "0.4.1"
Expand Down
1 change: 1 addition & 0 deletions HACKING.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ information.

- `x86/` -- the x86 emulator
- [`win32/`](win32/) -- the win32 emulator
- `pe/` -- PE (.exe/.dll) parser
- `cli/` -- a command-line emulator runner
- [`web/`](web/) -- a webapp that runs the emulator in a browser
- `exe/` -- some sample Windows executables
Expand Down
12 changes: 12 additions & 0 deletions pe/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[package]
name = "pe"
version = "0.1.0"
edition = "2021"

[dependencies]
log = { workspace = true }
memory = { workspace = true }

anyhow = "1.0"
bitflags = "1.3.2"
serde = "1.0"
6 changes: 6 additions & 0 deletions pe/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# PE parser

This crate traverses Windows Portable Executable (PE) files, aka .exe and .dll.

It doesn't interact with any of the emulation machinery, it just accepts byte
buffers and returns different views on to them.
File renamed without changes.
77 changes: 38 additions & 39 deletions win32/src/pe/file.rs → pe/src/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
#![allow(non_camel_case_types)]

use super::reader::Reader;
use crate::winapi::types::{DWORD, WORD};
use anyhow::{anyhow, bail};
use bitflags::bitflags;
use memory::Extensions;
Expand All @@ -13,19 +12,19 @@ use memory::Extensions;
fn dos_header<'m>(r: &mut Reader<'m>) -> anyhow::Result<u32> {
r.expect("MZ")?;
r.skip(0x3a)?;
Ok(r.read::<DWORD>())
Ok(r.read::<u32>())
}

#[derive(Debug, Default, Clone)]
#[repr(C)]
pub struct IMAGE_FILE_HEADER {
pub Machine: WORD,
pub NumberOfSections: WORD,
pub TimeDateStamp: DWORD,
pub PointerToSymbolTable: DWORD,
pub NumberOfSymbols: DWORD,
pub SizeOfOptionalHeader: WORD,
pub Characteristics: WORD,
pub Machine: u16,
pub NumberOfSections: u16,
pub TimeDateStamp: u32,
pub PointerToSymbolTable: u32,
pub NumberOfSymbols: u32,
pub SizeOfOptionalHeader: u16,
pub Characteristics: u16,
}
unsafe impl memory::Pod for IMAGE_FILE_HEADER {}

Expand All @@ -48,44 +47,44 @@ bitflags! {
#[repr(C)]
#[derive(Debug, Clone)]
pub struct IMAGE_OPTIONAL_HEADER32 {
pub Magic: WORD,
pub Magic: u16,
pub MajorLinkerVersion: u8,
pub MinorLinkerVersion: u8,
pub SizeOfCode: DWORD,
pub SizeOfInitializedData: DWORD,
pub SizeOfUninitializedData: DWORD,
pub AddressOfEntryPoint: DWORD,
pub BaseOfCode: DWORD,
pub BaseOfData: DWORD,
pub ImageBase: DWORD,
pub SectionAlignment: DWORD,
pub FileAlignment: DWORD,
pub MajorOperatingSystemVersion: WORD,
pub MinorOperatingSystemVersion: WORD,
pub MajorImageVersion: WORD,
pub MinorImageVersion: WORD,
pub MajorSubsystemVersion: WORD,
pub MinorSubsystemVersion: WORD,
pub Win32VersionValue: DWORD,
pub SizeOfImage: DWORD,
pub SizeOfHeaders: DWORD,
pub CheckSum: DWORD,
pub Subsystem: WORD,
pub DllCharacteristics: WORD,
pub SizeOfStackReserve: DWORD,
pub SizeOfStackCommit: DWORD,
pub SizeOfHeapReserve: DWORD,
pub SizeOfHeapCommit: DWORD,
pub LoaderFlags: DWORD,
pub NumberOfRvaAndSizes: DWORD,
pub SizeOfCode: u32,
pub SizeOfInitializedData: u32,
pub SizeOfUninitializedData: u32,
pub AddressOfEntryPoint: u32,
pub BaseOfCode: u32,
pub BaseOfData: u32,
pub ImageBase: u32,
pub SectionAlignment: u32,
pub FileAlignment: u32,
pub MajorOperatingSystemVersion: u16,
pub MinorOperatingSystemVersion: u16,
pub MajorImageVersion: u16,
pub MinorImageVersion: u16,
pub MajorSubsystemVersion: u16,
pub MinorSubsystemVersion: u16,
pub Win32VersionValue: u32,
pub SizeOfImage: u32,
pub SizeOfHeaders: u32,
pub CheckSum: u32,
pub Subsystem: u16,
pub DllCharacteristics: u16,
pub SizeOfStackReserve: u32,
pub SizeOfStackCommit: u32,
pub SizeOfHeapReserve: u32,
pub SizeOfHeapCommit: u32,
pub LoaderFlags: u32,
pub NumberOfRvaAndSizes: u32,
}
unsafe impl memory::Pod for IMAGE_OPTIONAL_HEADER32 {}

#[repr(C)]
#[derive(Clone, Debug, Default)]
pub struct IMAGE_DATA_DIRECTORY {
pub VirtualAddress: DWORD,
pub Size: DWORD,
pub VirtualAddress: u32,
pub Size: u32,
}
unsafe impl memory::Pod for IMAGE_DATA_DIRECTORY {}
impl IMAGE_DATA_DIRECTORY {
Expand Down
25 changes: 19 additions & 6 deletions win32/src/pe/imports.rs → pe/src/imports.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#![allow(non_snake_case)]
#![allow(non_camel_case_types)]

use crate::winapi::{types::DWORD, ImportSymbol};
use memory::{str16, Extensions};

// http://sandsprite.com/CodeStuff/Understanding_imports.html
Expand All @@ -21,12 +20,12 @@ use memory::{str16, Extensions};
#[repr(C)]
pub struct IMAGE_IMPORT_DESCRIPTOR {
/// ILT
OriginalFirstThunk: DWORD,
TimeDateStamp: DWORD,
ForwarderChain: DWORD,
Name: DWORD,
OriginalFirstThunk: u32,
TimeDateStamp: u32,
ForwarderChain: u32,
Name: u32,
/// IAT
FirstThunk: DWORD,
FirstThunk: u32,
}
unsafe impl memory::Pod for IMAGE_IMPORT_DESCRIPTOR {}

Expand Down Expand Up @@ -66,6 +65,20 @@ pub fn read_imports<'m>(buf: &'m [u8]) -> impl Iterator<Item = IMAGE_IMPORT_DESC
pub struct ILTEntry(u32);
unsafe impl memory::Pod for ILTEntry {}

#[derive(Debug)]
pub enum ImportSymbol<'a> {
Name(&'a str),
Ordinal(u32),
}
impl<'a> std::fmt::Display for ImportSymbol<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ImportSymbol::Name(name) => f.write_str(name),
ImportSymbol::Ordinal(ord) => f.write_fmt(format_args!("{}", ord)),
}
}
}

impl ILTEntry {
pub fn as_import_symbol(self, image: &[u8]) -> ImportSymbol {
let entry = self.0;
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
3 changes: 1 addition & 2 deletions win32/src/pe/resources.rs → pe/src/resources.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@
#![allow(non_snake_case)]
#![allow(non_camel_case_types)]

use crate::str16::Str16;
use memory::Extensions;
use memory::{str16::Str16, Extensions};
use std::{mem::size_of, ops::Range};

#[repr(C)]
Expand Down
1 change: 1 addition & 0 deletions win32/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ edition = "2021"
[dependencies]
log = { workspace = true }
memory = { workspace = true }
pe = { workspace = true }
win32-derive = { path = "derive" }
x86 = { workspace = true, optional = true }

Expand Down
1 change: 0 additions & 1 deletion win32/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
mod host;
pub mod loader;
mod machine;
pub mod pe;
mod segments;
pub mod shims;
pub mod trace;
Expand Down
2 changes: 1 addition & 1 deletion win32/src/loader.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! PE image loading.
use crate::{machine::Machine, pe, winapi};
use crate::{machine::Machine, winapi};
use memory::{Extensions, ExtensionsMut};
use std::{collections::HashMap, path::Path};

Expand Down
3 changes: 2 additions & 1 deletion win32/src/winapi/kernel32/dll.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ use crate::{
winapi::kernel32::set_last_error,
};
use memory::{str16, Extensions, Pod};
use pe::ImportSymbol;

use crate::{
host,
machine::Machine,
winapi::{self, builtin, calling_convention::ArrayWithSizeMut, types::*, ImportSymbol},
winapi::{self, builtin, calling_convention::ArrayWithSizeMut, types::*},
};
use std::io::Write;
use typed_path::WindowsPath;
Expand Down
1 change: 0 additions & 1 deletion win32/src/winapi/kernel32/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ use super::{
use crate::{
loader,
machine::MemImpl,
pe,
segments::SegmentDescriptor,
winapi::{alloc::Arena, handle::Handles, heap::Heap, types::*},
Machine,
Expand Down
7 changes: 3 additions & 4 deletions win32/src/winapi/kernel32/memory.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use crate::{
machine::{Machine, MemImpl},
pe::IMAGE_SCN,
winapi::calling_convention,
};
use bitflags::bitflags;
Expand All @@ -18,7 +17,7 @@ pub struct Mapping {
pub addr: u32,
pub size: u32,
pub desc: String,
pub flags: IMAGE_SCN,
pub flags: pe::IMAGE_SCN,
}

impl Mapping {
Expand All @@ -37,7 +36,7 @@ impl Mappings {
addr: 0,
size: 0x1000,
desc: "avoid null pointers".into(),
flags: IMAGE_SCN::empty(),
flags: pe::IMAGE_SCN::empty(),
}])
}

Expand Down Expand Up @@ -92,7 +91,7 @@ impl Mappings {
addr,
size,
desc,
flags: IMAGE_SCN::empty(),
flags: pe::IMAGE_SCN::empty(),
})
}

Expand Down
1 change: 0 additions & 1 deletion win32/src/winapi/kernel32/resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ use crate::winapi::kernel32::HMODULE;
use crate::winapi::types::HRSRC;
use crate::winapi::user32::HINSTANCE;
use crate::{
pe,
winapi::{
calling_convention::FromArg,
kernel32,
Expand Down
14 changes: 0 additions & 14 deletions win32/src/winapi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,6 @@ mod winmm;

pub use error::ERROR;

#[derive(Debug)]
pub enum ImportSymbol<'a> {
Name(&'a str),
Ordinal(u32),
}
impl<'a> std::fmt::Display for ImportSymbol<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ImportSymbol::Name(name) => f.write_str(name),
ImportSymbol::Ordinal(ord) => f.write_fmt(format_args!("{}", ord)),
}
}
}

pub struct State {
scratch: heap::Heap,

Expand Down
1 change: 0 additions & 1 deletion win32/src/winapi/user32/resource.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use super::{HINSTANCE, HMENU};
use crate::{
pe,
winapi::{
bitmap::{Bitmap, BITMAPFILEHEADER},
gdi32::HGDIOBJ,
Expand Down

0 comments on commit 05cccc2

Please sign in to comment.