def _deobfuscate_mov_eax(self, selection_outcome):
     num_deobfuscations = 0
     for referencing_call in selection_outcome.codeRefsToFunction:
         obfuscation_start_addr = referencing_call
         deobfusbcated_mov = "\xb8" + selection_outcome.selectionGroupdict["operand_1"]
         ida_lib.patch_bytes(obfuscation_start_addr, deobfusbcated_mov)
         num_deobfuscations += 1
     return num_deobfuscations, []
 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_dual_detour(self, validation_outcome):
        obfuscation_start_addr = validation_outcome.selection.selectionOffset
        rel_jmp_offset = validation_outcome.emulation.callbackResult - (obfuscation_start_addr + 10 + 5)
        deobfuscated_jmp = "\x90" * 10 + "\xE9" + struct.pack("I", (rel_jmp_offset) & 0xffffffff)
        ida_lib.patch_bytes(obfuscation_start_addr, deobfuscated_jmp)
        self.updateCallXref(obfuscation_start_addr + 10, validation_outcome.emulation.callbackResult)

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

        return 1, [fixed_destination]
    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]