aboutsummaryrefslogtreecommitdiff
path: root/src/memory/memory.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/memory/memory.cc')
-rw-r--r--src/memory/memory.cc54
1 files changed, 54 insertions, 0 deletions
diff --git a/src/memory/memory.cc b/src/memory/memory.cc
new file mode 100644
index 0000000..59fb50f
--- /dev/null
+++ b/src/memory/memory.cc
@@ -0,0 +1,54 @@
+#include "memory/memory.hh"
+
+namespace memory {
+
+buffer_t read_buffer(const std::size_t num_bytes, const pid_t& pid,
+ const void* const address) {
+ buffer_t buffer{num_bytes};
+ const struct iovec local {
+ .iov_base = std::data(buffer), .iov_len = std::size(buffer)
+ };
+ const struct iovec remote {
+ .iov_base = const_cast<void* const>(address), .iov_len = num_bytes
+ };
+
+ if (const auto read = process_vm_readv(pid, &local, 1, &remote, 1, 0);
+ static_cast<unsigned long>(read) != num_bytes) {
+
+ if (read == -1) {
+ throw std::runtime_error{"read fail - " +
+ std::string{strerror(errno)}};
+ }
+ throw std::runtime_error("read fail - not enough bytes read (" +
+ std::to_string(num_bytes) + " wanted, " +
+ std::to_string(read) + " read)");
+ }
+
+ return buffer;
+}
+
+void write_buffer(const buffer_t& buffer, const pid_t& pid,
+ const void* const address) {
+ const struct iovec local {
+ .iov_base = (void*)std::data(buffer), .iov_len = std::size(buffer)
+ };
+ const struct iovec remote {
+ .iov_base = const_cast<void* const>(address),
+ .iov_len = std::size(buffer)
+ };
+
+ if (const auto written = process_vm_writev(pid, &local, 1, &remote, 1, 0);
+ static_cast<unsigned long>(written) != std::size(buffer)) {
+
+ if (written == -1) {
+ throw std::runtime_error{"write fail - " +
+ std::string{strerror(errno)}};
+ }
+ throw std::runtime_error("read fail - not enough bytes written (" +
+ std::to_string(std::size(buffer)) +
+ " wanted, " + std::to_string(written) +
+ " written)");
+ }
+}
+
+} // namespace memory