LIEF: Library to Instrument Executable Formats Version 2.0.0
Loading...
Searching...
No Matches
Module.hpp
Go to the documentation of this file.
1/* Copyright 2017 - 2026 R. Thomas
2 * Copyright 2017 - 2026 Quarkslab
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#ifndef LIEF_RUNTIME_MODULE_H
17#define LIEF_RUNTIME_MODULE_H
18#include <string_view>
19#include <cstdint>
20#include <cstring>
21#include <fstream>
22#include <ostream>
23
25#include "LIEF/iterators.hpp"
26#include "LIEF/visibility.h"
27
28#include <memory>
29#include <string>
30#include <vector>
31
32namespace LIEF {
33class Binary;
34namespace runtime {
35
36namespace details {
37class ModuleIt;
38class Module;
39}
40
44 public:
45 class Iterator final
46 : public iterator_facade_base<Iterator, std::forward_iterator_tag, Module,
47 std::ptrdiff_t, const Module*, const Module&> {
48 public:
49 using implementation = details::ModuleIt;
50 using iterator_facade_base::operator++;
51
53
56
58 LIEF_API Iterator& operator=(Iterator&&) noexcept;
59
60 LIEF_API Iterator(std::unique_ptr<details::ModuleIt> impl);
62
63 friend LIEF_API bool operator==(const Iterator& LHS, const Iterator& RHS);
64 friend LIEF_API bool operator!=(const Iterator& LHS, const Iterator& RHS) {
65 return !(LHS == RHS);
66 }
67
68 // NOLINTNEXTLINE(bugprone-derived-method-shadowing-base-method)
70
72
73 // NOLINTNEXTLINE(bugprone-derived-method-shadowing-base-method)
74 LIEF_API const Module* operator->() const LIEF_LIFETIMEBOUND;
75
78 LIEF_API std::unique_ptr<Module> yield();
79
80 private:
81 void load() const;
82
83 std::unique_ptr<details::ModuleIt> impl_;
84 mutable std::unique_ptr<Module> cached_;
85 };
86 Module() = delete;
87 Module(std::unique_ptr<details::Module> impl);
88
89 Module(const Module&) = delete;
90 Module& operator=(const Module&) = delete;
91
92 Module(Module&&) noexcept;
93 Module& operator=(Module&&) noexcept;
94
95 virtual std::unique_ptr<Module> clone() const;
96
98 uint64_t imagebase() const;
99
101 uint64_t size() const;
102
104 uint64_t end() const {
105 return imagebase() + size();
106 }
107
109 std::string name() const;
110
112 std::string path() const;
113
115 bool contains(uintptr_t addr) const {
116 const uint64_t base = imagebase();
117 return base <= addr && addr < (base + size());
118 }
119
124 std::vector<uint8_t> dump() const {
125 const uint64_t base = imagebase();
126 const uint64_t nbytes = size();
127 if (base == 0 || nbytes == 0) {
128 return {};
129 }
130 std::vector<uint8_t> out(nbytes);
131 std::memcpy(out.data(), reinterpret_cast<const void*>(base), nbytes);
132 return out;
133 }
134
137 std::vector<uint8_t> dump(const std::string& filepath) const {
138 std::vector<uint8_t> out = dump();
139 std::ofstream ofs(filepath, std::ios::out | std::ios::binary);
140 if (ofs) {
141 ofs.write(reinterpret_cast<const char*>(out.data()),
142 // NOLINTNEXTLINE(clang-taidy-avoid-static-integer-cast)
143 static_cast<std::streamsize>(out.size()));
144 }
145 return out;
146 }
147
149 std::vector<uint8_t> dump(std::ostream& os) const {
150 std::vector<uint8_t> out = dump();
151 os.write(reinterpret_cast<const char*>(out.data()),
152 // NOLINTNEXTLINE(clang-taidy-avoid-static-integer-cast)
153 static_cast<std::streamsize>(out.size()));
154 return out;
155 }
156
157 std::string to_string() const;
158
160 template<class T>
161 const T* as() const LIEF_LIFETIMEBOUND {
162 static_assert(std::is_base_of_v<Module, T>, "Require Module inheritance");
163 if (T::classof(this)) {
164 return static_cast<const T*>(this);
165 }
166 return nullptr;
167 }
168
169 template<class T>
171 return const_cast<T*>(static_cast<const Module*>(this)->as<T>());
172 }
173
174 LIEF_API friend std::ostream& operator<<(std::ostream& os, const Module& M) {
175 os << M.to_string();
176 return os;
177 }
178
179 virtual ~Module();
180
181 protected:
182 std::unique_ptr<details::Module> impl_;
183};
184
186
190
194LIEF_API std::unique_ptr<Module> current_module();
195
197inline std::unique_ptr<Module> module_from_name(std::string_view name) {
198 auto range = modules();
199 for (auto it = range.begin(); it != range.end(); ++it) {
200 if (it->name() == name) {
201 return it.yield();
202 }
203 }
204 return nullptr;
205}
206
208inline std::unique_ptr<Module> module_from_path(std::string_view path) {
209 auto range = modules();
210 for (auto it = range.begin(); it != range.end(); ++it) {
211 if (it->path() == path) {
212 return it.yield();
213 }
214 }
215 return nullptr;
216}
217
219inline std::unique_ptr<Module> module_from_addr(uintptr_t addr) {
220 auto range = modules();
221 for (auto it = range.begin(); it != range.end(); ++it) {
222 if (it->contains(addr)) {
223 return it.yield();
224 }
225 }
226 return nullptr;
227}
228
229}
230}
231#endif
Generic interface representing a binary executable.
Definition Abstract/Binary.hpp:61
Definition iterators.hpp:681
Iterator(Iterator &&) noexcept
Iterator & operator=(const Iterator &)
details::ModuleIt implementation
Definition Module.hpp:49
const Module & operator*() const
std::unique_ptr< Module > yield()
Transfer ownership of the module at the current position to the caller. Returns nullptr if the iterat...
virtual std::unique_ptr< Module > clone() const
std::vector< uint8_t > dump(std::ostream &os) const
Same as dump() but also writes the content into the given output stream.
Definition Module.hpp:149
uint64_t imagebase() const
Base address where the module is loaded in memory.
friend std::ostream & operator<<(std::ostream &os, const Module &M)
Definition Module.hpp:174
T * as()
Definition Module.hpp:170
bool contains(uintptr_t addr) const
Check if the current module contains the given address.
Definition Module.hpp:115
uint64_t end() const
End address of the module.
Definition Module.hpp:104
std::vector< uint8_t > dump() const
Return the content of the module as it is currently mapped in memory.
Definition Module.hpp:124
std::string to_string() const
std::vector< uint8_t > dump(const std::string &filepath) const
Same as dump() but also writes the content into the file located at filepath.
Definition Module.hpp:137
std::string name() const
Name of the module (e.g. libc.so.6, kernel32.dll, libsystem_c.dylib).
std::string path() const
Path of the module.
uint64_t size() const
Virtual size of the current module.
const T * as() const
This function can be used to downcast a Module instance.
Definition Module.hpp:161
#define LIEF_LIFETIMEBOUND
Definition compiler_attributes.hpp:72
Definition MemoryLayout.hpp:34
Definition android/Host.hpp:24
modules_t modules()
Return an iterator over the different modules loaded in the current process.
iterator_range< Module::Iterator > modules_t
Definition Module.hpp:185
std::unique_ptr< Module > module_from_path(std::string_view path)
Find the module with the given path.
Definition Module.hpp:208
std::unique_ptr< Module > module_from_name(std::string_view name)
Find the module with the given name.
Definition Module.hpp:197
std::unique_ptr< Module > current_module()
Return the current module: the module that contains the code calling this function (e....
std::unique_ptr< Module > module_from_addr(uintptr_t addr)
Find the module that encompasses the given virtual address (absolute).
Definition Module.hpp:219
LIEF namespace.
Definition Abstract/Binary.hpp:42
#define LIEF_API
Definition visibility.h:45