From 98c8ea49e9f23f20ad551693f1f9fa0cdd446e2c Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 8 Feb 2012 18:40:24 +0100 Subject: [PATCH] Remove tamper detection code --- de4dot.code/de4dot.code.csproj | 1 + .../deobfuscators/CodeVeil/Deobfuscator.cs | 13 ++ .../deobfuscators/CodeVeil/MainType.cs | 23 ++++ .../deobfuscators/CodeVeil/TamperDetection.cs | 124 ++++++++++++++++++ 4 files changed, 161 insertions(+) create mode 100644 de4dot.code/deobfuscators/CodeVeil/TamperDetection.cs diff --git a/de4dot.code/de4dot.code.csproj b/de4dot.code/de4dot.code.csproj index 6a56f669..9ce9308a 100644 --- a/de4dot.code/de4dot.code.csproj +++ b/de4dot.code/de4dot.code.csproj @@ -86,6 +86,7 @@ + diff --git a/de4dot.code/deobfuscators/CodeVeil/Deobfuscator.cs b/de4dot.code/deobfuscators/CodeVeil/Deobfuscator.cs index bb4741fa..6cc9b45e 100644 --- a/de4dot.code/deobfuscators/CodeVeil/Deobfuscator.cs +++ b/de4dot.code/deobfuscators/CodeVeil/Deobfuscator.cs @@ -81,6 +81,7 @@ namespace de4dot.code.deobfuscators.CodeVeil { public Deobfuscator(Options options) : base(options) { this.options = options; + StringFeatures = StringFeatures.AllowStaticDecryption | StringFeatures.AllowDynamicDecryption; } protected override int detectInternal() { @@ -174,6 +175,8 @@ namespace de4dot.code.deobfuscators.CodeVeil { public override void deobfuscateBegin() { base.deobfuscateBegin(); + mainType.initialize(); + if (Operations.DecryptStrings != OpDecryptString.None) { stringDecrypter.initialize(); staticStringInliner.add(stringDecrypter.DecryptMethod, (method, args) => { @@ -186,10 +189,20 @@ namespace de4dot.code.deobfuscators.CodeVeil { assemblyResolver.initialize(); dumpEmbeddedAssemblies(); + removeTamperDetection(); + proxyDelegateFinder.initialize(); proxyDelegateFinder.find(); } + void removeTamperDetection() { + var tamperDetection = new TamperDetection(module, mainType); + tamperDetection.initialize(); + foreach (var tamperDetectionMethod in tamperDetection.Methods) + addCctorInitCallToBeRemoved(tamperDetectionMethod); + addTypeToBeRemoved(tamperDetection.Type, "Tamper detection type"); + } + void dumpEmbeddedAssemblies() { foreach (var info in assemblyResolver.AssemblyInfos) DeobfuscatedFile.createAssemblyFile(info.data, info.simpleName, info.extension); diff --git a/de4dot.code/deobfuscators/CodeVeil/MainType.cs b/de4dot.code/deobfuscators/CodeVeil/MainType.cs index 661eefdd..60d56693 100644 --- a/de4dot.code/deobfuscators/CodeVeil/MainType.cs +++ b/de4dot.code/deobfuscators/CodeVeil/MainType.cs @@ -29,6 +29,7 @@ namespace de4dot.code.deobfuscators.CodeVeil { ModuleDefinition module; TypeDefinition theType; MethodDefinition initMethod; + MethodDefinition tamperCheckMethod; ObfuscatorVersion obfuscatorVersion = ObfuscatorVersion.Unknown; List rvas = new List(); // _stub and _executive @@ -48,6 +49,10 @@ namespace de4dot.code.deobfuscators.CodeVeil { get { return initMethod; } } + public MethodDefinition TamperCheckMethod { + get { return tamperCheckMethod; } + } + public List Rvas { get { return rvas; } } @@ -60,6 +65,7 @@ namespace de4dot.code.deobfuscators.CodeVeil { this.module = module; this.theType = lookup(oldOne.theType, "Could not find main type"); this.initMethod = lookup(oldOne.initMethod, "Could not find main type init method"); + this.tamperCheckMethod = lookup(oldOne.tamperCheckMethod, "Could not find tamper detection method"); this.obfuscatorVersion = oldOne.obfuscatorVersion; this.rvas = oldOne.rvas; } @@ -166,5 +172,22 @@ namespace de4dot.code.deobfuscators.CodeVeil { } return fields; } + + public void initialize() { + tamperCheckMethod = findTamperCheckMethod(); + } + + MethodDefinition findTamperCheckMethod() { + foreach (var method in theType.Methods) { + if (!method.IsStatic || method.Body == null) + continue; + if (!DotNetUtils.isMethod(method, "System.Void", "(System.Reflection.Assembly,System.UInt64)")) + continue; + + return method; + } + + return null; + } } } diff --git a/de4dot.code/deobfuscators/CodeVeil/TamperDetection.cs b/de4dot.code/deobfuscators/CodeVeil/TamperDetection.cs new file mode 100644 index 00000000..1393eea8 --- /dev/null +++ b/de4dot.code/deobfuscators/CodeVeil/TamperDetection.cs @@ -0,0 +1,124 @@ +/* + 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.Collections.Generic; +using Mono.Cecil; +using Mono.Cecil.Metadata; +using de4dot.blocks; + +namespace de4dot.code.deobfuscators.CodeVeil { + class TamperDetection { + ModuleDefinition module; + MainType mainType; + TypeDefinition tamperDetectionType; + List tamperDetectionMethods = new List(); + + public TypeDefinition Type { + get { return tamperDetectionType; } + } + + public List Methods { + get { return tamperDetectionMethods; } + } + + public TamperDetection(ModuleDefinition module, MainType mainType) { + this.module = module; + this.mainType = mainType; + } + + public void initialize() { + if (!mainType.Detected) + return; + + if (mainType.TamperCheckMethod == null) + return; + + findTamperDetectionTypes(); + } + + void findTamperDetectionTypes() { + foreach (var type in module.Types) { + if (!type.HasNestedTypes) + continue; + if ((type.Attributes & ~TypeAttributes.Sealed) != 0) + continue; + + if (!checkTamperDetectionClasses(type.NestedTypes)) + continue; + + tamperDetectionType = type; + findTamperDetectionMethods(); + return; + } + } + + void findTamperDetectionMethods() { + foreach (var type in tamperDetectionType.NestedTypes) { + foreach (var method in type.Methods) { + if (!method.IsStatic || method.Body == null) + continue; + if (method.Name == ".cctor") + continue; + if (DotNetUtils.isMethod(method, "System.Void", "()")) + tamperDetectionMethods.Add(method); + } + } + } + + bool checkTamperDetectionClasses(IEnumerable types) { + foreach (var type in types) { + if (!isTamperDetectionClass(type)) + return false; + } + return true; + } + + bool isTamperDetectionClass(TypeDefinition type) { + if (type.BaseType == null || type.BaseType.EType != ElementType.Object) + return false; + if ((type.Attributes & ~TypeAttributes.Sealed) != TypeAttributes.NestedAssembly) + return false; + + MethodDefinition cctor = null, initMethod = null; + foreach (var method in type.Methods) { + if (!method.IsStatic || method.Body == null) + return false; + if (method.Name == ".cctor") + cctor = method; + else if (DotNetUtils.isMethod(method, "System.Void", "()")) + initMethod = method; + } + if (cctor == null || initMethod == null) + return false; + + if (!callsMainTypeTamperCheckMethod(cctor)) + return false; + + return true; + } + + bool callsMainTypeTamperCheckMethod(MethodDefinition method) { + foreach (var info in DotNetUtils.getCalledMethods(module, method)) { + if (info.Item2 == mainType.TamperCheckMethod) + return true; + } + return false; + } + } +}