Skip to content

Commit 28d926b

Browse files
committed
Mfuscator plugin: Support more unity versions
1 parent b9e514b commit 28d926b

1 file changed

Lines changed: 37 additions & 15 deletions

File tree

Cpp2IL.Plugin.Mfuscator/MfuscatorSupportPlugin.cs

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
using System.Diagnostics;
2-
using System.Runtime.InteropServices;
1+
using System.Runtime.InteropServices;
32
using AssetRipper.Primitives;
43
using Cpp2IL.Core.Api;
54
using Cpp2IL.Core.Attributes;
6-
using LibCpp2IL.Logging;
75

86
[assembly:RegisterCpp2IlPlugin(typeof(Cpp2IL.Plugin.Mfuscator.MfuscatorSupportPlugin))]
97

@@ -47,7 +45,7 @@ public int GetHashCode((int Start, int End)[] obj)
4745
}
4846
}
4947

50-
public override string Name => "Mfuscator Support";
48+
public override string Name => "Mfuscator Support"; //more like midfuscator amirite
5149
public override string Description => "Supports loading metadata files which have been mangled by mfuscator.";
5250
public override void OnLoad()
5351
{
@@ -480,8 +478,6 @@ private byte[] RebuildMetadata(byte[] encryptedMetadata, List<(int Start, int En
480478
{ 8, 8 }, //fieldAndParameterDefaultValueData
481479
};
482480

483-
const int OriginalHeaderSize = 256;
484-
485481
byte MetadataVersion;
486482
if (unityVersion.LessThan(2017))
487483
MetadataVersion = 23;
@@ -512,6 +508,23 @@ private byte[] RebuildMetadata(byte[] encryptedMetadata, List<(int Start, int En
512508
else if (MetadataVersion == 24 && unityVersion.LessThan(2019))
513509
assembliesSectionIndex = 22; //pre-24.2 we have rgctxEntries before assemblies
514510

511+
var expectedSectionCount = MetadataVersion switch
512+
{
513+
>= 104 => 32,
514+
>= 27 => 31,
515+
_ => throw new NotImplementedException("Metadata versions below 27 aren't currently supported (largely because mfuscator itself doesn't support these versions)")
516+
};
517+
var bytesPerSectionHeaderField = MetadataVersion switch
518+
{
519+
>= 38 => 12,
520+
_ => 8
521+
};
522+
523+
if(bytesPerSectionHeaderField == 12)
524+
throw new NotImplementedException("Metadata versions with 12 bytes per section header field aren't currently supported");
525+
526+
var originalHeaderSize = 8 + expectedSectionCount * bytesPerSectionHeaderField; //magic + version + 8 bytes per section header field
527+
515528
Logger.InfoNewline($"Mfuscator header decrypted successfully. Header length: {headerLength} bytes. String literals XOR key: 0x{stringLiteralsXorKey:X2}. String literals use {(stringLiteralsIsPlus ? "plus" : "minus")} rotation. Will rebuild as version {MetadataVersion} metadata with assemblies section at index {assembliesSectionIndex}.");
516529

517530
Logger.VerboseNewline("Decrypted header: " + string.Join("", decryptedHeader.Select(b => b.ToString("X2"))));
@@ -520,7 +533,7 @@ private byte[] RebuildMetadata(byte[] encryptedMetadata, List<(int Start, int En
520533
{
521534
Logger.VerboseNewline($"Trying metadata length 0x{metadataLength:X4}");
522535

523-
var paths = FindPathsThroughMetadata(headerWords, headerLength, metadataLength, out var bestDeadEnds, maxResults: 65536, debugBestN: 0, expectedSectionCount: 31, alignBefore: sectionAlignments, originalHeaderSize: OriginalHeaderSize);
536+
var paths = FindPathsThroughMetadata(headerWords, headerLength, metadataLength, out var bestDeadEnds, maxResults: 65536, debugBestN: 0, expectedSectionCount: expectedSectionCount, alignBefore: sectionAlignments, originalHeaderSize: originalHeaderSize);
524537

525538
if (paths.Count > 0)
526539
{
@@ -534,14 +547,23 @@ private byte[] RebuildMetadata(byte[] encryptedMetadata, List<(int Start, int En
534547
var distinct = actualRanges.Distinct(new SectionRangeComparer()).ToArray();
535548

536549
Logger.VerboseNewline($"These collapse to {distinct.Length} distinct actual section layouts.");
537-
538-
//We'll just accept any valid layout here, if there is more than one distinct layout it's likely they only differ in the irrelevant sections at the end of the file which cpp2il ignores
539-
var acceptedLayout = distinct[0];
540-
541-
Logger.VerboseNewline($"Accepted section layout: " + string.Join(", ", acceptedLayout.Select(range => $"({range.Item1:X4}-{range.Item2:X4})")));
542-
543-
Logger.InfoNewline("Returning decrypted metadata now...");
544-
return RebuildMetadata(originalBytes, acceptedLayout.ToList(), stringLiteralsXorKey, stringLiteralsIsPlus, offsetDelta: OriginalHeaderSize - headerLength, MetadataVersion, assembliesSectionIndex);
550+
551+
foreach (var acceptedLayout in distinct)
552+
{
553+
554+
Logger.VerboseNewline($"Trying section layout: " + string.Join(", ", acceptedLayout.Select(range => $"({range.Item1:X4}-{range.Item2:X4})")));
555+
556+
try
557+
{
558+
var ret = RebuildMetadata(originalBytes, acceptedLayout.ToList(), stringLiteralsXorKey, stringLiteralsIsPlus, offsetDelta: originalHeaderSize - headerLength, MetadataVersion, assembliesSectionIndex);
559+
Logger.InfoNewline("Returning decrypted metadata now...");
560+
return ret;
561+
}
562+
catch (Exception)
563+
{
564+
continue;
565+
}
566+
}
545567
}
546568

547569
metadataLength -= 4;

0 commit comments

Comments
 (0)