protected void RegisterAssembly(AssemblyDefinition assembly) { if (assembly == null) throw new ArgumentNullException("assembly"); var name = assembly.Name.FullName; if (cache.ContainsKey(name)) return; cache[name] = assembly; }
public Compilation(AssemblyDefinition mainAssembly) { MainAssembly = mainAssembly; mainAssembly.Compilation = this; Assemblies = new EventBasedCollection<AssemblyDefinition>() { mainAssembly, }; Assemblies.InsertingItem += Assemblies_InsertingItem; Assemblies.InsertedItem += Assemblies_InsertedItem; Assemblies.RemovedItem += Assemblies_RemovedItem; }
public void LoadFrom(FilePath assemblyPath) { FileName = assemblyPath; var tid = Runtime.SystemAssemblyService.GetTargetFrameworkForAssembly(Runtime.SystemAssemblyService.DefaultRuntime, assemblyPath); if (tid != null) { targetFramework = Runtime.SystemAssemblyService.GetTargetFramework(tid); } using (AssemblyDefinition adef = AssemblyDefinition.ReadAssembly(assemblyPath)) { MdbReaderProvider mdbProvider = new MdbReaderProvider(); try { ISymbolReader reader = mdbProvider.GetSymbolReader(adef.MainModule, assemblyPath); adef.MainModule.ReadSymbols(reader); } catch { // Ignore } var files = new HashSet <FilePath> (); foreach (TypeDefinition type in adef.MainModule.Types) { foreach (MethodDefinition met in type.Methods) { if (met.HasBody && met.Body.Instructions != null && met.Body.Instructions.Count > 0) { SequencePoint sp = met.DebugInformation.GetSequencePoint(met.Body.Instructions [0]); if (sp != null) { files.Add(sp.Document.Url); } } } } FilePath rootPath = FilePath.Empty; foreach (FilePath file in files) { AddFile(file, BuildAction.Compile); if (rootPath.IsNullOrEmpty) { rootPath = file.ParentDirectory; } else if (!file.IsChildPathOf(rootPath)) { rootPath = FindCommonRoot(rootPath, file); } } if (!rootPath.IsNullOrEmpty) { BaseDirectory = rootPath; } } /* * foreach (AssemblyNameReference aref in adef.MainModule.AssemblyReferences) { * if (aref.Name == "mscorlib") * continue; * string asm = assemblyPath.ParentDirectory.Combine (aref.Name); * if (File.Exists (asm + ".dll")) * References.Add (new ProjectReference (ReferenceType.Assembly, asm + ".dll")); * else if (File.Exists (asm + ".exe")) * References.Add (new ProjectReference (ReferenceType.Assembly, asm + ".exe")); * else * References.Add (new ProjectReference (ReferenceType.Package, aref.FullName)); * }*/ }
private void WriteModuleTreeMultiFile(Module mod, DirectoryInfo directory, StreamWriter file, string path = null, AssemblyDefinition asm = null) { if (mod.IsEmpty) { return; } const string IMPORTS = "use crate::prelude::*;"; string name = mod.Name.ToLower(); string newPath = path == null ? mod.Name : (path + "." + mod.Name); bool isNewAssembly = (asm != mod.Assembly); if (isNewAssembly && mod.Assembly.Name.Name != "Windows.Foundation") { var featureCond = new FeatureConditions(new string[] { mod.Assembly.Name.Name }).GetAttribute().TrimEnd(); file.Write(featureCond); file.Write(" "); } if (isNewAssembly || path == null || mod.ContainsMoreThanOneAssembly) { // write module to separate file file.WriteLine($"pub mod { name }; // { newPath }"); DirectoryInfo childDir; StreamWriter childFile; if (mod.ContainsMoreThanOneAssembly) { childDir = directory.CreateSubdirectory(name); childFile = new StreamWriter(Path.Combine(childDir.FullName, "mod.rs")); } else { childDir = directory; childFile = new StreamWriter(Path.Combine(childDir.FullName, name + ".rs")); } var text = mod.Text.ToString(); if (!string.IsNullOrWhiteSpace(text)) { childFile.Write(IMPORTS); childFile.WriteLine(text); } foreach (var child in mod.Children.Values) { WriteModuleTreeMultiFile(child, childDir, childFile, newPath, mod.Assembly); } childFile.Close(); } else { // write module inline file.WriteLine($"pub mod { name } {{ // { newPath }"); var text = mod.Text.ToString(); if (!string.IsNullOrWhiteSpace(text)) { file.Write(IMPORTS); file.WriteLine(text); } foreach (var child in mod.Children.Values) { WriteModuleTreeMultiFile(child, directory, file, newPath, mod.Assembly); } file.WriteLine($"}} // { newPath }"); } }
public IEnumerable <TypeDefinition> SelectTypes(AssemblyDefinition testAssembly, IncludeNested includeNested) => testAssembly.SelectTypes(includeNested);
static string GetFullyQualifiedName(AssemblyDefinition assembly) { return(assembly.MainModule.FileName); }
public AssemblyDefinition Resolve(AssemblyNameReference name, ReaderParameters parameters) { return(AssemblyDefinition.ReadAssembly(Find(name))); }
public AssemblyDefinition Resolve(string fullName, ReaderParameters parameters) { return(AssemblyDefinition.ReadAssembly(Find(fullName))); }
static bool Weave(string assName, IEnumerable <string> dependencies, string unityEngineDLLPath, string mirrorNetDLLPath, string outputDir) { using (DefaultAssemblyResolver asmResolver = new DefaultAssemblyResolver()) using (CurrentAssembly = AssemblyDefinition.ReadAssembly(assName, new ReaderParameters { ReadWrite = true, ReadSymbols = true, AssemblyResolver = asmResolver })) { asmResolver.AddSearchDirectory(Path.GetDirectoryName(assName)); asmResolver.AddSearchDirectory(Helpers.UnityEngineDLLDirectoryName()); asmResolver.AddSearchDirectory(Path.GetDirectoryName(unityEngineDLLPath)); asmResolver.AddSearchDirectory(Path.GetDirectoryName(mirrorNetDLLPath)); if (dependencies != null) { foreach (string path in dependencies) { asmResolver.AddSearchDirectory(path); } } SetupTargetTypes(); Readers.Init(CurrentAssembly); Writers.Init(CurrentAssembly); ModuleDefinition moduleDefinition = CurrentAssembly.MainModule; Console.WriteLine("Script Module: {0}", moduleDefinition.Name); // Process each NetworkBehaviour bool didWork = false; // We need to do 2 passes, because SyncListStructs might be referenced from other modules, so we must make sure we generate them first. for (int pass = 0; pass < 2; pass++) { System.Diagnostics.Stopwatch watch = System.Diagnostics.Stopwatch.StartNew(); foreach (TypeDefinition td in moduleDefinition.Types) { if (td.IsClass && td.BaseType.CanBeResolved()) { try { if (pass == 0) { didWork |= CheckSyncList(td); } else { didWork |= CheckNetworkBehaviour(td); didWork |= CheckMessageBase(td); } } catch (Exception ex) { Weaver.Error(ex.ToString()); throw ex; } } if (WeavingFailed) { return(false); } } watch.Stop(); Console.WriteLine("Pass: "******" took " + watch.ElapsedMilliseconds + " milliseconds"); } if (didWork) { // this must be done for ALL code, not just NetworkBehaviours try { PropertySiteProcessor.ProcessSitesModule(CurrentAssembly.MainModule); } catch (Exception e) { Log.Error("ProcessPropertySites exception: " + e); return(false); } if (WeavingFailed) { //Log.Error("Failed phase II."); return(false); } // write to outputDir if specified, otherwise perform in-place write WriterParameters writeParams = new WriterParameters { WriteSymbols = true }; if (outputDir != null) { CurrentAssembly.Write(Helpers.DestinationFileFor(outputDir, assName), writeParams); } else { CurrentAssembly.Write(writeParams); } } } return(true); }
public static void Convert(AssemblyDefinition assembly, IEnumerable<PdbFunction> functions, MonoSymbolWriter mdb) { var converter = new Converter (mdb); foreach (var function in functions) converter.ConvertFunction (function); mdb.WriteSymbolFile(assembly.MainModule.Mvid); converter = null; }
void CheckAssemblyAttributes(AssemblyDefinition assembly, MetadataReader reader, out string targetFrameworkIdentifier) { targetFrameworkIdentifier = null; foreach (var handle in assembly.GetCustomAttributes()) { var attribute = reader.GetCustomAttribute(handle); switch (reader.GetCustomAttributeFullName(attribute)) { case "Java.Interop.DoNotPackageAttribute": { var arguments = attribute.GetCustomAttributeArguments(); if (arguments.FixedArguments.Length > 0) { string file = arguments.FixedArguments [0].Value?.ToString(); if (string.IsNullOrWhiteSpace(file)) { LogError("In referenced assembly {0}, Java.Interop.DoNotPackageAttribute requires non-null file name.", assembly.GetAssemblyName().FullName); } do_not_package_atts.Add(Path.GetFileName(file)); } } break; case "System.Runtime.Versioning.TargetFrameworkAttribute": { var arguments = attribute.GetCustomAttributeArguments(); foreach (var p in arguments.FixedArguments) { // Of the form "MonoAndroid,Version=v8.1" var value = p.Value?.ToString(); if (!string.IsNullOrEmpty(value)) { int commaIndex = value.IndexOf(",", StringComparison.Ordinal); if (commaIndex != -1) { targetFrameworkIdentifier = value.Substring(0, commaIndex); if (targetFrameworkIdentifier == "MonoAndroid") { const string match = "Version="; var versionIndex = value.IndexOf(match, commaIndex, StringComparison.Ordinal); if (versionIndex != -1) { versionIndex += match.Length; string version = value.Substring(versionIndex, value.Length - versionIndex); var apiLevel = MonoAndroidHelper.SupportedVersions.GetApiLevelFromFrameworkVersion(version); if (apiLevel != null) { var assemblyName = reader.GetString(assembly.Name); LogDebugMessage("{0}={1}", assemblyName, apiLevel); api_levels [assemblyName] = apiLevel.Value; } } } } } } } break; default: break; } } }
public void FixtureSetUp () { string unit = Assembly.GetExecutingAssembly ().Location; assembly = AssemblyDefinition.ReadAssembly (unit); }
/// <summary> /// Modifies all the types in an assembly using the given type weaver. /// </summary> /// <param name="targetAssembly">The target assembly to be modified.</param> /// <param name="weaver">The weaver that will perform the modification.</param> public static void WeaveWith(this AssemblyDefinition targetAssembly, ITypeWeaver weaver) { WeaveWith(targetAssembly, weaver, _ => true); }
/// <summary> /// Modifies all the methods in an assembly using the given method weaver. /// </summary> /// <param name="targetAssembly">The target assembly to be modified.</param> /// <param name="weaver">The weaver that will perform the modification.</param> public static void WeaveWith(this AssemblyDefinition targetAssembly, IMethodWeaver weaver) { Func <MethodReference, bool> defaultFilter = m => m.IsDefinition; WeaveWith(targetAssembly, weaver, defaultFilter); }
public void SetDeclaringAssembly (AssemblyDefinition assembly) { // TODO: This setter is quite ugly but I have not found a way around it yet this.assembly = assembly; }
public static string GetIdentity(AssemblyDefinition ad) { return(Path.GetFileNameWithoutExtension(ad.MainModule.FileName)); }
public ConnectMethodDecompiler(AssemblyDefinition assembly) { this.assembly = assembly; }
/// <summary> /// Executes the bundled PEVerify executable on the specified assembly by first serializing it to file. PEVerify is an unmanaged, Windows-only application. /// </summary> /// <param name="targetAssembly">The assembly on which to run PEVerify.</param> /// <param name="input">The arguments with which to run PEVerify and process its output.</param> /// <returns></returns> public static PEVerifyOutput RunPeVerify(AssemblyDefinition targetAssembly, PEVerifyInput input) { var matchMdTokens = new Regex(@"\[(mdToken=|token:)0x(?<token> [0-9a-f]* ) \]", RegexOptions.IgnorePatternWhitespace | RegexOptions.ExplicitCapture | RegexOptions.IgnoreCase); var tempName = Guid.NewGuid().ToString(); var tempPath = Path.Combine(input.AssemblyResolutionFolder, tempName); var matchErrorCount = new Regex($@"(?<count>\d+) Error\(s\) Verifying {tempName}", RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture); try { //PEVerify is in the same folder as Patchwork, not the directory. targetAssembly.Write(tempPath); var info = new ProcessStartInfo() { UseShellExecute = false, FileName = PEVerifyLocation, RedirectStandardOutput = true, CreateNoWindow = true, WorkingDirectory = input.AssemblyResolutionFolder ?? Environment.CurrentDirectory, Arguments = $"{input.Switches} /ignore={input.IgnoreErrors.Select(x => x.ToString("X")).Join(",")} \"{tempPath}\"" }; string ret; using (var process = Process.Start(info)) { ret= process.StandardOutput.ReadToEnd().Replace(tempPath, targetAssembly.Name.Name); } var ass = AssemblyCache.Default.ReadAssembly(tempPath); if (input.ExpandMetadataTokens) { ret = matchMdTokens.Replace(ret, match => { var token = match.Groups["token"].Value; var tokenNumber = Convert.ToUInt32(token, 16); var tk = new MetadataToken(tokenNumber); var provider = (MemberReference) ass.MainModule.LookupTokenExtended(tk); var providerName = provider?.UserFriendlyName() ?? ""; var informativeFormat = $@"[{providerName}, 0x{token}]"; return informativeFormat; //return match.Value; }); } var countCapture = matchErrorCount.Match(ret).Groups["count"]; int errorCount; if (countCapture.Success) { if (!int.TryParse(countCapture.Value, out errorCount)) { errorCount = -1; } } else { errorCount = 0; } return new PEVerifyOutput() { Output = ret, ErrorCount = errorCount }; } finally { File.Delete(tempPath); } }
public void CheckSkipSerializableTypes() { string name = "AssemblyWithTypesAttrs3"; string xml = string.Format( @"<?xml version='1.0'?>" + @"<Obfuscator>" + @" <Var name='InPath' value='{0}' />" + @" <Var name='OutPath' value='{1}' />" + @" <Var name='KeepPublicApi' value='false' />" + @" <Var name='HidePrivateApi' value='true' />" + @" <Var name='SkipSerializableTypes' value='true' />" + @" <Module file='$(InPath){2}{3}.dll' />" + @"</Obfuscator>", TestHelper.InputPath, TestHelper.OutputPath, Path.DirectorySeparatorChar, name); var obfuscator = TestHelper.BuildAndObfuscate(name, string.Empty, xml); var map = obfuscator.Mapping; AssemblyDefinition inAssmDef = AssemblyDefinition.ReadAssembly(obfuscator.Project.AssemblyList[0].FileName); TypeDefinition classAType = inAssmDef.MainModule.GetType("TestClasses.TestEnum"); ObfuscatedThing classA = map.GetClass(new TypeKey(classAType)); Assert.Equal(ObfuscationStatus.Renamed, classA.Status); var enumField = classAType.Fields.FirstOrDefault(item => item.Name == "Default"); var f1 = map.GetField(new FieldKey(enumField)); Assert.Equal(ObfuscationStatus.Renamed, f1.Status); var enumField2 = classAType.Fields.FirstOrDefault(item => item.Name == "Test"); var f2 = map.GetField(new FieldKey(enumField2)); Assert.Equal(ObfuscationStatus.Renamed, f2.Status); TypeDefinition classBType = inAssmDef.MainModule.GetType("TestClasses.PublicClass"); var classBTypeKey = new TypeKey(classBType); ObfuscatedThing classB = map.GetClass(classBTypeKey); Assert.Equal(ObfuscationStatus.Skipped, classB.Status); var classBmethod1 = FindMethod(classBType, "PublicMethod"); var method1 = map.GetMethod(new MethodKey(classBmethod1)); Assert.Equal(ObfuscationStatus.Renamed, method1.Status); var classBproperty1 = FindProperty(classBType, "TestInt"); var property1 = map.GetProperty(new PropertyKey(classBTypeKey, classBproperty1)); Assert.Equal(ObfuscationStatus.Skipped, property1.Status); var classBfield1 = FindField(classBType, "TestSerializedField"); var field1 = map.GetField(new FieldKey(classBfield1)); Assert.Equal(ObfuscationStatus.Skipped, field1.Status); var classBfield2 = FindField(classBType, "TestNonSerializedField"); var field2 = map.GetField(new FieldKey(classBfield2)); Assert.Equal(ObfuscationStatus.Renamed, field2.Status); }
public void Create (AssemblyDefinition assembly, ModuleBuilder moduleBuilder) { this.assembly = assembly; builder = moduleBuilder; }
public void CheckExclusion() { string xml = string.Format( @"<?xml version='1.0'?>" + @" <Obfuscator>"+ @" <Var name='InPath' value='{0}' />"+ @" <Var name='OutPath' value='{1}' />"+ @" <Var name='HidePrivateApi' value='true' />" + @" <Module file='$(InPath){2}AssemblyWithTypesAttrs.dll'>"+ @" </Module>"+ @" </Obfuscator>", TestHelper.InputPath, TestHelper.OutputPath, Path.DirectorySeparatorChar); var obfuscator = TestHelper.BuildAndObfuscate("AssemblyWithTypesAttrs", string.Empty, xml); var map = obfuscator.Mapping; const string assmName = "AssemblyWithTypesAttrs.dll"; AssemblyDefinition inAssmDef = AssemblyDefinition.ReadAssembly( Path.Combine(TestHelper.InputPath, assmName)); { TypeDefinition classAType = inAssmDef.MainModule.GetType("TestClasses.InternalClass"); ObfuscatedThing classA = map.GetClass(new TypeKey(classAType)); var classAmethod1 = FindMethod(classAType, "PublicMethod"); var method = map.GetMethod(new MethodKey(classAmethod1)); TypeDefinition nestedClassAType = classAType.NestedTypes[0]; ObfuscatedThing nestedClassA = map.GetClass(new TypeKey(nestedClassAType)); TypeDefinition nestedClassAType2 = nestedClassAType.NestedTypes[0]; ObfuscatedThing nestedClassA2 = map.GetClass(new TypeKey(nestedClassAType2)); Assert.True(classA.Status == ObfuscationStatus.Skipped, "InternalClass shouldn't have been obfuscated."); Assert.True(method.Status == ObfuscationStatus.Skipped, "PublicMethod shouldn't have been obfuscated"); Assert.True(nestedClassA.Status == ObfuscationStatus.Skipped, "Nested class shouldn't have been obfuscated"); Assert.True(nestedClassA2.Status == ObfuscationStatus.Skipped, "Nested class shouldn't have been obfuscated"); } { TypeDefinition classAType = inAssmDef.MainModule.GetType("TestClasses.InternalClass3"); ObfuscatedThing classA = map.GetClass(new TypeKey(classAType)); var classAmethod1 = FindMethod(classAType, "PublicMethod"); var method = map.GetMethod(new MethodKey(classAmethod1)); TypeDefinition nestedClassAType = classAType.NestedTypes[0]; ObfuscatedThing nestedClassA = map.GetClass(new TypeKey(nestedClassAType)); TypeDefinition nestedClassAType2 = nestedClassAType.NestedTypes[0]; ObfuscatedThing nestedClassA2 = map.GetClass(new TypeKey(nestedClassAType2)); Assert.True(classA.Status == ObfuscationStatus.Skipped, "InternalClass shouldn't have been obfuscated."); Assert.True(method.Status == ObfuscationStatus.Renamed, "PublicMethod should have been obfuscated"); Assert.True(nestedClassA.Status == ObfuscationStatus.Renamed, "Nested class should have been obfuscated"); Assert.True(nestedClassA2.Status == ObfuscationStatus.Renamed, "Nested class should have been obfuscated"); } TypeDefinition classBType = inAssmDef.MainModule.GetType("TestClasses.PublicClass"); ObfuscatedThing classB = map.GetClass(new TypeKey(classBType)); var classBmethod1 = FindMethod(classBType, "PublicMethod"); var method2 = map.GetMethod(new MethodKey(classBmethod1)); Assert.True(classB.Status == ObfuscationStatus.Renamed, "PublicClass should have been obfuscated."); Assert.True(method2.Status == ObfuscationStatus.Renamed, "PublicMethod should have been obfuscated."); TypeDefinition classCType = inAssmDef.MainModule.GetType("TestClasses.InternalClass2"); ObfuscatedThing classC = map.GetClass(new TypeKey(classCType)); var classCmethod1 = FindMethod(classCType, "PublicMethod"); var method1 = map.GetMethod(new MethodKey(classCmethod1)); TypeDefinition nestedClassBType = classCType.NestedTypes[0]; ObfuscatedThing nestedClassB = map.GetClass(new TypeKey(nestedClassBType)); TypeDefinition nestedClassBType2 = nestedClassBType.NestedTypes[0]; ObfuscatedThing nestedClassB2 = map.GetClass(new TypeKey(nestedClassBType2)); Assert.True(classC.Status == ObfuscationStatus.Renamed, "InternalClass2 should have been obfuscated."); Assert.True(method1.Status == ObfuscationStatus.Skipped, "PublicMethod shouldn't have been obfuscated."); Assert.True(nestedClassB.Status == ObfuscationStatus.Renamed, "Nested class should have been obfuscated"); Assert.True(nestedClassB2.Status == ObfuscationStatus.Renamed, "Nested class should have been obfuscated"); TypeDefinition classDType = inAssmDef.MainModule.GetType("TestClasses.PublicClass2"); ObfuscatedThing classD = map.GetClass(new TypeKey(classDType)); var classDmethod1 = FindMethod(classDType, "PublicMethod"); var method3 = map.GetMethod(new MethodKey(classDmethod1)); Assert.True(classD.Status == ObfuscationStatus.Skipped, "PublicClass2 shouldn't have been obfuscated."); Assert.True(method3.Status == ObfuscationStatus.Renamed, "PublicMethod should have been obfuscated."); }
public AssemblyDefinition Resolve(string fullName) { return(AssemblyDefinition.ReadAssembly(Find(fullName))); }
public static TypeDefinition FindMatchingType(AssemblyDefinition adef, ITypeDefinition ictdef) { return(adef.MainModule.GetTypes().FirstOrDefault(t => t.FullName == ictdef.FullName)); }
public TypeDefinition GetType(AssemblyDefinition testAssembly, string typeName) => testAssembly.MainModule.GetType(typeName);
public static AssemblyNameReference FindMatchingAssemblyReference(AssemblyDefinition adef, object item) { return(adef.MainModule.AssemblyReferences.FirstOrDefault(p => p.ToString() == item.ToString())); }
public static void Inject(string[] args) { bool args_help = false; string dll_inject_to = null; string dll_hooker_at = null; string nameof_hooker = null; string method_name_b = null; string method_name_e = null; List <string> type_blacklist = new List <string>(); List <string> type_whitelist = new List <string>(); List <string> method_blacklist = new List <string>(); List <string> method_whitelist = new List <string>(); bool inject_getter = false; bool inject_setter = false; string finale_dll_suffix = ".ddd"; var options = new OptionSet { { "h|help", "show this message and exit", h => args_help = h != null }, { "t|dll_inject_to=", "被注入的DLL文件路径", t => dll_inject_to = t }, { "a|dll_hooker_at=", "钩子所在DLL文件路径", a => dll_hooker_at = a }, { "nameof_hooker=", "钩子完全类型名", noh => nameof_hooker = noh }, { "method_name_b=", "钩子方法名(前置)", mnb => method_name_b = mnb }, { "method_name_e=", "钩子方法名(后置)", mne => method_name_e = mne }, { "type_blacklist=", "被注入类型黑名单", s => type_blacklist.Add(s) }, { "type_whitelist=", "被注入类型白名单", s => type_whitelist.Add(s) }, { "method_blacklist=", "被注入方法黑名单", s => method_blacklist.Add(s) }, { "method_whitelist=", "被注入方法白名单", s => method_whitelist.Add(s) }, { "inject_getter", "要注入getter方法", s => inject_getter = s != null }, { "inject_setter", "要注入setter方法", s => inject_setter = s != null }, { "finale_dll_suffix=", "", s => finale_dll_suffix = s }, }; List <string> extra; try { extra = options.Parse(args); } catch (Exception) { Console.WriteLine("Oops...参数解析错误\n\n"); options.WriteOptionDescriptions(Console.Out); return; } if (args_help) { options.WriteOptionDescriptions(Console.Out); return; } if (null == dll_inject_to || "" == dll_inject_to) { Console.WriteLine($"Oops...请指定被注入的DLL文件路径"); return; } if (!File.Exists(dll_inject_to)) { Console.WriteLine($"Oops...被注入的DLL文件 \"{dll_inject_to}\" 不存在"); return; } if (null == dll_hooker_at || "" == dll_hooker_at) { Console.WriteLine($"Oops...请指定钩子所在DLL文件路径"); return; } if (!File.Exists(dll_hooker_at)) { Console.WriteLine($"Oops...钩子所在DLL文件路径 \"{dll_hooker_at}\" 不存在"); return; } if (null == nameof_hooker || "" == nameof_hooker) { Console.WriteLine($"Oops...请指定钩子完全类型名"); return; } if (null == method_name_b || "" == method_name_b) { Console.WriteLine($"Oops...钩子方法名(前置)"); return; } if (null == method_name_e || "" == method_name_e) { Console.WriteLine($"Oops...钩子方法名(后置)"); return; } var assembly_hooker_at = Assembly.LoadFrom(dll_hooker_at); var typeof_hooker = assembly_hooker_at.GetType(nameof_hooker); if (null == typeof_hooker) { Console.WriteLine($"Oops...钩子类型 \"{nameof_hooker}\" 不存在"); return; } // var rp = new ReaderParameters(ReadingMode.Immediate); // rp.ReadWrite = true; // rp.InMemory = true; var assembly_inject_to = AssemblyDefinition.ReadAssembly(dll_inject_to); var types_inject_to = assembly_inject_to.MainModule.GetTypes(); foreach (var type_inject_to in types_inject_to) { if (type_blacklist.Contains(type_inject_to.FullName) || nameof_hooker.Equals(type_inject_to.FullName)) { continue; } if (0 < type_whitelist.Count && !type_whitelist.Contains(type_inject_to.FullName)) { continue; } foreach (var method_inject_to in type_inject_to.Methods) { if (method_inject_to.IsConstructor || method_inject_to.IsAbstract || method_inject_to.IsVirtual || (!inject_getter && method_inject_to.IsGetter) || (!inject_setter && method_inject_to.IsSetter) || method_inject_to.IsPInvokeImpl) { continue; } if (method_blacklist.Contains(method_inject_to.Name)) { continue; } if (0 < method_whitelist.Count && !method_whitelist.Contains(method_inject_to.Name)) { continue; } Console.WriteLine("Injecting to " + type_inject_to.Name + "." + method_inject_to.Name); InjectMethod(method_inject_to, assembly_inject_to, typeof_hooker, method_name_b, new Type[] { typeof(string) }, typeof_hooker, method_name_e, new Type[] { typeof(string) }); } } // var wp = new WriterParameters(); // wp.WriteSymbols = true; assembly_inject_to.Write(dll_inject_to + finale_dll_suffix); Console.WriteLine("Finale DLL wrote to " + dll_inject_to + finale_dll_suffix); }
public static Resource FindMatchingResource(AssemblyDefinition adef, IResource item) { return(adef.MainModule.Resources.FirstOrDefault(p => p.Name == item.Name)); }
protected override void ProcessAssembly(AssemblyDefinition assembly) { ProcessReferences(assembly); }
public void Read(string typeName, string assemblyPath, uint format) { AssemblyDefinition asmDef = GetAssemblyWithDependencies(assemblyPath); Read(typeName, asmDef, format); }
public override bool Execute() { using var stream = File.Open(Input, FileMode.Open, FileAccess.ReadWrite); var resolver = new DefaultAssemblyResolver(); var obfuscatedAssembly = AssemblyDefinition.ReadAssembly(Path.Combine(AmongUs, "BepInEx", "unhollowed", "Assembly-CSharp.dll")); var referencedAssemblies = ReferencedAssemblies.Select(AssemblyDefinition.ReadAssembly).ToArray(); resolver.ResolveFailure += (_, reference) => { foreach (var referencedAssembly in referencedAssemblies) { if (referencedAssembly.Name.FullName == reference.FullName) { return(referencedAssembly); } } if (reference.FullName == obfuscatedAssembly.Name.FullName) { return(obfuscatedAssembly); } return(null); }; using var moduleDefinition = ModuleDefinition.ReadModule(stream, new ReaderParameters { AssemblyResolver = resolver }); var toObfuscate = new Dictionary <MemberReference, string>(); foreach (var type in moduleDefinition.GetTypeReferences()) { var typeDefinition = type.Resolve(); if (typeDefinition == null) { Log.LogWarning($"Unresolved type reference: {type.FullName}, {type.Scope}"); continue; } var obfuscated = GetObfuscated(typeDefinition); if (obfuscated != null) { toObfuscate[type] = obfuscated; } } foreach (var member in moduleDefinition.GetMemberReferences()) { var memberDefinition = member.Resolve(); if (memberDefinition == null) { Log.LogWarning($"Unresolved member reference: {member.FullName}, {member.DeclaringType.Scope}"); continue; } var obfuscated = GetObfuscated(memberDefinition); if (obfuscated != null) { toObfuscate[member] = obfuscated; } } var customAttributeProviders = new List <ICustomAttributeProvider>(); foreach (var type in moduleDefinition.GetAllTypes()) { customAttributeProviders.Add(type); customAttributeProviders.AddRange(type.Events); customAttributeProviders.AddRange(type.Fields); customAttributeProviders.AddRange(type.Methods); customAttributeProviders.AddRange(type.Properties); } foreach (var customAttributeProvider in customAttributeProviders) { void ReobfuscateType(TypeReference t) { while (t != null) { var obfuscated = GetObfuscated(t.Resolve()); if (obfuscated != null) { toObfuscate[t] = obfuscated; } t = t.DeclaringType; } } foreach (var customAttribute in customAttributeProvider.CustomAttributes) { TypeReference lastType = null; foreach (var argument in customAttribute.ConstructorArguments.ToList()) { if (argument.Type.FullName == "System.Type[]") { foreach (var nestedArgument in (CustomAttributeArgument[])argument.Value) { if (nestedArgument.Type.FullName == "System.Type") { ReobfuscateType((TypeReference)nestedArgument.Value); } } } else if (argument.Type.FullName == "System.Type") { lastType = (TypeReference)argument.Value; ReobfuscateType(lastType); } else { // obfuscate nameof if (argument.Type.FullName == "System.String" && lastType != null) { var value = (string)argument.Value; var lastTypeDef = lastType.Resolve(); IMemberDefinition member = null; var field = lastTypeDef.Fields.SingleOrDefault(x => x.Name == value); if (field != null) { member = field; } var method = lastTypeDef.Methods.FirstOrDefault(x => x.Name == value); if (method != null) { member = method; } var property = lastTypeDef.Properties.SingleOrDefault(x => x.Name == value); if (property != null) { member = property; } if (member != null) { var obfuscated = GetObfuscated(member); if (obfuscated != null) { customAttribute.ConstructorArguments[customAttribute.ConstructorArguments.IndexOf(argument)] = new CustomAttributeArgument(argument.Type, obfuscated); } } } lastType = null; } } } } // fix generic methods foreach (var methodDefinition in moduleDefinition.GetAllTypes().SelectMany(x => x.Methods)) { if (!methodDefinition.HasBody) { continue; } foreach (var instruction in methodDefinition.Body.Instructions) { if (instruction.Operand is MethodReference deobfuscatedCallReference) { var deobfuscatedCall = deobfuscatedCallReference.Resolve(); if (deobfuscatedCall == null) { continue; } var obfuscated = GetObfuscated(deobfuscatedCall); if (obfuscated != null) { // get same type from obfuscated assembly var hierarchy = new List <TypeDefinition>(); var type = deobfuscatedCall.DeclaringType; while (type != null) { hierarchy.Insert(0, type); type = type.DeclaringType; } var typeDefinition = obfuscatedAssembly.MainModule.GetType(GetObfuscated(hierarchy.First()) ?? hierarchy.First().FullName); foreach (var element in hierarchy.Skip(1)) { typeDefinition = typeDefinition.NestedTypes.Single(x => x.Name == (GetObfuscated(element) ?? element.Name)); } // get same method from obfuscated assembly var signature = deobfuscatedCall.GetSignature(t => GetObfuscated(t) ?? t.FullName); MethodReference definition = typeDefinition.GetMethods().Single(x => x.Name == obfuscated && x.GetSignature() == signature); // obfuscate generics if (deobfuscatedCallReference is GenericInstanceMethod generic) { var genericDefinition = new GenericInstanceMethod(definition); definition = genericDefinition; foreach (var parameter in generic.GenericArguments) { var resolved = parameter.Resolve(); if (resolved != null) { var s = GetObfuscated(resolved); if (s != null) { parameter.Name = s; } } genericDefinition.GenericArguments.Add(parameter); } } instruction.Operand = deobfuscatedCallReference.Module.ImportReference(definition); } } } } foreach (var pair in toObfuscate) { pair.Key.Name = pair.Value; } foreach (var typeReference in moduleDefinition.GetTypeReferences()) { typeReference.Module.Name = typeReference.Module.Name.Replace(postfix, string.Empty); typeReference.Scope.Name = typeReference.Scope.Name.Replace(postfix, string.Empty); } foreach (var memberReference in moduleDefinition.GetMemberReferences()) { memberReference.Module.Name = memberReference.Module.Name.Replace(postfix, string.Empty); memberReference.DeclaringType.Scope.Name = memberReference.DeclaringType.Scope.Name.Replace(postfix, string.Empty); } var outputDirectory = Path.Combine(Path.GetDirectoryName(Input), "reobfuscated"); Directory.CreateDirectory(outputDirectory); moduleDefinition.Write(Path.Combine(outputDirectory, Path.GetFileNameWithoutExtension(Input) + $"-{Context.GameVersion}.dll")); return(true); }
/// <summary> /// Gets cloners for the given source item. /// </summary> /// <param name="item">Item to get cloners for.</param> /// <returns>Cloners for the <paramref name="item"/>.</returns> protected override IReadOnlyCollection <ICloner <object, object> > InvokeForItem(AssemblyDefinition item) { return(new ICloner <object, object> [0]); }
protected bool SeenFirstTime(AssemblyDefinition assembly) { return(!_annotations.HasAction(assembly)); }
public void ReadFromFile(string fileName) { dataFileName = fileName; namespaces = new Hashtable(); classes = new Hashtable(); long begin = DateTime.Now.Ticks / 10000; long msec = DateTime.Now.Ticks / 10000; long msec2; loadedAssemblies = new Hashtable(); symbolFiles = new Hashtable(); XmlDocument dom = new XmlDocument(); Progress("XML reading", 0); Console.Write("Loading " + fileName + "..."); dom.Load(new XmlTextReader(new FileStream(fileName, FileMode.Open))); Console.WriteLine(" Done."); msec2 = DateTime.Now.Ticks / 10000; Console.WriteLine("XML Reading: " + (msec2 - msec) + " msec"); msec = msec2; Progress("Load assemblies", 0.2); LoadAssemblies(dom); LoadFilters(dom); msec2 = DateTime.Now.Ticks / 10000; Console.WriteLine("Load assemblies: " + (msec2 - msec) + " msec"); msec = msec2; Progress("Load methods", 0.4); foreach (XmlNode n in dom.GetElementsByTagName("method")) { string assemblyName = n.Attributes ["assembly"].Value; string className = n.Attributes ["class"].Value; string methodName = n.Attributes ["name"].Value; string token = n.Attributes ["token"].Value; string cov_info = n.FirstChild.Value; int itok = int.Parse(token); #if USE_REFLECTION Assembly assembly = (Assembly)loadedAssemblies [assemblyName]; MonoSymbolFile symbolFile = (MonoSymbolFile)symbolFiles [assembly]; if (symbolFile == null) { continue; } Type t = LoadType(assembly, className); if (t == null) { Console.WriteLine("ERROR: Unable to resolve type " + className + " in " + assembly); continue; } ClassCoverageItem klass = ProcessClass(t); MethodEntry entry = symbolFile.GetMethodByToken(Int32.Parse(token)); Module[] modules = assembly.GetModules(); if (modules.Length > 1) { Console.WriteLine("WARNING: Assembly had more than one module. Using the first."); } Module module = modules[0]; MethodBase monoMethod = module.ResolveMethod(Int32.Parse(token)); ProcessMethod(monoMethod, entry, klass, methodName, cov_info); #else if ((TokenType)(itok & 0xff000000) != TokenType.Method) { continue; } AssemblyDefinition assembly = (AssemblyDefinition)loadedAssemblies [assemblyName]; MonoSymbolFile symbolFile = (MonoSymbolFile)symbolFiles [assembly]; if (symbolFile == null) { continue; } TypeDefinition t = LoadType(assembly, className); if (t == null) { Console.WriteLine("ERROR: Unable to resolve type " + className + " in " + assembly); continue; } ClassCoverageItem klass = ProcessClass(t); MethodEntry entry = symbolFile.GetMethodByToken(itok); MethodDefinition monoMethod = assembly.MainModule.LookupToken( new MetadataToken((TokenType)(itok & 0xff000000), (uint)(itok & 0xffffff))) as MethodDefinition; //Console.WriteLine (monoMethod); ProcessMethod(monoMethod, entry, klass, methodName, cov_info); #endif } msec2 = DateTime.Now.Ticks / 10000; Console.WriteLine("Process methods: " + (msec2 - msec) + " msec"); msec = msec2; // Add info for klasses for which we have no coverage #if USE_REFLECTION foreach (Assembly assembly in loadedAssemblies.Values) { foreach (Type t in assembly.GetTypes()) { ProcessClass(t); } } // Add info for methods for which we have no coverage foreach (ClassCoverageItem klass in classes.Values) { foreach (MethodInfo mb in klass.type.GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly)) { MonoSymbolFile symbolFile = (MonoSymbolFile)symbolFiles [klass.type.Assembly]; if (symbolFile == null) { continue; } if (!klass.methodsByMethod.ContainsKey(mb)) { MethodEntry entry = symbolFile.GetMethod(mb); ProcessMethod(mb, entry, klass, mb.Name, null); } } } #else Progress("Not covered classes", 0.6); foreach (AssemblyDefinition assembly in loadedAssemblies.Values) { foreach (TypeDefinition t in assembly.MainModule.Types) { ProcessClass(t); } } Progress("Not covered methods", 0.7); // Add info for methods for which we have no coverage foreach (ClassCoverageItem klass in classes.Values) { foreach (MethodDefinition mb in klass.type.Methods) { MonoSymbolFile symbolFile = (MonoSymbolFile)symbolFiles [klass.type.Module.Assembly]; if (symbolFile == null) { continue; } if (!klass.methodsByMethod.ContainsKey(mb)) { MethodEntry entry = symbolFile.GetMethodByToken((int)mb.MetadataToken.ToUInt32()); ProcessMethod(mb, entry, klass, mb.Name, null); } } } #endif msec2 = DateTime.Now.Ticks / 10000; Console.WriteLine("Additional classes: " + (msec2 - msec) + " msec"); msec = msec2; Progress("Compute coverage", 0.9); // Compute coverage for all items computeCoverage(true); msec2 = DateTime.Now.Ticks / 10000; Console.WriteLine("Compute coverage: " + (msec2 - msec) + " msec"); msec = msec2; Console.WriteLine("All: " + (msec2 - begin) + " msec"); Progress("Done loading", 0.9); // Free memory symbolFiles = null; }
public bool TryGetValue(AssemblyDefinition asm, out Assembly assembly) { return(HashedAssemblies.TryGetValue(Assembly.GetIdentity(asm), out assembly)); }
void Register (AssemblyDefinition assembly) { assemblies [assembly.Name.Name] = assembly; RegisterAssembly (assembly); }
public static void FindAllAssemblyScripts(AssemblyDefinition.UnityAssembly assemblyId) { var editor = false; var firstPass = false; var pattern = ""; switch (assemblyId) { case AssemblyDefinition.UnityAssembly.CSharpFirstPass: case AssemblyDefinition.UnityAssembly.UnityScriptFirstPass: case AssemblyDefinition.UnityAssembly.BooFirstPass: case AssemblyDefinition.UnityAssembly.CSharpEditorFirstPass: case AssemblyDefinition.UnityAssembly.UnityScriptEditorFirstPass: case AssemblyDefinition.UnityAssembly.BooEditorFirstPass: firstPass = true; break; } switch (assemblyId) { case AssemblyDefinition.UnityAssembly.CSharpFirstPass: case AssemblyDefinition.UnityAssembly.CSharpEditorFirstPass: case AssemblyDefinition.UnityAssembly.CSharp: case AssemblyDefinition.UnityAssembly.CSharpEditor: pattern = ".cs"; break; case AssemblyDefinition.UnityAssembly.UnityScriptFirstPass: case AssemblyDefinition.UnityAssembly.UnityScriptEditorFirstPass: case AssemblyDefinition.UnityAssembly.UnityScript: case AssemblyDefinition.UnityAssembly.UnityScriptEditor: pattern = ".js"; break; case AssemblyDefinition.UnityAssembly.BooFirstPass: case AssemblyDefinition.UnityAssembly.BooEditorFirstPass: case AssemblyDefinition.UnityAssembly.Boo: case AssemblyDefinition.UnityAssembly.BooEditor: pattern = ".boo"; break; } switch (assemblyId) { case AssemblyDefinition.UnityAssembly.CSharpEditorFirstPass: case AssemblyDefinition.UnityAssembly.UnityScriptEditorFirstPass: case AssemblyDefinition.UnityAssembly.BooEditorFirstPass: case AssemblyDefinition.UnityAssembly.CSharpEditor: case AssemblyDefinition.UnityAssembly.UnityScriptEditor: case AssemblyDefinition.UnityAssembly.BooEditor: editor = true; break; } //var scripts = FindAssets("t:MonoScript"); var scripts = Directory.GetFiles("Assets", "*" + pattern, SearchOption.AllDirectories); var count = scripts.Length; if (assets == null) assets = new List<string>(count); bool isUnity_5_2_1p4_orNewer = true; #if UNITY_4_0 || UNITY_4_1 || UNITY_4_2 || UNITY_4_3 || UNITY_4_5 || UNITY_4_6 || UNITY_4_7 || UNITY_5_0 || UNITY_5_1 || UNITY_5_2 isUnity_5_2_1p4_orNewer = Application.unityVersion.StartsWith("5.2.1p") && int.Parse(Application.unityVersion.Substring("5.2.1p".Length)) >= 4; #endif for (var i = count; i --> 0; ) { var path = scripts[i]; scripts[i] = path = path.Replace('\\', '/'); string lowerPath = path.ToLowerInvariant(); if (path.Contains("/.") || lowerPath.StartsWith("assets/webplayertemplates/", System.StringComparison.Ordinal)) { scripts[i] = scripts[--count]; continue; } scripts[i] = AssetDatabase.AssetPathToGUID(scripts[i]); var extension = Path.GetExtension(lowerPath); if (extension != pattern) { scripts[i] = scripts[--count]; continue; } var isFirstPass = lowerPath.StartsWith("assets/standard assets/", System.StringComparison.Ordinal) || lowerPath.StartsWith("assets/pro standard assets/", System.StringComparison.Ordinal) || lowerPath.StartsWith("assets/plugins/", System.StringComparison.Ordinal); if (firstPass != isFirstPass) { scripts[i] = scripts[--count]; continue; } var isEditor = false; if (isFirstPass && !isUnity_5_2_1p4_orNewer) isEditor = lowerPath.StartsWith("assets/plugins/editor/", System.StringComparison.Ordinal) || lowerPath.StartsWith("assets/standard assets/editor/", System.StringComparison.Ordinal) || lowerPath.StartsWith("assets/pro standard assets/editor/", System.StringComparison.Ordinal); else isEditor = lowerPath.Contains("/editor/"); if (editor != isEditor) { scripts[i] = scripts[--count]; continue; } assets.Add(scripts[i]); } //var joined = string.Join(", ", scripts, 0, count); //Debug.Log(joined); }
public AssemblyDefinition Resolve(AssemblyNameReference name) { return(AssemblyDefinition.ReadAssembly(Find(name))); }
private void LoadAssemblies(XmlDocument dom) { foreach (XmlNode n in dom.GetElementsByTagName("assembly")) { string assemblyName = n.Attributes ["name"].Value; string guid = n.Attributes ["guid"].Value; string filename = n.Attributes ["filename"].Value; MonoSymbolFile symbolFile; if (!File.Exists(filename)) { string newFilename = Path.Combine(Path.GetDirectoryName(dataFileName), Path.GetFileName(filename)); if (File.Exists(newFilename)) { filename = newFilename; } } #if USE_REFLECTION Assembly assembly = Assembly.Load(assemblyName); MethodInfo getguid = typeof(Module).GetMethod( "Mono_GetGuid", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, CallingConventions.Any, new Type [0], null); if (getguid != null) { Guid assembly_guid = (Guid)getguid.Invoke(assembly.GetLoadedModules()[0], new object [0]); Console.WriteLine(assembly_guid); if (assembly_guid != new Guid(guid)) { Console.WriteLine("WARNING: Loaded version of assembly " + assembly + " is different from the version used to collect coverage data."); } } else { Console.WriteLine("WARNING: Can't verify the guid of " + assembly); } loadedAssemblies [assemblyName] = assembly; Console.Write("Reading symbols for " + assembly + " ..."); symbolFile = MonoSymbolFile.ReadSymbolFile(assembly); if (symbolFile == null) { Console.WriteLine(" (No symbols found)"); } else { symbolFiles [assembly] = symbolFile; Console.WriteLine(" (" + symbolFile.SourceCount + " files, " + symbolFile.MethodCount + " methods)"); } #else var assembly = AssemblyDefinition.ReadAssembly(filename); ModuleDefinition module = assembly.MainModule; if (module.Mvid != new Guid(guid)) { Console.WriteLine("WARNING: Loaded version of assembly " + assembly + " is different from the version used to collect coverage data."); } loadedAssemblies [assemblyName] = assembly; Console.Write("Reading symbols for " + assemblyName + " ..."); symbolFile = MonoSymbolFile.ReadSymbolFile(filename + ".mdb"); if (symbolFile == null) { Console.WriteLine(" (No symbols found)"); } else { symbolFiles [assembly] = symbolFile; Console.WriteLine(" (" + symbolFile.SourceCount + " files, " + symbolFile.MethodCount + " methods)"); } #endif } }
/// <summary> /// Remove the Strong Name of the given assembly /// </summary> /// <param name="asmdef">Strong Name assembly</param> public static void RemoveStrongName(AssemblyDefinition asmdef) { asmdef.Name.PublicKey = new byte[0]; asmdef.Name.PublicKeyToken = new byte[0]; asmdef.Name.Attributes = AssemblyAttributes.SideBySideCompatible; asmdef.MainModule.Attributes &= ~ModuleAttributes.StrongNameSigned; }