Format all the code

This commit is contained in:
momo5502
2025-01-06 17:13:33 +01:00
parent 64c2a79f0f
commit bff8420ffd
100 changed files with 16439 additions and 14509 deletions

View File

@@ -3,137 +3,134 @@
#include <utils/finally.hpp>
extern "C" {
extern "C"
{
#include <gdbstub.h>
}
namespace
{
gdb_action_t map_gdb_action(const gdb_action action)
{
switch (action)
{
case gdb_action::none:
return ACT_NONE;
case gdb_action::resume:
return ACT_RESUME;
case gdb_action::shutdown:
return ACT_SHUTDOWN;
}
gdb_action_t map_gdb_action(const gdb_action action)
{
switch (action)
{
case gdb_action::none:
return ACT_NONE;
case gdb_action::resume:
return ACT_RESUME;
case gdb_action::shutdown:
return ACT_SHUTDOWN;
}
throw std::runtime_error("Bad action");
}
throw std::runtime_error("Bad action");
}
breakpoint_type map_breakpoint_type(const bp_type_t type)
{
switch (type)
{
case BP_SOFTWARE:
return breakpoint_type::software;
case BP_HARDWARE_EXEC:
return breakpoint_type::hardware_exec;
case BP_HARDWARE_WRITE:
return breakpoint_type::hardware_write;
case BP_HARDWARE_READ:
return breakpoint_type::hardware_read;
case BP_HARDWARE_READ_WRITE:
return breakpoint_type::hardware_read_write;
}
breakpoint_type map_breakpoint_type(const bp_type_t type)
{
switch (type)
{
case BP_SOFTWARE:
return breakpoint_type::software;
case BP_HARDWARE_EXEC:
return breakpoint_type::hardware_exec;
case BP_HARDWARE_WRITE:
return breakpoint_type::hardware_write;
case BP_HARDWARE_READ:
return breakpoint_type::hardware_read;
case BP_HARDWARE_READ_WRITE:
return breakpoint_type::hardware_read_write;
}
throw std::runtime_error("Bad breakpoint type");
}
throw std::runtime_error("Bad breakpoint type");
}
gdb_stub_handler& get_handler(void* args)
{
return *static_cast<gdb_stub_handler*>(args);
}
gdb_stub_handler& get_handler(void* args)
{
return *static_cast<gdb_stub_handler*>(args);
}
gdb_action_t cont(void* args)
{
return map_gdb_action(get_handler(args).cont());
}
gdb_action_t cont(void* args)
{
return map_gdb_action(get_handler(args).cont());
}
gdb_action_t stepi(void* args)
{
return map_gdb_action(get_handler(args).stepi());
}
gdb_action_t stepi(void* args)
{
return map_gdb_action(get_handler(args).stepi());
}
int read_reg(void* args, const int regno, size_t* value)
{
return get_handler(args).read_reg(regno, value) ? 0 : 1;
}
int read_reg(void* args, const int regno, size_t* value)
{
return get_handler(args).read_reg(regno, value) ? 0 : 1;
}
int write_reg(void* args, const int regno, const size_t value)
{
return get_handler(args).write_reg(regno, value) ? 0 : 1;
}
int write_reg(void* args, const int regno, const size_t value)
{
return get_handler(args).write_reg(regno, value) ? 0 : 1;
}
int read_mem(void* args, const size_t addr, const size_t len, void* val)
{
return get_handler(args).read_mem(addr, len, val) ? 0 : 1;
}
int read_mem(void* args, const size_t addr, const size_t len, void* val)
{
return get_handler(args).read_mem(addr, len, val) ? 0 : 1;
}
int write_mem(void* args, const size_t addr, const size_t len, void* val)
{
return get_handler(args).write_mem(addr, len, val) ? 0 : 1;
}
int write_mem(void* args, const size_t addr, const size_t len, void* val)
{
return get_handler(args).write_mem(addr, len, val) ? 0 : 1;
}
bool set_bp(void* args, const size_t addr, const bp_type_t type, const size_t size)
{
return get_handler(args).set_bp(map_breakpoint_type(type), addr, size);
}
bool set_bp(void* args, const size_t addr, const bp_type_t type, const size_t size)
{
return get_handler(args).set_bp(map_breakpoint_type(type), addr, size);
}
bool del_bp(void* args, const size_t addr, const bp_type_t type, const size_t size)
{
return get_handler(args).del_bp(map_breakpoint_type(type), addr, size);
}
bool del_bp(void* args, const size_t addr, const bp_type_t type, const size_t size)
{
return get_handler(args).del_bp(map_breakpoint_type(type), addr, size);
}
void on_interrupt(void* args)
{
get_handler(args).on_interrupt();
}
void on_interrupt(void* args)
{
get_handler(args).on_interrupt();
}
target_ops get_target_ops()
{
target_ops ops{};
target_ops get_target_ops()
{
target_ops ops{};
ops.cont = cont;
ops.stepi = stepi;
ops.read_reg = read_reg;
ops.write_reg = write_reg;
ops.read_mem = read_mem;
ops.write_mem = write_mem;
ops.set_bp = set_bp;
ops.del_bp = del_bp;
ops.on_interrupt = on_interrupt;
ops.cont = cont;
ops.stepi = stepi;
ops.read_reg = read_reg;
ops.write_reg = write_reg;
ops.read_mem = read_mem;
ops.write_mem = write_mem;
ops.set_bp = set_bp;
ops.del_bp = del_bp;
ops.on_interrupt = on_interrupt;
return ops;
}
return ops;
}
}
bool run_gdb_stub(gdb_stub_handler& handler, std::string target_description, const size_t register_count,
std::string bind_address)
{
const arch_info_t info
{
target_description.data(),
static_cast<int>(register_count),
sizeof(uint64_t),
};
const arch_info_t info{
target_description.data(),
static_cast<int>(register_count),
sizeof(uint64_t),
};
auto ops = get_target_ops();
auto ops = get_target_ops();
gdbstub_t stub{};
gdbstub_t stub{};
if (!gdbstub_init(&stub, &ops, info, bind_address.data()))
{
return false;
}
if (!gdbstub_init(&stub, &ops, info, bind_address.data()))
{
return false;
}
const auto _ = utils::finally([&]
{
gdbstub_close(&stub);
});
const auto _ = utils::finally([&] { gdbstub_close(&stub); });
return gdbstub_run(&stub, &handler);
return gdbstub_run(&stub, &handler);
}

View File

@@ -2,37 +2,37 @@
enum class gdb_action : uint8_t
{
none,
resume,
shutdown,
none,
resume,
shutdown,
};
enum class breakpoint_type : uint8_t
{
software,
hardware_exec,
hardware_write,
hardware_read,
hardware_read_write,
software,
hardware_exec,
hardware_write,
hardware_read,
hardware_read_write,
};
struct gdb_stub_handler
{
virtual ~gdb_stub_handler() = default;
virtual ~gdb_stub_handler() = default;
virtual gdb_action cont() = 0;
virtual gdb_action stepi() = 0;
virtual gdb_action cont() = 0;
virtual gdb_action stepi() = 0;
virtual bool read_reg(int regno, size_t* value) = 0;
virtual bool write_reg(int regno, size_t value) = 0;
virtual bool read_reg(int regno, size_t* value) = 0;
virtual bool write_reg(int regno, size_t value) = 0;
virtual bool read_mem(size_t addr, size_t len, void* val) = 0;
virtual bool write_mem(size_t addr, size_t len, void* val) = 0;
virtual bool read_mem(size_t addr, size_t len, void* val) = 0;
virtual bool write_mem(size_t addr, size_t len, void* val) = 0;
virtual bool set_bp(breakpoint_type type, size_t addr, size_t size) = 0;
virtual bool del_bp(breakpoint_type type, size_t addr, size_t size) = 0;
virtual bool set_bp(breakpoint_type type, size_t addr, size_t size) = 0;
virtual bool del_bp(breakpoint_type type, size_t addr, size_t size) = 0;
virtual void on_interrupt() = 0;
virtual void on_interrupt() = 0;
};
bool run_gdb_stub(gdb_stub_handler& handler, std::string target_description, size_t register_count,

View File

@@ -5,41 +5,41 @@
class win_x64_gdb_stub_handler : public x64_gdb_stub_handler
{
public:
win_x64_gdb_stub_handler(windows_emulator& win_emu)
: x64_gdb_stub_handler(win_emu.emu())
, win_emu_(&win_emu)
{
}
public:
win_x64_gdb_stub_handler(windows_emulator& win_emu)
: x64_gdb_stub_handler(win_emu.emu()),
win_emu_(&win_emu)
{
}
gdb_action cont() override
{
try
{
this->win_emu_->start();
}
catch (const std::exception& e)
{
puts(e.what());
}
gdb_action cont() override
{
try
{
this->win_emu_->start();
}
catch (const std::exception& e)
{
puts(e.what());
}
return gdb_action::resume;
}
return gdb_action::resume;
}
gdb_action stepi() override
{
try
{
this->win_emu_->start({}, 1);
}
catch (const std::exception& e)
{
puts(e.what());
}
gdb_action stepi() override
{
try
{
this->win_emu_->start({}, 1);
}
catch (const std::exception& e)
{
puts(e.what());
}
return gdb_action::resume;
}
return gdb_action::resume;
}
private:
windows_emulator* win_emu_{};
private:
windows_emulator* win_emu_{};
};

View File

@@ -4,212 +4,194 @@
#include "scoped_hook.hpp"
inline std::vector gdb_registers{
x64_register::rax,
x64_register::rbx,
x64_register::rcx,
x64_register::rdx,
x64_register::rsi,
x64_register::rdi,
x64_register::rbp,
x64_register::rsp,
x64_register::r8,
x64_register::r9,
x64_register::r10,
x64_register::r11,
x64_register::r12,
x64_register::r13,
x64_register::r14,
x64_register::r15,
x64_register::rip,
x64_register::rflags,
/*x64_register::cs,
x64_register::ss,
x64_register::ds,
x64_register::es,
x64_register::fs,
x64_register::gs,*/
x64_register::rax, x64_register::rbx, x64_register::rcx, x64_register::rdx, x64_register::rsi, x64_register::rdi,
x64_register::rbp, x64_register::rsp, x64_register::r8, x64_register::r9, x64_register::r10, x64_register::r11,
x64_register::r12, x64_register::r13, x64_register::r14, x64_register::r15, x64_register::rip, x64_register::rflags,
/*x64_register::cs,
x64_register::ss,
x64_register::ds,
x64_register::es,
x64_register::fs,
x64_register::gs,*/
};
inline memory_operation map_breakpoint_type(const breakpoint_type type)
{
switch (type)
{
case breakpoint_type::software:
case breakpoint_type::hardware_exec:
return memory_operation::exec;
case breakpoint_type::hardware_read:
return memory_permission::read;
case breakpoint_type::hardware_write:
return memory_permission::write;
case breakpoint_type::hardware_read_write:
return memory_permission::read_write;
default:
throw std::runtime_error("Bad bp type");
}
switch (type)
{
case breakpoint_type::software:
case breakpoint_type::hardware_exec:
return memory_operation::exec;
case breakpoint_type::hardware_read:
return memory_permission::read;
case breakpoint_type::hardware_write:
return memory_permission::write;
case breakpoint_type::hardware_read_write:
return memory_permission::read_write;
default:
throw std::runtime_error("Bad bp type");
}
}
struct breakpoint_key
{
size_t addr{};
size_t size{};
breakpoint_type type{};
size_t addr{};
size_t size{};
breakpoint_type type{};
bool operator==(const breakpoint_key& other) const
{
return this->addr == other.addr && this->size == other.size && this->type == other.type;
}
bool operator==(const breakpoint_key& other) const
{
return this->addr == other.addr && this->size == other.size && this->type == other.type;
}
};
template <>
struct std::hash<breakpoint_key>
{
std::size_t operator()(const breakpoint_key& k) const noexcept
{
return ((std::hash<size_t>()(k.addr)
^ (std::hash<size_t>()(k.size) << 1)) >> 1)
^ (std::hash<size_t>()(static_cast<size_t>(k.type)) << 1);
}
std::size_t operator()(const breakpoint_key& k) const noexcept
{
return ((std::hash<size_t>()(k.addr) ^ (std::hash<size_t>()(k.size) << 1)) >> 1) ^
(std::hash<size_t>()(static_cast<size_t>(k.type)) << 1);
}
};
class x64_gdb_stub_handler : public gdb_stub_handler
{
public:
x64_gdb_stub_handler(x64_emulator& emu)
: emu_(&emu)
{
}
public:
x64_gdb_stub_handler(x64_emulator& emu)
: emu_(&emu)
{
}
~x64_gdb_stub_handler() override = default;
~x64_gdb_stub_handler() override = default;
gdb_action cont() override
{
try
{
this->emu_->start_from_ip();
}
catch (const std::exception& e)
{
puts(e.what());
}
gdb_action cont() override
{
try
{
this->emu_->start_from_ip();
}
catch (const std::exception& e)
{
puts(e.what());
}
return gdb_action::resume;
}
return gdb_action::resume;
}
gdb_action stepi() override
{
try
{
this->emu_->start_from_ip({}, 1);
}
catch (const std::exception& e)
{
puts(e.what());
}
gdb_action stepi() override
{
try
{
this->emu_->start_from_ip({}, 1);
}
catch (const std::exception& e)
{
puts(e.what());
}
return gdb_action::resume;
}
return gdb_action::resume;
}
bool read_reg(const int regno, size_t* value) override
{
*value = 0;
bool read_reg(const int regno, size_t* value) override
{
*value = 0;
try
{
if (static_cast<size_t>(regno) >= gdb_registers.size())
{
return true;
}
try
{
if (static_cast<size_t>(regno) >= gdb_registers.size())
{
return true;
}
this->emu_->read_register(gdb_registers[regno], value, sizeof(*value));
return true;
}
catch (...)
{
return true;
}
}
this->emu_->read_register(gdb_registers[regno], value, sizeof(*value));
return true;
}
catch (...)
{
return true;
}
}
bool write_reg(const int regno, const size_t value) override
{
try
{
if (static_cast<size_t>(regno) >= gdb_registers.size())
{
return true;
}
bool write_reg(const int regno, const size_t value) override
{
try
{
if (static_cast<size_t>(regno) >= gdb_registers.size())
{
return true;
}
this->emu_->write_register(gdb_registers[regno], &value, sizeof(value));
return true;
}
catch (...)
{
return false;
}
}
this->emu_->write_register(gdb_registers[regno], &value, sizeof(value));
return true;
}
catch (...)
{
return false;
}
}
bool read_mem(const size_t addr, const size_t len, void* val) override
{
return this->emu_->try_read_memory(addr, val, len);
}
bool read_mem(const size_t addr, const size_t len, void* val) override
{
return this->emu_->try_read_memory(addr, val, len);
}
bool write_mem(const size_t addr, const size_t len, void* val) override
{
try
{
this->emu_->write_memory(addr, val, len);
return true;
}
catch (...)
{
return false;
}
}
bool write_mem(const size_t addr, const size_t len, void* val) override
{
try
{
this->emu_->write_memory(addr, val, len);
return true;
}
catch (...)
{
return false;
}
}
bool set_bp(const breakpoint_type type, const size_t addr, const size_t size) override
{
try
{
this->hooks_[{addr, size, type}] = scoped_hook(*this->emu_, this->emu_->hook_memory_access(
addr, size, map_breakpoint_type(type),
[this](uint64_t, size_t, uint64_t, memory_operation)
{
this->on_interrupt();
}));
bool set_bp(const breakpoint_type type, const size_t addr, const size_t size) override
{
try
{
this->hooks_[{addr, size, type}] = scoped_hook(
*this->emu_, this->emu_->hook_memory_access(
addr, size, map_breakpoint_type(type),
[this](uint64_t, size_t, uint64_t, memory_operation) { this->on_interrupt(); }));
return true;
}
catch (...)
{
return false;
}
}
return true;
}
catch (...)
{
return false;
}
}
bool del_bp(const breakpoint_type type, const size_t addr, const size_t size) override
{
try
{
const auto entry = this->hooks_.find({addr, size, type});
if (entry == this->hooks_.end())
{
return false;
}
bool del_bp(const breakpoint_type type, const size_t addr, const size_t size) override
{
try
{
const auto entry = this->hooks_.find({addr, size, type});
if (entry == this->hooks_.end())
{
return false;
}
this->hooks_.erase(entry);
this->hooks_.erase(entry);
return true;
}
catch (...)
{
return false;
}
}
return true;
}
catch (...)
{
return false;
}
}
void on_interrupt() override
{
this->emu_->stop();
}
void on_interrupt() override
{
this->emu_->stop();
}
private:
x64_emulator* emu_{};
std::unordered_map<breakpoint_key, scoped_hook> hooks_{};
private:
x64_emulator* emu_{};
std::unordered_map<breakpoint_key, scoped_hook> hooks_{};
};