diff --git a/src/common/utils/string.hpp b/src/common/utils/string.hpp index 2b5100b8..0c1bb0c5 100644 --- a/src/common/utils/string.hpp +++ b/src/common/utils/string.hpp @@ -109,7 +109,7 @@ namespace utils::string return to_hex_string(&i, sizeof(Integer), uppercase); } - inline std::string to_hex_string(const std::span data, const bool uppercase = false) + inline std::string to_hex_string(const std::span data, const bool uppercase = false) { return to_hex_string(data.data(), data.size(), uppercase); } diff --git a/src/emulator/cpu_interface.hpp b/src/emulator/cpu_interface.hpp index 4d30eef0..06e35593 100644 --- a/src/emulator/cpu_interface.hpp +++ b/src/emulator/cpu_interface.hpp @@ -12,8 +12,8 @@ struct cpu_interface virtual void start(uint64_t start, uint64_t end = 0, std::chrono::nanoseconds timeout = {}, size_t count = 0) = 0; virtual void stop() = 0; - virtual void read_raw_register(int reg, void* value, size_t size) = 0; - virtual void write_raw_register(int reg, const void* value, size_t size) = 0; + virtual size_t read_raw_register(int reg, void* value, size_t size) = 0; + virtual size_t write_raw_register(int reg, const void* value, size_t size) = 0; virtual std::vector save_registers() = 0; virtual void restore_registers(const std::vector& register_data) = 0; diff --git a/src/emulator/typed_emulator.hpp b/src/emulator/typed_emulator.hpp index d7224940..63516cba 100644 --- a/src/emulator/typed_emulator.hpp +++ b/src/emulator/typed_emulator.hpp @@ -20,14 +20,14 @@ class typed_emulator : public emulator this->start(this->read_instruction_pointer(), 0, timeout, count); } - void write_register(registers reg, const void* value, const size_t size) + size_t write_register(registers reg, const void* value, const size_t size) { - this->write_raw_register(static_cast(reg), value, size); + return this->write_raw_register(static_cast(reg), value, size); } - void read_register(registers reg, void* value, const size_t size) + size_t read_register(registers reg, void* value, const size_t size) { - this->read_raw_register(static_cast(reg), value, size); + return this->read_raw_register(static_cast(reg), value, size); } template @@ -90,6 +90,6 @@ class typed_emulator : public emulator private: emulator_hook* hook_instruction(int instruction_type, instruction_hook_callback callback) override = 0; - void read_raw_register(int reg, void* value, size_t size) override = 0; - void write_raw_register(int reg, const void* value, size_t size) override = 0; + size_t read_raw_register(int reg, void* value, size_t size) override = 0; + size_t write_raw_register(int reg, const void* value, size_t size) override = 0; }; diff --git a/src/gdb-stub/gdb_stub.cpp b/src/gdb-stub/gdb_stub.cpp index 308cded5..764fbf14 100644 --- a/src/gdb-stub/gdb_stub.cpp +++ b/src/gdb-stub/gdb_stub.cpp @@ -209,16 +209,16 @@ namespace gdb_stub for (size_t i = 0; i < registers; ++i) { - memset(data.data(), 0, data.size()); - const auto res = handler.read_register(i, data.data(), data.size()); + const auto size = handler.read_register(i, data.data(), data.size()); - if (!res) + if (!size) { connection.send_reply("E01"); return; } - response.append(utils::string::to_hex_string(data)); + const std::span register_data(data.data(), size); + response.append(utils::string::to_hex_string(register_data)); } connection.send_reply(response); @@ -231,20 +231,21 @@ namespace gdb_stub const auto registers = handler.get_register_count(); const auto register_size = handler.get_max_register_size(); + size_t offset = 0; for (size_t i = 0; i < registers; ++i) { - const auto offset = i * register_size; - const auto end_offset = offset + register_size; - - if (data.size() < end_offset) + if (offset >= data.size()) { connection.send_reply("E01"); return; } - const auto res = handler.write_register(i, data.data() + offset, register_size); + const auto max_size = std::min(register_size, data.size() - offset); + const auto size = handler.write_register(i, data.data() + offset, max_size); - if (!res) + offset += size; + + if (!size) { connection.send_reply("E01"); return; @@ -263,11 +264,12 @@ namespace gdb_stub std::vector data{}; data.resize(handler.get_max_register_size()); - const auto res = handler.read_register(reg, data.data(), data.size()); + const auto size = handler.read_register(reg, data.data(), data.size()); - if (res) + if (size) { - connection.send_reply(utils::string::to_hex_string(data)); + const std::span register_data(data.data(), size); + connection.send_reply(utils::string::to_hex_string(register_data)); } else { @@ -283,12 +285,8 @@ namespace gdb_stub size_t register_index{}; rt_assert(sscanf_s(std::string(reg).c_str(), "%zx", ®ister_index) == 1); - const auto register_size = handler.get_max_register_size(); const auto data = utils::string::from_hex_string(hex_data); - - const auto res = register_size <= data.size() && // - handler.write_register(register_index, data.data(), register_size); - + const auto res = handler.write_register(register_index, data.data(), data.size()) > 0; connection.send_reply(res ? "OK" : "E01"); } diff --git a/src/gdb-stub/gdb_stub.hpp b/src/gdb-stub/gdb_stub.hpp index 493a960e..c779aaaa 100644 --- a/src/gdb-stub/gdb_stub.hpp +++ b/src/gdb-stub/gdb_stub.hpp @@ -31,8 +31,8 @@ namespace gdb_stub virtual size_t get_register_count() = 0; virtual size_t get_max_register_size() = 0; - virtual bool read_register(size_t reg, void* data, size_t max_length) = 0; - virtual bool write_register(size_t reg, const void* data, size_t size) = 0; + virtual size_t read_register(size_t reg, void* data, size_t max_length) = 0; + virtual size_t write_register(size_t reg, const void* data, size_t size) = 0; virtual bool read_memory(uint64_t address, void* data, size_t length) = 0; virtual bool write_memory(uint64_t address, const void* data, size_t length) = 0; diff --git a/src/unicorn-emulator/unicorn_x64_emulator.cpp b/src/unicorn-emulator/unicorn_x64_emulator.cpp index 2fe9f4ef..369cf7fb 100644 --- a/src/unicorn-emulator/unicorn_x64_emulator.cpp +++ b/src/unicorn-emulator/unicorn_x64_emulator.cpp @@ -301,9 +301,9 @@ namespace unicorn uce(uc_emu_stop(*this)); } - void write_raw_register(const int reg, const void* value, const size_t size) override + size_t write_raw_register(const int reg, const void* value, const size_t size) override { - size_t result_size = size; + auto result_size = size; uce(uc_reg_write2(*this, reg, value, &result_size)); if (size < result_size) @@ -311,9 +311,11 @@ namespace unicorn throw std::runtime_error("Register size mismatch: " + std::to_string(size) + " != " + std::to_string(result_size)); } + + return result_size; } - void read_raw_register(const int reg, void* value, const size_t size) override + size_t read_raw_register(const int reg, void* value, const size_t size) override { size_t result_size = size; memset(value, 0, size); @@ -324,6 +326,8 @@ namespace unicorn throw std::runtime_error("Register size mismatch: " + std::to_string(size) + " != " + std::to_string(result_size)); } + + return result_size; } void map_mmio(const uint64_t address, const size_t size, mmio_read_callback read_cb, diff --git a/src/windows-emulator/debugging/x64_gdb_stub_handler.hpp b/src/windows-emulator/debugging/x64_gdb_stub_handler.hpp index 7dde76a4..4489a03f 100644 --- a/src/windows-emulator/debugging/x64_gdb_stub_handler.hpp +++ b/src/windows-emulator/debugging/x64_gdb_stub_handler.hpp @@ -105,46 +105,40 @@ class x64_gdb_stub_handler : public gdb_stub::debugging_handler size_t get_max_register_size() override { - // return 256 / 8; - return 64 / 8; + return 512 / 8; } - bool read_register(const size_t reg, void* data, const size_t max_length) override + size_t read_register(const size_t reg, void* data, const size_t max_length) override { try { if (reg >= gdb_registers.size()) { - // TODO: Fix - return true; + return 0; } - this->emu_->read_register(gdb_registers[reg], data, max_length); - return true; + return this->emu_->read_register(gdb_registers[reg], data, max_length); } catch (...) { - // TODO: Fix - return true; + return 0; } } - bool write_register(const size_t reg, const void* data, const size_t size) override + size_t write_register(const size_t reg, const void* data, const size_t size) override { try { if (reg >= gdb_registers.size()) { - // TODO: Fix - return true; + return 0; } - this->emu_->write_register(gdb_registers[reg], data, size); - return true; + return this->emu_->write_register(gdb_registers[reg], data, size); } catch (...) { - return false; + return 0; } }