diff --git a/blocks/blocks.csproj b/blocks/blocks.csproj index 22f41d00..a0bae6cc 100644 --- a/blocks/blocks.csproj +++ b/blocks/blocks.csproj @@ -48,6 +48,7 @@ + diff --git a/blocks/cflow/BlocksCflowDeobfuscator.cs b/blocks/cflow/BlocksCflowDeobfuscator.cs index 9a3f42ba..7e297293 100644 --- a/blocks/cflow/BlocksCflowDeobfuscator.cs +++ b/blocks/cflow/BlocksCflowDeobfuscator.cs @@ -43,6 +43,7 @@ namespace de4dot.blocks.cflow { ourBlocksDeobfuscators.Add(new DeadCodeRemover { ExecuteOnNoChange = false }); ourBlocksDeobfuscators.Add(new ConstantsFolder { ExecuteOnNoChange = true }); ourBlocksDeobfuscators.Add(new StLdlocFixer { ExecuteOnNoChange = true }); + ourBlocksDeobfuscators.Add(new DupBlockCflowDeobfuscator { ExecuteOnNoChange = true }); } public void add(IEnumerable blocksDeobfuscators) { diff --git a/blocks/cflow/DupBlockDeobfuscator.cs b/blocks/cflow/DupBlockDeobfuscator.cs new file mode 100644 index 00000000..bb841b14 --- /dev/null +++ b/blocks/cflow/DupBlockDeobfuscator.cs @@ -0,0 +1,49 @@ +/* + 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; +using System.Collections.Generic; +using dnlib.DotNet.Emit; + +namespace de4dot.blocks.cflow { + // If a block is just a dup followed by a bcc, try to append the block + // to all its sources. Will fix some SA assemblies. + class DupBlockCflowDeobfuscator : BlockDeobfuscator { + protected override bool deobfuscate(Block block) { + if (block.Instructions.Count != 2) + return false; + if (block.Instructions[0].OpCode.Code != Code.Dup) + return false; + if (!block.LastInstr.isConditionalBranch() && block.LastInstr.OpCode.Code != Code.Switch) + return false; + + bool modified = false; + foreach (var source in new List(block.Sources)) { + if (source.getOnlyTarget() != block) + continue; + if (!source.canAppend(block)) + continue; + + source.append(block); + modified = true; + } + return modified; + } + } +}