From 037cb5bc68eaa5d3ea1cc79cfaa9a530cbc3d223 Mon Sep 17 00:00:00 2001 From: de4dot Date: Sun, 12 Feb 2012 14:28:53 +0100 Subject: [PATCH] Decrypt the remaining (EREX) resources --- de4dot.code/de4dot.code.csproj | 1 + .../CodeVeil/ErexResourceReader.cs | 88 +++++++++++++++++++ .../CodeVeil/ResourceDecrypter.cs | 8 +- 3 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 de4dot.code/deobfuscators/CodeVeil/ErexResourceReader.cs diff --git a/de4dot.code/de4dot.code.csproj b/de4dot.code/de4dot.code.csproj index 3b346e49..3fdcb213 100644 --- a/de4dot.code/de4dot.code.csproj +++ b/de4dot.code/de4dot.code.csproj @@ -81,6 +81,7 @@ + diff --git a/de4dot.code/deobfuscators/CodeVeil/ErexResourceReader.cs b/de4dot.code/deobfuscators/CodeVeil/ErexResourceReader.cs new file mode 100644 index 00000000..49ddba94 --- /dev/null +++ b/de4dot.code/deobfuscators/CodeVeil/ErexResourceReader.cs @@ -0,0 +1,88 @@ +/* + Copyright (C) 2011-2012 de4dot@gmail.com + + This file is part of de4dot. + + de4dot is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + de4dot is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with de4dot. If not, see . +*/ + +using System; +using System.IO; + +namespace de4dot.code.deobfuscators.CodeVeil { + class ErexResourceReader { + BinaryReader reader; + uint[] key; + + public ErexResourceReader(Stream stream) { + reader = new BinaryReader(stream); + } + + public byte[] decrypt() { + if (reader.ReadUInt32() != 0x58455245) + throw new InvalidDataException("Invalid EREX sig"); + if (reader.ReadInt32() > 1) + throw new ApplicationException("Invalid EREX file"); + + byte flags = reader.ReadByte(); + bool isEncrypted = (flags & 1) != 0; + bool isDeflated = (flags & 2) != 0; + + int length = reader.ReadInt32(); + if (length < 0) + throw new ApplicationException("Invalid length"); + + if (isEncrypted) + readKey(); + + if (isDeflated) + reader = new BinaryReader(inflate(length)); + + if (isEncrypted) + reader = new BinaryReader(decrypt(length)); + + return reader.ReadBytes(length); + } + + void readKey() { + key = new uint[reader.ReadByte()]; + for (int i = 0; i < key.Length; i++) + key[i] = reader.ReadUInt32(); + } + + Stream inflate(int length) { + var data = reader.ReadBytes((int)(reader.BaseStream.Length - reader.BaseStream.Position)); + return new MemoryStream(DeobUtils.inflate(data, true)); + } + + Stream decrypt(int length) { + var block = new uint[4]; + var decrypted = new byte[16]; + + var outStream = new MemoryStream(length); + while (reader.BaseStream.Position < reader.BaseStream.Length) { + block[0] = reader.ReadUInt32(); + block[1] = reader.ReadUInt32(); + block[2] = reader.ReadUInt32(); + block[3] = reader.ReadUInt32(); + DeobUtils.xxteaDecrypt(block, key); + Buffer.BlockCopy(block, 0, decrypted, 0, decrypted.Length); + outStream.Write(decrypted, 0, decrypted.Length); + } + + outStream.Position = 0; + return outStream; + } + } +} diff --git a/de4dot.code/deobfuscators/CodeVeil/ResourceDecrypter.cs b/de4dot.code/deobfuscators/CodeVeil/ResourceDecrypter.cs index 4c492267..2deb7cc6 100644 --- a/de4dot.code/deobfuscators/CodeVeil/ResourceDecrypter.cs +++ b/de4dot.code/deobfuscators/CodeVeil/ResourceDecrypter.cs @@ -340,9 +340,11 @@ namespace de4dot.code.deobfuscators.CodeVeil { stream.Position = 0; var reader = new BinaryReader(stream); uint sig = reader.ReadUInt32(); + stream.Position = 0; if (sig == 0xBEEFCACE) return decryptBeefcace(reader); - //TODO: Decrypt the other type + if (sig == 0x58455245) + return decryptErex(reader); return null; } catch (InvalidDataException) { @@ -362,6 +364,10 @@ namespace de4dot.code.deobfuscators.CodeVeil { return new ResourceConverter(module, resourceReader.read()).convert(); } + byte[] decryptErex(BinaryReader reader) { + return new ErexResourceReader(reader.BaseStream).decrypt(); + } + public void deobfuscate(Blocks blocks) { foreach (var block in blocks.MethodBlocks.getAllBlocks()) { var instrs = block.Instructions;