mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-11 16:46:16 +00:00
Fix debugging
This commit is contained in:
@@ -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 (...)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
{
|
||||
if (timeout.count() < 0)
|
||||
{
|
||||
timeout = {};
|
||||
}
|
||||
|
||||
// TODO: Fix adjusting timeout and count
|
||||
while (true)
|
||||
{
|
||||
if (timeout.count() < 0)
|
||||
{
|
||||
timeout = {};
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
45
src/windows-emulator/debugging/win_x64_gdb_stub_handler.hpp
Normal file
45
src/windows-emulator/debugging/win_x64_gdb_stub_handler.hpp
Normal 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_{};
|
||||
};
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user