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]