diff --git a/Confuser.Core/ConfuserAssemblyResolver.cs b/Confuser.Core/ConfuserAssemblyResolver.cs index 05ef4731f..22346b13e 100644 --- a/Confuser.Core/ConfuserAssemblyResolver.cs +++ b/Confuser.Core/ConfuserAssemblyResolver.cs @@ -33,8 +33,50 @@ public AssemblyDef Resolve(IAssembly assembly, ModuleDef sourceModule) { if (assembly is AssemblyDef assemblyDef) return assemblyDef; - var resolvedAssemblyDef = InternalExactResolver.Resolve(assembly, sourceModule); - return resolvedAssemblyDef ?? InternalFuzzyResolver.Resolve(assembly, sourceModule); + var resolvedAssemblyDef = + InternalExactResolver.Resolve(assembly, sourceModule) ?? + InternalFuzzyResolver.Resolve(assembly, sourceModule); + + // Remove AssemblyAttributes.PA_NoPlatform + if (null != resolvedAssemblyDef && + (AssemblyAttributes.PA_Mask & resolvedAssemblyDef.Attributes) == AssemblyAttributes.PA_NoPlatform) { + resolvedAssemblyDef.Attributes = + resolvedAssemblyDef.Attributes & ~AssemblyAttributes.PA_FullMask; + } + + if (resolvedAssemblyDef?.Name == "netstandard" && 0 < resolvedAssemblyDef.ManifestModule.ExportedTypes.Count) { + // Move types from AssemblyRef to here + var module = resolvedAssemblyDef.ManifestModule; + var newTypes = new List(); + var allAssemblyRefs = new List(); + + module.ExportedTypes.Clear(); + + foreach (var assemblyRef in module.GetAssemblyRefs()) { + var subAss = + InternalExactResolver.Resolve(assemblyRef, module) ?? + InternalFuzzyResolver.Resolve(assemblyRef, module); + allAssemblyRefs.Add(subAss); + foreach (var subModule in subAss?.Modules) { + foreach (var defType in subModule.Types) { + newTypes.Add(defType); + } + subModule.Types.Clear(); + foreach (var defType in newTypes) { + module.Types.Add(defType); + } + newTypes.Clear(); + } + } + + // Remove them because their types has been removed. + foreach (var subAss in allAssemblyRefs) { + InternalExactResolver.Remove(subAss); + InternalFuzzyResolver.Remove(subAss); + } + } + + return resolvedAssemblyDef; } public void Clear() { diff --git a/Confuser.Core/Helpers/InjectHelper.cs b/Confuser.Core/Helpers/InjectHelper.cs index 6aaf566a0..6cb066c23 100644 --- a/Confuser.Core/Helpers/InjectHelper.cs +++ b/Confuser.Core/Helpers/InjectHelper.cs @@ -292,7 +292,16 @@ public override ITypeDefOrRef Map(ITypeDefOrRef source) { // check if the assembly reference needs to be fixed. if (source is TypeRef sourceRef) { var targetAssemblyRef = TargetModule.GetAssemblyRef(sourceRef.DefinitionAssembly.Name); - if (!(targetAssemblyRef is null) && !string.Equals(targetAssemblyRef.FullName, source.DefinitionAssembly.FullName, StringComparison.Ordinal)) { + if (targetAssemblyRef is null) { + // Handle assemblies referenced by netstandard + var corLibAssemblyRef = TargetModule.CorLibTypes.AssemblyRef; + var corLibAssembly = TargetModule.Context.AssemblyResolver.Resolve(corLibAssemblyRef, TargetModule); + if (null != corLibAssembly?.ManifestModule.GetAssemblyRef(sourceRef.DefinitionAssembly.Name)) { + var fixedTypeRef = new TypeRefUser(sourceRef.Module, sourceRef.Namespace, sourceRef.Name, corLibAssemblyRef); + return Importer.Import(fixedTypeRef); + } + } + else if (!string.Equals(targetAssemblyRef.FullName, source.DefinitionAssembly.FullName, StringComparison.Ordinal)) { // We got a matching assembly by the simple name, but not by the full name. // This means the injected code uses a different assembly version than the target assembly. // We'll fix the assembly reference, to avoid breaking anything. diff --git a/Confuser.Protections/Compress/Compressor.cs b/Confuser.Protections/Compress/Compressor.cs index 33c0ea6b7..abbbd13c6 100644 --- a/Confuser.Protections/Compress/Compressor.cs +++ b/Confuser.Protections/Compress/Compressor.cs @@ -175,7 +175,7 @@ void PackModules(ConfuserContext context, CompressorContext compCtx, ModuleDef s context.Logger.EndProgress(); } - void InjectData(ModuleDef stubModule, MethodDef method, byte[] data) { + void InjectData(ConfuserContext context, ModuleDef stubModule, MethodDef method, byte[] data) { var dataType = new TypeDefUser("", "DataType", stubModule.CorLibTypes.GetTypeRef("System", "ValueType")); dataType.Layout = TypeAttributes.ExplicitLayout; dataType.Visibility = TypeAttributes.NestedPrivate; @@ -197,7 +197,7 @@ void InjectData(ModuleDef stubModule, MethodDef method, byte[] data) { repl.Add(Instruction.Create(OpCodes.Dup)); repl.Add(Instruction.Create(OpCodes.Ldtoken, dataField)); repl.Add(Instruction.Create(OpCodes.Call, stubModule.Import( - typeof(RuntimeHelpers).GetMethod("InitializeArray")))); + context, typeof(RuntimeHelpers), "InitializeArray"))); return repl.ToArray(); }); } @@ -254,7 +254,7 @@ void InjectStub(ConfuserContext context, CompressorContext compCtx, ProtectionPa MutationHelper.InjectKeys(entryPoint, new[] { 0, 1 }, new[] { encryptedModule.Length >> 2, (int)seed }); - InjectData(stubModule, entryPoint, encryptedModule); + InjectData(context, stubModule, entryPoint, encryptedModule); // Decrypt MethodDef decrypter = defs.OfType().Single(method => method.Name == "Decrypt"); diff --git a/Confuser.Protections/Constants/EncodePhase.cs b/Confuser.Protections/Constants/EncodePhase.cs index 4eba9118e..ade681d17 100644 --- a/Confuser.Protections/Constants/EncodePhase.cs +++ b/Confuser.Protections/Constants/EncodePhase.cs @@ -122,7 +122,7 @@ protected override void Execute(ConfuserContext context, ProtectionParameters pa repl.Add(Instruction.Create(OpCodes.Dup)); repl.Add(Instruction.Create(OpCodes.Ldtoken, moduleCtx.DataField)); repl.Add(Instruction.Create(OpCodes.Call, moduleCtx.Module.Import( - typeof(RuntimeHelpers).GetMethod("InitializeArray")))); + context, typeof(RuntimeHelpers), "InitializeArray"))); return repl.ToArray(); }); } diff --git a/Confuser.Protections/Resources/InjectPhase.cs b/Confuser.Protections/Resources/InjectPhase.cs index 540591750..27c58ab03 100644 --- a/Confuser.Protections/Resources/InjectPhase.cs +++ b/Confuser.Protections/Resources/InjectPhase.cs @@ -137,10 +137,10 @@ void MutateInitializer(REContext moduleCtx, MethodDef decomp) { repl.Add(Instruction.Create(OpCodes.Dup)); repl.Add(Instruction.Create(OpCodes.Ldtoken, moduleCtx.DataField)); repl.Add(Instruction.Create(OpCodes.Call, moduleCtx.Module.Import( - typeof(RuntimeHelpers).GetMethod("InitializeArray")))); + moduleCtx.Context, typeof(RuntimeHelpers), "InitializeArray"))); return repl.ToArray(); }); moduleCtx.Context.Registry.GetService().ExcludeMethod(moduleCtx.Context, moduleCtx.InitMethod); } } -} \ No newline at end of file +} diff --git a/Confuser.Protections/Utils.cs b/Confuser.Protections/Utils.cs new file mode 100644 index 000000000..e46f701c1 --- /dev/null +++ b/Confuser.Protections/Utils.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Text; +using System.Threading.Tasks; +using Confuser.Core; +using dnlib.DotNet; + +namespace Confuser.Protections { + internal static class Utils { + public static IMethod Import(this ModuleDef module, ConfuserContext context, Type classType, string method) { + var corLib = context.Resolver.Resolve(context.CurrentModule?.CorLibTypes.AssemblyRef, context.CurrentModule); + var typeInfo = corLib?.ManifestModule.Find(classType.FullName, true); + return (typeInfo == null) ? module.Import(classType.GetMethod(method)) : module.Import(typeInfo.FindMethod(method)); + } + } +}