1use std::prelude::v1::*;
6
7use crate::Result;
8
9use super::pe::validate_headers;
10use super::{Align, Pe, PeObject};
11
12#[derive(Copy, Clone)]
14pub struct PeFile<'a> {
15 image: &'a [u8],
16}
17
18impl<'a> PeFile<'a> {
19 pub fn from_bytes<T: AsRef<[u8]> + ?Sized>(image: &'a T) -> Result<PeFile<'a>> {
38 let image = image.as_ref();
39 let _ = validate_headers(image)?;
40 Ok(PeFile { image })
41 }
42 pub fn to_view(self) -> Vec<u8> {
44 let (sizeof_headers, sizeof_image) = {
45 let optional_header = self.optional_header();
46 (optional_header.SizeOfHeaders, optional_header.SizeOfImage)
47 };
48
49 let mut vec = vec![0u8; sizeof_image as usize];
51
52 let image = self.image();
54 unsafe {
55 let dest_headers = vec.get_unchecked_mut(..sizeof_headers as usize);
57 let src_headers = image.get_unchecked(..sizeof_headers as usize);
58 dest_headers.copy_from_slice(src_headers);
59 }
60
61 for section in self.section_headers() {
63 let dest = vec.get_mut(section.VirtualAddress as usize..u32::wrapping_add(section.VirtualAddress, section.VirtualSize) as usize);
64 let src = image.get(section.PointerToRawData as usize..u32::wrapping_add(section.PointerToRawData, section.SizeOfRawData) as usize);
65 if let (Some(dest), Some(src)) = (dest, src) {
67 dest.copy_from_slice(src);
68 }
69 }
70
71 vec
72 }
73}
74
75unsafe impl<'a> Pe<'a> for PeFile<'a> {}
78
79unsafe impl<'a> PeObject<'a> for PeFile<'a> {
80 fn image(&self) -> &'a [u8] {
81 self.image
82 }
83 fn align(&self) -> Align {
84 Align::File
85 }
86 #[cfg(feature = "serde")]
87 fn serde_name(&self) -> &'static str {
88 "PeFile"
89 }
90}
91
92#[cfg(feature = "serde")]
95impl<'a> serde::Serialize for PeFile<'a> {
96 fn serialize<S: serde::Serializer>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error> {
97 super::pe::serialize_pe(*self, serializer)
98 }
99}
100
101#[test]
104fn from_byte_slice() {
105 assert!(match PeFile::from_bytes(&[]) { Err(crate::Error::Bounds) => true, _ => false });
106}