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 32 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
22 32 : f.debug_struct("RichHeader")
23 32 : .field("key", &self.key())
24 32 : .finish()
25 32 : }
26 : }
27 :
28 : impl<'a> FromFFI<ffi::PE_RichHeader> for RichHeader<'a> {
29 32 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_RichHeader>) -> Self {
30 32 : RichHeader {
31 32 : ptr,
32 32 : _owner: PhantomData,
33 32 : }
34 32 : }
35 : }
36 :
37 : impl<'a> RichHeader<'a> {
38 : /// Key used to encode the header (xor operation)
39 32 : pub fn key(&self) -> u32 {
40 32 : self.ptr.key()
41 32 : }
42 :
43 : /// Return an iterator over the [`RichEntry`] within the header
44 32 : pub fn entries(&self) -> Entries {
45 32 : Entries::new(self.ptr.entries())
46 32 : }
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 360 : pub fn id(&self) -> u16 {
58 360 : self.ptr.id()
59 360 : }
60 :
61 : /// Build number of the tool (if any)
62 360 : pub fn build_id(&self) -> u16 {
63 360 : self.ptr.build_id()
64 360 : }
65 :
66 : /// *Occurrence* count.
67 360 : pub fn count(&self) -> u32 {
68 360 : self.ptr.count()
69 360 : }
70 : }
71 :
72 : impl std::fmt::Debug for RichEntry<'_> {
73 360 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
74 360 : f.debug_struct("RichEntry")
75 360 : .field("id", &self.id())
76 360 : .field("build_id", &self.build_id())
77 360 : .field("count", &self.count())
78 360 : .finish()
79 360 : }
80 : }
81 :
82 : impl<'a> FromFFI<ffi::PE_RichEntry> for RichEntry<'a> {
83 360 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_RichEntry>) -> Self {
84 360 : RichEntry {
85 360 : ptr,
86 360 : _owner: PhantomData,
87 360 : }
88 360 : }
89 : }
90 :
91 360 : declare_iterator!(
92 360 : Entries,
93 360 : RichEntry<'a>,
94 360 : ffi::PE_RichEntry,
95 360 : ffi::PE_RichHeader,
96 360 : ffi::PE_RichHeader_it_entries
97 360 : );
|