Fix debugging

This commit is contained in:
momo5502
2024-10-23 17:10:23 +02:00
parent adf9713993
commit c992d17300
7 changed files with 117 additions and 26 deletions

View File

@@ -1,7 +1,7 @@
#include "std_include.hpp"
#include <windows_emulator.hpp>
#include <debugging/x64_gdb_stub_handler.hpp>
#include <debugging/win_x64_gdb_stub_handler.hpp>
#include "object_watching.hpp"
@@ -43,22 +43,12 @@ namespace
const auto* address = "0.0.0.0:28960";
win_emu.logger.print(color::pink, "Waiting for GDB connection on %s...\n", address);
x64_gdb_stub_handler handler{win_emu.emu()};
win_x64_gdb_stub_handler handler{win_emu};
run_gdb_stub(handler, "i386:x86-64", gdb_registers.size(), address);
}
else
{
while (true)
{
win_emu.emu().start_from_ip();
if (win_emu.switch_thread)
{
win_emu.perform_thread_switch();
continue;
}
break;
}
win_emu.start();
}
}
catch (...)

View File

@@ -58,7 +58,7 @@ public:
emulator(emulator&&) = delete;
emulator& operator=(emulator&&) = delete;
virtual void start(uint64_t start, uint64_t end = 0, std::chrono::microseconds timeout = {}, size_t count = 0) = 0;
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;

View File

@@ -15,7 +15,7 @@ public:
static constexpr registers stack_pointer = StackPointer;
static constexpr registers instruction_pointer = InstructionPointer;
void start_from_ip(const std::chrono::microseconds timeout = {}, const size_t count = 0)
void start_from_ip(const std::chrono::nanoseconds timeout = {}, const size_t count = 0)
{
this->start(this->read_instruction_pointer(), 0, timeout, count);
}

View File

@@ -235,18 +235,21 @@ namespace unicorn
uc_close(this->uc_);
}
void start(uint64_t start, const uint64_t end, std::chrono::microseconds timeout,
void start(uint64_t start, const uint64_t end, std::chrono::nanoseconds timeout,
const size_t count) override
{
while (true)
{
if (timeout.count() < 0)
{
timeout = {};
}
// TODO: Fix adjusting timeout and count
while (true)
{
this->retry_after_violation_ = false;
const auto res = uc_emu_start(*this, start, end, static_cast<uint64_t>(timeout.count()), count);
const auto timeoutYs = std::chrono::duration_cast<std::chrono::microseconds>(timeout);
const auto res = uc_emu_start(*this, start, end, static_cast<uint64_t>(timeoutYs.count()),
count);
if (res == UC_ERR_OK)
{
return;
@@ -259,13 +262,12 @@ namespace unicorn
res == UC_ERR_WRITE_PROT || //
res == UC_ERR_FETCH_PROT;
if (is_violation && this->retry_after_violation_)
if (!is_violation || !this->retry_after_violation_)
{
start = this->read_instruction_pointer();
continue;
uce(res);
}
uce(res);
start = this->read_instruction_pointer();
}
}

View File

@@ -0,0 +1,45 @@
#pragma once
#include "x64_gdb_stub_handler.hpp"
#include "../windows_emulator.hpp"
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)
{
}
gdb_action cont() override
{
try
{
this->win_emu_->start();
}
catch (const std::exception& e)
{
puts(e.what());
}
return gdb_action::resume;
}
gdb_action stepi() override
{
try
{
this->win_emu_->start({}, 1);
}
catch (const std::exception& e)
{
puts(e.what());
}
return gdb_action::resume;
}
private:
windows_emulator* win_emu_{};
};

View File

@@ -853,6 +853,58 @@ void windows_emulator::setup_hooks()
});
}
void windows_emulator::start(std::chrono::nanoseconds timeout, size_t count)
{
const auto use_count = count > 0;
const auto use_timeout = timeout != std::chrono::nanoseconds{};
auto start_time = std::chrono::high_resolution_clock::now();
auto start_instructions = this->process().executed_instructions;
while (true)
{
if (this->switch_thread)
{
this->perform_thread_switch();
}
this->emu().start_from_ip(timeout, count);
if (!this->switch_thread)
{
break;
}
if (use_timeout)
{
const auto now = std::chrono::high_resolution_clock::now();
const auto diff = now - start_time;
if (diff >= timeout)
{
break;
}
timeout = timeout - diff;
start_time = now;
}
if (use_count)
{
const auto current_instructions = this->process().executed_instructions;
const auto diff = current_instructions - start_instructions;
if(diff >= count)
{
break;
}
count = diff;
start_instructions = current_instructions;
}
}
}
void windows_emulator::serialize(utils::buffer_serializer& buffer) const
{
this->emu().serialize(buffer);

View File

@@ -61,6 +61,8 @@ public:
return *this->process_.active_thread;
}
void start(std::chrono::nanoseconds timeout = {}, size_t count = 0);
void serialize(utils::buffer_serializer& buffer) const;
void deserialize(utils::buffer_deserializer& buffer);