diff --git a/de4dot.code/de4dot.code.csproj b/de4dot.code/de4dot.code.csproj index 2ae93ab0..7548bd53 100644 --- a/de4dot.code/de4dot.code.csproj +++ b/de4dot.code/de4dot.code.csproj @@ -70,6 +70,7 @@ + diff --git a/de4dot.code/deobfuscators/dotNET_Reactor/BoolValueInliner.cs b/de4dot.code/deobfuscators/dotNET_Reactor/BoolValueInliner.cs new file mode 100644 index 00000000..d037df7a --- /dev/null +++ b/de4dot.code/deobfuscators/dotNET_Reactor/BoolValueInliner.cs @@ -0,0 +1,70 @@ +/* + Copyright (C) 2011 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; +using de4dot.blocks; + +namespace de4dot.deobfuscators.dotNET_Reactor { + class BoolValueInliner : MethodReturnValueInliner { + Dictionary> boolDecrypters = new Dictionary>(); + + class MyCallResult : CallResult { + public MethodReferenceAndDeclaringTypeKey methodKey; + public MyCallResult(Block block, int callEndIndex, MethodReference method) + : base(block, callEndIndex) { + this.methodKey = new MethodReferenceAndDeclaringTypeKey(method); + } + } + + public bool HasHandlers { + get { return boolDecrypters.Count != 0; } + } + + public void add(MethodDefinition method, Func handler) { + if (method != null) + boolDecrypters[new MethodReferenceAndDeclaringTypeKey(method)] = handler; + } + + protected override void inlineReturnValues(IList callResults) { + foreach (var callResult in callResults) { + var block = callResult.block; + int num = callResult.callEndIndex - callResult.callStartIndex + 1; + + block.replace(callResult.callStartIndex, num, DotNetUtils.createLdci4((bool)callResult.returnValue ? 1 : 0)); + Log.v("Decrypted boolean: {0}", callResult.returnValue); + } + } + + protected override void inlineAllCalls() { + foreach (var tmp in callResults) { + var callResult = (MyCallResult)tmp; + var handler = boolDecrypters[callResult.methodKey]; + callResult.returnValue = handler((MethodDefinition)callResult.methodKey.MethodReference, callResult.args); + } + } + + protected override CallResult createCallResult(MethodReference method, Block block, int callInstrIndex) { + if (!boolDecrypters.ContainsKey(new MethodReferenceAndDeclaringTypeKey(method))) + return null; + return new MyCallResult(block, callInstrIndex, method); + } + } +} diff --git a/de4dot.code/deobfuscators/dotNET_Reactor/BooleanDecrypter.cs b/de4dot.code/deobfuscators/dotNET_Reactor/BooleanDecrypter.cs index 0c68c7d4..c8f235dc 100644 --- a/de4dot.code/deobfuscators/dotNET_Reactor/BooleanDecrypter.cs +++ b/de4dot.code/deobfuscators/dotNET_Reactor/BooleanDecrypter.cs @@ -32,6 +32,10 @@ namespace de4dot.deobfuscators.dotNET_Reactor { get { return encryptedResource.ResourceDecrypterMethod != null; } } + public MethodDefinition BoolDecrypterMethod { + get { return encryptedResource.ResourceDecrypterMethod; } + } + public BooleanDecrypter(ModuleDefinition module) { this.module = module; this.encryptedResource = new EncryptedResource(module); diff --git a/de4dot.code/deobfuscators/dotNET_Reactor/Deobfuscator.cs b/de4dot.code/deobfuscators/dotNET_Reactor/Deobfuscator.cs index 51d10097..4323f6f5 100644 --- a/de4dot.code/deobfuscators/dotNET_Reactor/Deobfuscator.cs +++ b/de4dot.code/deobfuscators/dotNET_Reactor/Deobfuscator.cs @@ -56,6 +56,7 @@ namespace de4dot.deobfuscators.dotNET_Reactor { MethodsDecrypter methodsDecrypter; StringDecrypter stringDecrypter; BooleanDecrypter booleanDecrypter; + BoolValueInliner boolValueInliner; internal class Options : OptionsBase { } @@ -134,6 +135,11 @@ namespace de4dot.deobfuscators.dotNET_Reactor { stringDecrypter.init(peImage, DeobfuscatedFile); booleanDecrypter.init(fileData, DeobfuscatedFile); + boolValueInliner = new BoolValueInliner(); + + boolValueInliner.add(booleanDecrypter.BoolDecrypterMethod, (method, args) => { + return booleanDecrypter.decrypt((int)args[0]); + }); foreach (var info in stringDecrypter.DecrypterInfos) { staticStringDecrypter.add(info.method, (method2, args) => { @@ -144,6 +150,9 @@ namespace de4dot.deobfuscators.dotNET_Reactor { } public override void deobfuscateMethodEnd(Blocks blocks) { + if (boolValueInliner.HasHandlers) + boolValueInliner.decrypt(blocks); + base.deobfuscateMethodEnd(blocks); }