bool FindEntryPointToken(ISimpleDeobfuscator simpleDeobfuscator, MethodDef cctor, MethodDef entryPoint, out uint token) { token = 0; if (!FindBase(cctor, out ulong @base)) { return(false); } var modPowMethod = DotNetUtils.GetMethod(cctor.DeclaringType, "System.UInt64", "(System.UInt64,System.UInt64,System.UInt64)"); if (modPowMethod == null) { throw new ApplicationException("Could not find modPow()"); } simpleDeobfuscator.Deobfuscate(entryPoint); if (!FindMod(entryPoint, out ulong mod)) { throw new ApplicationException("Could not find modulus"); } token = 0x06000000 | (uint)ModPow(@base, 0x47, mod); if ((token >> 24) != 0x06) { throw new ApplicationException("Illegal entry point token"); } return(true); }
public void FindDelegateCreator(ModuleDefMD module) { var callCounter = new CallCounter(); foreach (var type in module.Types) { if (type.Namespace != "" || !DotNetUtils.DerivesFromDelegate(type)) { continue; } var cctor = type.FindStaticConstructor(); if (cctor == null) { continue; } foreach (var method in DotNetUtils.GetMethodCalls(cctor)) { callCounter.Add(method); } } var mostCalls = callCounter.Most(); if (mostCalls == null) { return; } SetDelegateCreatorMethod(DotNetUtils.GetMethod(module, mostCalls)); }
public void Find() { foreach (var type in module.Types) { if (type.HasFields || type.HasEvents || type.HasProperties) { continue; } var checkMethod = GetAntiTamperingDetectionMethod(type); if (checkMethod == null) { continue; } if (DotNetUtils.GetMethod(type, "System.Byte[]", "(System.Reflection.Assembly)") == null) { continue; } if (DotNetUtils.GetMethod(type, "System.String", "(System.Collections.Generic.Stack`1<System.Int32>)") == null) { continue; } if (DotNetUtils.GetMethod(type, "System.Int32", "(System.Int32,System.Byte[])") == null) { continue; } strongNameType = type; strongNameCheckMethod = checkMethod; return; } }
TypeDef FindMethodsDecrypterType(TypeDef type) { foreach (var field in type.Fields) { var fieldType = DotNetUtils.GetType(module, field.FieldSig.GetFieldType()); if (fieldType == null) { continue; } if (fieldType.FindMethod("Finalize") == null) { continue; } if (!new FieldTypes(fieldType).Exists("System.Collections.Hashtable")) { continue; } if (DotNetUtils.GetMethod(fieldType, "System.String", "()") == null) { continue; } return(fieldType); } return(null); }
public static bool CouldBeResourceDecrypter(MethodDef method, LocalTypes localTypes, IList <string> additionalTypes) { var requiredTypes = new List <string> { "System.Byte[]", "System.IO.BinaryReader", "System.IO.MemoryStream", "System.Security.Cryptography.CryptoStream", "System.Security.Cryptography.ICryptoTransform", }; requiredTypes.AddRange(additionalTypes); if (!localTypes.All(requiredTypes)) { return(false); } if (DotNetUtils.GetMethod(method.DeclaringType, "System.Security.Cryptography.SymmetricAlgorithm", "()") != null) { if (localTypes.Exists("System.UInt64") || (localTypes.Exists("System.UInt32") && !localTypes.Exists("System.Reflection.Assembly"))) { return(false); } } if (!localTypes.Exists("System.Security.Cryptography.RijndaelManaged") && !localTypes.Exists("System.Security.Cryptography.AesManaged") && !localTypes.Exists("System.Security.Cryptography.SymmetricAlgorithm")) { return(false); } return(true); }
bool CheckMethods(TypeDef type) { methodI4 = DotNetUtils.GetMethod(type, "System.Int32", "(System.Int32)"); methodI8 = DotNetUtils.GetMethod(type, "System.Int64", "(System.Int32)"); methodR4 = DotNetUtils.GetMethod(type, "System.Single", "(System.Int32)"); methodR8 = DotNetUtils.GetMethod(type, "System.Double", "(System.Int32)"); methodArray = DotNetUtils.GetMethod(type, "System.Void", "(System.Array,System.Int32)"); return(methodI4 != null && methodI8 != null && methodR4 != null && methodR8 != null && methodArray != null); }
public static bool FindRegisterMethod(TypeDef type, out MethodDef regMethod, out MethodDef handler) { foreach (var method in type.Methods) { if (!method.IsStatic || method.Body == null) { continue; } if (method.Body.ExceptionHandlers.Count != 1) { continue; } foreach (var instr in method.Body.Instructions) { if (instr.OpCode.Code != Code.Ldftn) { continue; } var handlerRef = instr.Operand as IMethod; if (handlerRef == null) { continue; } if (!DotNetUtils.IsMethod(handlerRef, "System.Reflection.Assembly", "(System.Object,System.ResolveEventArgs)")) { continue; } if (!new SigComparer().Equals(type, handlerRef.DeclaringType)) { continue; } handler = DotNetUtils.GetMethod(type, handlerRef); if (handler == null) { continue; } if (handler.Body == null || handler.Body.ExceptionHandlers.Count != 1) { continue; } regMethod = method; return(true); } } regMethod = null; handler = null; return(false); }
bool CheckMethod(MethodDef method, out MethodDef exceptionMethod) { exceptionMethod = null; var body = method.Body; if (body == null) { return(false); } var instrs = body.Instructions; if (instrs.Count < 1) { return(false); } if (body.ExceptionHandlers.Count == 0) { return(false); } var eh = body.ExceptionHandlers[body.ExceptionHandlers.Count - 1]; if (eh.HandlerType != ExceptionHandlerType.Catch) { return(false); } if (eh.FilterStart != null) { return(false); } if (eh.CatchType == null || eh.CatchType.FullName != "System.Exception") { return(false); } if (eh.HandlerStart == null) { return(false); } int handlerStart = instrs.IndexOf(eh.HandlerStart); int handlerEnd = eh.HandlerEnd == null ? instrs.Count : instrs.IndexOf(eh.HandlerEnd); exceptionMethod = DotNetUtils.GetMethod(module, CheckHandler(instrs, handlerStart, handlerEnd)); if (exceptionMethod == null || !exceptionMethod.IsStatic || exceptionMethod.Body == null) { return(false); } return(IsExceptionLoggerMethod(exceptionMethod)); }
public void Deobfuscate(Blocks blocks) { if (type == null) { return; } var gpContext = GenericParamContext.Create(blocks.Method); foreach (var block in blocks.MethodBlocks.GetAllBlocks()) { var instrs = block.Instructions; for (int i = 0; i < instrs.Count - 1; i++) { var instr = instrs[i]; if (instr.OpCode.Code != Code.Ldc_I4) { continue; } var call = instrs[i + 1]; if (call.OpCode.Code != Code.Call) { continue; } var method = call.Operand as IMethod; if (method == null) { continue; } if (!new SigComparer().Equals(type, method.DeclaringType)) { continue; } var methodDef = DotNetUtils.GetMethod(module, method); if (methodDef == null) { continue; } if (methodDef != typeMethod && methodDef != fieldMethod) { continue; } uint token = (uint)(int)instrs[i].Operand; instrs[i] = new Instr(OpCodes.Nop.ToInstruction()); instrs[i + 1] = new Instr(new Instruction(OpCodes.Ldtoken, module.ResolveToken(token, gpContext) as ITokenOperand)); } } }
Version DetectVersion() { var ep = Module.EntryPoint; if (ep == null || ep.Body == null) { return(Version.Unknown); } var type = ep.DeclaringType; if (type == null) { return(Version.Unknown); } if (!new FieldTypes(type).Exactly(requiredFields)) { return(Version.Unknown); } if (Module.Types.Count != 2) { return(Version.Unknown); } if (Module.Types[1] != type) { return(Version.Unknown); } if (Module.Types[0].Methods.Count != 0) { return(Version.Unknown); } if (CheckMethods(type, methods_v0x)) { return(Version.V0x); } if (CheckMethods(type, methods_v1x)) { var lfMethod = DotNetUtils.GetMethod(type, "System.Boolean", "(System.String,System.Byte[]&)"); if (lfMethod != null) { if (DeobUtils.HasInteger(lfMethod, (int)Machine.AMD64)) { return(Version.V218); } return(Version.V1x_217); } } return(Version.Unknown); }
IEnumerable <MethodDef> GetResolverHandlers(MethodDef method) { int numHandlers = 0; var instructions = method.Body.Instructions; for (int i = 0; i < instructions.Count; i++) { var instrs = DotNetUtils.GetInstructions(instructions, i, OpCodes.Call, OpCodes.Ldnull, OpCodes.Ldftn, OpCodes.Newobj, OpCodes.Callvirt); if (instrs == null) { continue; } var call = instrs[0]; if (!DotNetUtils.IsMethod(call.Operand as IMethod, "System.AppDomain", "()")) { continue; } var ldftn = instrs[2]; var handlerDef = DotNetUtils.GetMethod(module, ldftn.Operand as IMethod); if (handlerDef == null) { continue; } var newobj = instrs[3]; if (!DotNetUtils.IsMethod(newobj.Operand as IMethod, "System.Void", "(System.Object,System.IntPtr)")) { continue; } var callvirt = instrs[4]; if (!DotNetUtils.IsMethod(callvirt.Operand as IMethod, "System.Void", "(System.ResolveEventHandler)")) { continue; } numHandlers++; yield return(handlerDef); } // If no handlers found, it's possible that the method itself is the handler. if (numHandlers == 0) { yield return(method); } }
public IMethod TryGetMethodDef(IMethod methodRef) { var methodDef = methodRef as MethodDef; if (methodDef != null) { return(methodDef); } var declaringType = DotNetUtils.GetType(module, methodRef.DeclaringType); if (declaringType == null) { return(methodRef); } return(DotNetUtils.GetMethod(declaringType, methodRef)); }
public void Find() { foreach (var type in module.Types) { if (!IsConstantDecrypter(type)) { continue; } int32Decrypter = DotNetUtils.GetMethod(type, "System.Int32", "(System.Int32)"); int64Decrypter = DotNetUtils.GetMethod(type, "System.Int64", "(System.Int32)"); singleDecrypter = DotNetUtils.GetMethod(type, "System.Single", "(System.Int32)"); doubleDecrypter = DotNetUtils.GetMethod(type, "System.Double", "(System.Int32)"); arrayDecrypter = DotNetUtils.GetMethod(type, "System.Array", "(System.Byte[])"); decrypterType = type; return; } }
void FindResourceType() { var cctor = DotNetUtils.GetModuleTypeCctor(module); if (cctor == null) { return; } foreach (var calledMethod in DotNetUtils.GetCalledMethods(module, cctor)) { if (!calledMethod.IsStatic || calledMethod.Body == null) { continue; } if (!DotNetUtils.IsMethod(calledMethod, "System.Void", "()")) { continue; } var type = calledMethod.DeclaringType; var fieldTypes = new FieldTypes(type); if (!fieldTypes.Exactly(requiredFields1) && !fieldTypes.Exactly(requiredFields2)) { continue; } var resolveHandler = DotNetUtils.GetMethod(type, "System.Reflection.Assembly", "(System.Object,System.ResolveEventArgs)"); var decryptMethod = DotNetUtils.GetMethod(type, "System.Byte[]", "(System.IO.Stream)"); if (resolveHandler == null || !resolveHandler.IsStatic) { continue; } if (decryptMethod == null || !decryptMethod.IsStatic) { continue; } rsrcType = type; rsrcRrrMethod = calledMethod; rsrcResolveMethod = resolveHandler; return; } }
bool IsConstantDecrypter(TypeDef type) { if (type.HasEvents) { return(false); } if (type.NestedTypes.Count != 1) { return(false); } var nested = type.NestedTypes[0]; if (!CheckNestedFields(nested)) { return(false); } resourceDecrypter.DecryptMethod = ResourceDecrypter.FindDecrypterMethod(nested.FindMethod(".ctor")); if (DotNetUtils.GetMethod(type, "System.Int32", "(System.Int32)") == null) { return(false); } if (DotNetUtils.GetMethod(type, "System.Int64", "(System.Int32)") == null) { return(false); } if (DotNetUtils.GetMethod(type, "System.Single", "(System.Int32)") == null) { return(false); } if (DotNetUtils.GetMethod(type, "System.Double", "(System.Int32)") == null) { return(false); } if (DotNetUtils.GetMethod(type, "System.Array", "(System.Byte[])") == null) { return(false); } return(true); }
public static bool IsSimpleZipDecryptMethod_QuickCheck(ModuleDefMD module, IMethod method, out MethodDef simpleZipTypeMethod) { simpleZipTypeMethod = null; if (!DotNetUtils.IsMethod(method, "System.Byte[]", "(System.Byte[])")) { return(false); } var methodDef = DotNetUtils.GetMethod(DotNetUtils.GetType(module, method.DeclaringType), method); if (methodDef == null) { return(false); } simpleZipTypeMethod = methodDef; return(true); }
bool CheckType(TypeDef type) { if (DotNetUtils.GetMethod(type, "System.Byte[]", "(System.Byte[],System.String,System.String,System.Int32,System.String,System.Int32)") == null) { return(false); } if (DotNetUtils.GetMethod(type, "System.String", "(System.String)") == null) { return(false); } if (DotNetUtils.GetMethod(type, "System.Byte[]", "(System.Reflection.Assembly,System.String)") == null) { return(false); } if (DotNetUtils.GetMethod(type, "System.Void", "(System.IO.Stream,System.IO.Stream)") == null) { return(false); } return(true); }
public void Find() { var requiredFields = new string[] { "System.Threading.ReaderWriterLock", "System.Collections.Hashtable", }; foreach (var type in module.GetTypes()) { var fieldTypes = new FieldTypes(type); if (!fieldTypes.All(requiredFields)) { continue; } if (type.FindMethod("Finalize") == null) { continue; } var executeMethod = DotNetUtils.GetMethod(type, "System.Object", "(System.String,System.Object[])"); if (executeMethod == null || !executeMethod.IsStatic || executeMethod.Body == null) { continue; } var decrypterType = FindMethodsDecrypterType(type); if (decrypterType == null) { continue; } resourceDecrypter.DecryptMethod = FindDecryptMethod(decrypterType); methodsDecrypterCreator = type; methodsDecrypter = decrypterType; decryptExecuteMethod = executeMethod; return; } }
bool FindFirstBlocks(Block block, TamperBlocks tamperBlocks, IList <Block> allBlocks, IList <Local> locals) { if (!block.LastInstr.IsBrfalse()) { return(false); } /* * ldc.i4.0 * stloc X * call GetExecutingAssembly() * stloc Y * ldloc Y * callvirt Location * ldc.i4.1 * ldloca X * call StrongNameSignatureVerificationEx * pop / brfalse bad_code * ldloc X * brfalse bad_code * ldloc Y * callvirt FullName() * ldstr "......" * callvirt EndsWith(string) * brfalse bad_code / brtrue good_code */ var instrs = block.Instructions; int end = instrs.Count - 1; Instr instr; IMethod method; tamperBlocks.type = Type.V1; int index = 0; int start = FindCallMethod(block, index, true, (calledMethod) => calledMethod.ToString() == "System.Reflection.Assembly System.Reflection.Assembly::GetExecutingAssembly()"); if (start < 0) { return(false); } index = start + 1; instr = instrs[--start]; if (!instr.IsStloc()) { return(false); } var loc0 = Instr.GetLocalVar(locals, instr); instr = instrs[--start]; if (!instr.IsLdcI4()) { return(false); } index = FindCallMethod(block, index, false, (calledMethod) => calledMethod.ToString() == "System.String System.Reflection.Assembly::get_Location()"); if (index < 0) { return(false); } index++; index = FindCallMethod(block, index, false, (calledMethod) => { tamperBlocks.pinvokeMethod = DotNetUtils.GetMethod(module, calledMethod); return(DotNetUtils.IsPinvokeMethod(tamperBlocks.pinvokeMethod, "mscorwks", "StrongNameSignatureVerificationEx")); }); if (index < 0) { return(false); } index++; if (!instrs[index].IsBrfalse()) { if (instrs[index].OpCode.Code != Code.Pop) { return(false); } instr = instrs[index + 1]; if (!instr.IsLdloc() || Instr.GetLocalVar(locals, instr) != loc0) { return(false); } if (!instrs[index + 2].IsBrfalse()) { return(false); } tamperBlocks.type = Type.V1; tamperBlocks.first = new BlockInfo { Block = block, Start = start, End = end, }; } else { tamperBlocks.type = Type.V2; tamperBlocks.first = new BlockInfo { Block = block, Start = start, End = end, }; block = block.FallThrough; if (block == null) { return(false); } instrs = block.Instructions; index = 0; instr = instrs[index]; if (!instr.IsLdloc() || Instr.GetLocalVar(locals, instr) != loc0) { return(false); } if (!instrs[index + 1].IsBrfalse()) { return(false); } } block = block.FallThrough; instrs = block.Instructions; start = end = 0; instr = instrs[end++]; if (!instr.IsLdloc()) { return(false); } instr = instrs[end++]; if (instr.OpCode != OpCodes.Callvirt) { return(false); } method = instr.Operand as IMethod; if (method == null || method.ToString() != "System.String System.Reflection.Assembly::get_FullName()") { return(false); } instr = instrs[end++]; if (instr.OpCode != OpCodes.Ldstr) { return(false); } instr = instrs[end++]; if (instr.OpCode != OpCodes.Callvirt) { return(false); } method = instr.Operand as IMethod; if (method == null || method.ToString() != "System.Boolean System.String::EndsWith(System.String)") { return(false); } instr = instrs[end++]; if (!instr.IsBrfalse() && !instr.IsBrtrue()) { return(false); } end--; tamperBlocks.second = new BlockInfo { Block = block, Start = start, End = end, }; return(true); }
IDecrypterInfo CheckNested(TypeDef type, TypeDef nested) { if (nested.HasProperties || nested.HasEvents) { return(null); } if (nested.FindMethod(".ctor") == null) { return(null); } if (nested.Fields.Count == 1 || nested.Fields.Count == 3) { // 4.0+ if (!HasFieldType(nested.Fields, nested)) { return(null); } var decrypterBuilderMethod = DotNetUtils.GetMethod(nested, "System.Reflection.Emit.MethodBuilder", "(System.Reflection.Emit.TypeBuilder)"); if (decrypterBuilderMethod == null) { return(null); } resourceDecrypter.DecryptMethod = ResourceDecrypter.FindDecrypterMethod(nested.FindMethod(".ctor")); var nestedDecrypter = DotNetUtils.GetMethod(nested, "System.String", "(System.Int32)"); if (nestedDecrypter == null || nestedDecrypter.IsStatic) { return(null); } var decrypter = DotNetUtils.GetMethod(type, "System.String", "(System.Int32)"); if (decrypter == null || !decrypter.IsStatic) { return(null); } simpleDeobfuscator.Deobfuscate(decrypterBuilderMethod); return(new DecrypterInfoV3(resourceDecrypter) { Decrypter = decrypter, OffsetCalcInstructions = GetOffsetCalcInstructions(decrypterBuilderMethod), }); } else if (nested.Fields.Count == 2) { // 3.0 - 3.5 if (CheckFields(nested, "System.Collections.Hashtable", nested)) { // 3.0 - 3.5 var nestedDecrypter = DotNetUtils.GetMethod(nested, "System.String", "(System.Int32)"); if (nestedDecrypter == null || nestedDecrypter.IsStatic) { return(null); } var decrypter = DotNetUtils.GetMethod(type, "System.String", "(System.Int32)"); if (decrypter == null || !decrypter.IsStatic) { return(null); } resourceDecrypter.DecryptMethod = ResourceDecrypter.FindDecrypterMethod(nested.FindMethod(".ctor")); return(new DecrypterInfoV3(resourceDecrypter) { Decrypter = decrypter }); } else if (CheckFields(nested, "System.Byte[]", nested)) { // 3.0 var nestedDecrypter = DotNetUtils.GetMethod(nested, "System.String", "(System.String,System.Int32)"); if (nestedDecrypter == null || nestedDecrypter.IsStatic) { return(null); } var decrypter = DotNetUtils.GetMethod(type, "System.String", "(System.String,System.Int32)"); if (decrypter == null || !decrypter.IsStatic) { return(null); } return(new DecrypterInfoV2 { Decrypter = decrypter }); } else { return(null); } } return(null); }