Public release 0.1

This commit is contained in:
Adam Macdonald
2025-01-31 18:28:43 +00:00
commit 984b49d683
19 changed files with 1538 additions and 0 deletions

7
donIV/include/inject.hpp Normal file
View File

@@ -0,0 +1,7 @@
#pragma once
#include "process.hpp"
#include <filesystem>
bool inject_library(const std::filesystem::path& library_path, const process& process);

61
donIV/include/process.hpp Normal file
View File

@@ -0,0 +1,61 @@
#pragma once
#include <cassert>
#include <cstdint>
#include <expected>
#include <filesystem>
#include <optional>
#include <span>
#include <string>
#include <string_view>
#include <unordered_map>
#include <vector>
class memory_region {
public:
std::uintptr_t start_addr = 0x0;
std::uintptr_t end_addr = 0x0;
std::uintptr_t offset = 0x0;
std::string path_name;
std::uint8_t dev_major = 0;
std::uint8_t dev_minor = 0;
std::uint64_t inode = 0;
bool read = false;
bool write = false;
bool execute = false;
bool priv = false;
bool shared = false;
};
class process {
public:
using pid_t = std::uint32_t;
using lib_map_t = std::unordered_map<std::string, std::vector<memory_region>>;
static constexpr pid_t INVALID_PID = 0;
process(pid_t pid)
: m_process_id(pid) {};
public:
inline pid_t pid() const noexcept {
return m_process_id;
}
std::expected<std::size_t, std::error_code> read_memory(void* target_addr,
void* local_addr,
std::size_t len) const noexcept;
std::expected<std::size_t, std::error_code> write_memory(void* target_addr,
void* local_addr,
std::size_t len) const noexcept;
std::expected<std::vector<std::uintptr_t>, std::error_code> find_bytes_in_memory(
void* start_addr, std::size_t len, std::span<const std::uint8_t> bytes) const noexcept;
std::expected<void, std::error_code> send_signal(int signum) const noexcept;
std::optional<std::filesystem::path> get_exe_path() const;
std::vector<memory_region> get_memory_regions() const;
std::vector<memory_region> get_library_memory_regions(std::string_view lib_name) const;
lib_map_t get_loaded_libraries() const;
private:
pid_t m_process_id = INVALID_PID;
};

105
donIV/include/ptrace.hpp Normal file
View File

@@ -0,0 +1,105 @@
#pragma once
#include <bitset>
#include <cstdint>
#include <cstdlib>
#include <expected>
#include <system_error>
#include <variant>
extern "C"
{
#include <sys/ptrace.h>
#include <sys/signal.h>
#include <sys/user.h>
#include <linux/ptrace.h> // Must be included after <sys/ptrace.h>
}
namespace ptrace_cpp
{
using void_expected_t = std::expected<void, std::error_code>;
using int_expected_t = std::expected<int, std::error_code>;
using syscall_info_t = ptrace_syscall_info;
using syscall_info_expected_t = std::expected<syscall_info_t, std::error_code>;
using user_regs_t = user_regs_struct;
using regs_expected_t = std::expected<user_regs_t, std::error_code>;
struct sig_stop_t {
int signal = 0;
};
struct exited_t {
int exit_code = 0;
};
struct term_by_t {
int term_sig = 0;
};
struct continued_t {};
using syscall_stop_t = syscall_info_t; // ptrace_syscall_info
using wait_status_type_t = std::variant<sig_stop_t, syscall_stop_t, exited_t, term_by_t, continued_t, std::error_code>;
constexpr int TRACESYSGOOD_TRAP_MASK = (SIGTRAP | 0x80);
void_expected_t attach_to_process(std::uint32_t pid);
void_expected_t detach_from_process(std::uint32_t pid);
void_expected_t set_options(std::uint32_t pid, std::bitset<32> options);
regs_expected_t get_regs(std::uint32_t pid);
syscall_info_expected_t get_syscall_info(std::uint32_t pid);
void_expected_t set_regs(std::uint32_t pid, const user_regs_t& regs);
wait_status_type_t wait_on_process(std::uint32_t pid);
void_expected_t continue_execution(std::uint32_t pid, int sig_num = 0);
void_expected_t continue_to_next_syscall(std::uint32_t pid, int sig_num = 0);
void_expected_t singlestep(std::uint32_t pid, int sig_num = 0);
} // namespace ptrace_cpp
namespace ptrace_cpp::status
{
inline int status_to_stop_sig(int status) noexcept {
return WSTOPSIG(status);
}
inline bool is_stopped(int status) noexcept {
return WIFSTOPPED(status);
}
inline bool is_exited(int status) noexcept {
return WIFEXITED(status);
}
inline bool is_signalled(int status) noexcept {
return WIFSIGNALED(status);
}
inline bool is_continued(int status) noexcept {
return WIFCONTINUED(status);
}
} // namespace ptrace_cpp::status
namespace ptrace_cpp::signal
{
inline bool is_syscall(int sig_num) noexcept {
return sig_num == TRACESYSGOOD_TRAP_MASK;
}
inline int unmask_sysgood(int sig_num) noexcept {
return sig_num & 0x7F;
}
} // namespace ptrace_cpp::signal
namespace ptrace_cpp::debug
{
void print_user_regs(const user_regs_t& regs);
void print_wait_status(const wait_status_type_t& wait);
} // namespace ptrace_cpp::debug

View File

@@ -0,0 +1,11 @@
#pragma once
namespace syscalls
{
namespace x64
{
constexpr const unsigned int mmap = 9;
constexpr const unsigned int munmap = 11;
constexpr const unsigned int kill = 62;
} // namespace x64
} // namespace syscalls