AsmGrader 0.0.0
Loading...
Searching...
No Matches
memory_io_base.hpp
Go to the documentation of this file.
1#pragma once
2
8
9#include <cstddef>
10#include <cstdint>
11#include <functional>
12#include <span>
13#include <type_traits>
14
15#include <sched.h>
16#include <sys/types.h>
17
18namespace asmgrader {
19
25{
26public:
27 explicit MemoryIOBase(pid_t pid)
28 : pid_{pid} {};
29 virtual ~MemoryIOBase() = default;
30
31 template <MemoryReadSupported T>
32 Result<T> read(std::uintptr_t address) {
33 return MemoryIOSerde<T>::read(address, *this);
34 }
35
36 template <MemoryReadSupported T>
37 requires std::is_trivial_v<T> // more complex types may have sizes that don't correspond
38 Result<std::vector<T>> read_array(std::uintptr_t address, std::size_t size) {
39 std::vector<T> result;
40 result.reserve(size);
41
42 for (std::uintptr_t current_address = address; size > 0; current_address += sizeof(T), --size) {
43 result.push_back(TRY(MemoryIOSerde<T>::read(current_address, *this)));
44 }
45
46 return result;
47 }
48
49 template <MemoryReadSupported T>
50 requires std::is_trivial_v<T> // more complex types may have sizes that don't correspond
51 Result<std::vector<T>> read_array(std::uintptr_t address, std::function<bool(const T&)> until_predicate) {
52 std::vector<T> result;
53
54 for (std::uintptr_t current_address = address;; current_address += sizeof(T)) {
55 T elem = TRY(MemoryIOSerde<T>::read(current_address, *this));
56
57 if (!until_predicate(elem)) {
58 break;
59 }
60
61 result.push_back(std::move(elem));
62 }
63
64 return result;
65 }
66
67 Result<NativeByteVector> read_bytes(std::uintptr_t address, std::size_t length) {
68 return this->read_block_impl(address, length);
69 }
70
71 // FIXME: The reinterpret_cast's to/from std::uintptr_t and pointer types seems kinda bad
72 template <MemoryReadSupported T>
74 if constexpr (std::is_pointer_v<T>) {
75 using NextType = std::remove_pointer_t<T>;
76
77 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
78 auto next_address = reinterpret_cast<std::uintptr_t>(TRY(read<T>(address)));
79
80 return TRY(read_deref_all<NextType>(next_address));
81 } else {
82 return TRY(read<T>(address));
83 }
84 }
85
86 template <MemoryWriteSupported T>
87 Result<std::size_t> write(std::uintptr_t address, const T& data) {
89 TRY(this->write_block_impl(address, bytes));
90 return bytes.size();
91 }
92
93 pid_t get_pid() const { return pid_; }
94
95private:
96 pid_t pid_;
97
98 template <typename T>
99 friend struct MemoryIOSerde;
100
101 virtual Result<NativeByteVector> read_until(std::uintptr_t address, const std::function<bool(Byte)>& predicate);
102 virtual Result<NativeByteVector> read_until(std::uintptr_t address,
103 const std::function<bool(std::span<const Byte>)>& predicate,
104 std::size_t block_size);
105
106 virtual Result<NativeByteVector> read_block_impl(std::uintptr_t address, std::size_t length) = 0;
107 virtual Result<void> write_block_impl(std::uintptr_t address, const NativeByteVector& data) = 0;
108};
109
110} // namespace asmgrader
Definition byte_vector.hpp:34
size_t size() const
Definition byte_vector.hpp:103
More user-friendly interface wrapper for a byte-like integral.
Definition byte.hpp:18
std::variant wrapper for a partial implementation of C++23's expected type
Definition expected.hpp:34
Base class for interacting with a tracee's memory in a variety of ways at a (relatively) high-level F...
Definition memory_io_base.hpp:25
pid_t get_pid() const
Definition memory_io_base.hpp:93
Result< std::size_t > write(std::uintptr_t address, const T &data)
Definition memory_io_base.hpp:87
Result< NativeByteVector > read_bytes(std::uintptr_t address, std::size_t length)
Definition memory_io_base.hpp:67
MemoryIOBase(pid_t pid)
Definition memory_io_base.hpp:27
Result< std::vector< T > > read_array(std::uintptr_t address, std::function< bool(const T &)> until_predicate)
Definition memory_io_base.hpp:51
Result< remove_all_pointers_t< T > > read_deref_all(std::uintptr_t address)
Definition memory_io_base.hpp:73
virtual ~MemoryIOBase()=default
Result< std::vector< T > > read_array(std::uintptr_t address, std::size_t size)
Definition memory_io_base.hpp:38
Result< T > read(std::uintptr_t address)
Definition memory_io_base.hpp:32
#define TRY(val)
If the supplied argument is an error (unexpected) type, then propegate it up the call stack....
Definition error_types.hpp:52
Definition asm_buffer.hpp:20
Example class implementation:
Definition memory_io_serde.hpp:34