From 6e80b5bb9449247b48604d241c564748d8bbe037 Mon Sep 17 00:00:00 2001 From: de4dot Date: Tue, 3 Jan 2012 10:38:09 +0100 Subject: [PATCH] Move bool inliner and create some more useful value inliners --- de4dot.code/de4dot.code.csproj | 2 +- de4dot.code/deobfuscators/ValueInlinerBase.cs | 124 ++++++++++++++++++ .../dotNET_Reactor/v4/BoolValueInliner.cs | 70 ---------- .../dotNET_Reactor/v4/Deobfuscator.cs | 10 +- 4 files changed, 130 insertions(+), 76 deletions(-) create mode 100644 de4dot.code/deobfuscators/ValueInlinerBase.cs delete mode 100644 de4dot.code/deobfuscators/dotNET_Reactor/v4/BoolValueInliner.cs diff --git a/de4dot.code/de4dot.code.csproj b/de4dot.code/de4dot.code.csproj index 187942ec..59cc8ad2 100644 --- a/de4dot.code/de4dot.code.csproj +++ b/de4dot.code/de4dot.code.csproj @@ -87,7 +87,6 @@ - @@ -135,6 +134,7 @@ + diff --git a/de4dot.code/deobfuscators/ValueInlinerBase.cs b/de4dot.code/deobfuscators/ValueInlinerBase.cs new file mode 100644 index 00000000..364def54 --- /dev/null +++ b/de4dot.code/deobfuscators/ValueInlinerBase.cs @@ -0,0 +1,124 @@ +/* + 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.code.deobfuscators { + abstract class ValueInlinerBase : MethodReturnValueInliner { + MethodDefinitionAndDeclaringTypeDict> decrypterMethods = new MethodDefinitionAndDeclaringTypeDict>(); + + class MyCallResult : CallResult { + public MethodReference methodReference; + public MyCallResult(Block block, int callEndIndex, MethodReference method) + : base(block, callEndIndex) { + this.methodReference = method; + } + } + + public bool HasHandlers { + get { return decrypterMethods.Count != 0; } + } + + public IEnumerable Methods { + get { return decrypterMethods.getKeys(); } + } + + public void add(MethodDefinition method, Func handler) { + if (method != null) + decrypterMethods.add(method, handler); + } + + protected override void inlineAllCalls() { + foreach (var tmp in callResults) { + var callResult = (MyCallResult)tmp; + var handler = decrypterMethods.find(callResult.methodReference); + callResult.returnValue = handler((MethodDefinition)callResult.methodReference, callResult.args); + } + } + + protected override CallResult createCallResult(MethodReference method, Block block, int callInstrIndex) { + if (decrypterMethods.find(method) == null) + return null; + return new MyCallResult(block, callInstrIndex, method); + } + } + + class BooleanValueInliner : ValueInlinerBase { + 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); + } + } + } + + class Int32ValueInliner : ValueInlinerBase { + 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((int)callResult.returnValue)); + Log.v("Decrypted int32: {0}", callResult.returnValue); + } + } + } + + class Int64ValueInliner : ValueInlinerBase { + 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, Instruction.Create(OpCodes.Ldc_I8, (long)callResult.returnValue)); + Log.v("Decrypted int64: {0}", callResult.returnValue); + } + } + } + + class SingleValueInliner : ValueInlinerBase { + 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, Instruction.Create(OpCodes.Ldc_R4, (float)callResult.returnValue)); + Log.v("Decrypted single: {0}", callResult.returnValue); + } + } + } + + class DoubleValueInliner : ValueInlinerBase { + 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, Instruction.Create(OpCodes.Ldc_R8, (double)callResult.returnValue)); + Log.v("Decrypted double: {0}", callResult.returnValue); + } + } + } +} diff --git a/de4dot.code/deobfuscators/dotNET_Reactor/v4/BoolValueInliner.cs b/de4dot.code/deobfuscators/dotNET_Reactor/v4/BoolValueInliner.cs deleted file mode 100644 index 54249121..00000000 --- a/de4dot.code/deobfuscators/dotNET_Reactor/v4/BoolValueInliner.cs +++ /dev/null @@ -1,70 +0,0 @@ -/* - 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.code.deobfuscators.dotNET_Reactor.v4 { - class BoolValueInliner : MethodReturnValueInliner { - MethodDefinitionAndDeclaringTypeDict> boolDecrypters = new MethodDefinitionAndDeclaringTypeDict>(); - - class MyCallResult : CallResult { - public MethodReference methodReference; - public MyCallResult(Block block, int callEndIndex, MethodReference method) - : base(block, callEndIndex) { - this.methodReference = method; - } - } - - public bool HasHandlers { - get { return boolDecrypters.Count != 0; } - } - - public void add(MethodDefinition method, Func handler) { - if (method != null) - boolDecrypters.add(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.find(callResult.methodReference); - callResult.returnValue = handler((MethodDefinition)callResult.methodReference, callResult.args); - } - } - - protected override CallResult createCallResult(MethodReference method, Block block, int callInstrIndex) { - if (boolDecrypters.find(method) == null) - return null; - return new MyCallResult(block, callInstrIndex, method); - } - } -} diff --git a/de4dot.code/deobfuscators/dotNET_Reactor/v4/Deobfuscator.cs b/de4dot.code/deobfuscators/dotNET_Reactor/v4/Deobfuscator.cs index 3672d514..c73b4c14 100644 --- a/de4dot.code/deobfuscators/dotNET_Reactor/v4/Deobfuscator.cs +++ b/de4dot.code/deobfuscators/dotNET_Reactor/v4/Deobfuscator.cs @@ -106,7 +106,7 @@ namespace de4dot.code.deobfuscators.dotNET_Reactor.v4 { MethodsDecrypter methodsDecrypter; StringDecrypter stringDecrypter; BooleanDecrypter booleanDecrypter; - BoolValueInliner boolValueInliner; + BooleanValueInliner booleanValueInliner; MetadataTokenObfuscator metadataTokenObfuscator; AssemblyResolver assemblyResolver; ResourceResolver resourceResolver; @@ -411,11 +411,11 @@ namespace de4dot.code.deobfuscators.dotNET_Reactor.v4 { stringDecrypter.init(peImage, fileData, DeobfuscatedFile); booleanDecrypter.init(fileData, DeobfuscatedFile); - boolValueInliner = new BoolValueInliner(); + booleanValueInliner = new BooleanValueInliner(); emptyClass = new EmptyClass(module); if (options.DecryptBools) { - boolValueInliner.add(booleanDecrypter.Method, (method, args) => { + booleanValueInliner.add(booleanDecrypter.Method, (method, args) => { return booleanDecrypter.decrypt((int)args[0]); }); } @@ -518,8 +518,8 @@ namespace de4dot.code.deobfuscators.dotNET_Reactor.v4 { } public override bool deobfuscateOther(Blocks blocks) { - if (boolValueInliner.HasHandlers) - return boolValueInliner.decrypt(blocks) > 0; + if (booleanValueInliner.HasHandlers) + return booleanValueInliner.decrypt(blocks) > 0; return false; }