AOTAssemblyMetadataStripper.cs 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. using dnlib.DotNet;
  2. using dnlib.DotNet.Writer;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.IO;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. namespace HybridCLR.Editor.AOT
  10. {
  11. public class AOTAssemblyMetadataStripper
  12. {
  13. public static byte[] Strip(byte[] assemblyBytes)
  14. {
  15. var context = ModuleDef.CreateModuleContext();
  16. var readerOption = new ModuleCreationOptions(context)
  17. {
  18. Runtime = CLRRuntimeReaderKind.Mono
  19. };
  20. var mod = ModuleDefMD.Load(assemblyBytes, readerOption);
  21. // remove all resources
  22. mod.Resources.Clear();
  23. foreach (var type in mod.GetTypes())
  24. {
  25. if (type.HasGenericParameters)
  26. {
  27. continue;
  28. }
  29. foreach (var method in type.Methods)
  30. {
  31. if (!method.HasBody || method.HasGenericParameters)
  32. {
  33. continue;
  34. }
  35. method.Body = null;
  36. }
  37. }
  38. var writer = new System.IO.MemoryStream();
  39. var options = new ModuleWriterOptions(mod);
  40. options.MetadataOptions.Flags |= MetadataFlags.PreserveRids;
  41. mod.Write(writer, options);
  42. writer.Flush();
  43. return writer.ToArray();
  44. }
  45. public static void Strip(string originalAssemblyPath, string strippedAssemblyPath)
  46. {
  47. byte[] originDllBytes = System.IO.File.ReadAllBytes(originalAssemblyPath);
  48. byte[] strippedDllBytes = Strip(originDllBytes);
  49. UnityEngine.Debug.Log($"aot dll:{originalAssemblyPath}, length: {originDllBytes.Length} -> {strippedDllBytes.Length}, stripping rate:{(originDllBytes.Length - strippedDllBytes.Length)/(double)originDllBytes.Length} ");
  50. Directory.CreateDirectory(System.IO.Path.GetDirectoryName(strippedAssemblyPath));
  51. System.IO.File.WriteAllBytes(strippedAssemblyPath, strippedDllBytes);
  52. }
  53. }
  54. }