Line data Source code
1 : //! Module for the ELF file format support in LIEF.
2 : //!
3 : //! The [`Binary`] structure exposes the main API to inspect an ELF file. It can be instantiated,
4 : //! using either: [`crate::elf::parse`], [`crate::elf::Binary::parse`] or [`crate::Binary::parse`]
5 : //!
6 : //! ```
7 : //! let elf = lief::elf::parse("/bin/ls").unwrap();
8 : //! for section in elf.sections() {
9 : //! println!("section: {}", section.name());
10 : //! }
11 : //! ```
12 :
13 : use std::path::Path;
14 : use lief_ffi as ffi;
15 : use crate::common::AsFFI;
16 :
17 : pub mod binary;
18 : pub mod builder;
19 : pub mod dynamic;
20 : pub mod hash;
21 : pub mod header;
22 : pub mod note;
23 : pub mod relocation;
24 : pub mod section;
25 : pub mod segment;
26 : pub mod symbol;
27 : pub mod symbol_versioning;
28 : pub mod parser_config;
29 :
30 : #[doc(inline)]
31 : pub use binary::Binary;
32 :
33 : #[doc(inline)]
34 : pub use header::Header;
35 :
36 : #[doc(inline)]
37 : pub use section::Section;
38 :
39 : #[doc(inline)]
40 : pub use segment::Segment;
41 :
42 : #[doc(inline)]
43 : pub use symbol::Symbol;
44 :
45 : #[doc(inline)]
46 : pub use hash::Sysv as SysvHash;
47 :
48 : #[doc(inline)]
49 : pub use hash::Gnu as GnuHash;
50 :
51 : #[doc(inline)]
52 : pub use note::Notes;
53 :
54 : #[doc(inline)]
55 : pub use dynamic::Entries as DynamicEntries;
56 :
57 : #[doc(inline)]
58 : pub use relocation::Relocation;
59 :
60 : #[doc(inline)]
61 : pub use symbol_versioning::{
62 : SymbolVersion, SymbolVersionAux, SymbolVersionAuxRequirement, SymbolVersionDefinition,
63 : SymbolVersionRequirement,
64 : };
65 :
66 : #[doc(inline)]
67 : pub use parser_config::Config as ParserConfig;
68 :
69 : /// Strategy used for relocating the PHDR table
70 : #[allow(non_camel_case_types)]
71 0 : #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
72 : pub enum PhdrReloc {
73 : /// Let LIEF choose the best strategy
74 : AUTO,
75 : /// Shift content after the PHDR table (PIE binaries only)
76 : PIE_SHIFT,
77 : /// Relocate the PHDR after the first BSS-like segment
78 : BSS_END,
79 : /// Relocate at the end of the binary
80 : BINARY_END,
81 : /// Relocate between two LOAD segments
82 : SEGMENT_GAP,
83 : UNKNOWN(u32),
84 : }
85 :
86 : impl From<u32> for PhdrReloc {
87 0 : fn from(value: u32) -> Self {
88 0 : match value {
89 0 : 0 => PhdrReloc::AUTO,
90 0 : 1 => PhdrReloc::PIE_SHIFT,
91 0 : 2 => PhdrReloc::BSS_END,
92 0 : 3 => PhdrReloc::BINARY_END,
93 0 : 4 => PhdrReloc::SEGMENT_GAP,
94 0 : _ => PhdrReloc::UNKNOWN(value),
95 : }
96 0 : }
97 : }
98 :
99 : impl From<PhdrReloc> for u32 {
100 0 : fn from(value: PhdrReloc) -> u32 {
101 0 : match value {
102 0 : PhdrReloc::AUTO => 0,
103 0 : PhdrReloc::PIE_SHIFT => 1,
104 0 : PhdrReloc::BSS_END => 2,
105 0 : PhdrReloc::BINARY_END => 3,
106 0 : PhdrReloc::SEGMENT_GAP => 4,
107 0 : PhdrReloc::UNKNOWN(v) => v,
108 : }
109 0 : }
110 : }
111 :
112 : /// Strategy for inserting a new section
113 : #[allow(non_camel_case_types)]
114 0 : #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
115 : pub enum SecInsertPos {
116 : /// Let LIEF choose the best strategy
117 : AUTO,
118 : /// Insert after the last segment offset, before debug info
119 : POST_SEGMENT,
120 : /// Insert after the last section offset, at binary end
121 : POST_SECTION,
122 : UNKNOWN(u32),
123 : }
124 :
125 : impl From<u32> for SecInsertPos {
126 0 : fn from(value: u32) -> Self {
127 0 : match value {
128 0 : 0 => SecInsertPos::AUTO,
129 0 : 1 => SecInsertPos::POST_SEGMENT,
130 0 : 2 => SecInsertPos::POST_SECTION,
131 0 : _ => SecInsertPos::UNKNOWN(value),
132 : }
133 0 : }
134 : }
135 :
136 : impl From<SecInsertPos> for u32 {
137 0 : fn from(value: SecInsertPos) -> u32 {
138 0 : match value {
139 0 : SecInsertPos::AUTO => 0,
140 0 : SecInsertPos::POST_SEGMENT => 1,
141 0 : SecInsertPos::POST_SECTION => 2,
142 0 : SecInsertPos::UNKNOWN(v) => v,
143 : }
144 0 : }
145 : }
146 :
147 : /// Parse an ELF file from the given filepath
148 0 : pub fn parse<P: AsRef<Path>>(path: P) -> Option<Binary> {
149 0 : Binary::parse(path)
150 0 : }
151 :
152 : /// Parse an ELF file from the given filepath and configuration
153 0 : pub fn parse_with_config<P: AsRef<Path>>(path: P, config: &ParserConfig) -> Option<Binary> {
154 0 : Binary::parse_with_config(path, config)
155 0 : }
156 :
157 : /// Check that the layout of the given binary is correct
158 0 : pub fn check_layout(binary: &Binary) -> Result<(), String> {
159 0 : cxx::let_cxx_string!(error = "");
160 0 : unsafe {
161 0 : if ffi::ELF_Utils::check_layout(binary.as_ffi(), error.as_mut().get_unchecked_mut()) {
162 0 : return Ok(());
163 0 : }
164 0 : }
165 0 : Err(error.to_string())
166 0 : }
|