Line data Source code
1 : //! PE Rich Header module
2 : use std::marker::PhantomData;
3 :
4 : use lief_ffi as ffi;
5 :
6 : use crate::{common::FromFFI, declare_iterator};
7 :
8 : /// Structure which represents the not-so-documented rich header
9 : ///
10 : /// This structure is usually located at the end of the [`crate::pe::Binary::dos_stub`]
11 : /// and contains information about the build environment.
12 : /// It is generated by the Microsoft linker `link.exe` and there are no options to disable
13 : /// or remove this information.
14 : pub struct RichHeader<'a> {
15 : ptr: cxx::UniquePtr<ffi::PE_RichHeader>,
16 : _owner: PhantomData<&'a ffi::PE_Binary>,
17 : }
18 :
19 : impl std::fmt::Debug for RichHeader<'_> {
20 104 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
21 104 : f.debug_struct("RichHeader")
22 104 : .field("key", &self.key())
23 104 : .finish()
24 104 : }
25 : }
26 :
27 : impl<'a> FromFFI<ffi::PE_RichHeader> for RichHeader<'a> {
28 104 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_RichHeader>) -> Self {
29 104 : RichHeader {
30 104 : ptr,
31 104 : _owner: PhantomData,
32 104 : }
33 104 : }
34 : }
35 :
36 : impl<'a> RichHeader<'a> {
37 : /// Key used to encode the header (xor operation)
38 104 : pub fn key(&self) -> u32 {
39 104 : self.ptr.key()
40 104 : }
41 :
42 : /// Return the raw bytes of the Rich header (decoded, without xor-encoding)
43 0 : pub fn raw(&self) -> Vec<u8> {
44 0 : Vec::from(self.ptr.raw().as_slice())
45 0 : }
46 :
47 : /// Return the raw bytes of the Rich header XOR-ed with the given key
48 0 : pub fn raw_with_key(&self, xor_key: u32) -> Vec<u8> {
49 0 : Vec::from(self.ptr.raw_with_key(xor_key).as_slice())
50 0 : }
51 :
52 : /// Return an iterator over the [`RichEntry`] within the header
53 104 : pub fn entries(&self) -> Entries<'_> {
54 104 : Entries::new(self.ptr.entries())
55 104 : }
56 : }
57 :
58 : pub struct RichEntry<'a> {
59 : ptr: cxx::UniquePtr<ffi::PE_RichEntry>,
60 : _owner: PhantomData<&'a ffi::PE_RichHeader>,
61 : }
62 :
63 : impl RichEntry<'_> {
64 : /// Entry type
65 1183 : pub fn id(&self) -> u16 {
66 1183 : self.ptr.id()
67 1183 : }
68 :
69 : /// Build number of the tool (if any)
70 1183 : pub fn build_id(&self) -> u16 {
71 1183 : self.ptr.build_id()
72 1183 : }
73 :
74 : /// *Occurrence* count.
75 1183 : pub fn count(&self) -> u32 {
76 1183 : self.ptr.count()
77 1183 : }
78 : }
79 :
80 : impl std::fmt::Debug for RichEntry<'_> {
81 1183 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
82 1183 : f.debug_struct("RichEntry")
83 1183 : .field("id", &self.id())
84 1183 : .field("build_id", &self.build_id())
85 1183 : .field("count", &self.count())
86 1183 : .finish()
87 1183 : }
88 : }
89 :
90 : impl<'a> FromFFI<ffi::PE_RichEntry> for RichEntry<'a> {
91 1183 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_RichEntry>) -> Self {
92 1183 : RichEntry {
93 1183 : ptr,
94 1183 : _owner: PhantomData,
95 1183 : }
96 1183 : }
97 : }
98 :
99 1183 : declare_iterator!(
100 1183 : Entries,
101 1183 : RichEntry<'a>,
102 1183 : ffi::PE_RichEntry,
103 1183 : ffi::PE_RichHeader,
104 1183 : ffi::PE_RichHeader_it_entries
105 1183 : );
|