:fortelove:

This commit is contained in:
js6pak committed 2021-01-22 10:16:12 +01:00
1 parent c855b1936e
commit 36291c009c
18 files changed
+561 -232

No files matched your search

+1 -1
View File
@@ -129,7 +129,7 @@ namespace Reactor.Greenhouse
foreach (var nested in type.Nested)
{
var nestedDef = typeDef.NestedTypes.Single(t =>
TestType(type, t, mappings) &&
TestType(nested, t, mappings) &&
nested.Original.Index == null || typeDef.NestedTypes.IndexOf(t) == nested.Original.Index
);
+12
View File
@@ -1,3 +1,5 @@
using System;
using System.Diagnostics;
using System.Linq;
using Mono.Cecil;
@@ -24,5 +26,15 @@ namespace Reactor.Greenhouse
var offset = attribute.Fields.Single(x => x.Name == "Offset");
return new System.ComponentModel.UInt32Converter().ConvertFrom(offset) as uint?;
}
private static readonly Stopwatch _stopwatch = new Stopwatch();
public static TimeSpan Time(this Action action)
{
_stopwatch.Restart();
action();
_stopwatch.Stop();
return _stopwatch.Elapsed;
}
}
}
@@ -0,0 +1,26 @@
using System.Collections.Generic;
using Mono.Cecil;
using Mono.Cecil.Rocks;
namespace Reactor.Greenhouse.Generation
{
public class GenerationContext
{
public ModuleDefinition CleanModule { get; }
public ModuleDefinition ObfuscatedModule { get; }
public IEnumerable<TypeDefinition> AllCleanTypes { get; }
public IEnumerable<TypeDefinition> AllObfuscatedTypes { get; }
public Dictionary<TypeDefinition, TypeContext> Map { get; } = new Dictionary<TypeDefinition, TypeContext>();
public GenerationContext(ModuleDefinition cleanModule, ModuleDefinition obfuscatedModule)
{
CleanModule = cleanModule;
ObfuscatedModule = obfuscatedModule;
AllCleanTypes = CleanModule.GetAllTypes();
AllObfuscatedTypes = ObfuscatedModule.GetAllTypes();
}
}
}
+277
View File
@@ -0,0 +1,277 @@
using System;
using Mono.Cecil;
using Reactor.OxygenFilter;
namespace Reactor.Greenhouse.Generation
{
public static class Generator
{
public static TypeAttributes IgnoreVisibility(this TypeAttributes typeAttributes)
{
return typeAttributes & ~TypeAttributes.VisibilityMask;
}
public static FieldAttributes IgnoreVisibility(this FieldAttributes fieldAttributes)
{
return fieldAttributes & ~FieldAttributes.FieldAccessMask;
}
public static MethodAttributes IgnoreVisibility(this MethodAttributes methodAttributes)
{
return methodAttributes & ~MethodAttributes.MemberAccessMask;
}
private static bool IsAssemblyCSharp(this IMetadataScope scope)
{
return scope.Name != "Assembly-CSharp.dll";
}
public static Mappings Generate(GenerationContext context)
{
var result = new Mappings();
var lookupTypes = Extensions.Time(() =>
{
LookupTypes(context);
});
Console.WriteLine("LookupTypes took " + lookupTypes);
foreach (var (obfuscatedType, typeContext) in context.Map)
{
var mappedType = typeContext.ToMappedType(obfuscatedType);
if (mappedType == null)
continue;
result.Types.Add(mappedType);
}
return result;
}
private static bool TestEnum(TypeDefinition cleanType, TypeDefinition obfuscatedType)
{
if (!obfuscatedType.IsEnum)
return false;
if (cleanType.Fields.Count != obfuscatedType.Fields.Count)
return false;
for (var i = 0; i < cleanType.Fields.Count; i++)
{
var cleanField = cleanType.Fields[i];
var obfuscatedField = obfuscatedType.Fields[i];
if (cleanField.Name != obfuscatedField.Name)
{
return false;
}
if (cleanField.HasConstant && !cleanField.Constant.Equals(obfuscatedField.Constant))
{
return false;
}
}
return true;
}
private static double TestField(FieldDefinition cleanField, FieldDefinition obfuscatedField)
{
var points = 0d;
if (cleanField.Attributes.IgnoreVisibility() != obfuscatedField.Attributes.IgnoreVisibility())
{
points -= 1;
}
if (cleanField.HasConstant)
{
points += cleanField.Constant.Equals(obfuscatedField.Constant) ? 1 : -1;
}
if (cleanField.Name == obfuscatedField.Name)
{
points += 1;
}
if (cleanField.FieldType.FullName == obfuscatedField.FieldType.FullName)
{
points += 1;
}
return points;
}
private static double TestMethod(MethodDefinition cleanMethod, MethodDefinition obfuscatedMethod)
{
var points = 0d;
if (cleanMethod.Name == obfuscatedMethod.Name)
{
points += 1;
}
if (cleanMethod.ReturnType.FullName == obfuscatedMethod.ReturnType.FullName)
{
points += cleanMethod.ReturnType.FullName == "System.Void" ? 0.5 : 1;
}
else if (cleanMethod.ReturnType.Scope.IsAssemblyCSharp())
{
points -= 1;
}
for (var i = 0; i < cleanMethod.Parameters.Count; i++)
{
var cleanParameter = cleanMethod.Parameters[i];
if (obfuscatedMethod.Parameters.Count <= i)
{
points -= 1;
continue;
}
var obfuscatedParameter = obfuscatedMethod.Parameters[i];
if (cleanParameter.ParameterType.FullName == obfuscatedParameter.ParameterType.FullName)
{
points += 1;
}
else if (cleanParameter.ParameterType.Scope.IsAssemblyCSharp())
{
points -= 1;
}
}
if (obfuscatedMethod.Parameters.Count > cleanMethod.Parameters.Count)
{
points -= obfuscatedMethod.Parameters.Count - cleanMethod.Parameters.Count;
}
return points;
}
private static double TestType(TypeDefinition cleanType, TypeDefinition obfuscatedType)
{
if (cleanType.Name.StartsWith("<"))
return 0;
if (cleanType.Attributes.IgnoreVisibility() != obfuscatedType.Attributes.IgnoreVisibility())
return 0;
if (cleanType.IsEnum)
{
return TestEnum(cleanType, obfuscatedType) ? double.MaxValue : 0;
}
if (cleanType.BaseType != null && obfuscatedType.BaseType != null && cleanType.BaseType.FullName != obfuscatedType.BaseType.FullName)
{
if (cleanType.BaseType.Scope.IsAssemblyCSharp() && !obfuscatedType.BaseType.Name.IsObfuscated())
{
return 0;
}
}
var points = 0d;
// this will only work with up to date mono dll (:fortelove:)
if (obfuscatedType.Fields.Count != cleanType.Fields.Count || obfuscatedType.Properties.Count != cleanType.Properties.Count || obfuscatedType.NestedTypes.Count != cleanType.NestedTypes.Count)
{
return 0;
}
for (var i = 0; i < cleanType.Fields.Count; i++)
{
var cleanField = cleanType.Fields[i];
if (obfuscatedType.Fields.Count <= i)
{
points -= 1;
continue;
}
var obfuscatedField = obfuscatedType.Fields[i];
points += TestField(cleanField, obfuscatedField);
}
if (obfuscatedType.Fields.Count > cleanType.Fields.Count)
{
points -= obfuscatedType.Fields.Count - cleanType.Fields.Count;
}
foreach (var cleanMethod in cleanType.Methods)
{
var winnerPoints = 0d;
foreach (var obfuscatedMethod in obfuscatedType.Methods)
{
var methodPoints = TestMethod(cleanMethod, obfuscatedMethod);
if (methodPoints > winnerPoints && methodPoints >= 1)
{
winnerPoints = methodPoints;
}
}
if (winnerPoints > 0)
{
points += winnerPoints;
}
}
return points;
}
private static void LookupTypes(GenerationContext context)
{
foreach (var cleanType in context.AllCleanTypes)
{
if (cleanType.Name.StartsWith("<"))
continue;
TypeDefinition winner = null;
var winnerPoints = 0d;
foreach (var obfuscatedType in context.AllObfuscatedTypes)
{
if (obfuscatedType.Name.StartsWith("<") && obfuscatedType.Name.EndsWith(">"))
continue;
var points = TestType(cleanType, obfuscatedType);
if (points > winnerPoints)
{
winnerPoints = points;
winner = obfuscatedType;
}
}
if (winnerPoints != 0 && winner != null)
{
var typeContext = new TypeContext(context, winnerPoints, cleanType);
if (!context.Map.TryAdd(winner, typeContext))
{
Console.WriteLine($"{winner.FullName} = {cleanType.FullName} - {winnerPoints}");
var points = context.Map[winner].Points;
if (points.Equals(winnerPoints))
{
Console.WriteLine("Warning: duplicate, remove all");
context.Map.Remove(winner);
}
else if (winnerPoints >= points)
{
Console.WriteLine("Warning: duplicate, replace");
context.Map[winner] = typeContext;
}
else
{
Console.WriteLine("Warning: duplicate, skip");
}
}
}
}
}
}
}
@@ -0,0 +1,174 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text.RegularExpressions;
using Mono.Cecil;
using Mono.Cecil.Rocks;
using Reactor.OxygenFilter;
namespace Reactor.Greenhouse.Generation
{
public class TypeContext
{
public GenerationContext Context { get; }
public double Points { get; }
public TypeDefinition CleanType { get; }
public string CleanFullName => CleanType.FullName;
public TypeContext(GenerationContext context, double points, TypeDefinition cleanType)
{
Context = context;
Points = points;
CleanType = cleanType;
}
public override string ToString()
{
return CleanFullName;
}
private static readonly Regex CompilerGeneratedRegex = new Regex(@"^<([\w\d]+)>.__\d+$", RegexOptions.Compiled);
public MappedType ToMappedType(TypeDefinition obfuscatedType)
{
var mappedType = new MappedType(obfuscatedType.FullName, CleanType.Name);
for (var i = 0; i < CleanType.Fields.Count; i++)
{
var cleanField = CleanType.Fields[i];
var obfuscatedField = obfuscatedType.Fields[i];
if (!obfuscatedField.Name.IsObfuscated())
continue;
mappedType.Fields.Add(new MappedMember(obfuscatedField.Name, cleanField.Name));
}
for (var i = 0; i < CleanType.Properties.Count; i++)
{
var cleanProperty = CleanType.Properties[i];
var obfuscatedProperty = obfuscatedType.Properties[i];
if (!obfuscatedProperty.Name.IsObfuscated())
continue;
mappedType.Properties.Add(new MappedMember(obfuscatedProperty.Name, cleanProperty.Name));
}
foreach (var cleanMethod in CleanType.GetMethods())
{
var matching = new List<MethodDefinition>();
foreach (var obfuscatedMethod in obfuscatedType.GetMethods())
{
if (cleanMethod.ReturnType.FullName != obfuscatedMethod.ReturnType.FullName)
continue;
if (cleanMethod.Attributes.IgnoreVisibility() != obfuscatedMethod.Attributes.IgnoreVisibility())
continue;
if (cleanMethod.Parameters.Count != obfuscatedMethod.Parameters.Count)
continue;
var validParameters = true;
for (var i = 0; i < cleanMethod.Parameters.Count; i++)
{
var cleanParameter = cleanMethod.Parameters[i];
var obfuscatedParameter = obfuscatedMethod.Parameters[i];
var obfuscatedParameterContext = Context.Map.SingleOrDefault(x => x.Key.FullName == obfuscatedParameter.ParameterType.FullName).Value;
if (cleanParameter.ParameterType.FullName != (obfuscatedParameterContext == null ? obfuscatedParameter.ParameterType.FullName : obfuscatedParameterContext.CleanFullName))
{
validParameters = false;
break;
}
}
if (!validParameters)
continue;
matching.Add(obfuscatedMethod);
if (matching.Count > 1)
break;
}
if (matching.Count == 1)
{
var matched = matching.Single();
mappedType.Methods.Add(new MappedMethod(new OriginalDescriptor
{
Name = matched.Name,
Signature = matched.GetSignature()
}, cleanMethod.Name));
}
}
for (var i = 0; i < CleanType.NestedTypes.Count; i++)
{
var cleanNested = CleanType.NestedTypes[i];
var obfuscatedNested = obfuscatedType.NestedTypes[i];
if (cleanNested.Fields.Count != obfuscatedNested.Fields.Count)
{
break;
}
var match = CompilerGeneratedRegex.Match(cleanNested.Name);
var nested = new MappedType(obfuscatedNested.FullName, match.Success ? (match.Groups[1].Value + "__d") : cleanNested.Name.Replace("<>", ""));
foreach (var nestedField in obfuscatedNested.Fields)
{
switch (nestedField.Name)
{
case "<>1__state":
nested.Fields.Add(new MappedMember(nestedField.Name, "__state"));
continue;
case "<>2__current":
nested.Fields.Add(new MappedMember(nestedField.Name, "__current"));
continue;
case "<>4__this":
nested.Fields.Add(new MappedMember(nestedField.Name, "__this"));
continue;
}
var fieldMatch = CompilerGeneratedRegex.Match(nestedField.Name);
if (fieldMatch.Success)
{
nested.Fields.Add(new MappedMember(nestedField.Name, fieldMatch.Groups[1].Value));
}
}
foreach (var nestedMethod in obfuscatedNested.Methods)
{
var methodMatch = CompilerGeneratedRegex.Match(nestedMethod.Name);
if (methodMatch.Success)
{
nested.Methods.Add(new MappedMethod(new OriginalDescriptor
{
Name = nestedMethod.Name,
Signature = nestedMethod.GetSignature()
}, methodMatch.Groups[1].Value));
}
}
if (!obfuscatedNested.Name.IsObfuscated() && nested.Mapped == cleanNested.Name && !nested.Fields.Any() && !nested.Methods.Any())
continue;
mappedType.Nested.Add(nested);
}
if (!obfuscatedType.Name.IsObfuscated() && !mappedType.Fields.Any() && !mappedType.Methods.Any() && !mappedType.Properties.Any() && !mappedType.Nested.Any())
return null;
return mappedType;
}
}
}
-161
View File
@@ -1,161 +0,0 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Mono.Cecil;
using Mono.Cecil.Rocks;
using Reactor.OxygenFilter;
namespace Reactor.Greenhouse
{
public static class Generator
{
private static TypeAttributes IgnoreVisibility(this TypeAttributes typeAttributes)
{
return typeAttributes & ~TypeAttributes.VisibilityMask;
}
public static Mappings Generate(ModuleDefinition old, ModuleDefinition latest)
{
var matches = new Dictionary<TypeDefinition, SortedList<double, TypeDefinition>>();
var result = new Mappings();
foreach (var oldType in old.GetAllTypes())
{
if (oldType.Name.StartsWith("<") || oldType.Namespace.StartsWith("GoogleMobileAds"))
continue;
var list = new SortedList<double, TypeDefinition>(Comparer<double>.Create((x, y) => y.CompareTo(x)));
matches[oldType] = list;
var exact = latest.GetAllTypes().FirstOrDefault(x => x.FullName == oldType.FullName);
if (exact != null)
{
list.Add(double.MaxValue, exact);
continue;
}
if (oldType.IsEnum)
{
var first = oldType.Fields.Select(x => x.Name).ToArray();
var type = latest.GetAllTypes().SingleOrDefault(x => x.IsEnum && x.Fields.Select(f => f.Name).SequenceEqual(first));
if (type != null)
{
list.Add(double.MaxValue, type);
}
continue;
}
static bool Test(TypeReference typeReference)
{
return typeReference.IsGenericParameter || typeReference.Namespace != string.Empty || !typeReference.Name.IsObfuscated();
}
var methodNames = oldType.GetMethods().Select(x => x.Name).ToArray();
var fieldNames = oldType.Fields.Select(x => x.Name).ToArray();
var propertyNames = oldType.Properties.Select(x => x.Name).ToArray();
var methodSignatures = oldType.GetMethods().Where(x => Test(x.ReturnType) && x.Parameters.All(p => Test(p.ParameterType))).Select(x => x.GetSignature()).ToArray();
var fieldSignatures = oldType.Fields.Where(x => Test(x.FieldType) && (!x.FieldType.HasGenericParameters || x.FieldType.GenericParameters.All(Test))).Select(x => x.GetSignature()).ToArray();
var types = latest.GetAllTypes()
.Where(t => t.Attributes.IgnoreVisibility() == oldType.Attributes.IgnoreVisibility())
.ToArray();
foreach (var t in types)
{
var points = 0d;
points += t.GetMethods().Count(m => !m.Name.IsObfuscated() && methodNames.Contains(m.Name));
points += t.Fields.Count(f => !f.Name.IsObfuscated() && fieldNames.Contains(f.Name)) * 2d;
points += t.Properties.Count(p => propertyNames.Contains((p.GetMethod?.Name ?? p.SetMethod.Name).Substring(4))) * 2d;
var fieldSignaturesPoints = fieldSignatures.Count(s => t.Fields.Any(f => f.GetSignature().ToString() == s.ToString()));
points += Math.Max(0, fieldSignaturesPoints - Math.Abs(t.Fields.Count - fieldSignaturesPoints)) / 2d;
var methodSignaturesPoints = methodSignatures.Count(s => t.GetMethods().Any(m => m.GetSignature().ToString() == s.ToString()));
points += Math.Max(0, methodSignaturesPoints - Math.Abs(t.GetMethods().Count() - methodSignaturesPoints) / 2d) / 2d;
if (points != 0)
{
list.TryAdd(points, t);
}
}
}
foreach (var (oldType, list) in matches)
{
foreach (var (points, type) in list)
{
if (matches.Where(x => x.Key != oldType).SelectMany(x => x.Value).Any(x => x.Value == type && x.Key > points))
{
continue;
}
list.Clear();
list.Add(double.MaxValue, type);
var mapped = new MappedType(new OriginalDescriptor { Name = type.FullName }, oldType.Name);
var i = 0;
foreach (var field in type.Fields)
{
var j = 0;
var i1 = i;
var oldFields = oldType.Fields.Where(x => j++ == i1 && x.GetSignature().ToString() == field.GetSignature().ToString()).ToArray();
if (oldFields.Length == 1)
{
var oldField = oldFields.First();
if (oldField.Name == field.Name || !field.Name.IsObfuscated())
continue;
mapped.Fields.Add(new MappedMember(new OriginalDescriptor { Index = i1 }, oldField.Name));
}
i++;
}
foreach (var method in type.Methods)
{
if (!method.HasParameters || method.IsSetter || method.IsGetter)
{
continue;
}
var oldMethods = oldType.Methods.Where(x => x.Name == method.Name && x.Parameters.Count == method.Parameters.Count).ToArray();
if (oldMethods.Length != 1)
{
continue;
}
var oldMethod = oldMethods.Single();
var oldParameters = oldMethod.Parameters.Select(x => x.Name).ToList();
if (method.Parameters.Select(x => x.Name).SequenceEqual(oldParameters))
{
continue;
}
mapped.Methods.Add(new MappedMethod(new OriginalDescriptor { Name = method.Name, Signature = method.GetSignature() }, null)
{
Parameters = oldParameters
});
}
if (type.Name == oldType.Name || (!type.Name.IsObfuscated() && !mapped.Fields.Any() && !mapped.Methods.Any()))
{
break;
}
result.Types.Add(mapped);
break;
}
}
return result;
}
}
}
+10 -6
View File
@@ -10,6 +10,7 @@ using System.Threading.Tasks;
using Mono.Cecil;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using Reactor.Greenhouse.Generation;
using Reactor.Greenhouse.Setup;
using Reactor.Greenhouse.Setup.Provider;
using Reactor.OxygenFilter;
@@ -45,8 +46,9 @@ namespace Reactor.Greenhouse
ContractResolver = ShouldSerializeContractResolver.Instance,
};
Console.WriteLine($"Generating mappings from {gameManager.PreObfuscation.Name} ({gameManager.PreObfuscation.Version})");
using var old = ModuleDefinition.ReadModule(File.OpenRead(gameManager.PreObfuscation.Dll));
var oldFile = Path.Combine("work", "Assembly-CSharp-2020.12.9s.dll");
Console.WriteLine($"Generating mappings from {oldFile}");
using var cleanModule = ModuleDefinition.ReadModule(File.OpenRead(oldFile));
if (!steam && !itch)
{
@@ -56,16 +58,18 @@ namespace Reactor.Greenhouse
if (steam)
{
await GenerateAsync(gameManager.Steam, old);
await GenerateAsync(gameManager.Steam, cleanModule);
}
if (itch)
{
await GenerateAsync(gameManager.Itch, old);
await GenerateAsync(gameManager.Itch, cleanModule);
}
new OxygenFilter.OxygenFilter().Start(File.ReadAllText(Path.Combine("bin", "2020.12.9s.json")), new FileInfo(gameManager.Steam.Dll), new FileInfo("test.dll"));
}
private static async Task GenerateAsync(Game game, ModuleDefinition old)
private static async Task GenerateAsync(Game game, ModuleDefinition cleanModule)
{
Console.WriteLine($"Compiling mappings for {game.Name} ({game.Version})");
@@ -73,7 +77,7 @@ namespace Reactor.Greenhouse
var version = game.Version;
var postfix = game.Postfix;
var generated = Generator.Generate(old, moduleDef);
var generated = Generator.Generate(new GenerationContext(cleanModule, moduleDef));
await File.WriteAllTextAsync(Path.Combine("work", version + postfix + ".generated.json"), JsonConvert.SerializeObject(generated, Formatting.Indented));
@@ -10,6 +10,7 @@
<PackageReference Include="AngleSharp" Version="0.14.0" />
<PackageReference Include="DepotDownloader.Library" Version="0.1.2" />
<PackageReference Include="Iced" Version="1.10.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="5.0.0" />
<PackageReference Include="Mono.Cecil" Version="0.11.3" />
<PackageReference Include="System.CommandLine" Version="2.0.0-beta1.20574.7" />
<ProjectReference Include="..\Reactor.OxygenFilter\Reactor.OxygenFilter.csproj" />
+1 -19
View File
@@ -10,34 +10,25 @@ namespace Reactor.Greenhouse.Setup
{
public string WorkPath { get; }
public Game PreObfuscation { get; }
public Game Steam { get; }
public Game Itch { get; }
public GameManager()
{
WorkPath = Path.GetFullPath("work");
PreObfuscation = new Game(new SteamProvider(true), "preobfuscation", Path.Combine(WorkPath, "preobfuscation"));
Steam = new Game(new SteamProvider(false), "steam", Path.Combine(WorkPath, "steam"));
Itch = new Game(new ItchProvider(), "itch", Path.Combine(WorkPath, "itch"));
}
public async Task SetupAsync(bool setupSteam, bool setupItch)
{
var preObfuscation = PreObfuscation.Provider.IsUpdateNeeded();
var steam = setupSteam && Steam.Provider.IsUpdateNeeded();
var itch = setupItch && Itch.Provider.IsUpdateNeeded();
if (preObfuscation || steam || itch)
if (steam || itch)
{
ContentDownloader.ShutdownSteam3();
if (preObfuscation)
{
await PreObfuscation.DownloadAsync();
Console.WriteLine($"Downloaded {nameof(PreObfuscation)} ({PreObfuscation.Version})");
}
if (steam)
{
await Steam.DownloadAsync();
@@ -53,8 +44,6 @@ namespace Reactor.Greenhouse.Setup
ContentDownloader.ShutdownSteam3();
PreObfuscation.UpdateVersion();
if (setupSteam)
{
Steam.UpdateVersion();
@@ -65,13 +54,6 @@ namespace Reactor.Greenhouse.Setup
Itch.UpdateVersion();
}
if (PreObfuscation.Version != "2020.9.9")
{
throw new ArgumentException("Pre obfuscation version is invalid");
}
PreObfuscation.Dump();
if (setupSteam)
{
Steam.Dump();
+20 -4
View File
@@ -8,8 +8,13 @@ namespace Reactor.OxygenFilter.MSBuild
public static class Context
{
// Path#Combine is borken on visual studio
public static string DataPath { get; } = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + Path.DirectorySeparatorChar + ".reactor";
public static string TempPath { get; } = Path.Combine(DataPath, "temp");
public static string RootPath { get; } = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + Path.DirectorySeparatorChar + ".reactor";
public static string TempPath { get; } = Path.Combine(RootPath, "tmp");
public static string DataPath => RootPath + Path.DirectorySeparatorChar + GameVersion;
public static string MappedPath => DataPath + Path.DirectorySeparatorChar + ComputeHash(MappingsJson);
public static string GameVersion { get; internal set; }
public static string MappingsJson { get; internal set; }
public static string ComputeHash(FileInfo file)
{
@@ -18,7 +23,7 @@ namespace Reactor.OxygenFilter.MSBuild
var hash = md5.ComputeHash(assemblyStream);
return Encoding.UTF8.GetString(hash);
return ByteArrayToString(hash);
}
public static string ComputeHash(string text)
@@ -27,7 +32,18 @@ namespace Reactor.OxygenFilter.MSBuild
var hash = md5.ComputeHash(Encoding.UTF8.GetBytes(text));
return Encoding.UTF8.GetString(hash);
return ByteArrayToString(hash);
}
public static string ByteArrayToString(byte[] data)
{
var builder = new StringBuilder(data.Length * 2);
foreach (var b in data)
{
builder.AppendFormat("{0:x2}", b);
}
return builder.ToString();
}
}
}
+3 -6
View File
@@ -17,15 +17,12 @@ namespace Reactor.OxygenFilter.MSBuild
[Required]
public string[] Input { get; set; }
[Required]
public string Mappings { get; set; }
[Output]
public string[] Deobfuscated { get; set; }
public override bool Execute()
{
var path = Path.Combine(Context.DataPath, "mapped");
var path = Path.Combine(Context.MappedPath, "mapped");
Directory.CreateDirectory(path);
@@ -34,10 +31,10 @@ namespace Reactor.OxygenFilter.MSBuild
ContractResolver = new CamelCasePropertyNamesContractResolver()
};
var mappings = JsonConvert.DeserializeObject<Mappings>(Mappings);
var mappings = JsonConvert.DeserializeObject<Mappings>(Context.MappingsJson);
var resolver = new DefaultAssemblyResolver();
resolver.AddSearchDirectory(Path.Combine(Context.DataPath, "references"));
resolver.AddSearchDirectory(Path.Combine(Context.MappedPath, "references"));
resolver.AddSearchDirectory(Path.Combine(AmongUs, "BepInEx", "core"));
resolver.AddSearchDirectory(Path.Combine(AmongUs, "BepInEx", "plugins"));
resolver.AddSearchDirectory(Path.Combine(AmongUs, "BepInEx", "unhollowed"));
@@ -10,31 +10,29 @@ namespace Reactor.OxygenFilter.MSBuild
[Required]
public string AmongUs { get; set; }
[Required]
public string Mappings { get; set; }
[Output]
public string ReferencesPath { get; set; }
public override bool Execute()
{
ReferencesPath = Path.Combine(Context.DataPath, "references");
ReferencesPath = Path.Combine(Context.MappedPath, "references");
Directory.CreateDirectory(Context.DataPath);
Directory.CreateDirectory(Context.MappedPath);
var skip = true;
var gameAssemblyPath = Path.Combine(AmongUs, "GameAssembly.dll");
var hash = Context.ComputeHash(new FileInfo(gameAssemblyPath));
var hashPath = Path.Combine(Context.DataPath, "GameAssembly.dll.md5");
var hashPath = Path.Combine(Context.MappedPath, "GameAssembly.dll.md5");
if (!File.Exists(hashPath) || hash != File.ReadAllText(hashPath))
{
skip = false;
}
var mappingsHash = Context.ComputeHash(Mappings);
var mappingsHashPath = Path.Combine(Context.DataPath, "mappings.md5");
var mappingsHash = Context.ComputeHash(Context.MappingsJson);
var mappingsHashPath = Path.Combine(Context.MappedPath, "mappings.md5");
if (!File.Exists(mappingsHashPath) || mappingsHash != File.ReadAllText(mappingsHashPath))
{
@@ -46,11 +44,6 @@ namespace Reactor.OxygenFilter.MSBuild
return true;
}
if (Directory.Exists(Context.TempPath))
{
Directory.Delete(Context.TempPath, true);
}
var dumperConfig = new Il2CppDumper.Config
{
GenerateScript = false,
@@ -62,7 +55,7 @@ namespace Reactor.OxygenFilter.MSBuild
Il2CppDumper.Il2CppDumper.PerformDump(
gameAssemblyPath,
Path.Combine(AmongUs, "Among Us_Data", "il2cpp_data", "Metadata", "global-metadata.dat"),
Context.TempPath, dumperConfig, _ =>
Context.DataPath, dumperConfig, _ =>
{
}
);
@@ -71,8 +64,8 @@ namespace Reactor.OxygenFilter.MSBuild
var oxygenFilter = new OxygenFilter();
var dumpedDll = new FileInfo(Path.Combine(Context.TempPath, "DummyDll", "Assembly-CSharp.dll"));
oxygenFilter.Start(Mappings, dumpedDll, dumpedDll);
var dumpedDll = new FileInfo(Path.Combine(Context.DataPath, "DummyDll", "Assembly-CSharp.dll"));
oxygenFilter.Start(Context.MappingsJson, dumpedDll, dumpedDll);
Log.LogMessage(MessageImportance.High, "Executing Il2CppUnhollower generator");
@@ -83,8 +76,8 @@ namespace Reactor.OxygenFilter.MSBuild
{
GameAssemblyPath = gameAssemblyPath,
MscorlibPath = Path.Combine(AmongUs, "mono", "Managed", "mscorlib.dll"),
SourceDir = Path.Combine(Context.TempPath, "DummyDll"),
OutputDir = Path.Combine(Context.TempPath, "unhollowed"),
SourceDir = Path.Combine(Context.DataPath, "DummyDll"),
OutputDir = Path.Combine(Context.DataPath, "unhollowed"),
UnityBaseLibsDir = Path.Combine(AmongUs, "BepInEx", "unity-libs"),
NoCopyUnhollowerLibs = true
};
+5 -6
View File
@@ -14,14 +14,13 @@ namespace Reactor.OxygenFilter.MSBuild
[Required]
public string Mappings { get; set; }
[Output]
public string MappingsJson { get; set; }
public override bool Execute()
{
Context.GameVersion = GameVersion;
if (File.Exists(Mappings))
{
MappingsJson = File.ReadAllText(Mappings);
Context.MappingsJson = File.ReadAllText(Mappings);
return true;
}
@@ -35,14 +34,14 @@ namespace Reactor.OxygenFilter.MSBuild
if (File.Exists(file))
{
MappingsJson = File.ReadAllText(file);
Context.MappingsJson = File.ReadAllText(file);
return true;
}
var httpClient = new HttpClient();
var json = httpClient.GetStringAsync($"https://github.com/{repo}/releases/download/{version}/{GameVersion}.json").GetAwaiter().GetResult();
MappingsJson = json;
Context.MappingsJson = json;
try
{
@@ -18,13 +18,11 @@
</Target>
<Target Name="LoadMappings">
<LoadMappings GameVersion="$(GameVersion)" Mappings="$(Mappings)">
<Output TaskParameter="MappingsJson" PropertyName="MappingsJson" />
</LoadMappings>
<LoadMappings GameVersion="$(GameVersion)" Mappings="$(Mappings)" />
</Target>
<Target Name="GenerateReferences" BeforeTargets="PrepareForBuild" DependsOnTargets="LoadMappings">
<GenerateReferences AmongUs="$(AmongUs)" Mappings="$(MappingsJson)">
<GenerateReferences AmongUs="$(AmongUs)">
<Output TaskParameter="ReferencesPath" PropertyName="ReferencesPath" />
</GenerateReferences>
@@ -38,7 +36,7 @@
</Target>
<Target Name="Deobfuscate" AfterTargets="GenerateReferences">
<Deobfuscate AmongUs="$(AmongUs)" Input="@(Deobfuscate)" Mappings="$(MappingsJson)">
<Deobfuscate AmongUs="$(AmongUs)" Input="@(Deobfuscate)">
<Output TaskParameter="Deobfuscated" PropertyName="Deobfuscated" />
</Deobfuscate>
@@ -48,6 +46,6 @@
</Target>
<Target Name="Reobfuscate" AfterTargets="Build">
<Reobfuscate GameVersion="$(GameVersion)" AmongUs="$(AmongUs)" Input="$(ProjectDir)$(OutputPath)$(AssemblyName).dll" ReferencedAssemblies="@(ReferencePath)" />
<Reobfuscate AmongUs="$(AmongUs)" Input="$(ProjectDir)$(OutputPath)$(AssemblyName).dll" ReferencedAssemblies="@(ReferencePath)" />
</Target>
</Project>
@@ -4,7 +4,7 @@
<LangVersion>latest</LangVersion>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<Version>0.2.3</Version>
<Version>0.2.4</Version>
<RepositoryType>git</RepositoryType>
<RepositoryUrl>https://github.com/NuclearPowered/Reactor.OxygenFilter</RepositoryUrl>
<PackageLicenseExpression>LGPL-3.0-or-later</PackageLicenseExpression>
+1 -4
View File
@@ -11,9 +11,6 @@ namespace Reactor.OxygenFilter.MSBuild
{
public class Reobfuscate : Task
{
[Required]
public string GameVersion { get; set; }
[Required]
public string AmongUs { get; set; }
@@ -270,7 +267,7 @@ namespace Reactor.OxygenFilter.MSBuild
var outputDirectory = Path.Combine(Path.GetDirectoryName(Input), "reobfuscated");
Directory.CreateDirectory(outputDirectory);
moduleDefinition.Write(Path.Combine(outputDirectory, Path.GetFileNameWithoutExtension(Input) + $"-{GameVersion}.dll"));
moduleDefinition.Write(Path.Combine(outputDirectory, Path.GetFileNameWithoutExtension(Input) + $"-{Context.GameVersion}.dll"));
return true;
}
+14
View File
@@ -156,6 +156,16 @@ namespace Reactor.OxygenFilter
}
}
public MappedMember(string original, string mapped) : this(
new OriginalDescriptor
{
Name = original
},
mapped
)
{
}
public bool Equals(MappedMember obj, bool compareOriginal = true)
{
if (obj == null)
@@ -195,5 +205,9 @@ namespace Reactor.OxygenFilter
public MappedType(OriginalDescriptor original, string mapped) : base(original, mapped)
{
}
public MappedType(string original, string mapped) : base(original, mapped)
{
}
}
}