From 09178a6e956b2c29e369d8aca57b90c3f0095d40 Mon Sep 17 00:00:00 2001 From: de4dot Date: Thu, 27 Oct 2011 22:25:44 +0200 Subject: [PATCH] Update methods decrypter and string decrypter --- .../dotNET_Reactor/Deobfuscator.cs | 5 +++ .../dotNET_Reactor/MethodsDecrypter.cs | 41 +++++++++++-------- .../dotNET_Reactor/StringDecrypter.cs | 37 +++++++++++++++++ 3 files changed, 65 insertions(+), 18 deletions(-) diff --git a/de4dot.code/deobfuscators/dotNET_Reactor/Deobfuscator.cs b/de4dot.code/deobfuscators/dotNET_Reactor/Deobfuscator.cs index 1d2aa16b..39deda38 100644 --- a/de4dot.code/deobfuscators/dotNET_Reactor/Deobfuscator.cs +++ b/de4dot.code/deobfuscators/dotNET_Reactor/Deobfuscator.cs @@ -162,6 +162,11 @@ namespace de4dot.deobfuscators.dotNET_Reactor { return stringDecrypter.decrypt(method2, (int)args[0]); }); } + if (stringDecrypter.OtherStringDecrypter != null) { + staticStringDecrypter.add(stringDecrypter.OtherStringDecrypter, (method2, args) => { + return stringDecrypter.decrypt((string)args[0]); + }); + } DeobfuscatedFile.stringDecryptersAdded(); if (Operations.DecryptStrings != OpDecryptString.None) diff --git a/de4dot.code/deobfuscators/dotNET_Reactor/MethodsDecrypter.cs b/de4dot.code/deobfuscators/dotNET_Reactor/MethodsDecrypter.cs index f2203ae8..fb8c0c3a 100644 --- a/de4dot.code/deobfuscators/dotNET_Reactor/MethodsDecrypter.cs +++ b/de4dot.code/deobfuscators/dotNET_Reactor/MethodsDecrypter.cs @@ -112,40 +112,45 @@ namespace de4dot.deobfuscators.dotNET_Reactor { var methodsDataReader = new BinaryReader(new MemoryStream(methodsData)); int patchCount = methodsDataReader.ReadInt32(); int mode = methodsDataReader.ReadInt32(); - if (!useXorKey || mode == 1) { - // Here if DNR 4.0, 4.1 - for (int i = 0; i < patchCount; i++) { - uint rva = methodsDataReader.ReadUInt32(); - uint data = methodsDataReader.ReadUInt32(); - peImage.write(rva, BitConverter.GetBytes(data)); - } + + int tmp = methodsDataReader.ReadInt32(); + methodsDataReader.BaseStream.Position -= 4; + if ((tmp & 0xFF000000) == 0x06000000) { + // It's method token + rva. DNR <= 3.9.0.1 ??? + methodsDataReader.BaseStream.Position += 8 * patchCount; + patchCount = methodsDataReader.ReadInt32(); + mode = methodsDataReader.ReadInt32(); + + patchDwords(peImage, methodsDataReader, patchCount); while (methodsDataReader.BaseStream.Position < methodsData.Length - 1) { - uint rva = methodsDataReader.ReadUInt32(); uint token = methodsDataReader.ReadUInt32(); - int size = methodsDataReader.ReadInt32(); - if (size > 0) - peImage.write(rva, methodsDataReader.ReadBytes(size)); + int numDwords = methodsDataReader.ReadInt32(); + patchDwords(peImage, methodsDataReader, numDwords / 2); } } else { - for (int i = 0; i < patchCount; i++) { - uint rva = methodsDataReader.ReadUInt32(); - uint data = methodsDataReader.ReadUInt32(); - peImage.write(rva, BitConverter.GetBytes(data)); - } - int count = methodsDataReader.ReadInt32(); + // DNR 3.9.8.0, 4.0, 4.1, 4.2 + patchDwords(peImage, methodsDataReader, patchCount); while (methodsDataReader.BaseStream.Position < methodsData.Length - 1) { uint rva = methodsDataReader.ReadUInt32(); uint token = methodsDataReader.ReadUInt32(); int size = methodsDataReader.ReadInt32(); if (size > 0) - peImage.write(rva, methodsDataReader.ReadBytes(size)); + peImage.dotNetSafeWrite(rva, methodsDataReader.ReadBytes(size)); } } return true; } + static void patchDwords(PE.PeImage peImage, BinaryReader reader, int count) { + for (int i = 0; i < count; i++) { + uint rva = reader.ReadUInt32(); + uint data = reader.ReadUInt32(); + peImage.dotNetSafeWrite(rva, BitConverter.GetBytes(data)); + } + } + void initXorKey() { useXorKey = false; diff --git a/de4dot.code/deobfuscators/dotNET_Reactor/StringDecrypter.cs b/de4dot.code/deobfuscators/dotNET_Reactor/StringDecrypter.cs index c8e8fa8b..cd1f9076 100644 --- a/de4dot.code/deobfuscators/dotNET_Reactor/StringDecrypter.cs +++ b/de4dot.code/deobfuscators/dotNET_Reactor/StringDecrypter.cs @@ -30,6 +30,7 @@ namespace de4dot.deobfuscators.dotNET_Reactor { ModuleDefinition module; EncryptedResource encryptedResource; List decrypterInfos = new List(); + MethodDefinition otherStringDecrypter; byte[] decryptedData; PE.PeImage peImage; @@ -57,6 +58,10 @@ namespace de4dot.deobfuscators.dotNET_Reactor { get { return decrypterInfos; } } + public MethodDefinition OtherStringDecrypter { + get { return otherStringDecrypter; } + } + public StringDecrypter(ModuleDefinition module) { this.module = module; this.encryptedResource = new EncryptedResource(module); @@ -71,6 +76,11 @@ namespace de4dot.deobfuscators.dotNET_Reactor { throw new ApplicationException("Could not find string decrypter method"); decrypterInfos.Add(new DecrypterInfo(method, oldInfo.key, oldInfo.iv)); } + if (oldOne.otherStringDecrypter != null) { + otherStringDecrypter = module.LookupToken(oldOne.otherStringDecrypter.MetadataToken.ToInt32()) as MethodDefinition; + if (otherStringDecrypter == null) + throw new ApplicationException("Could not find string decrypter method"); + } } public void find() { @@ -79,6 +89,8 @@ namespace de4dot.deobfuscators.dotNET_Reactor { }; EmbeddedResource stringsResource = null; foreach (var type in module.Types) { + if (decrypterInfos.Count > 0) + break; if (type.BaseType == null || type.BaseType.FullName != "System.Object") continue; foreach (var method in type.Methods) { @@ -100,6 +112,26 @@ namespace de4dot.deobfuscators.dotNET_Reactor { decrypterInfos.Add(new DecrypterInfo(method, null, null)); } } + + if (decrypterInfos.Count > 0) + findOtherStringDecrypter(decrypterInfos[0].method.DeclaringType); + } + + void findOtherStringDecrypter(TypeDefinition type) { + foreach (var method in type.Methods) { + if (!method.IsStatic || !method.HasBody) + continue; + if (method.MethodReturnType.ReturnType.FullName != "System.String") + continue; + if (method.Parameters.Count != 1) + continue; + if (method.Parameters[0].ParameterType.FullName != "System.Object" && + method.Parameters[0].ParameterType.FullName != "System.String") + continue; + + otherStringDecrypter = method; + return; + } } public void init(PE.PeImage peImage, ISimpleDeobfuscator simpleDeobfuscator) { @@ -190,5 +222,10 @@ namespace de4dot.deobfuscators.dotNET_Reactor { return Encoding.Unicode.GetString(decryptedStringData, 0, decryptedStringData.Length); } } + + public string decrypt(string s) { + var data = Convert.FromBase64String(s); + return Encoding.Unicode.GetString(data, 0, data.Length); + } } }