From 83e8fac8eafb540405a04890ee34567ce83ae262 Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 2 May 2012 13:49:12 +0200 Subject: [PATCH] Add CachedCflowDeobfuscator class --- blocks/blocks.csproj | 1 + blocks/cflow/CachedCflowDeobfuscator.cs | 74 +++++++++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 blocks/cflow/CachedCflowDeobfuscator.cs diff --git a/blocks/blocks.csproj b/blocks/blocks.csproj index 22bf7642..1e3daa86 100644 --- a/blocks/blocks.csproj +++ b/blocks/blocks.csproj @@ -40,6 +40,7 @@ + diff --git a/blocks/cflow/CachedCflowDeobfuscator.cs b/blocks/cflow/CachedCflowDeobfuscator.cs new file mode 100644 index 00000000..c3a8bd86 --- /dev/null +++ b/blocks/cflow/CachedCflowDeobfuscator.cs @@ -0,0 +1,74 @@ +/* + 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.Cil; + +namespace de4dot.blocks.cflow { + // Only deobfuscates a method once. A copy of the method (now deobfuscated) is returned. + public class CachedCflowDeobfuscator { + BlocksCflowDeobfuscator cflowDeobfuscator = new BlocksCflowDeobfuscator(); + Dictionary deobfuscated = new Dictionary(); + + public CachedCflowDeobfuscator() { + } + + public CachedCflowDeobfuscator(IEnumerable blocksDeobfuscators) { + add(blocksDeobfuscators); + } + + public void add(IEnumerable blocksDeobfuscators) { + foreach (var bd in blocksDeobfuscators) + cflowDeobfuscator.add(bd); + } + + public void add(IBlocksDeobfuscator blocksDeobfuscator) { + cflowDeobfuscator.add(blocksDeobfuscator); + } + + public MethodDefinition deobfuscate(MethodDefinition method) { + MethodDefinition deobfuscatedMethod; + if (deobfuscated.TryGetValue(method, out deobfuscatedMethod)) + return deobfuscatedMethod; + + if (method.Body == null || method.Body.Instructions.Count == 0) { + deobfuscated[method] = method; + return method; + } + + deobfuscatedMethod = DotNetUtils.clone(method); + deobfuscated[method] = deobfuscatedMethod; + + var blocks = new Blocks(deobfuscatedMethod); + deobfuscate(blocks); + IList allInstructions; + IList allExceptionHandlers; + blocks.getCode(out allInstructions, out allExceptionHandlers); + DotNetUtils.restoreBody(deobfuscatedMethod, allInstructions, allExceptionHandlers); + + return deobfuscatedMethod; + } + + void deobfuscate(Blocks blocks) { + cflowDeobfuscator.init(blocks); + cflowDeobfuscator.deobfuscate(); + } + } +}