LIEF: Library to Instrument Executable Formats Version 1.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 <ostream>
19#include <cstdint>
20#include <cstring>
21#include <vector>
22#include <utility>
23
24#include "LIEF/visibility.h"
25#include "LIEF/optional.hpp"
26#include "LIEF/logging.hpp"
28
30
31namespace LIEF {
32namespace runtime {
33
36 public:
38 enum MMAP_FLAGS : uint32_t {
40
42 MP_PRIVATE = 1 << 0,
43
45 MP_ANONYMOUS = 1 << 1,
46
48 MP_SHARED = 1 << 2,
49
51 MP_FIXED = 1 << 3,
52
54 MP_JIT = 1 << 4,
55 };
56
57 enum PERM : uint32_t {
58 P_NONE = 0,
59 P_READ = 1 << 0,
60 P_WRITE = 1 << 1,
61 P_EXEC = 1 << 2,
62 };
63
67 public:
68 friend class Memory;
69
70 Chunk(void* addr, size_t size, uint32_t permissions) :
71 addr_(addr),
72 size_(size),
73 permissions_(permissions) {}
74
75 Chunk(void* addr, size_t size) :
76 Chunk(addr, size, /*permissions=*/P_NONE) {}
77
78 Chunk(void* addr) :
79 Chunk(addr, /*size=*/0, /*permissions=*/P_NONE) {}
80
82 void* addr_ptr() {
83 return addr_;
84 }
85
86 const void* addr_ptr() const {
87 return addr_;
88 }
89
91 uintptr_t addr() const {
92 return reinterpret_cast<uintptr_t>(addr_);
93 }
94
96 size_t size() const {
97 return size_;
98 }
99
101 uint32_t permissions() const {
102 return permissions_;
103 }
104
106 uintptr_t page_start() const;
107
108
110 uintptr_t page_end() const;
111
114 if (!Memory::mprotect(*this, p)) {
115 logging::err("mprotect failed for chunk: {}", to_string());
116 }
117 permissions_ = p;
118 return *this;
119 }
120
125
130
135
140
145
149
151 bool is_valid() const {
152 return addr_ != nullptr;
153 }
154
155 operator bool() const {
156 return is_valid();
157 }
158
160 return Memory::munmap(*this);
161 }
162
163 std::string to_string() const;
164
165 friend LIEF_API std::ostream& operator<<(std::ostream& os, const Chunk& C) {
166 os << C.to_string();
167 return os;
168 }
169
170 protected:
171 void* addr_ = 0;
172 size_t size_ = 0;
173 uint32_t permissions_ = P_NONE;
174 };
175
178 public:
179 explicit ScopedPermissions(Chunk& chunk, uint32_t perms) :
180 chunk_(&chunk),
181 perms_(chunk.permissions()) {
182 chunk_->change_permissions(perms);
183 }
184
186 chunk_->change_permissions(perms_);
187 }
188
189 private:
190 Chunk* chunk_ = nullptr;
191 uint32_t perms_ = P_NONE;
192 };
193
195 static optional<Chunk> mmap(size_t size, uint32_t flags,
196 uint32_t permissions = P_NONE);
197
200
202 static ok_error_t mprotect(Chunk& C, uint32_t flags);
203
208 static ok_error_t write(const uint8_t* buffer, size_t size, uintptr_t addr) {
209 std::memcpy(reinterpret_cast<void*>(addr), buffer, size);
210 return ok();
211 }
212
217 static ok_error_t write(const std::vector<uint8_t>& buffer, uintptr_t addr) {
218 return write(buffer.data(), buffer.size(), addr);
219 }
220
222 template<class T,
223 typename = typename std::enable_if<std::is_standard_layout<T>::value &&
224 std::is_trivial<T>::value>::type>
225 static ok_error_t write(const T& value, uintptr_t addr) {
226 return write(reinterpret_cast<const uint8_t*>(&value), sizeof(T), addr);
227 }
228
230 template<class T>
231 static T read(uintptr_t addr) {
232 T out{};
233 std::memcpy(&out, reinterpret_cast<const void*>(addr), sizeof(T));
234 return out;
235 }
236
239 static void read(uintptr_t addr, std::vector<uint8_t>& out, size_t size) {
240 if (out.size() < size) {
241 std::vector<uint8_t> buffer(size);
242 read(addr, buffer.data(), buffer.size());
243 out = std::move(buffer);
244 return;
245 }
246 read(addr, out.data(), size);
247 }
248
254 static void read(uintptr_t addr, uint8_t* out, size_t size) {
255 std::memcpy(out, reinterpret_cast<const void*>(addr), size);
256 }
257
258 static std::string perm_str(uint32_t flags);
259
260 static constexpr bool support_rwx() {
261 return platform() != PLATFORMS::IOS;
262 }
263};
264
265}
266}
267#endif
Opaque structure that is used by LIEF to avoid writing result<void> f(...). Instead,...
Definition errors.hpp:119
Definition optional.hpp:23
Represents a contiguous chunk of memory allocated or inspected by the runtime.
Definition runtime/Memory.hpp:66
Chunk & make_rx()
Sets the permissions to Read and Execute.
Definition runtime/Memory.hpp:132
friend std::ostream & operator<<(std::ostream &os, const Chunk &C)
Definition runtime/Memory.hpp:165
Chunk(void *addr, size_t size, uint32_t permissions)
Definition runtime/Memory.hpp:70
uint32_t permissions() const
Returns the current permissions of the memory chunk.
Definition runtime/Memory.hpp:101
friend class Memory
Definition runtime/Memory.hpp:68
Chunk & make_rwx()
Sets the permissions to Read, Write, and Execute.
Definition runtime/Memory.hpp:137
Chunk(void *addr, size_t size)
Definition runtime/Memory.hpp:75
bool is_valid() const
Check if this chunk is valid.
Definition runtime/Memory.hpp:151
uintptr_t page_end() const
Returns the address of the end of the page containing this chunk.
Chunk(void *addr)
Definition runtime/Memory.hpp:78
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:122
std::string to_string() const
const void * addr_ptr() const
Definition runtime/Memory.hpp:86
size_t size() const
Returns the size of the memory chunk in bytes.
Definition runtime/Memory.hpp:96
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:142
Chunk & make_rw()
Sets the permissions to Read and Write.
Definition runtime/Memory.hpp:127
Chunk & change_permissions(uint32_t p)
Changes the permissions of the memory chunk.
Definition runtime/Memory.hpp:113
void * addr_ptr()
Returns the start address of the memory chunk as an opaque pointer.
Definition runtime/Memory.hpp:82
ok_error_t deallocate()
Definition runtime/Memory.hpp:159
uintptr_t addr() const
Returns the start address of the memory chunk.
Definition runtime/Memory.hpp:91
~ScopedPermissions()
Definition runtime/Memory.hpp:185
ScopedPermissions(Chunk &chunk, uint32_t perms)
Definition runtime/Memory.hpp:179
This class exposes API to access and manage memory.
Definition runtime/Memory.hpp:35
MMAP_FLAGS
Flags used when creating a memory map (mmap).
Definition runtime/Memory.hpp:38
@ MP_FIXED
Interpret the address as a fixed requirement.
Definition runtime/Memory.hpp:51
@ MP_JIT
Map for Just-In-Time code generation.
Definition runtime/Memory.hpp:54
@ MP_NONE
Definition runtime/Memory.hpp:39
@ MP_PRIVATE
Changes are private to this process (copy-on-write).
Definition runtime/Memory.hpp:42
@ MP_SHARED
Changes are shared.
Definition runtime/Memory.hpp:48
@ MP_ANONYMOUS
The mapping is not backed by any file.
Definition runtime/Memory.hpp:45
static constexpr bool support_rwx()
Definition runtime/Memory.hpp:260
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:254
static ok_error_t write(const T &value, uintptr_t addr)
Generic function to write a typed value.
Definition runtime/Memory.hpp:225
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:208
static std::string perm_str(uint32_t flags)
static optional< Chunk > mmap(size_t size, uint32_t flags, uint32_t permissions=P_NONE)
Allocate a memory chunk through mmap-like function.
static T read(uintptr_t addr)
Generic function to read a typed value.
Definition runtime/Memory.hpp:231
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:217
PERM
Definition runtime/Memory.hpp:57
@ P_READ
Definition runtime/Memory.hpp:59
@ P_WRITE
Definition runtime/Memory.hpp:60
@ P_EXEC
Definition runtime/Memory.hpp:61
@ P_NONE
Definition runtime/Memory.hpp:58
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:239
#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
LIEF namespace.
Definition Abstract/Binary.hpp:41
ok_t ok()
Return success for function with return type ok_error_t.
Definition errors.hpp:103
#define LIEF_API
Definition visibility.h:45