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]