From 2ede24598d1c5492a93f016e6481803027aca917 Mon Sep 17 00:00:00 2001 From: de4dot Date: Sat, 29 Oct 2011 20:28:29 +0200 Subject: [PATCH] Detect DNR version --- .../dotNET_Reactor/Deobfuscator.cs | 75 ++++++++++++++++++- .../dotNET_Reactor/MethodsDecrypter.cs | 7 +- .../dotNET_Reactor/StringDecrypter.cs | 16 ++-- 3 files changed, 86 insertions(+), 12 deletions(-) diff --git a/de4dot.code/deobfuscators/dotNET_Reactor/Deobfuscator.cs b/de4dot.code/deobfuscators/dotNET_Reactor/Deobfuscator.cs index 8287ee58..bdf9228b 100644 --- a/de4dot.code/deobfuscators/dotNET_Reactor/Deobfuscator.cs +++ b/de4dot.code/deobfuscators/dotNET_Reactor/Deobfuscator.cs @@ -60,6 +60,7 @@ namespace de4dot.deobfuscators.dotNET_Reactor { class Deobfuscator : DeobfuscatorBase { Options options; + string obfuscatorName = ".NET Reactor"; PE.PeImage peImage; byte[] fileData; @@ -78,7 +79,7 @@ namespace de4dot.deobfuscators.dotNET_Reactor { } public override string Name { - get { return ".NET Reactor"; } + get { return obfuscatorName; } } public Deobfuscator(Options options) @@ -113,9 +114,79 @@ namespace de4dot.deobfuscators.dotNET_Reactor { methodsDecrypter = new MethodsDecrypter(module); methodsDecrypter.find(); stringDecrypter = new StringDecrypter(module); - stringDecrypter.find(); + stringDecrypter.find(DeobfuscatedFile); booleanDecrypter = new BooleanDecrypter(module); booleanDecrypter.find(); + obfuscatorName = detectVersion(); + } + + string detectVersion() { + /* + Methods decrypter locals (not showing its own types): + 3.7.0.3: + "System.Byte[]" + "System.Int32" + "System.Int32[]" + "System.IntPtr" + "System.IO.BinaryReader" + "System.IO.MemoryStream" + "System.Object" + "System.Reflection.Assembly" + "System.Security.Cryptography.CryptoStream" + "System.Security.Cryptography.ICryptoTransform" + "System.Security.Cryptography.RijndaelManaged" + "System.String" + + 3.9.8.0: + - "System.Int32[]" + + "System.Diagnostics.StackFrame" + + 4.3.1.0 (jitter): + - "System.Diagnostics.StackFrame" + - "System.Object" + + "System.Boolean" + + "System.Byte&" + + "System.Collections.IEnumerator" + + "System.Delegate" + + "System.Diagnostics.Process" + + "System.Diagnostics.ProcessModule" + + "System.Diagnostics.ProcessModuleCollection" + + "System.IDisposable" + + "System.Int64" + + "System.UInt32" + + "System.UInt64" + */ + + LocalTypes localTypes; + int minVer = -1; + foreach (var info in stringDecrypter.DecrypterInfos) { + if (info.key == null) + continue; + localTypes = new LocalTypes(info.method); + if (!localTypes.exists("System.IntPtr")) + return ".NET Reactor <= 3.7"; + minVer = 3800; + break; + } + + if (methodsDecrypter.MethodsDecrypterMethod == null) { + if (minVer >= 3800) + return ".NET Reactor >= 3.8"; + return ".NET Reactor"; + } + localTypes = new LocalTypes(methodsDecrypter.MethodsDecrypterMethod); + + if (localTypes.exists("System.Int32[]")) { + if (minVer >= 3800) + return ".NET Reactor 3.8.4.1 - 3.9.0.1"; + return ".NET Reactor <= 3.9.0.1"; + } + + if (localTypes.exists("System.Diagnostics.StackFrame")) + return ".NET Reactor 3.9.8.0 - 4.2"; + if (!localTypes.exists("System.Byte&")) + return ".NET Reactor 4.0-4.2"; + return ".NET Reactor 4.3-4.4"; } public override bool getDecryptedModule(ref byte[] newFileData, ref Dictionary dumpedMethods) { diff --git a/de4dot.code/deobfuscators/dotNET_Reactor/MethodsDecrypter.cs b/de4dot.code/deobfuscators/dotNET_Reactor/MethodsDecrypter.cs index 58fb4eec..001dbe89 100644 --- a/de4dot.code/deobfuscators/dotNET_Reactor/MethodsDecrypter.cs +++ b/de4dot.code/deobfuscators/dotNET_Reactor/MethodsDecrypter.cs @@ -101,9 +101,10 @@ namespace de4dot.deobfuscators.dotNET_Reactor { var methodsData = encryptedResource.decrypt(); ArrayFinder arrayFinder = new ArrayFinder(encryptedResource.ResourceDecrypterMethod); - bool hasJitter = arrayFinder.exists(new byte[] { (byte)'g', (byte)'e', (byte)'t', (byte)'J', (byte)'i', (byte)'t' }); + bool hooksJitter = arrayFinder.exists(new byte[] { (byte)'g', (byte)'e', (byte)'t', (byte)'J', (byte)'i', (byte)'t' }); if (useXorKey) { + // DNR 4.3, 4.4 var stream = new MemoryStream(methodsData); var reader = new BinaryReader(stream); var writer = new BinaryWriter(stream); @@ -135,7 +136,7 @@ namespace de4dot.deobfuscators.dotNET_Reactor { patchDwords(peImage, methodsDataReader, numDwords / 2); } } - else if (!hasJitter || mode == 1) { + else if (!hooksJitter || mode == 1) { // DNR 3.9.8.0, 4.0, 4.1, 4.2, 4.3, 4.4 patchDwords(peImage, methodsDataReader, patchCount); while (methodsDataReader.BaseStream.Position < methodsData.Length - 1) { @@ -147,7 +148,7 @@ namespace de4dot.deobfuscators.dotNET_Reactor { } } else { - // DNR 4.4 (jitter is hooked) + // DNR (4.0-4.2?), 4.3, 4.4 (jitter is hooked) var metadataTables = peImage.Cor20Header.createMetadataTables(); var methodDef = metadataTables.getMetadataType(PE.MetadataIndex.iMethodDef); diff --git a/de4dot.code/deobfuscators/dotNET_Reactor/StringDecrypter.cs b/de4dot.code/deobfuscators/dotNET_Reactor/StringDecrypter.cs index f8405307..22ecffb0 100644 --- a/de4dot.code/deobfuscators/dotNET_Reactor/StringDecrypter.cs +++ b/de4dot.code/deobfuscators/dotNET_Reactor/StringDecrypter.cs @@ -92,7 +92,7 @@ namespace de4dot.deobfuscators.dotNET_Reactor { } } - public void find() { + public void find(ISimpleDeobfuscator simpleDeobfuscator) { var additionalTypes = new string[] { "System.String", }; @@ -118,7 +118,12 @@ namespace de4dot.deobfuscators.dotNET_Reactor { stringsResource = resource; encryptedResource.ResourceDecrypterMethod = method; - decrypterInfos.Add(new DecrypterInfo(method, null, null)); + + var info = new DecrypterInfo(method, null, null); + simpleDeobfuscator.deobfuscate(info.method); + findKeyIv(info.method, out info.key, out info.iv); + + decrypterInfos.Add(info); } } @@ -149,12 +154,9 @@ namespace de4dot.deobfuscators.dotNET_Reactor { this.peImage = peImage; this.fileData = fileData; - foreach (var info in decrypterInfos) { - simpleDeobfuscator.deobfuscate(info.method); - findKeyIv(info.method, out info.key, out info.iv); - } - encryptedResource.init(simpleDeobfuscator); + if (encryptedResource.EncryptedDataResource != null) + Log.v("Adding string decrypter. Resource: {0}", Utils.toCsharpString(encryptedResource.EncryptedDataResource.Name)); decryptedData = encryptedResource.decrypt(); }