-
Notifications
You must be signed in to change notification settings - Fork 48
/
RewriteGlobalContext.cs
94 lines (77 loc) · 4.34 KB
/
RewriteGlobalContext.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
using System;
using System.Collections.Generic;
using System.IO;
using AssemblyUnhollower.Extensions;
using Mono.Cecil;
namespace AssemblyUnhollower.Contexts
{
public class RewriteGlobalContext : IDisposable
{
public UnhollowerOptions Options { get; }
private readonly Dictionary<string, AssemblyRewriteContext> myAssemblies = new Dictionary<string, AssemblyRewriteContext>();
private readonly Dictionary<AssemblyDefinition, AssemblyRewriteContext> myAssembliesByOld = new Dictionary<AssemblyDefinition, AssemblyRewriteContext>();
private readonly Resolver myAssemblyResolver = new Resolver();
internal readonly Dictionary<(object, string, int), List<TypeDefinition>> RenameGroups = new Dictionary<(object, string, int), List<TypeDefinition>>();
internal readonly Dictionary<TypeDefinition, string> RenamedTypes = new Dictionary<TypeDefinition, string>();
internal readonly Dictionary<TypeDefinition, string> PreviousRenamedTypes = new Dictionary<TypeDefinition, string>();
public IEnumerable<AssemblyRewriteContext> Assemblies => myAssemblies.Values;
public RewriteGlobalContext(UnhollowerOptions options, IEnumerable<string> sourceAssemblyPaths)
{
Options = options;
var metadataResolver = new MetadataResolver(myAssemblyResolver);
var mscorlib = AssemblyDefinition.ReadAssembly(options.MscorlibPath);
TargetTypeSystemHandler.Init(mscorlib);
myAssemblyResolver.Register(mscorlib);
foreach (var sourceAssemblyPath in sourceAssemblyPaths)
{
var assemblyName = Path.GetFileNameWithoutExtension(sourceAssemblyPath);
if(assemblyName == "Il2CppDummyDll") continue;
var sourceAssembly = AssemblyDefinition.ReadAssembly(sourceAssemblyPath, new ReaderParameters(ReadingMode.Immediate) {MetadataResolver = metadataResolver});
myAssemblyResolver.Register(sourceAssembly);
var newAssembly = AssemblyDefinition.CreateAssembly(
new AssemblyNameDefinition(sourceAssembly.Name.Name.UnSystemify(), sourceAssembly.Name.Version),
sourceAssembly.MainModule.Name.UnSystemify(), sourceAssembly.MainModule.Kind);
var assemblyRewriteContext = new AssemblyRewriteContext(this, sourceAssembly, newAssembly);
myAssemblies[assemblyName] = assemblyRewriteContext;
myAssembliesByOld[sourceAssembly] = assemblyRewriteContext;
}
}
private class Resolver : DefaultAssemblyResolver
{
public void Register(AssemblyDefinition ass) => RegisterAssembly(ass);
}
public AssemblyRewriteContext GetNewAssemblyForOriginal(AssemblyDefinition oldAssembly)
{
return myAssembliesByOld[oldAssembly];
}
public TypeRewriteContext GetNewTypeForOriginal(TypeDefinition originalType)
{
return GetNewAssemblyForOriginal(originalType.Module.Assembly)
.GetContextForOriginalType(originalType);
}
public TypeRewriteContext.TypeSpecifics JudgeSpecificsByOriginalType(TypeReference typeRef)
{
if (typeRef.IsPrimitive || typeRef.IsPointer || typeRef.FullName == "System.TypedReference") return TypeRewriteContext.TypeSpecifics.BlittableStruct;
if (typeRef.FullName == "System.String" || typeRef.FullName == "System.Object" || typeRef.IsArray || typeRef.IsByReference || typeRef.IsGenericParameter || typeRef.IsGenericInstance)
return TypeRewriteContext.TypeSpecifics.ReferenceType;
var fieldTypeContext = GetNewTypeForOriginal(typeRef.Resolve());
return fieldTypeContext.ComputedTypeSpecifics;
}
public AssemblyRewriteContext GetAssemblyByName(string name)
{
return myAssemblies[name];
}
public AssemblyRewriteContext? TryGetAssemblyByName(string name)
{
return myAssemblies.TryGetValue(name, out var result) ? result : null;
}
public void Dispose()
{
foreach (var assembly in Assemblies)
{
assembly.NewAssembly.Dispose();
assembly.OriginalAssembly.Dispose();
}
}
}
}