Skip to content

Commit

Permalink
Perform retrigger after violation
Browse files Browse the repository at this point in the history
  • Loading branch information
momo5502 committed Nov 3, 2024
1 parent fae6184 commit b840fac
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 26 deletions.
2 changes: 2 additions & 0 deletions src/emulator/emulator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,8 @@ class emulator : public memory_manager
this->perform_deserialization(deserializer, true);
}

virtual bool has_violation() const = 0;

private:
std::vector<std::byte> last_snapshot_data_{};

Expand Down
50 changes: 25 additions & 25 deletions src/unicorn-emulator/unicorn_x64_emulator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -241,39 +241,34 @@ namespace unicorn
uc_close(this->uc_);
}

void start(uint64_t start, const uint64_t end, std::chrono::nanoseconds timeout,
void start(const 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)
this->has_violation_ = false;
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)
{
this->retry_after_violation_ = false;
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;
}

const auto is_violation = res == UC_ERR_READ_UNMAPPED || //
res == UC_ERR_WRITE_UNMAPPED || //
res == UC_ERR_FETCH_UNMAPPED || //
res == UC_ERR_READ_PROT || //
res == UC_ERR_WRITE_PROT || //
res == UC_ERR_FETCH_PROT;
return;
}

if (!is_violation || !this->retry_after_violation_)
{
uce(res);
}
const auto is_violation = //
res == UC_ERR_READ_UNMAPPED || //
res == UC_ERR_WRITE_UNMAPPED || //
res == UC_ERR_FETCH_UNMAPPED || //
res == UC_ERR_READ_PROT || //
res == UC_ERR_WRITE_PROT || //
res == UC_ERR_FETCH_PROT;

start = this->read_instruction_pointer();
if (!is_violation || !this->has_violation_)
{
uce(res);
}
}

Expand Down Expand Up @@ -493,7 +488,7 @@ namespace unicorn
return false;
}

this->retry_after_violation_ = resume && has_ip_changed;
this->has_violation_ = resume && has_ip_changed;

if (has_ip_changed)
{
Expand Down Expand Up @@ -609,10 +604,15 @@ namespace unicorn
serializer.deserialize(buffer);
}

bool has_violation() const override
{
return this->has_violation_;
}

private:
mutable bool has_snapshots_{false};
uc_engine* uc_{};
bool retry_after_violation_{false};
bool has_violation_{false};
std::vector<std::unique_ptr<hook_object>> hooks_{};
};
}
Expand Down
2 changes: 1 addition & 1 deletion src/windows-emulator/windows_emulator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -964,7 +964,7 @@ void windows_emulator::start(std::chrono::nanoseconds timeout, size_t count)

this->emu().start_from_ip(timeout, count);

if (!this->switch_thread)
if (!this->switch_thread && !this->emu().has_violation())
{
break;
}
Expand Down

0 comments on commit b840fac

Please sign in to comment.