public ResolverBase(ModuleDefinition module, ISimpleDeobfuscator simpleDeobfuscator, IDeobfuscator deob) { this.module = module; this.frameworkType = DotNetUtils.getFrameworkType(module); this.simpleDeobfuscator = simpleDeobfuscator; this.deob = deob; }
public void find(ISimpleDeobfuscator simpleDeobfuscator, IDeobfuscator deob) { foreach (var type in module.Types) { if (type.Fields.Count != 1) continue; if (type.HasNestedTypes || type.HasGenericParameters || type.IsValueType) continue; if (DotNetUtils.getField(type, "System.Reflection.Assembly") == null) continue; if (DotNetUtils.getMethod(type, ".cctor") == null) continue; var getStream2 = getTheOnlyMethod(type, "System.IO.Stream", "(System.Reflection.Assembly,System.Type,System.String)"); var getNames = getTheOnlyMethod(type, "System.String[]", "(System.Reflection.Assembly)"); if (getStream2 == null && getNames == null) continue; var resource = findGetManifestResourceStreamTypeResource(type, simpleDeobfuscator, deob); if (resource == null && getStream2 != null) continue; getManifestResourceStreamType = type; getManifestResourceStream1Method = null; getManifestResourceStream2Method = getStream2; getManifestResourceNamesMethod = getNames; getManifestResourceStreamTypeResource = resource; break; } }
public static EmbeddedResource findEmbeddedResource(ModuleDefinition module, TypeDefinition decrypterType, ISimpleDeobfuscator simpleDeobfuscator, IDeobfuscator deob) { return findEmbeddedResource(module, decrypterType, (method) => { simpleDeobfuscator.deobfuscate(method); simpleDeobfuscator.decryptStrings(method, deob); }); }
public void Find(ISimpleDeobfuscator simpleDeobfuscator, IDeobfuscator deob) { foreach (var type in module.Types) { if (type.Fields.Count != 1) continue; if (type.HasNestedTypes || type.HasGenericParameters || type.IsValueType) continue; if (DotNetUtils.GetField(type, "System.Reflection.Assembly") == null) continue; if (type.FindStaticConstructor() == null) continue; var getStream2 = GetTheOnlyMethod(type, "System.IO.Stream", "(System.Reflection.Assembly,System.Type,System.String)"); var getNames = GetTheOnlyMethod(type, "System.String[]", "(System.Reflection.Assembly)"); var getRefAsms = GetTheOnlyMethod(type, "System.Reflection.AssemblyName[]", "(System.Reflection.Assembly)"); var bitmapCtor = GetTheOnlyMethod(type, "System.Drawing.Bitmap", "(System.Type,System.String)"); var iconCtor = GetTheOnlyMethod(type, "System.Drawing.Icon", "(System.Type,System.String)"); if (getStream2 == null && getNames == null && getRefAsms == null && bitmapCtor == null && iconCtor == null) continue; var resource = FindGetManifestResourceStreamTypeResource(type, simpleDeobfuscator, deob); if (resource == null && getStream2 != null) continue; getManifestResourceStreamType = type; CreateGetManifestResourceStream2(getStream2); CreateGetManifestResourceNames(getNames); CreateGetReferencedAssemblies(getRefAsms); CreateBitmapCtor(bitmapCtor); CreateIconCtor(iconCtor); getManifestResourceStreamTypeResource = resource; break; } }
bool CheckMethod(ISimpleDeobfuscator simpleDeobfuscator, MethodDef method) { if (method == null || method.Body == null) return false; foreach (var instr in method.Body.Instructions) { if (instr.OpCode.Code != Code.Call) continue; var calledMethod = instr.Operand as MethodDef; if (calledMethod == null) continue; if (calledMethod == null || !calledMethod.IsStatic) continue; if (!DotNetUtils.IsMethod(calledMethod, "System.Void", "()")) continue; var type = calledMethod.DeclaringType; if (type.NestedTypes.Count > 0) continue; simpleDeobfuscator.Deobfuscate(calledMethod, SimpleDeobfuscatorFlags.Force | SimpleDeobfuscatorFlags.DisableConstantsFolderExtraInstrs); if (CheckType(type, calledMethod)) { initMethod = calledMethod; return true; } } return false; }
public void find(ISimpleDeobfuscator simpleDeobfuscator, IDeobfuscator deob) { if (checkInitMethod(DotNetUtils.getModuleTypeCctor(module), simpleDeobfuscator, deob)) return; if (checkInitMethod(module.EntryPoint, simpleDeobfuscator, deob)) return; }
public ResolverInfoBase(ModuleDefinition module, ISimpleDeobfuscator simpleDeobfuscator, IDeobfuscator deob) { this.module = module; this.simpleDeobfuscator = simpleDeobfuscator; this.deob = deob; findTypes(); }
public void Initialize(byte[] fileData, ISimpleDeobfuscator simpleDeobfuscator) { if (encryptedResource.Method == null) return; this.fileData = fileData; encryptedResource.Initialize(simpleDeobfuscator); if (!encryptedResource.FoundResource) return; Logger.v("Adding boolean decrypter. Resource: {0}", Utils.ToCsharpString(encryptedResource.Resource.Name)); decryptedData = encryptedResource.Decrypt(); }
public void Find(ISimpleDeobfuscator simpleDeobfuscator) { var cctor = DotNetUtils.GetModuleTypeCctor(module); if (cctor == null) return; foreach (var method in DotNetUtils.GetCalledMethods(module, cctor)) { if (method.Name == ".cctor" || method.Name == ".ctor") continue; if (!method.IsStatic || !DotNetUtils.IsMethod(method, "System.Void", "()")) continue; if (CheckType(method.DeclaringType, method, simpleDeobfuscator)) break; } }
EmbeddedResource FindGetManifestResourceStreamTypeResource(TypeDef type, ISimpleDeobfuscator simpleDeobfuscator, IDeobfuscator deob) { foreach (var method in type.Methods) { if (!method.IsPrivate || !method.IsStatic || method.Body == null) continue; if (!DotNetUtils.IsMethod(method, "System.String", "(System.Reflection.Assembly,System.Type,System.String)")) continue; simpleDeobfuscator.Deobfuscate(method); simpleDeobfuscator.DecryptStrings(method, deob); foreach (var s in DotNetUtils.GetCodeStrings(method)) { var resource = DotNetUtils.GetResource(module, s) as EmbeddedResource; if (resource != null) return resource; } } return null; }
void Find(ISimpleDeobfuscator simpleDeobfuscator) { switch (frameworkType) { case FrameworkType.Silverlight: FindSilverlight(); break; case FrameworkType.Desktop: case FrameworkType.CompactFramework: if (!module.IsClr1x) { if (FindDesktopOrCompactFramework()) break; } FindDesktopOrCompactFrameworkV1(); break; } InitializeHeaderInfo(simpleDeobfuscator); }
bool checkInitMethod(MethodDef checkMethod, ISimpleDeobfuscator simpleDeobfuscator, IDeobfuscator deob) { var requiredFields = new string[] { "System.Collections.Hashtable", "System.Boolean", }; foreach (var method in DotNetUtils.getCalledMethods(module, checkMethod)) { if (method.Body == null) continue; if (!method.IsStatic) continue; if (!DotNetUtils.isMethod(method, "System.Void", "()")) continue; var type = method.DeclaringType; if (!new FieldTypes(type).exactly(requiredFields)) continue; var ctor = type.FindMethod(".ctor"); if (ctor == null) continue; var handler = DeobUtils.getResolveMethod(ctor); if (handler == null) continue; simpleDeobfuscator.decryptStrings(handler, deob); var resourcePrefix = getResourcePrefix(handler); if (resourcePrefix == null) continue; for (int i = 0; ; i++) { var resource = DotNetUtils.getResource(module, resourcePrefix + i.ToString("D5")) as EmbeddedResource; if (resource == null) break; resources.Add(resource); } initMethod = method; return true; } return false; }
void RestoreMethodBodies(ISimpleDeobfuscator simpleDeobfuscator) { var methodToOrigMethods = new MethodDefAndDeclaringTypeDict<List<MethodDef>>(); foreach (var t in module.Types) { var types = new List<TypeDef>(AllTypesHelper.Types(new List<TypeDef> { t })); foreach (var type in types) { if (methodsTypes.Find(type)) continue; foreach (var method in type.Methods) { if (method.Name == ".ctor" || method.Name == ".cctor") continue; MethodDef calledMethod; if (!CheckRestoreBody(method, out calledMethod)) continue; if (!CheckSameMethods(method, calledMethod)) continue; if (!methodsTypes.Find(calledMethod.DeclaringType)) continue; if (types.IndexOf(calledMethod.DeclaringType) < 0) continue; var list = methodToOrigMethods.Find(calledMethod); if (list == null) methodToOrigMethods.Add(calledMethod, list = new List<MethodDef>()); list.Add(method); } } } foreach (var calledMethod in methodToOrigMethods.GetKeys()) { var list = methodToOrigMethods.Find(calledMethod); var method = list[0]; Logger.v("Restored method body {0:X8} from method {1:X8}", method.MDToken.ToInt32(), calledMethod.MDToken.ToInt32()); DotNetUtils.CopyBodyFromTo(calledMethod, method); classMethods.Add(calledMethod, method); simpleDeobfuscator.MethodModified(method); } }
void Initialize(ISimpleDeobfuscator simpleDeobfuscator, MethodDef method) { var desList = new List<byte[]>(2); var aesList = new List<byte[]>(2); var instructions = method.Body.Instructions; simpleDeobfuscator.Deobfuscate(method); for (int i = 0; i <= instructions.Count - 2; i++) { var ldtoken = instructions[i]; if (ldtoken.OpCode.Code != Code.Ldtoken) continue; var field = DotNetUtils.GetField(module, ldtoken.Operand as IField); if (field == null) continue; if (field.InitialValue == null) continue; var call = instructions[i + 1]; if (call.OpCode.Code != Code.Call) continue; var calledMethod = call.Operand as IMethod; if (!DotNetUtils.IsMethod(calledMethod, "System.Void", "(System.Array,System.RuntimeFieldHandle)")) continue; if (field.InitialValue.Length == 8) desList.Add(field.InitialValue); else if (field.InitialValue.Length == 16) aesList.Add(field.InitialValue); } if (desList.Count >= 2) { DES_Key = desList[desList.Count - 2]; DES_IV = desList[desList.Count - 1]; } if (aesList.Count >= 2) { AES_Key = aesList[aesList.Count - 2]; AES_IV = aesList[aesList.Count - 1]; } }
bool CheckType(TypeDef type, MethodDef initMethod, ISimpleDeobfuscator simpleDeobfuscator) { if (DotNetUtils.FindFieldType(type, "System.Collections.Hashtable", true) == null) return false; simpleDeobfuscator.Deobfuscate(initMethod); if (!CheckInitMethod(initMethod)) return false; if ((asmSeparator = FindAssemblySeparator(initMethod)) == null) return false; List<AssemblyInfo> newAssemblyInfos = null; foreach (var s in DotNetUtils.GetCodeStrings(initMethod)) { newAssemblyInfos = InitializeEmbeddedAssemblies(s); if (newAssemblyInfos != null) break; } if (newAssemblyInfos == null) return false; resolverType = type; resolverMethod = initMethod; assemblyInfos = newAssemblyInfos; return true; }
public void Find(ISimpleDeobfuscator simpleDeobfuscator) { var additionalTypes = new string[] { "System.String", }; foreach (var type in module.Types) { if (type.BaseType == null || type.BaseType.FullName != "System.Object") continue; if (!CheckFields(type.Fields)) continue; foreach (var method in type.Methods) { if (!method.IsStatic || !method.HasBody) continue; if (!DotNetUtils.IsMethod(method, "System.Reflection.Assembly", "(System.Object,System.ResolveEventArgs)") && !DotNetUtils.IsMethod(method, "System.Reflection.Assembly", "(System.Object,System.Object)")) continue; if (!encryptedResource.CouldBeResourceDecrypter(method, additionalTypes, false)) continue; encryptedResource.Method = method; return; } } }
void FindStringDecrypterMethods(TypeDef type, ISimpleDeobfuscator simpleDeobfuscator) { foreach (var method in DotNetUtils.FindMethods(type.Methods, "System.String", new string[] { "System.String", "System.Int32" })) { if (method.Body.HasExceptionHandlers) continue; if (DotNetUtils.GetMethodCalls(method, "System.Char[] System.String::ToCharArray()") != 1) continue; if (DotNetUtils.GetMethodCalls(method, "System.String System.String::Intern(System.String)") != 1) continue; simpleDeobfuscator.Deobfuscate(method); var instrs = method.Body.Instructions; for (int i = 0; i < instrs.Count - 3; i++) { var ldarg = instrs[i]; if (!ldarg.IsLdarg() || ldarg.GetParameterIndex() != 0) continue; var callvirt = instrs[i + 1]; if (callvirt.OpCode.Code != Code.Callvirt) continue; var calledMethod = callvirt.Operand as MemberRef; if (calledMethod == null || calledMethod.FullName != "System.Char[] System.String::ToCharArray()") continue; var stloc = instrs[i + 2]; if (!stloc.IsStloc()) continue; var ldci4 = instrs[i + 3]; if (!ldci4.IsLdcI4()) continue; var info = new StringDecrypterInfo(method, ldci4.GetLdcI4Value()); stringDecrypterMethods.Add(info.method, info); Logger.v("Found string decrypter method: {0}, magic: 0x{1:X8}", Utils.RemoveNewlines(info.method), info.magic); break; } } }
public void Find(ISimpleDeobfuscator simpleDeobfuscator, IDeobfuscator deob) { var entryPoint = module.EntryPoint; if (entryPoint == null) { return; } if (!new LocalTypes(entryPoint).All(requiredEntryPointLocals)) { return; } var type = entryPoint.DeclaringType; if (!new FieldTypes(type).All(requiredFields)) { return; } bool use7zip = type.NestedTypes.Count == 6; MethodDef decyptMethod; if (use7zip) { decyptMethod = FindDecryptMethod_7zip(type); } else { decyptMethod = FindDecryptMethod_inflate(type); } if (decyptMethod == null) { return; } ConfuserVersion theVersion = ConfuserVersion.Unknown; var decryptLocals = new LocalTypes(decyptMethod); if (decryptLocals.Exists("System.IO.MemoryStream")) { if (DotNetUtils.CallsMethod(entryPoint, "System.Void", "(System.String,System.Byte[])")) { theVersion = ConfuserVersion.v10_r42915; } else if (DotNetUtils.CallsMethod(entryPoint, "System.Void", "(System.Security.Permissions.PermissionState)")) { theVersion = ConfuserVersion.v10_r48717; } else { theVersion = ConfuserVersion.v14_r57778; } } else { theVersion = ConfuserVersion.v14_r58564; } var cctor = type.FindStaticConstructor(); if (cctor == null) { return; } if ((asmResolverMethod = FindAssemblyResolverMethod(entryPoint.DeclaringType)) != null) { theVersion = ConfuserVersion.v14_r58802; simpleDeobfuscator.Deobfuscate(asmResolverMethod); if (!FindKey1(asmResolverMethod, out key1)) { return; } } switch (theVersion) { case ConfuserVersion.v10_r42915: case ConfuserVersion.v10_r48717: case ConfuserVersion.v14_r57778: break; case ConfuserVersion.v14_r58564: case ConfuserVersion.v14_r58802: simpleDeobfuscator.Deobfuscate(decyptMethod); if (FindKey0_v14_r58564(decyptMethod, out key0)) { break; } if (FindKey0_v14_r58852(decyptMethod, out key0)) { if (!decryptLocals.Exists("System.Security.Cryptography.RijndaelManaged")) { theVersion = ConfuserVersion.v14_r58852; break; } if (use7zip) { if (new LocalTypes(decyptMethod).Exists("System.IO.MemoryStream")) { theVersion = ConfuserVersion.v17_r75076; } else if (module.Name == "Stub.exe") { theVersion = ConfuserVersion.v18_r75184; } else if (!IsGetLenToPosStateMethodPrivate(type)) { theVersion = ConfuserVersion.v18_r75367; } else { theVersion = ConfuserVersion.v19_r77172; } } else if (IsDecryptMethod_v17_r73404(decyptMethod)) { theVersion = ConfuserVersion.v17_r73404; } else { theVersion = ConfuserVersion.v15_r60785; } break; } throw new ApplicationException("Could not find magic"); default: throw new ApplicationException("Invalid version"); } simpleDeobfuscator.Deobfuscate(cctor); simpleDeobfuscator.DecryptStrings(cctor, deob); if (FindEntryPointToken(simpleDeobfuscator, cctor, entryPoint, out entryPointToken) && !use7zip) { if (DotNetUtils.CallsMethod(asmResolverMethod, "System.Void", "(System.String)")) { theVersion = ConfuserVersion.v17_r73477; } else { theVersion = ConfuserVersion.v17_r73566; } } mainAsmResource = FindResource(cctor); if (mainAsmResource == null) { throw new ApplicationException("Could not find main assembly resource"); } version = theVersion; }
bool initializeInfos(ISimpleDeobfuscator simpleDeobfuscator, IDeobfuscator deob) { if (handlerMethod == null) return true; foreach (var method in resolverType.Methods) { if (!method.IsStatic || method.Body == null) continue; if (!DotNetUtils.isMethod(method, "System.Void", "()")) continue; if (!DeobUtils.hasInteger(method, ':') || !DeobUtils.hasInteger(method, '|')) continue; simpleDeobfuscator.deobfuscate(method); simpleDeobfuscator.decryptStrings(method, deob); if (!initializeInfos(method)) continue; return true; } return false; }
public ResourceResolver(ModuleDefinition module, ISimpleDeobfuscator simpleDeobfuscator, IDeobfuscator deob) : base(module, simpleDeobfuscator, deob) { }
public bool Decrypt(MyPEImage peImage, ISimpleDeobfuscator simpleDeobfuscator, ref DumpedMethods dumpedMethods, Dictionary <uint, byte[]> tokenToNativeCode, bool unpackedNativeFile) { if (encryptedResource.Method == null) { return(false); } encryptedResource.Initialize(simpleDeobfuscator); if (!encryptedResource.FoundResource) { return(false); } var methodsData = encryptedResource.Decrypt(); bool hooksJitter = FindDnrCompileMethod(encryptedResource.Method.DeclaringType) != null; xorKey = GetXorKey(); XorEncrypt(methodsData); var methodsDataReader = ByteArrayDataReaderFactory.CreateReader(methodsData); int patchCount = methodsDataReader.ReadInt32(); int mode = methodsDataReader.ReadInt32(); int tmp = methodsDataReader.ReadInt32(); methodsDataReader.Position -= 4; if ((tmp & 0xFF000000) == 0x06000000) { // It's method token + rva. DNR 3.7.0.3 (and earlier?) - 3.9.0.1 methodsDataReader.Position += 8 * (uint)patchCount; patchCount = methodsDataReader.ReadInt32(); mode = methodsDataReader.ReadInt32(); PatchDwords(peImage, ref methodsDataReader, patchCount); while (methodsDataReader.Position < methodsData.Length - 1) { /*uint token =*/ methodsDataReader.ReadUInt32(); int numDwords = methodsDataReader.ReadInt32(); PatchDwords(peImage, ref methodsDataReader, numDwords / 2); } } else if (!hooksJitter || mode == 1) { // DNR 3.9.8.0, 4.0+ PatchDwords(peImage, ref methodsDataReader, patchCount); bool oldCode = !IsNewer45Decryption(encryptedResource.Method); while (methodsDataReader.Position < methodsData.Length - 1) { uint rva = methodsDataReader.ReadUInt32(); int size; if (oldCode) { methodsDataReader.ReadUInt32(); // token, unknown, or index size = methodsDataReader.ReadInt32(); } else { size = methodsDataReader.ReadInt32() * 4; } var newData = methodsDataReader.ReadBytes(size); if (unpackedNativeFile) { peImage.DotNetSafeWriteOffset(rva, newData); } else { peImage.DotNetSafeWrite(rva, newData); } } } else { // DNR 4.0+ (jitter is hooked) var methodDef = peImage.Metadata.TablesStream.MethodTable; var rvaToIndex = new Dictionary <uint, int>((int)methodDef.Rows); uint offset = (uint)methodDef.StartOffset; for (int i = 0; i < methodDef.Rows; i++) { uint rva = peImage.OffsetReadUInt32(offset); offset += methodDef.RowSize; if (rva == 0) { continue; } if ((peImage.ReadByte(rva) & 3) == 2) { rva++; } else { rva += (uint)(4 * (peImage.ReadByte(rva + 1) >> 4)); } rvaToIndex[rva] = i; } PatchDwords(peImage, ref methodsDataReader, patchCount); /*int count =*/ methodsDataReader.ReadInt32(); dumpedMethods = new DumpedMethods(); while (methodsDataReader.Position < methodsData.Length - 1) { uint rva = methodsDataReader.ReadUInt32(); uint index = methodsDataReader.ReadUInt32(); bool isNativeCode = index >= 0x70000000; int size = methodsDataReader.ReadInt32(); var methodData = methodsDataReader.ReadBytes(size); if (!rvaToIndex.TryGetValue(rva, out int methodIndex)) { Logger.w("Could not find method having code RVA {0:X8}", rva); continue; } uint methodToken = 0x06000001 + (uint)methodIndex; if (isNativeCode) { totalEncryptedNativeMethods++; if (tokenToNativeCode != null) { tokenToNativeCode[methodToken] = methodData; } // Convert return true / false methods. The others are converted to // throw 0xDEADCODE. if (DeobUtils.IsCode(nativeLdci4, methodData)) { uint val = BitConverter.ToUInt32(methodData, 4); // ldc.i4 XXXXXXXXh / ret methodData = new byte[] { 0x20, 0, 0, 0, 0, 0x2A }; methodData[1] = (byte)val; methodData[2] = (byte)(val >> 8); methodData[3] = (byte)(val >> 16); methodData[4] = (byte)(val >> 24); } else if (DeobUtils.IsCode(nativeLdci4_0, methodData)) { // ldc.i4.0 / ret methodData = new byte[] { 0x16, 0x2A }; } else { tokenToNativeMethod[methodToken] = methodData; // ldc.i4 0xDEADCODE / conv.u4 / throw methodData = new byte[] { 0x20, 0xDE, 0xC0, 0xAD, 0xDE, 0x6D, 0x7A }; } } var dm = new DumpedMethod(); peImage.ReadMethodTableRowTo(dm, MDToken.ToRID(methodToken)); dm.code = methodData; var codeReader = peImage.Reader; codeReader.Position = peImage.RvaToOffset(dm.mdRVA); var mbHeader = MethodBodyParser.ParseMethodBody(ref codeReader, out var code, out dm.extraSections); peImage.UpdateMethodHeaderInfo(dm, mbHeader); dumpedMethods.Add(dm); } } return(true); }
public void Initialize(ISimpleDeobfuscator simpleDeobfuscator) { InitializeArrays(simpleDeobfuscator, DotNetUtils.GetModuleTypeCctor(module)); }
public MemoryMethodsDecrypter(ModuleDefMD module, ISimpleDeobfuscator simpleDeobfuscator) : base(module, simpleDeobfuscator) { }
public bool init(IDeobfuscator deob, ISimpleDeobfuscator simpleDeobfuscator) { var cctor = stringsEncodingClass.FindStaticConstructor(); if (cctor != null) { simpleDeobfuscator.deobfuscate(cctor); } decrypterVersion = guessVersion(cctor); if (!findDecrypterMethod()) { throw new ApplicationException("Could not find string decrypter method"); } if (!findStringsResource(deob, simpleDeobfuscator, cctor)) { return(false); } if (decrypterVersion <= StringDecrypterVersion.V3) { MethodDef initMethod; if (decrypterVersion == StringDecrypterVersion.V3) { initMethod = cctor; } else if (decrypterVersion == StringDecrypterVersion.V2) { initMethod = stringDecrypterMethod; } else { initMethod = stringDecrypterMethod; } stringOffset = 0; if (decrypterVersion != StringDecrypterVersion.V1) { if (callsGetPublicKeyToken(initMethod)) { var pkt = PublicKeyBase.ToPublicKeyToken(module.Assembly.PublicKeyToken); if (!PublicKeyBase.IsNullOrEmpty2(pkt)) { for (int i = 0; i < pkt.Data.Length - 1; i += 2) { stringOffset ^= ((int)pkt.Data[i] << 8) + pkt.Data[i + 1]; } } } if (DeobUtils.hasInteger(initMethod, 0xFFFFFF) && DeobUtils.hasInteger(initMethod, 0xFFFF)) { stringOffset ^= ((stringDecrypterMethod.MDToken.ToInt32() & 0xFFFFFF) - 1) % 0xFFFF; } } } else { var offsetVal = findOffsetValue(cctor); if (offsetVal == null) { throw new ApplicationException("Could not find string offset"); } stringOffset = offsetVal.Value; decrypterVersion = StringDecrypterVersion.V4; } simpleZipTypeMethod = findSimpleZipTypeMethod(cctor) ?? findSimpleZipTypeMethod(stringDecrypterMethod); if (simpleZipTypeMethod != null) { resourceDecrypter = new ResourceDecrypter(new ResourceDecrypterInfo(module, simpleZipTypeMethod, simpleDeobfuscator)); } return(true); }
public bool init(IDeobfuscator deob, ISimpleDeobfuscator simpleDeobfuscator) { var cctor = DotNetUtils.getMethod(stringsEncodingClass, ".cctor"); if (cctor == null) throw new ApplicationException("Could not find .cctor"); simpleDeobfuscator.deobfuscate(cctor); stringsResource = findStringResource(cctor); if (stringsResource == null) { simpleDeobfuscator.decryptStrings(cctor, deob); stringsResource = findStringResource(cctor); if (stringsResource == null) return false; } var offsetVal = findOffsetValue(cctor); if (offsetVal == null) throw new ApplicationException("Could not find string offset"); stringOffset = offsetVal.Value; if (!findDecrypterMethod()) throw new ApplicationException("Could not find string decrypter method"); simpleZipType = findSimpleZipType(cctor); if (simpleZipType != null) resourceDecrypter = new ResourceDecrypter(new ResourceDecrypterInfo(module, simpleZipType, simpleDeobfuscator)); return true; }
public ProxyCallFixer(ModuleDefMD module, ISimpleDeobfuscator simpleDeobfuscator) : base(module) { this.simpleDeobfuscator = simpleDeobfuscator; }
public StringEncoderClassFinder(ModuleDefMD module, ISimpleDeobfuscator simpleDeobfuscator) { this.module = module; this.simpleDeobfuscator = simpleDeobfuscator; }
void RestoreMethodBodies(ISimpleDeobfuscator simpleDeobfuscator) { var methodToOrigMethods = new MethodDefAndDeclaringTypeDict <List <MethodDef> >(); foreach (var t in module.Types) { var types = new List <TypeDef>(AllTypesHelper.Types(new List <TypeDef> { t })); foreach (var type in types) { if (methodsTypes.Find(type)) { continue; } foreach (var method in type.Methods) { if (method.Name == ".ctor" || method.Name == ".cctor") { continue; } MethodDef calledMethod; if (!CheckRestoreBody(method, out calledMethod)) { continue; } if (!CheckSameMethods(method, calledMethod)) { continue; } if (!methodsTypes.Find(calledMethod.DeclaringType)) { continue; } if (types.IndexOf(calledMethod.DeclaringType) < 0) { continue; } var list = methodToOrigMethods.Find(calledMethod); if (list == null) { methodToOrigMethods.Add(calledMethod, list = new List <MethodDef>()); } list.Add(method); } } } foreach (var calledMethod in methodToOrigMethods.GetKeys()) { var list = methodToOrigMethods.Find(calledMethod); var method = list[0]; Logger.v("Restored method body {0:X8} from method {1:X8}", method.MDToken.ToInt32(), calledMethod.MDToken.ToInt32()); DotNetUtils.CopyBodyFromTo(calledMethod, method); classMethods.Add(calledMethod, method); simpleDeobfuscator.MethodModified(method); } }
public void Initialize(ISimpleDeobfuscator simpleDeobfuscator) { InitializeMethodsTypes(); RestoreMethodBodies(simpleDeobfuscator); }
public CflowConstantsInliner(ModuleDefMD module, ISimpleDeobfuscator simpleDeobfuscator) { this.module = module; this.simpleDeobfuscator = simpleDeobfuscator; Find(); }
public void initialize(ISimpleDeobfuscator simpleDeobfuscator) { foreach (var info in stringEncrypterInfos.getValues()) { simpleDeobfuscator.deobfuscate(info.Method); info.Resource = findResource(info.Method); if (info.Resource == null) { Logger.w("Could not find encrypted strings resource (Method {0:X8})", info.Method.MDToken.ToInt32()); continue; } info.Magic1 = findMagic1(info.Method); info.Magic2 = findMagic2(info.Method); info.Magic3 = findMagic3(info.Method); info.Reader = info.Resource.Data; info.Reader.Position = 0; } }
public ProxyCallFixer(ModuleDefinition module, ISimpleDeobfuscator simpleDeobfuscator) : base(module) { this.memberReferences = new List <MemberReference>(module.GetMemberReferences()); this.simpleDeobfuscator = simpleDeobfuscator; }
bool FindStringsResource(IDeobfuscator deob, ISimpleDeobfuscator simpleDeobfuscator, MethodDef cctor) { if (stringsResource != null) return true; if (decrypterVersion <= StringDecrypterVersion.V3) { stringsResource = DotNetUtils.GetResource(module, (module.Mvid ?? Guid.NewGuid()).ToString("B")) as EmbeddedResource; if (stringsResource != null) return true; } if (FindStringsResource2(deob, simpleDeobfuscator, cctor)) return true; if (FindStringsResource2(deob, simpleDeobfuscator, stringDecrypterMethod)) return true; return false; }
public ResourceDecrypterInfo(ModuleDefMD module, MethodDef simpleZipTypeDecryptMethod, ISimpleDeobfuscator simpleDeobfuscator) : this(module) { setSimpleZipType(simpleZipTypeDecryptMethod, simpleDeobfuscator); }
protected MethodsDecrypterBase(ModuleDefMD module, ISimpleDeobfuscator simpleDeobfuscator) { this.module = module; this.simpleDeobfuscator = simpleDeobfuscator; }
public ConstantsDecrypter(ModuleDef module, MethodDef lzmaMethod, ISimpleDeobfuscator deobfsucator) { _module = module; _lzmaMethod = lzmaMethod; _deobfuscator = deobfsucator; }
bool findConstants(ISimpleDeobfuscator simpleDeobfuscator) { dynocode = new Dynocode(simpleDeobfuscator); simpleDeobfuscator.deobfuscate(stringMethod); stringMethodConsts = new EfConstantsReader(stringMethod); if (!findResource(stringMethod)) { return(false); } checkMinus2 = isV32OrLater || DeobUtils.hasInteger(stringMethod, -2); usePublicKeyToken = callsGetPublicKeyToken(stringMethod); var int64Method = findInt64Method(stringMethod); if (int64Method != null) { decrypterType.Type = int64Method.DeclaringType; } if (!findShorts()) { return(false); } if (!findInt3()) { return(false); } if (!findInt4()) { return(false); } if (checkMinus2 && !findInt5()) { return(false); } dataDecrypterType = findDataDecrypterType(stringMethod); if (dataDecrypterType == null) { return(false); } if (isV32OrLater) { bool initializedAll; int index = findInitIntsIndex(stringMethod, out initializedAll); var cctor = stringType.FindStaticConstructor(); if (!initializedAll && cctor != null) { simpleDeobfuscator.deobfuscate(cctor); if (!findIntsCctor(cctor)) { return(false); } } if (decrypterType.Detected && !decrypterType.initialize()) { return(false); } if (!findInts(index)) { return(false); } } initializeFlags(); initialize(); return(true); }
bool UpdateFlags(MethodDef method, ISimpleDeobfuscator simpleDeobfuscator) { if (method == null || method.Body == null || method.Body.Variables.Count < 3) { return(false); } var constants = new List <int>(); simpleDeobfuscator.Deobfuscate(method); var instructions = method.Body.Instructions; for (int i = 2; i < instructions.Count; i++) { var and = instructions[i]; if (and.OpCode.Code != Code.And) { continue; } var ldci4 = instructions[i - 1]; if (!ldci4.IsLdcI4()) { continue; } int flagValue = ldci4.GetLdcI4Value(); if (!IsFlag(flagValue)) { continue; } var ldloc = instructions[i - 2]; if (!ldloc.IsLdloc()) { continue; } var local = ldloc.GetLocal(method.Body.Variables); if (local.Type.GetElementType().GetPrimitiveSize() < 0) { continue; } constants.Add(flagValue); } flipFlagsBits = CheckFlipBits(method); skipBytes = GetHeaderSkipBytes(method); switch (frameworkType) { case FrameworkType.Desktop: if (!module.IsClr1x) { if (constants.Count == 2) { desEncryptedFlag = (byte)constants[0]; deflatedFlag = (byte)constants[1]; return(true); } } if (constants.Count == 1) { desEncryptedFlag = (byte)constants[0]; return(true); } break; case FrameworkType.Silverlight: if (constants.Count == 1) { bitwiseNotEncryptedFlag = (byte)constants[0]; return(true); } break; case FrameworkType.CompactFramework: if (constants.Count == 1) { desEncryptedFlag = (byte)constants[0]; return(true); } break; } return(false); }
public ResourceResolverInfo(ModuleDefMD module, ISimpleDeobfuscator simpleDeobfuscator, IDeobfuscator deob, AssemblyResolverInfo assemblyResolverInfo) : base(module, simpleDeobfuscator, deob) => this.assemblyResolverInfo = assemblyResolverInfo;
public ResourceDecrypter(ModuleDefMD module, ISimpleDeobfuscator simpleDeobfuscator) { this.module = module; frameworkType = DotNetUtils.GetFrameworkType(module); Find(simpleDeobfuscator); }
public DecrypterType(ModuleDefMD module, ISimpleDeobfuscator simpleDeobfuscator) { this.module = module; this.simpleDeobfuscator = simpleDeobfuscator; }
public ResourceResolver(ModuleDefMD module, ResourceDecrypter resourceDecrypter, ISimpleDeobfuscator simpleDeobfuscator) { this.module = module; this.resourceDecrypter = resourceDecrypter; this.simpleDeobfuscator = simpleDeobfuscator; }
public ConstantsDecrypterBase(ModuleDefMD module, byte[] fileData, ISimpleDeobfuscator simpleDeobfuscator) { this.module = module; this.fileData = fileData; this.simpleDeobfuscator = simpleDeobfuscator; }
bool FindConstants(ISimpleDeobfuscator simpleDeobfuscator) { dynocode = new DynamicDynocodeIterator(); simpleDeobfuscator.Deobfuscate(stringMethod); stringMethodConsts = new EfConstantsReader(stringMethod); if (!FindResource(stringMethod)) { return(false); } checkMinus2 = isV32OrLater || DeobUtils.HasInteger(stringMethod, -2); usePublicKeyToken = CallsGetPublicKeyToken(stringMethod); var int64Method = FindInt64Method(stringMethod); if (int64Method != null) { decrypterType.Type = int64Method.DeclaringType; } if (!FindShorts()) { return(false); } if (!FindInt3()) { return(false); } if (!FindInt4()) { return(false); } if (checkMinus2 && !FindInt5()) { return(false); } // The method body of the data decrypter method has been moved into // the string decrypter helper method in 5.0 if (!isV50OrLater) { dataDecrypterType = FindDataDecrypterType(stringMethod); if (dataDecrypterType == null) { return(false); } } if (isV32OrLater) { bool initializedAll; int index = FindInitIntsIndex(stringMethod, out initializedAll); var cctor = stringType.FindStaticConstructor(); if (!initializedAll && cctor != null) { simpleDeobfuscator.Deobfuscate(cctor); if (!FindIntsCctor(cctor)) { return(false); } } if (decrypterType.Detected && !decrypterType.Initialize()) { return(false); } if (!FindInts(index)) { return(false); } } InitializeFlags(); Initialize(); return(true); }
public ResourceDecrypter(ModuleDefMD module, ISimpleDeobfuscator simpleDeobfuscator) { this.module = module; this.simpleDeobfuscator = simpleDeobfuscator; }
public void initialize(ISimpleDeobfuscator simpleDeobfuscator, IDeobfuscator deob) { if (!initializeInfos(simpleDeobfuscator, deob)) throw new ApplicationException("Could not initialize resource decrypter"); }
void InitializeHeaderInfo(ISimpleDeobfuscator simpleDeobfuscator) { skipBytes = 0; foreach (var method in GetDecrypterMethods(resourceDecrypterType)) { if (UpdateFlags(method, simpleDeobfuscator)) return; } desEncryptedFlag = 1; deflatedFlag = 2; bitwiseNotEncryptedFlag = 4; }
public bool Initialize(IDeobfuscator deob, ISimpleDeobfuscator simpleDeobfuscator) { var cctor = stringsEncodingClass.FindStaticConstructor(); if (cctor != null) simpleDeobfuscator.Deobfuscate(cctor); decrypterVersion = GuessVersion(cctor); if (!FindDecrypterMethod()) throw new ApplicationException("Could not find string decrypter method"); if (!FindStringsResource(deob, simpleDeobfuscator, cctor)) return false; if (decrypterVersion <= StringDecrypterVersion.V3) { MethodDef initMethod; if (decrypterVersion == StringDecrypterVersion.V3) initMethod = cctor; else if (decrypterVersion == StringDecrypterVersion.V2) initMethod = stringDecrypterMethod; else initMethod = stringDecrypterMethod; stringOffset = 0; if (decrypterVersion != StringDecrypterVersion.V1) { if (CallsGetPublicKeyToken(initMethod)) { var pkt = PublicKeyBase.ToPublicKeyToken(module.Assembly.PublicKeyToken); if (!PublicKeyBase.IsNullOrEmpty2(pkt)) { for (int i = 0; i < pkt.Data.Length - 1; i += 2) stringOffset ^= ((int)pkt.Data[i] << 8) + pkt.Data[i + 1]; } } if (DeobUtils.HasInteger(initMethod, 0xFFFFFF) && DeobUtils.HasInteger(initMethod, 0xFFFF)) { stringOffset ^= ((stringDecrypterMethod.MDToken.ToInt32() & 0xFFFFFF) - 1) % 0xFFFF; } } } else { var offsetVal = FindOffsetValue(cctor); if (offsetVal == null) throw new ApplicationException("Could not find string offset"); stringOffset = offsetVal.Value; decrypterVersion = StringDecrypterVersion.V4; } simpleZipTypeMethod = FindSimpleZipTypeMethod(cctor) ?? FindSimpleZipTypeMethod(stringDecrypterMethod); if (simpleZipTypeMethod != null) resourceDecrypter = new ResourceDecrypter(new ResourceDecrypterInfo(module, simpleZipTypeMethod, simpleDeobfuscator)); return true; }
bool FindStringsResource2(IDeobfuscator deob, ISimpleDeobfuscator simpleDeobfuscator, MethodDef initMethod) { if (initMethod == null) return false; stringsResource = FindStringResource(initMethod); if (stringsResource != null) return true; simpleDeobfuscator.DecryptStrings(initMethod, deob); stringsResource = FindStringResource(initMethod); if (stringsResource != null) return true; return false; }
public AntiDebugger(ModuleDefMD module, ISimpleDeobfuscator simpleDeobfuscator, IDeobfuscator deob) { this.module = module; this.simpleDeobfuscator = simpleDeobfuscator; this.deob = deob; }
public void Find(ISimpleDeobfuscator simpleDeobfuscator) { if (CheckMethod(simpleDeobfuscator, DotNetUtils.GetModuleTypeCctor(module))) return; }
public ConstantsDecrypterV17(ModuleDefMD module, byte[] fileData, ISimpleDeobfuscator simpleDeobfuscator) : base(module, fileData, simpleDeobfuscator) { }
public ConstantsDecrypterV18(ModuleDefMD module, byte[] fileData, ISimpleDeobfuscator simpleDeobfuscator) { this.module = module; this.fileData = fileData; this.simpleDeobfuscator = simpleDeobfuscator; }
bool CheckMethod(ISimpleDeobfuscator simpleDeobfuscator, MethodDef methodToCheck) { if (methodToCheck == null) { return(false); } var resolverLocals = new string[] { "System.Byte[]", "System.Reflection.Assembly", "System.String", "System.IO.BinaryReader", "System.IO.Stream", }; simpleDeobfuscator.Deobfuscate(methodToCheck); foreach (var method in DotNetUtils.GetCalledMethods(module, methodToCheck)) { var type = method.DeclaringType; if (!DotNetUtils.IsMethod(method, "System.Void", "()")) { continue; } if (!method.IsStatic) { continue; } if (type.Fields.Count != 2) { continue; } if (type.HasNestedTypes) { continue; } if (type.HasEvents || type.HasProperties) { continue; } if (!CheckFields(type.Fields)) { continue; } var resolverMethod = FindAssemblyResolveMethod(type); if (resolverMethod == null) { continue; } var localTypes = new LocalTypes(resolverMethod); if (!localTypes.All(resolverLocals)) { continue; } assemblyResolverType = type; assemblyResolverMethod = resolverMethod; assemblyResolverInitMethod = method; return(true); } return(false); }
bool UpdateFlags(MethodDef method, ISimpleDeobfuscator simpleDeobfuscator) { if (method == null || method.Body == null || method.Body.Variables.Count < 3) return false; var constants = new List<int>(); simpleDeobfuscator.Deobfuscate(method); var instructions = method.Body.Instructions; for (int i = 2; i < instructions.Count; i++) { var and = instructions[i]; if (and.OpCode.Code != Code.And) continue; var ldci4 = instructions[i - 1]; if (!ldci4.IsLdcI4()) continue; int flagValue = ldci4.GetLdcI4Value(); if (!IsFlag(flagValue)) continue; var ldloc = instructions[i - 2]; if (!ldloc.IsLdloc()) continue; var local = ldloc.GetLocal(method.Body.Variables); if (local.Type.GetElementType().GetPrimitiveSize() < 0) continue; constants.Add(flagValue); } int notIndex, skipIndex; flipFlagsBits = CheckFlipBits(method, out notIndex); skipBytes = GetHeaderSkipBytes(method, out skipIndex); skipBeforeFlag = skipIndex < notIndex; switch (frameworkType) { case FrameworkType.Desktop: if (!module.IsClr1x) { if (constants.Count == 2) { desEncryptedFlag = (byte)constants[0]; deflatedFlag = (byte)constants[1]; return true; } } if (constants.Count == 1) { desEncryptedFlag = (byte)constants[0]; return true; } break; case FrameworkType.Silverlight: if (constants.Count == 1) { bitwiseNotEncryptedFlag = (byte)constants[0]; return true; } break; case FrameworkType.CompactFramework: if (constants.Count == 1) { desEncryptedFlag = (byte)constants[0]; return true; } break; } return false; }
public AssemblyResolverInfo(ModuleDefMD module, ISimpleDeobfuscator simpleDeobfuscator, IDeobfuscator deob) : base(module, simpleDeobfuscator, deob) { }
public AssemblyDecrypter(ModuleDefMD module, ISimpleDeobfuscator simpleDeobfuscator, IDeobfuscator deob) { this.module = module; this.simpleDeobfuscator = simpleDeobfuscator; this.deob = deob; }
public static EmbeddedResource FindEmbeddedResource(ModuleDefMD module, TypeDef decrypterType, ISimpleDeobfuscator simpleDeobfuscator, IDeobfuscator deob) { return(FindEmbeddedResource(module, decrypterType, (method) => { simpleDeobfuscator.Deobfuscate(method); simpleDeobfuscator.DecryptStrings(method, deob); })); }