def _deobfuscate_push_reg(self, validation_outcome):
     obfuscation_start_addr = validation_outcome.selection.selectionOffset
     # reg IDs: EAX - 0x30, EDX: 0x31, ... (was 0x31, ... in older versions?)
     reg_id = idc.Byte(obfuscation_start_addr + 1)
     # rewrite deobfuscation as <6x NOP>, <push reg> where reg can be numerically derived from
     # reg ID by adding 0x1F. E.g. EAX has parameter 31, so <push EAX> has opcode byte 0x50
     deobfuscated = ida_lib.get_multi_nop_buf(6) + chr(reg_id + 0x20)
     ida_lib.patch_bytes(obfuscation_start_addr, deobfuscated)
     return 1, []
    def _deobfuscate_jump_single_detour(self, validation_outcome):
        obfuscation_start_addr = validation_outcome.selection.selectionOffset
        rel_jmp_offset = validation_outcome.emulation.callbackResult - (obfuscation_start_addr + 5 + 5)
        deobfuscated_jmp = "\x90" * 5 + "\xE9" + struct.pack("I", (rel_jmp_offset) & 0xffffffff)
        ida_lib.patch_bytes(obfuscation_start_addr, deobfuscated_jmp)
        self.updateCallXref(obfuscation_start_addr + 5, validation_outcome.emulation.callbackResult)
        # replace the post jump bytes with NOP to improve IDA's code recognition
        ida_lib.patch_bytes(obfuscation_start_addr + 5 + 5, ida_lib.get_multi_nop_buf(4))

        rel_s = obfuscation_start_addr + 5 - self.emulator.textstart + 1
        dw = self.memory[rel_s:rel_s + 4]
        fixed_destination = (5 + obfuscation_start_addr + 5 + struct.unpack("I", dw)[0]) & 0xffffffff

        return 1, [fixed_destination]