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