Support Confuser 1.4 r58564 compressor

This commit is contained in:
de4dot 2012-07-31 19:56:10 +02:00
parent d99133658c
commit 3e49c0bfa5
5 changed files with 65 additions and 21 deletions

View File

@ -195,23 +195,23 @@ namespace de4dot.code.deobfuscators.Confuser {
var peImage = new PeImage(fileData); var peImage = new PeImage(fileData);
if ((decryptState & DecryptState.CanDecryptMethods) != 0) { if ((decryptState & DecryptState.CanDecryptMethods) != 0) {
bool decrypted = false;
if (jitMethodsDecrypter != null && jitMethodsDecrypter.Detected) { if (jitMethodsDecrypter != null && jitMethodsDecrypter.Detected) {
jitMethodsDecrypter.initialize(); jitMethodsDecrypter.initialize();
if (!jitMethodsDecrypter.decrypt(peImage, fileData, ref dumpedMethods)) if (!jitMethodsDecrypter.decrypt(peImage, fileData, ref dumpedMethods))
return false; return false;
decrypted = true;
decryptState &= ~DecryptState.CanDecryptMethods;
newFileData = fileData;
ModuleBytes = newFileData;
return true;
} }
else if (memoryMethodsDecrypter != null && memoryMethodsDecrypter.Detected) {
if (memoryMethodsDecrypter != null && memoryMethodsDecrypter.Detected) {
memoryMethodsDecrypter.initialize(); memoryMethodsDecrypter.initialize();
if (!memoryMethodsDecrypter.decrypt(peImage, fileData, ref dumpedMethods)) if (!memoryMethodsDecrypter.decrypt(peImage, fileData, ref dumpedMethods))
return false; return false;
decrypted = true;
}
if (decrypted) {
decryptState &= ~DecryptState.CanDecryptMethods; decryptState &= ~DecryptState.CanDecryptMethods;
decryptState |= DecryptState.CanUnpack;
newFileData = fileData; newFileData = fileData;
ModuleBytes = newFileData; ModuleBytes = newFileData;
return true; return true;
@ -220,8 +220,7 @@ namespace de4dot.code.deobfuscators.Confuser {
if ((decryptState & DecryptState.CanUnpack) != 0) { if ((decryptState & DecryptState.CanUnpack) != 0) {
if (unpacker != null && unpacker.Detected) { if (unpacker != null && unpacker.Detected) {
decryptState &= ~DecryptState.CanUnpack; decryptState |= DecryptState.CanDecryptMethods | DecryptState.CanUnpack;
decryptState |= DecryptState.CanDecryptMethods;
newFileData = unpacker.unpack(); newFileData = unpacker.unpack();
ModuleBytes = newFileData; ModuleBytes = newFileData;
return true; return true;
@ -238,8 +237,8 @@ namespace de4dot.code.deobfuscators.Confuser {
newOne.DeobfuscatedFile = DeobfuscatedFile; newOne.DeobfuscatedFile = DeobfuscatedFile;
newOne.ModuleBytes = ModuleBytes; newOne.ModuleBytes = ModuleBytes;
newOne.setModule(module); newOne.setModule(module);
newOne.jitMethodsDecrypter = new JitMethodsDecrypter(module, jitMethodsDecrypter); newOne.jitMethodsDecrypter = new JitMethodsDecrypter(module, DeobfuscatedFile, jitMethodsDecrypter);
if ((decryptState & DecryptState.CanDecryptMethods) != 0) { if ((newOne.decryptState & DecryptState.CanDecryptMethods) != 0) {
try { try {
newOne.jitMethodsDecrypter.find(); newOne.jitMethodsDecrypter.find();
} }
@ -248,8 +247,8 @@ namespace de4dot.code.deobfuscators.Confuser {
if (newOne.jitMethodsDecrypter.Detected) if (newOne.jitMethodsDecrypter.Detected)
return newOne; return newOne;
} }
newOne.memoryMethodsDecrypter = new MemoryMethodsDecrypter(module, memoryMethodsDecrypter); newOne.memoryMethodsDecrypter = new MemoryMethodsDecrypter(module, DeobfuscatedFile, memoryMethodsDecrypter);
if ((decryptState & DecryptState.CanDecryptMethods) != 0) { if ((newOne.decryptState & DecryptState.CanDecryptMethods) != 0) {
newOne.memoryMethodsDecrypter.find(); newOne.memoryMethodsDecrypter.find();
if (newOne.memoryMethodsDecrypter.Detected) if (newOne.memoryMethodsDecrypter.Detected)
return newOne; return newOne;

View File

@ -46,8 +46,8 @@ namespace de4dot.code.deobfuscators.Confuser {
: base(module, simpleDeobfuscator) { : base(module, simpleDeobfuscator) {
} }
public JitMethodsDecrypter(ModuleDefinition module, JitMethodsDecrypter other) public JitMethodsDecrypter(ModuleDefinition module, ISimpleDeobfuscator simpleDeobfuscator, JitMethodsDecrypter other)
: base(module, other) { : base(module, simpleDeobfuscator, other) {
} }
protected override bool checkType(TypeDefinition type, MethodDefinition initMethod) { protected override bool checkType(TypeDefinition type, MethodDefinition initMethod) {

View File

@ -41,8 +41,8 @@ namespace de4dot.code.deobfuscators.Confuser {
: base(module, simpleDeobfuscator) { : base(module, simpleDeobfuscator) {
} }
public MemoryMethodsDecrypter(ModuleDefinition module, MemoryMethodsDecrypter other) public MemoryMethodsDecrypter(ModuleDefinition module, ISimpleDeobfuscator simpleDeobfuscator, MemoryMethodsDecrypter other)
: base(module, other) { : base(module, simpleDeobfuscator, other) {
} }
protected override bool checkType(TypeDefinition type, MethodDefinition initMethod) { protected override bool checkType(TypeDefinition type, MethodDefinition initMethod) {

View File

@ -53,8 +53,9 @@ namespace de4dot.code.deobfuscators.Confuser {
this.simpleDeobfuscator = simpleDeobfuscator; this.simpleDeobfuscator = simpleDeobfuscator;
} }
protected MethodsDecrypterBase(ModuleDefinition module, MethodsDecrypterBase other) { protected MethodsDecrypterBase(ModuleDefinition module, ISimpleDeobfuscator simpleDeobfuscator, MethodsDecrypterBase other) {
this.module = module; this.module = module;
this.simpleDeobfuscator = simpleDeobfuscator;
if (other != null) if (other != null)
this.initMethod = lookup(other.initMethod, "Could not find initMethod"); this.initMethod = lookup(other.initMethod, "Could not find initMethod");
} }

View File

@ -17,6 +17,8 @@
along with de4dot. If not, see <http://www.gnu.org/licenses/>. along with de4dot. If not, see <http://www.gnu.org/licenses/>.
*/ */
using System;
using System.IO;
using Mono.Cecil; using Mono.Cecil;
using Mono.Cecil.Cil; using Mono.Cecil.Cil;
using de4dot.blocks; using de4dot.blocks;
@ -25,6 +27,14 @@ namespace de4dot.code.deobfuscators.Confuser {
class Unpacker { class Unpacker {
ModuleDefinition module; ModuleDefinition module;
EmbeddedResource resource; EmbeddedResource resource;
uint key;
ConfuserVersion version = ConfuserVersion.Unknown;
enum ConfuserVersion {
Unknown,
v10_r42915,
v14_r58564,
}
public bool Detected { public bool Detected {
get { return resource != null; } get { return resource != null; }
@ -52,19 +62,48 @@ namespace de4dot.code.deobfuscators.Confuser {
var type = entryPoint.DeclaringType; var type = entryPoint.DeclaringType;
if (!new FieldTypes(type).all(requiredFields)) if (!new FieldTypes(type).all(requiredFields))
return; return;
if (findDecryptMethod(type) == null) var decyptMethod = findDecryptMethod(type);
if (decyptMethod == null)
return; return;
if (new LocalTypes(decyptMethod).exists("System.IO.MemoryStream"))
version = ConfuserVersion.v10_r42915;
else
version = ConfuserVersion.v14_r58564;
var cctor = DotNetUtils.getMethod(type, ".cctor"); var cctor = DotNetUtils.getMethod(type, ".cctor");
if (cctor == null) if (cctor == null)
return; return;
if (version == ConfuserVersion.v14_r58564) {
simpleDeobfuscator.deobfuscate(decyptMethod);
if (!findKey(decyptMethod, out key))
throw new ApplicationException("Could not find magic");
}
simpleDeobfuscator.deobfuscate(cctor); simpleDeobfuscator.deobfuscate(cctor);
simpleDeobfuscator.decryptStrings(cctor, deob); simpleDeobfuscator.decryptStrings(cctor, deob);
resource = findResource(cctor); resource = findResource(cctor);
} }
static bool findKey(MethodDefinition method, out uint key) {
var instrs = method.Body.Instructions;
for (int i = 0; i < instrs.Count - 2; i++) {
if (instrs[i].OpCode.Code != Code.Xor)
continue;
var ldci4 = instrs[i + 1];
if (!DotNetUtils.isLdcI4(ldci4))
continue;
if (instrs[i + 2].OpCode.Code != Code.Xor)
continue;
key = (uint)DotNetUtils.getLdcI4Value(ldci4);
return true;
}
key = 0;
return false;
}
EmbeddedResource findResource(MethodDefinition method) { EmbeddedResource findResource(MethodDefinition method) {
return DotNetUtils.getResource(module, DotNetUtils.getCodeStrings(method)) as EmbeddedResource; return DotNetUtils.getResource(module, DotNetUtils.getCodeStrings(method)) as EmbeddedResource;
} }
@ -72,7 +111,6 @@ namespace de4dot.code.deobfuscators.Confuser {
static string[] requiredDecryptLocals = new string[] { static string[] requiredDecryptLocals = new string[] {
"System.Byte[]", "System.Byte[]",
"System.IO.Compression.DeflateStream", "System.IO.Compression.DeflateStream",
"System.IO.MemoryStream",
}; };
static MethodDefinition findDecryptMethod(TypeDefinition type) { static MethodDefinition findDecryptMethod(TypeDefinition type) {
foreach (var method in type.Methods) { foreach (var method in type.Methods) {
@ -93,8 +131,14 @@ namespace de4dot.code.deobfuscators.Confuser {
return null; return null;
var data = resource.GetResourceData(); var data = resource.GetResourceData();
for (int i = 0; i < data.Length; i++) for (int i = 0; i < data.Length; i++)
data[i] ^= (byte)i; data[i] ^= (byte)(i ^ key);
data = DeobUtils.inflate(data, true); data = DeobUtils.inflate(data, true);
if (version == ConfuserVersion.v14_r58564) {
var reader = new BinaryReader(new MemoryStream(data));
data = reader.ReadBytes(reader.ReadInt32());
}
return data; return data;
} }
} }