Merge branch 'master' into newcode

This commit is contained in:
de4dot 2012-01-13 21:26:48 +01:00
commit c583891151
14 changed files with 144 additions and 46 deletions

View File

@ -44,10 +44,13 @@
<Compile Include="cflow\DeadCodeRemover.cs" />
<Compile Include="cflow\DeadStoreRemover.cs" />
<Compile Include="cflow\ICflowDeobfuscator.cs" />
<Compile Include="cflow\IMethodCallInliner.cs" />
<Compile Include="cflow\InstructionEmulator.cs" />
<Compile Include="cflow\Int32Value.cs" />
<Compile Include="cflow\Int64Value.cs" />
<Compile Include="cflow\MethodCallInliner.cs" />
<Compile Include="cflow\MethodCallInlinerBase.cs" />
<Compile Include="cflow\NoMethodInliner.cs" />
<Compile Include="cflow\Real8Value.cs" />
<Compile Include="cflow\StLdlocFixer.cs" />
<Compile Include="cflow\SwitchCflowDeobfuscator.cs" />

View File

@ -30,11 +30,9 @@ namespace de4dot.blocks.cflow {
DeadCodeRemover deadCodeRemover = new DeadCodeRemover();
DeadStoreRemover deadStoreRemover = new DeadStoreRemover();
StLdlocFixer stLdlocFixer = new StLdlocFixer();
MethodCallInliner methodCallInliner = new MethodCallInliner();
ConstantsFolder constantsFolder = new ConstantsFolder();
public bool InlineMethods { get; set; }
public bool InlineInstanceMethods { get; set; }
public IMethodCallInliner MethodCallInliner { get; set; }
public void init(Blocks blocks) {
this.blocks = blocks;
@ -54,11 +52,9 @@ namespace de4dot.blocks.cflow {
if (iterations == 0)
changed |= fixDotfuscatorLoop();
if (InlineMethods) {
foreach (var block in allBlocks) {
methodCallInliner.init(blocks, block, InlineInstanceMethods);
changed |= methodCallInliner.deobfuscate();
}
foreach (var block in allBlocks) {
MethodCallInliner.init(blocks, block);
changed |= MethodCallInliner.deobfuscate();
}
foreach (var block in allBlocks) {

View File

@ -25,18 +25,12 @@ namespace de4dot.blocks.cflow {
public class CflowDeobfuscator : ICflowDeobfuscator {
BlocksCflowDeobfuscator cflowDeobfuscator = new BlocksCflowDeobfuscator();
public bool InlineMethods { get; set; }
public bool InlineInstanceMethods { get; set; }
public CflowDeobfuscator() {
InlineMethods = true;
InlineInstanceMethods = false;
public CflowDeobfuscator(IMethodCallInliner methodCallInliner) {
cflowDeobfuscator.MethodCallInliner = methodCallInliner;
}
public void deobfuscate(MethodDefinition method) {
deobfuscate(method, (blocks) => {
cflowDeobfuscator.InlineMethods = InlineMethods;
cflowDeobfuscator.InlineInstanceMethods = InlineInstanceMethods;
cflowDeobfuscator.init(blocks);
cflowDeobfuscator.deobfuscate();
});

View File

@ -0,0 +1,27 @@
/*
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 <http://www.gnu.org/licenses/>.
*/
namespace de4dot.blocks.cflow {
public interface IMethodCallInliner {
void init(Blocks blocks, Block block);
// Returns true if something was inlined
bool deobfuscate();
}
}

View File

@ -22,26 +22,14 @@ using Mono.Cecil;
using Mono.Cecil.Cil;
namespace de4dot.blocks.cflow {
class MethodCallInliner {
// We can't catch all infinite loops, so inline methods at most this many times
const int MAX_ITERATIONS = 10;
Blocks blocks;
Block block;
int iteration;
public class MethodCallInliner : MethodCallInlinerBase {
bool inlineInstanceMethods;
public void init(Blocks blocks, Block block, bool inlineInstanceMethods) {
this.blocks = blocks;
this.block = block;
this.iteration = 0;
public MethodCallInliner(bool inlineInstanceMethods) {
this.inlineInstanceMethods = inlineInstanceMethods;
}
public bool deobfuscate() {
if (iteration++ >= MAX_ITERATIONS)
return false;
protected override bool deobfuscateInternal() {
bool changed = false;
var instructions = block.Instructions;
for (int i = 0; i < instructions.Count; i++) {

View File

@ -0,0 +1,44 @@
/*
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 <http://www.gnu.org/licenses/>.
*/
namespace de4dot.blocks.cflow {
public abstract class MethodCallInlinerBase : IMethodCallInliner {
// We can't catch all infinite loops, so inline methods at most this many times
const int MAX_ITERATIONS = 10;
protected Blocks blocks;
protected Block block;
int iteration;
public void init(Blocks blocks, Block block) {
this.blocks = blocks;
this.block = block;
this.iteration = 0;
}
public bool deobfuscate() {
if (iteration++ >= MAX_ITERATIONS)
return false;
return deobfuscateInternal();
}
protected abstract bool deobfuscateInternal();
}
}

View File

@ -0,0 +1,29 @@
/*
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 <http://www.gnu.org/licenses/>.
*/
namespace de4dot.blocks.cflow {
public class NoMethodInliner : IMethodCallInliner {
public void init(Blocks blocks, Block block) {
}
public bool deobfuscate() {
return false;
}
}
}

View File

@ -537,7 +537,7 @@ namespace de4dot.code {
Log.v("Deobfuscating methods");
var methodPrinter = new MethodPrinter();
var cflowDeobfuscator = new BlocksCflowDeobfuscator { InlineMethods = deob.CanInlineMethods };
var cflowDeobfuscator = new BlocksCflowDeobfuscator { MethodCallInliner = deob.MethodCallInliner };
foreach (var method in allMethods) {
Log.v("Deobfuscating {0} ({1:X8})", Utils.removeNewlines(method), method.MetadataToken.ToUInt32());
Log.indent();
@ -893,8 +893,7 @@ namespace de4dot.code {
return;
deobfuscate(method, "Deobfuscating control flow", (blocks) => {
var cflowDeobfuscator = new BlocksCflowDeobfuscator();
cflowDeobfuscator.InlineMethods = deob.CanInlineMethods;
var cflowDeobfuscator = new BlocksCflowDeobfuscator { MethodCallInliner = deob.MethodCallInliner };
cflowDeobfuscator.init(blocks);
cflowDeobfuscator.deobfuscate();
});

View File

@ -23,6 +23,7 @@ using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.MyStuff;
using de4dot.blocks;
using de4dot.blocks.cflow;
using de4dot.code.PE;
namespace de4dot.code.deobfuscators {
@ -81,10 +82,18 @@ namespace de4dot.code.deobfuscators {
public abstract string TypeLong { get; }
public abstract string Name { get; }
public virtual bool CanInlineMethods {
protected virtual bool CanInlineMethods {
get { return false; }
}
public virtual IMethodCallInliner MethodCallInliner {
get {
if (CanInlineMethods)
return new MethodCallInliner(false);
return new NoMethodInliner();
}
}
public DeobfuscatorBase(OptionsBase optionsBase) {
this.optionsBase = optionsBase;
StringFeatures = StringFeatures.AllowAll;

View File

@ -22,6 +22,7 @@ using System.Collections.Generic;
using Mono.Cecil;
using Mono.MyStuff;
using de4dot.blocks;
using de4dot.blocks.cflow;
using de4dot.code.renamer;
using de4dot.code.PE;
@ -60,13 +61,11 @@ namespace de4dot.code.deobfuscators {
StringFeatures StringFeatures { get; }
RenamingOptions RenamingOptions { get; }
DecrypterType DefaultDecrypterType { get; }
IMethodCallInliner MethodCallInliner { get; }
// This is non-null only in detect() and deobfuscateBegin().
IDeobfuscatedFile DeobfuscatedFile { get; set; }
// Return true if methods can be inlined
bool CanInlineMethods { get; }
// Returns null or the unpacked .NET PE file
byte[] unpackNativeFile(PeImage peImage);

View File

@ -162,12 +162,25 @@ namespace de4dot.code.deobfuscators {
}
}
protected virtual bool ProxyCallIsObfuscated {
get { return false; }
}
public void deobfuscate(Blocks blocks) {
if (blocks.Method.DeclaringType != null && delegateTypesDict.ContainsKey(blocks.Method.DeclaringType))
return;
var allBlocks = blocks.MethodBlocks.getAllBlocks();
int loops = ProxyCallIsObfuscated ? 50 : 1;
for (int i = 0; i < loops; i++) {
if (!deobfuscate(blocks, allBlocks))
break;
}
fixBrokenCalls(blocks.Method, allBlocks);
}
bool deobfuscate(Blocks blocks, IList<Block> allBlocks) {
var removeInfos = new Dictionary<Block, List<RemoveInfo>>();
var allBlocks = blocks.MethodBlocks.getAllBlocks();
foreach (var block in allBlocks) {
var instrs = block.Instructions;
for (int i = 0; i < instrs.Count; i++) {
@ -222,7 +235,7 @@ namespace de4dot.code.deobfuscators {
block.remove(removeIndexes);
}
fixBrokenCalls(blocks.Method, allBlocks);
return removeInfos.Count > 0;
}
void add(Dictionary<Block, List<RemoveInfo>> removeInfos, Block block, int index, DelegateInfo di) {

View File

@ -49,10 +49,7 @@ namespace de4dot.code.deobfuscators.dotNET_Reactor.v3 {
}
void find() {
var cflowDeobfuscator = new CflowDeobfuscator() {
InlineMethods = true,
InlineInstanceMethods = true,
};
var cflowDeobfuscator = new CflowDeobfuscator(new MethodCallInliner(true));
foreach (var type in module.Types) {
if (DotNetUtils.getPInvokeMethod(type, "kernel32", "CloseHandle") == null)

View File

@ -111,7 +111,7 @@ namespace de4dot.code.deobfuscators.dotNET_Reactor.v3 {
get { return obfuscatorName; }
}
public override bool CanInlineMethods {
protected override bool CanInlineMethods {
get { return startedDeobfuscating ? options.InlineMethods : true; }
}

View File

@ -142,7 +142,7 @@ namespace de4dot.code.deobfuscators.dotNET_Reactor.v4 {
get { return obfuscatorName; }
}
public override bool CanInlineMethods {
protected override bool CanInlineMethods {
get { return startedDeobfuscating ? options.InlineMethods : true; }
}