mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-19 03:33:56 +00:00
Prepare emulation bisection
This commit is contained in:
@@ -486,19 +486,37 @@ namespace utils
|
||||
this->break_offset_ = break_offset;
|
||||
}
|
||||
|
||||
void print_diff(const buffer_serializer& other) const
|
||||
std::optional<size_t> get_diff(const buffer_serializer& other) const
|
||||
{
|
||||
auto& b1 = this->get_buffer();
|
||||
auto& b2 = other.get_buffer();
|
||||
|
||||
for (size_t i = 0; i < b1.size() && i < b2.size(); ++i)
|
||||
const auto s1 = b1.size();
|
||||
const auto s2 = b2.size();
|
||||
|
||||
for (size_t i = 0; i < s1 && i < s2; ++i)
|
||||
{
|
||||
if (b1.at(i) != b2.at(i))
|
||||
{
|
||||
printf("Diff at %zd\n", i);
|
||||
break;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
if (s1 != s2)
|
||||
{
|
||||
return std::min(s1, s2);
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
void print_diff(const buffer_serializer& other) const
|
||||
{
|
||||
const auto diff = this->get_diff(other);
|
||||
if (diff)
|
||||
{
|
||||
printf("Diff at %zd\n", *diff);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -62,4 +62,64 @@ namespace test
|
||||
|
||||
return create_sample_emulator(std::move(settings));
|
||||
}
|
||||
|
||||
inline void bisect_emulation(windows_emulator& emu)
|
||||
{
|
||||
utils::buffer_serializer start_state{};
|
||||
emu.serialize(start_state);
|
||||
|
||||
emu.start();
|
||||
const auto limit = emu.process().executed_instructions;
|
||||
|
||||
const auto reset_emulator = [&] {
|
||||
utils::buffer_deserializer deserializer{start_state.get_buffer()};
|
||||
emu.deserialize(deserializer);
|
||||
};
|
||||
|
||||
const auto get_state_for_count = [&](const size_t count) {
|
||||
reset_emulator();
|
||||
emu.start({}, count);
|
||||
|
||||
utils::buffer_serializer state{};
|
||||
emu.serialize(state);
|
||||
return state;
|
||||
};
|
||||
|
||||
const auto has_diff_after_count = [&](const size_t count) {
|
||||
const auto s1 = get_state_for_count(count);
|
||||
const auto s2 = get_state_for_count(count);
|
||||
|
||||
return s1.get_diff(s2).has_value();
|
||||
};
|
||||
|
||||
if (!has_diff_after_count(limit))
|
||||
{
|
||||
puts("Emulation has no diff");
|
||||
}
|
||||
|
||||
auto lower_bound = 0ULL;
|
||||
auto upper_bound = limit;
|
||||
|
||||
printf("Bounds: %" PRIx64 " - %" PRIx64 "\n", lower_bound, upper_bound);
|
||||
|
||||
while (lower_bound + 1 < upper_bound)
|
||||
{
|
||||
const auto diff = (upper_bound - lower_bound);
|
||||
const auto pivot = lower_bound + (diff / 2);
|
||||
|
||||
const auto has_diff = has_diff_after_count(pivot);
|
||||
|
||||
auto& bound = has_diff ? upper_bound : lower_bound;
|
||||
bound = pivot;
|
||||
|
||||
printf("Bounds: %" PRIx64 " - %" PRIx64 "\n", lower_bound, upper_bound);
|
||||
}
|
||||
|
||||
(void)get_state_for_count(lower_bound);
|
||||
|
||||
const auto rip = emu.emu().read_instruction_pointer();
|
||||
|
||||
printf("Diff detected after 0x%" PRIx64 " instructions at 0x%" PRIx64 " (%s)\n", lower_bound, rip,
|
||||
emu.process().mod_manager.find_name(rip));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user