Prepare emulation bisection

This commit is contained in:
momo5502
2025-01-25 20:59:10 +01:00
parent 130367619b
commit 45d7c542c3
2 changed files with 82 additions and 4 deletions

View File

@@ -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:

View File

@@ -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));
}
}