diff --git a/de4dot.code/deobfuscators/ValueInlinerBase.cs b/de4dot.code/deobfuscators/ValueInlinerBase.cs index 358d63ae..1ad85168 100644 --- a/de4dot.code/deobfuscators/ValueInlinerBase.cs +++ b/de4dot.code/deobfuscators/ValueInlinerBase.cs @@ -26,6 +26,7 @@ using de4dot.blocks; namespace de4dot.code.deobfuscators { abstract class ValueInlinerBase : MethodReturnValueInliner { MethodDefinitionAndDeclaringTypeDict> decrypterMethods = new MethodDefinitionAndDeclaringTypeDict>(); + bool removeUnbox = false; class MyCallResult : CallResult { public MethodReference methodReference; @@ -37,6 +38,11 @@ namespace de4dot.code.deobfuscators { } } + public bool RemoveUnbox { + get { return removeUnbox; } + set { removeUnbox = value; } + } + public override bool HasHandlers { get { return decrypterMethods.Count != 0; } } @@ -67,6 +73,22 @@ namespace de4dot.code.deobfuscators { return null; return new MyCallResult(block, callInstrIndex, method, gim); } + + protected bool removeUnboxInstruction(Block block, int index, string unboxType) { + if (!removeUnbox) + return false; + var instrs = block.Instructions; + if (index >= instrs.Count) + return false; + var unbox = instrs[index]; + if (unbox.OpCode.Code != Code.Unbox_Any) + return false; + var type = unbox.Operand as TypeReference; + if (type == null || type.FullName != unboxType) + return false; + block.remove(index, 1); + return true; + } } class BooleanValueInliner : ValueInlinerBase { @@ -76,6 +98,7 @@ namespace de4dot.code.deobfuscators { int num = callResult.callEndIndex - callResult.callStartIndex + 1; block.replace(callResult.callStartIndex, num, DotNetUtils.createLdci4((bool)callResult.returnValue ? 1 : 0)); + removeUnboxInstruction(block, callResult.callStartIndex + 1, "System.Boolean"); Log.v("Decrypted boolean: {0}", callResult.returnValue); } } @@ -88,6 +111,7 @@ namespace de4dot.code.deobfuscators { int num = callResult.callEndIndex - callResult.callStartIndex + 1; block.replace(callResult.callStartIndex, num, DotNetUtils.createLdci4((int)callResult.returnValue)); + removeUnboxInstruction(block, callResult.callStartIndex + 1, "System.Int32"); Log.v("Decrypted int32: {0}", callResult.returnValue); } } @@ -100,6 +124,7 @@ namespace de4dot.code.deobfuscators { int num = callResult.callEndIndex - callResult.callStartIndex + 1; block.replace(callResult.callStartIndex, num, Instruction.Create(OpCodes.Ldc_I8, (long)callResult.returnValue)); + removeUnboxInstruction(block, callResult.callStartIndex + 1, "System.Int64"); Log.v("Decrypted int64: {0}", callResult.returnValue); } } @@ -112,6 +137,7 @@ namespace de4dot.code.deobfuscators { int num = callResult.callEndIndex - callResult.callStartIndex + 1; block.replace(callResult.callStartIndex, num, Instruction.Create(OpCodes.Ldc_R4, (float)callResult.returnValue)); + removeUnboxInstruction(block, callResult.callStartIndex + 1, "System.Single"); Log.v("Decrypted single: {0}", callResult.returnValue); } } @@ -124,6 +150,7 @@ namespace de4dot.code.deobfuscators { int num = callResult.callEndIndex - callResult.callStartIndex + 1; block.replace(callResult.callStartIndex, num, Instruction.Create(OpCodes.Ldc_R8, (double)callResult.returnValue)); + removeUnboxInstruction(block, callResult.callStartIndex + 1, "System.Double"); Log.v("Decrypted double: {0}", callResult.returnValue); } }