save instruction starts

This commit is contained in:
2025-12-02 17:45:39 +01:00
parent 2d19460095
commit d3788d132d

View File

@@ -178,15 +178,24 @@ pub fn patchRegion(patcher: *Patcher, region: []align(page_size) u8) !void {
defer arena_impl.deinit(); defer arena_impl.deinit();
var patch_requests: std.ArrayListUnmanaged(PatchRequest) = .empty; var patch_requests: std.ArrayListUnmanaged(PatchRequest) = .empty;
// We save the bytes where instructions start to be able to disassemble them on the fly. This is
// necessary for the neighbor eviction, since we can't just iterate forwards from a target
// instruction and disassemble happily. This is because some bytes may already be the patched
// ones which means that we might disassemble garbage or something different that wasn't there
// before. This means that we would need to stop disassembling on the first byte that is locked,
// which kind of defeats the purpose of neighbor eviction.
var instruction_starts = try std.DynamicBitSetUnmanaged.initEmpty(arena, region.len);
{ {
// Get where to patch. // Get where to patch.
var instruction_iterator = InstructionIterator.init(region); var instruction_iterator = InstructionIterator.init(region);
while (instruction_iterator.next()) |instruction| { while (instruction_iterator.next()) |instruction| {
const should_patch = instruction.instruction.attributes & zydis.ZYDIS_ATTRIB_HAS_LOCK > 0 or const offset = instruction.address - @intFromPtr(region.ptr);
instruction.instruction.mnemonic == zydis.ZYDIS_MNEMONIC_SYSCALL; instruction_starts.set(offset);
const should_patch = instruction.instruction.mnemonic == zydis.ZYDIS_MNEMONIC_SYSCALL or
instruction.instruction.attributes & zydis.ZYDIS_ATTRIB_HAS_LOCK > 0;
if (should_patch) { if (should_patch) {
const offset = instruction.address - @intFromPtr(region.ptr);
const request: PatchRequest = .{ const request: PatchRequest = .{
.flicken = .nop, .flicken = .nop,
.offset = offset, .offset = offset,