LIEF: Library to Instrument Executable Formats Version 2.0.0
Loading...
Searching...
No Matches
runtime/Memory.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_MEMORY_H
17#define LIEF_RUNTIME_MEMORY_H
18#include "LIEF/errors.hpp"
19#include <cstdint>
20#include <cstring>
21#include <ostream>
22#include <string>
23#include <utility>
24#include <vector>
25
27#include "LIEF/logging.hpp"
28#include "LIEF/visibility.h"
29#include <optional>
30
32
33
34namespace LIEF::runtime {
35
38 public:
40 enum MMAP_FLAGS : uint32_t {
42
44 MP_PRIVATE = 1 << 0,
45
47 MP_ANONYMOUS = 1 << 1,
48
50 MP_SHARED = 1 << 2,
51
53 MP_FIXED = 1 << 3,
54
56 MP_JIT = 1 << 4,
57 };
58
59 enum PERM : uint32_t {
60 P_NONE = 0,
61 P_READ = 1 << 0,
62 P_WRITE = 1 << 1,
63 P_EXEC = 1 << 2,
64 };
65
69 public:
70 friend class Memory;
71
72 Chunk(void* addr, size_t size, uint32_t permissions) :
73 addr_(addr),
74 size_(size),
75 permissions_(permissions) {}
76
77 Chunk(void* addr, size_t size) :
78 Chunk(addr, size, /*permissions=*/P_NONE) {}
79
80 Chunk(void* addr) :
81 Chunk(addr, /*size=*/0, /*permissions=*/P_NONE) {}
82
84 void* addr_ptr() {
85 return addr_;
86 }
87
88 const void* addr_ptr() const {
89 return addr_;
90 }
91
93 uintptr_t addr() const {
94 return reinterpret_cast<uintptr_t>(addr_);
95 }
96
98 size_t size() const {
99 return size_;
100 }
101
103 uint32_t permissions() const {
104 return permissions_;
105 }
106
108 uintptr_t page_start() const;
109
110
112 uintptr_t page_end() const;
113
116 if (!Memory::mprotect(*this, p)) {
117 logging::err("mprotect failed for chunk: {}", to_string());
118 }
119 permissions_ = p;
120 return *this;
121 }
122
127
132
137
142
147
151
153 bool is_valid() const {
154 return addr_ != nullptr;
155 }
156
157 operator bool() const {
158 return is_valid();
159 }
160
162 return Memory::munmap(*this);
163 }
164
165 std::string to_string() const;
166
167 friend LIEF_API std::ostream& operator<<(std::ostream& os, const Chunk& C) {
168 os << C.to_string();
169 return os;
170 }
171
172 protected:
173 void* addr_ = 0;
174 size_t size_ = 0;
175 uint32_t permissions_ = P_NONE;
176 };
177
180 public:
181 explicit ScopedPermissions(Chunk& chunk, uint32_t perms) :
182 chunk_(&chunk),
183 perms_(chunk.permissions()) {
184 chunk_->change_permissions(perms);
185 }
186
188 chunk_->change_permissions(perms_);
189 }
190
191 private:
192 Chunk* chunk_ = nullptr;
193 uint32_t perms_ = P_NONE;
194 };
195
197 static std::optional<Chunk> mmap(size_t size, uint32_t flags,
198 uint32_t permissions = P_NONE);
199
202
204 static ok_error_t mprotect(Chunk& C, uint32_t flags);
205
210 static ok_error_t write(const uint8_t* buffer, size_t size, uintptr_t addr) {
211 std::memcpy(reinterpret_cast<void*>(addr), buffer, size);
212 return ok();
213 }
214
219 static ok_error_t write(const std::vector<uint8_t>& buffer, uintptr_t addr) {
220 return write(buffer.data(), buffer.size(), addr);
221 }
222
224 template<class T, typename = std::enable_if_t<std::is_standard_layout_v<T> &&
225 std::is_trivial_v<T>>>
226 static ok_error_t write(const T& value, uintptr_t addr) {
227 return write(reinterpret_cast<const uint8_t*>(&value), sizeof(T), addr);
228 }
229
231 template<class T>
232 static T read(uintptr_t addr) {
233 T out{};
234 std::memcpy(&out, reinterpret_cast<const void*>(addr), sizeof(T));
235 return out;
236 }
237
240 static void read(uintptr_t addr, std::vector<uint8_t>& out, size_t size) {
241 if (out.size() < size) {
242 std::vector<uint8_t> buffer(size);
243 read(addr, buffer.data(), buffer.size());
244 out = std::move(buffer);
245 return;
246 }
247 read(addr, out.data(), size);
248 }
249
255 static void read(uintptr_t addr, uint8_t* out, size_t size) {
256 std::memcpy(out, reinterpret_cast<const void*>(addr), size);
257 }
258
259 static std::string perm_str(uint32_t flags);
260
261 static constexpr bool support_rwx() {
262 return platform() != PLATFORMS::IOS;
263 }
264};
265
266}
267
268#endif
Opaque structure that is used by LIEF to avoid writing result<void> f(...). Instead,...
Definition errors.hpp:119
Represents a contiguous chunk of memory allocated or inspected by the runtime.
Definition runtime/Memory.hpp:68
Chunk & make_rx()
Sets the permissions to Read and Execute.
Definition runtime/Memory.hpp:134
friend std::ostream & operator<<(std::ostream &os, const Chunk &C)
Definition runtime/Memory.hpp:167
Chunk(void *addr, size_t size, uint32_t permissions)
Definition runtime/Memory.hpp:72
uint32_t permissions() const
Returns the current permissions of the memory chunk.
Definition runtime/Memory.hpp:103
friend class Memory
Definition runtime/Memory.hpp:70
Chunk & make_rwx()
Sets the permissions to Read, Write, and Execute.
Definition runtime/Memory.hpp:139
Chunk(void *addr, size_t size)
Definition runtime/Memory.hpp:77
bool is_valid() const
Check if this chunk is valid.
Definition runtime/Memory.hpp:153
uintptr_t page_end() const
Returns the address of the end of the page containing this chunk.
Chunk(void *addr)
Definition runtime/Memory.hpp:80
Chunk & cache_flush()
Flushes the instruction cache for this memory chunk. This should be used when modifying code in memor...
Chunk & make_x()
Sets the permissions to Execute only.
Definition runtime/Memory.hpp:124
std::string to_string() const
const void * addr_ptr() const
Definition runtime/Memory.hpp:88
size_t size() const
Returns the size of the memory chunk in bytes.
Definition runtime/Memory.hpp:98
uintptr_t page_start() const
Returns the address of the start of the page containing this chunk.
Chunk & make_ro()
Sets the permissions to Read Only.
Definition runtime/Memory.hpp:144
Chunk & make_rw()
Sets the permissions to Read and Write.
Definition runtime/Memory.hpp:129
Chunk & change_permissions(uint32_t p)
Changes the permissions of the memory chunk.
Definition runtime/Memory.hpp:115
void * addr_ptr()
Returns the start address of the memory chunk as an opaque pointer.
Definition runtime/Memory.hpp:84
ok_error_t deallocate()
Definition runtime/Memory.hpp:161
uintptr_t addr() const
Returns the start address of the memory chunk.
Definition runtime/Memory.hpp:93
~ScopedPermissions()
Definition runtime/Memory.hpp:187
ScopedPermissions(Chunk &chunk, uint32_t perms)
Definition runtime/Memory.hpp:181
This class exposes API to access and manage memory.
Definition runtime/Memory.hpp:37
MMAP_FLAGS
Flags used when creating a memory map (mmap).
Definition runtime/Memory.hpp:40
@ MP_FIXED
Interpret the address as a fixed requirement.
Definition runtime/Memory.hpp:53
@ MP_JIT
Map for Just-In-Time code generation.
Definition runtime/Memory.hpp:56
@ MP_NONE
Definition runtime/Memory.hpp:41
@ MP_PRIVATE
Changes are private to this process (copy-on-write).
Definition runtime/Memory.hpp:44
@ MP_SHARED
Changes are shared.
Definition runtime/Memory.hpp:50
@ MP_ANONYMOUS
The mapping is not backed by any file.
Definition runtime/Memory.hpp:47
static constexpr bool support_rwx()
Definition runtime/Memory.hpp:261
static ok_error_t mprotect(Chunk &C, uint32_t flags)
Sets the permission of the given memory chunk.
static ok_error_t munmap(Chunk &C)
Deallocate a mmaped memory chunk.
static void read(uintptr_t addr, uint8_t *out, size_t size)
Read the content at the address pointed by the first parameter and write the result in the buffer pro...
Definition runtime/Memory.hpp:255
static ok_error_t write(const T &value, uintptr_t addr)
Generic function to write a typed value.
Definition runtime/Memory.hpp:226
static std::optional< Chunk > mmap(size_t size, uint32_t flags, uint32_t permissions=P_NONE)
Allocate a memory chunk through mmap-like function.
static ok_error_t write(const uint8_t *buffer, size_t size, uintptr_t addr)
Write the buffer at the address given in the third parameter.
Definition runtime/Memory.hpp:210
static std::string perm_str(uint32_t flags)
static T read(uintptr_t addr)
Generic function to read a typed value.
Definition runtime/Memory.hpp:232
static ok_error_t write(const std::vector< uint8_t > &buffer, uintptr_t addr)
Write the buffer at the address given in the third parameter.
Definition runtime/Memory.hpp:219
PERM
Definition runtime/Memory.hpp:59
@ P_READ
Definition runtime/Memory.hpp:61
@ P_WRITE
Definition runtime/Memory.hpp:62
@ P_EXEC
Definition runtime/Memory.hpp:63
@ P_NONE
Definition runtime/Memory.hpp:60
static void read(uintptr_t addr, std::vector< uint8_t > &out, size_t size)
Read the content at the address pointed by the first parameter and write the result in the std::vecto...
Definition runtime/Memory.hpp:240
#define LIEF_LIFETIMEBOUND
Definition compiler_attributes.hpp:72
const char * to_string(lief_errors err)
void err(const std::string &msg)
Definition logging.hpp:143
Definition android/Host.hpp:24
@ IOS
Definition runtime/utils.hpp:34
ok_t ok()
Return success for function with return type ok_error_t.
Definition errors.hpp:103
#define LIEF_API
Definition visibility.h:45