From 02d6de8f39acf82ee69d0528155fc7cee43dcb6c Mon Sep 17 00:00:00 2001 From: de4dot Date: Thu, 29 Oct 2015 22:36:17 +0100 Subject: [PATCH] Fix old Confuser deobfuscator code --- .../cflow/BlocksCflowDeobfuscator.cs | 20 +++++++++++++------ de4dot.blocks/cflow/ConstantsFolder.cs | 4 ++++ de4dot.code/ObfuscatedFile.cs | 8 +++++--- .../deobfuscators/Confuser/AntiDumping.cs | 2 +- .../Confuser/ConstantsDecrypterV17.cs | 2 +- .../Confuser/ConstantsDecrypterV18.cs | 6 +++--- .../deobfuscators/Confuser/ProxyCallFixer.cs | 2 +- .../Confuser/ResourceDecrypter.cs | 4 ++-- .../deobfuscators/DeepSea/ArrayBlockState.cs | 2 +- .../deobfuscators/ISimpleDeobfuscator.cs | 12 ++++++++++- 10 files changed, 43 insertions(+), 19 deletions(-) diff --git a/de4dot.blocks/cflow/BlocksCflowDeobfuscator.cs b/de4dot.blocks/cflow/BlocksCflowDeobfuscator.cs index 61f008c4..19ef2cde 100644 --- a/de4dot.blocks/cflow/BlocksCflowDeobfuscator.cs +++ b/de4dot.blocks/cflow/BlocksCflowDeobfuscator.cs @@ -27,21 +27,29 @@ namespace de4dot.blocks.cflow { List userBlocksDeobfuscators = new List(); List ourBlocksDeobfuscators = new List(); - public BlocksCflowDeobfuscator() { - Initialize(); + public BlocksCflowDeobfuscator() + : this(false) { } - public BlocksCflowDeobfuscator(IEnumerable blocksDeobfuscator) { - Initialize(); + public BlocksCflowDeobfuscator(bool disableNewCFCode) { + Initialize(disableNewCFCode); + } + + public BlocksCflowDeobfuscator(IEnumerable blocksDeobfuscator) + : this(blocksDeobfuscator, false) { + } + + public BlocksCflowDeobfuscator(IEnumerable blocksDeobfuscator, bool disableNewCFCode) { + Initialize(disableNewCFCode); Add(blocksDeobfuscator); } - void Initialize() { + void Initialize(bool disableNewCFCode) { ourBlocksDeobfuscators.Add(new BlockCflowDeobfuscator { ExecuteIfNotModified = false }); ourBlocksDeobfuscators.Add(new SwitchCflowDeobfuscator { ExecuteIfNotModified = false }); ourBlocksDeobfuscators.Add(new DeadStoreRemover { ExecuteIfNotModified = false }); ourBlocksDeobfuscators.Add(new DeadCodeRemover { ExecuteIfNotModified = false }); - ourBlocksDeobfuscators.Add(new ConstantsFolder { ExecuteIfNotModified = true }); + ourBlocksDeobfuscators.Add(new ConstantsFolder { ExecuteIfNotModified = true, DisableNewCode = disableNewCFCode }); ourBlocksDeobfuscators.Add(new StLdlocFixer { ExecuteIfNotModified = true }); ourBlocksDeobfuscators.Add(new DupBlockCflowDeobfuscator { ExecuteIfNotModified = true }); } diff --git a/de4dot.blocks/cflow/ConstantsFolder.cs b/de4dot.blocks/cflow/ConstantsFolder.cs index b5227acf..2e93c083 100644 --- a/de4dot.blocks/cflow/ConstantsFolder.cs +++ b/de4dot.blocks/cflow/ConstantsFolder.cs @@ -29,6 +29,8 @@ namespace de4dot.blocks.cflow { InstructionEmulator instructionEmulator = new InstructionEmulator(); IList args; + public bool DisableNewCode { get; set; } + protected override void Initialize(List allBlocks) { base.Initialize(allBlocks); args = blocks.Method.Parameters; @@ -131,6 +133,8 @@ namespace de4dot.blocks.cflow { case Code.Sub_Ovf: case Code.Sub_Ovf_Un: case Code.Xor: + if (DisableNewCode) + break; if (i + 1 < instrs.Count && instrs[i + 1].OpCode.Code == Code.Pop) break; if (!VerifyValidArgs(instr.Instruction)) diff --git a/de4dot.code/ObfuscatedFile.cs b/de4dot.code/ObfuscatedFile.cs index 49e2a9a9..05e409f1 100644 --- a/de4dot.code/ObfuscatedFile.cs +++ b/de4dot.code/ObfuscatedFile.cs @@ -789,15 +789,17 @@ namespace de4dot.code { } void ISimpleDeobfuscator.Deobfuscate(MethodDef method) { - ((ISimpleDeobfuscator)this).Deobfuscate(method, false); + ((ISimpleDeobfuscator)this).Deobfuscate(method, 0); } - void ISimpleDeobfuscator.Deobfuscate(MethodDef method, bool force) { + void ISimpleDeobfuscator.Deobfuscate(MethodDef method, SimpleDeobfuscatorFlags flags) { + bool force = (flags & SimpleDeobfuscatorFlags.Force) != 0; if (method == null || (!force && Check(method, SimpleDeobFlags.HasDeobfuscated))) return; Deobfuscate(method, "Deobfuscating control flow", (blocks) => { - var cflowDeobfuscator = new BlocksCflowDeobfuscator(deob.BlocksDeobfuscators); + bool disableNewCFCode = (flags & SimpleDeobfuscatorFlags.DisableConstantsFolderExtraInstrs) != 0; + var cflowDeobfuscator = new BlocksCflowDeobfuscator(deob.BlocksDeobfuscators, disableNewCFCode); cflowDeobfuscator.Initialize(blocks); cflowDeobfuscator.Deobfuscate(); }); diff --git a/de4dot.code/deobfuscators/Confuser/AntiDumping.cs b/de4dot.code/deobfuscators/Confuser/AntiDumping.cs index 83297746..ec16bde2 100644 --- a/de4dot.code/deobfuscators/Confuser/AntiDumping.cs +++ b/de4dot.code/deobfuscators/Confuser/AntiDumping.cs @@ -78,7 +78,7 @@ namespace de4dot.code.deobfuscators.Confuser { if (type.NestedTypes.Count > 0) continue; - simpleDeobfuscator.Deobfuscate(calledMethod, true); + simpleDeobfuscator.Deobfuscate(calledMethod, SimpleDeobfuscatorFlags.Force | SimpleDeobfuscatorFlags.DisableConstantsFolderExtraInstrs); if (CheckType(type, calledMethod)) { initMethod = calledMethod; return true; diff --git a/de4dot.code/deobfuscators/Confuser/ConstantsDecrypterV17.cs b/de4dot.code/deobfuscators/Confuser/ConstantsDecrypterV17.cs index 8746c426..2f56e86a 100644 --- a/de4dot.code/deobfuscators/Confuser/ConstantsDecrypterV17.cs +++ b/de4dot.code/deobfuscators/Confuser/ConstantsDecrypterV17.cs @@ -232,7 +232,7 @@ namespace de4dot.code.deobfuscators.Confuser { if (!new LocalTypes(cctor).All(requiredLocalsCctor)) return; - simpleDeobfuscator.Deobfuscate(cctor, true); + simpleDeobfuscator.Deobfuscate(cctor, SimpleDeobfuscatorFlags.Force | SimpleDeobfuscatorFlags.DisableConstantsFolderExtraInstrs); if (!Add(ConstantsDecrypterUtils.FindDictField(cctor, cctor.DeclaringType))) return; if (!Add(ConstantsDecrypterUtils.FindStreamField(cctor, cctor.DeclaringType))) diff --git a/de4dot.code/deobfuscators/Confuser/ConstantsDecrypterV18.cs b/de4dot.code/deobfuscators/Confuser/ConstantsDecrypterV18.cs index dfc85283..ef28564c 100644 --- a/de4dot.code/deobfuscators/Confuser/ConstantsDecrypterV18.cs +++ b/de4dot.code/deobfuscators/Confuser/ConstantsDecrypterV18.cs @@ -202,7 +202,7 @@ namespace de4dot.code.deobfuscators.Confuser { var cctor = DotNetUtils.GetModuleTypeCctor(module); if (cctor == null) return; - simpleDeobfuscator.Deobfuscate(cctor, true); + simpleDeobfuscator.Deobfuscate(cctor, SimpleDeobfuscatorFlags.Force | SimpleDeobfuscatorFlags.DisableConstantsFolderExtraInstrs); if ((dictField = ConstantsDecrypterUtils.FindDictField(cctor, cctor.DeclaringType)) == null) return; @@ -216,7 +216,7 @@ namespace de4dot.code.deobfuscators.Confuser { var method = GetDecryptMethod(); if (method == null) return; - simpleDeobfuscator.Deobfuscate(method); + simpleDeobfuscator.Deobfuscate(method, SimpleDeobfuscatorFlags.DisableConstantsFolderExtraInstrs); var info = new DecrypterInfo(this, method, ConfuserVersion.Unknown); if (FindKeys_v18_r75367(info)) InitVersion(cctor, ConfuserVersion.v18_r75367_normal, ConfuserVersion.v18_r75367_dynamic, ConfuserVersion.v18_r75367_native); @@ -425,7 +425,7 @@ namespace de4dot.code.deobfuscators.Confuser { if (!IsDecryptMethodSignature(method)) return null; - simpleDeobfuscator.Deobfuscate(method); + simpleDeobfuscator.Deobfuscate(method, SimpleDeobfuscatorFlags.DisableConstantsFolderExtraInstrs); var info = new DecrypterInfo(this, method, version); if (!FindKeys(info)) return null; diff --git a/de4dot.code/deobfuscators/Confuser/ProxyCallFixer.cs b/de4dot.code/deobfuscators/Confuser/ProxyCallFixer.cs index ddb8b303..a386a020 100644 --- a/de4dot.code/deobfuscators/Confuser/ProxyCallFixer.cs +++ b/de4dot.code/deobfuscators/Confuser/ProxyCallFixer.cs @@ -492,7 +492,7 @@ namespace de4dot.code.deobfuscators.Confuser { if (proxyType == ProxyCreatorType.Newobj) foundNewobjProxy = true; - simpleDeobfuscator.Deobfuscate(method); + simpleDeobfuscator.Deobfuscate(method, SimpleDeobfuscatorFlags.DisableConstantsFolderExtraInstrs); MethodDef nativeMethod = null; uint magic; if (FindMagic_v14_r58564(method, out magic)) { diff --git a/de4dot.code/deobfuscators/Confuser/ResourceDecrypter.cs b/de4dot.code/deobfuscators/Confuser/ResourceDecrypter.cs index 8c890da0..c7171da4 100644 --- a/de4dot.code/deobfuscators/Confuser/ResourceDecrypter.cs +++ b/de4dot.code/deobfuscators/Confuser/ResourceDecrypter.cs @@ -77,7 +77,7 @@ namespace de4dot.code.deobfuscators.Confuser { return false; if (!DotNetUtils.CallsMethod(method, "System.Void System.AppDomain::add_ResourceResolve(System.ResolveEventHandler)")) return false; - simpleDeobfuscator.Deobfuscate(method, true); + simpleDeobfuscator.Deobfuscate(method, SimpleDeobfuscatorFlags.Force | SimpleDeobfuscatorFlags.DisableConstantsFolderExtraInstrs); fields.Clear(); var tmpHandler = GetHandler(method); @@ -88,7 +88,7 @@ namespace de4dot.code.deobfuscators.Confuser { if (tmpResource == null) return false; - simpleDeobfuscator.Deobfuscate(tmpHandler, true); + simpleDeobfuscator.Deobfuscate(tmpHandler, SimpleDeobfuscatorFlags.Force | SimpleDeobfuscatorFlags.DisableConstantsFolderExtraInstrs); ConfuserVersion tmpVersion = ConfuserVersion.Unknown; if (DotNetUtils.CallsMethod(tmpHandler, "System.Object System.AppDomain::GetData(System.String)")) { if (!DotNetUtils.CallsMethod(tmpHandler, "System.Void System.Buffer::BlockCopy(System.Array,System.Int32,System.Array,System.Int32,System.Int32)")) { diff --git a/de4dot.code/deobfuscators/DeepSea/ArrayBlockState.cs b/de4dot.code/deobfuscators/DeepSea/ArrayBlockState.cs index a3fda1ff..de4bb64c 100644 --- a/de4dot.code/deobfuscators/DeepSea/ArrayBlockState.cs +++ b/de4dot.code/deobfuscators/DeepSea/ArrayBlockState.cs @@ -109,7 +109,7 @@ namespace de4dot.code.deobfuscators.DeepSea { bool InitializeArrays2(ISimpleDeobfuscator simpleDeobfuscator, MethodDef method) { bool foundField = false; - simpleDeobfuscator.Deobfuscate(method, true); + simpleDeobfuscator.Deobfuscate(method, SimpleDeobfuscatorFlags.Force); var instructions = method.Body.Instructions; for (int i = 0; i < instructions.Count; i++) { var ldci4 = instructions[i]; diff --git a/de4dot.code/deobfuscators/ISimpleDeobfuscator.cs b/de4dot.code/deobfuscators/ISimpleDeobfuscator.cs index b39edc2f..8093aa5f 100644 --- a/de4dot.code/deobfuscators/ISimpleDeobfuscator.cs +++ b/de4dot.code/deobfuscators/ISimpleDeobfuscator.cs @@ -17,13 +17,23 @@ along with de4dot. If not, see . */ +using System; using dnlib.DotNet; namespace de4dot.code.deobfuscators { + [Flags] + public enum SimpleDeobfuscatorFlags : uint { + Force = 0x00000001, + + // Hack for Confuser deobfuscator code. That code was written before the + // constants folder was updated and it now breaks the old Confuser code. + DisableConstantsFolderExtraInstrs = 0x00000002, + } + public interface ISimpleDeobfuscator { void MethodModified(MethodDef method); void Deobfuscate(MethodDef method); - void Deobfuscate(MethodDef method, bool force); + void Deobfuscate(MethodDef method, SimpleDeobfuscatorFlags flags); void DecryptStrings(MethodDef method, IDeobfuscator deob); } }