1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
//! # libgoblin
//!
//! 
//!
//! `libgoblin` is a cross-platform trifecta of binary parsing and loading fun. Currently, it supports:
//!
//! * the ELF32/64 formats
//! * A Unix archive parser and loader
//! * A PE 32-bit parser
//! * The mach parser is in progress
//!
//! Goblin requires at least `rustc` 1.15
//!
//! # Example
//!
//! ```rust
//! use goblin::{error, Hint, pe, elf, mach, archive};
//! use std::path::Path;
//! use std::env;
//! use std::fs::File;
//!
//! fn run () -> error::Result<()> {
//! for (i, arg) in env::args().enumerate() {
//! if i == 1 {
//! let path = Path::new(arg.as_str());
//! let mut fd = File::open(path)?;
//! match goblin::peek(&mut fd)? {
//! Hint::Elf(_) => {
//! let elf = elf::Elf::try_from(&mut fd)?;
//! println!("elf: {:#?}", &elf);
//! },
//! Hint::PE => {
//! let pe = pe::PE::try_from(&mut fd)?;
//! println!("pe: {:#?}", &pe);
//! },
//! // wip
//! Hint::Mach => {
//! let mach = mach::Mach::try_from(&mut fd)?;
//! println!("mach: {:#?}", &mach);
//! },
//! Hint::Archive => {
//! let archive = archive::Archive::try_from(&mut fd)?;
//! println!("archive: {:#?}", &archive);
//! },
//! _ => {}
//! }
//! }
//! }
//! Ok(())
//! }
//! ```
//!
//! # Feature Usage
//!
//! `libgoblin` is engineered to be tailored towards very different use-case scenarios, for example:
//!
//! * a no-std mode; just simply set default features to false
//! * a endian aware parsing and reading
//! * for binary loaders which don't require this, simply use `elf32` and `elf64` (and `std` of course)
//!
//! For example, if you are writing a 64-bit kernel, or just want a barebones C-like
//! header interface which defines the structures, just select `elf64`, `--cfg
//! feature=\"elf64\"`, which will compile without `std`.
//!
//! Similarly, if you want to use host endianness loading via the various `from_fd` methods, `--cfg
//! feature=\"std\"`, which will not use the `byteorder` extern crate, and read the bytes
//! from disk in the endianness of the host machine.
//!
//! If you want endian aware reading, and you don't use `default`, then you need to opt in as normal
//! via `endian_fd`
// if the no_endian feature flag is set the libary will only be able to
// process files with the same endianess as the machine.
extern crate scroll;
extern crate scroll_derive;
extern crate core;
// if racer gets path understanding, i think this is the way to go; it hides everything from the
// user w.r.t. module internals like _64, etc. though i did like the more declarative version
// below, without using paths, i just for the life of me cannot get the compiler to reexport values
// two mods down while keeping the internal mod name private... and i don't see anyone else doing
// this
pub use *;