NLDClient-yudde/Tool/Obfuz/EditorAssets/Editor/KedrExtension/Patches.cs

96 lines
2.5 KiB
C#

using System;
using System.Linq;
using dnlib.DotNet.Emit;
using dnlib.DotNet.PolymorphicWriter;
using dnlib.DotNet.Writer;
using HarmonyLib;
using Obfuz.Settings;
internal static class DnlibPolymorphicContext
{
[ThreadStatic] public static byte[] OpcodeMapping;
}
[HarmonyPatch(typeof(PolymorphicMetadata), "WriteMethodBodies")]
static class WriteMethodBodiesPatch
{
static void Prefix()
{
if (!KedrExtensionSettings.Instance.enableOpcodeShuffle)
return;
var seed = HashUtil.Hash(ObfuzSettings.Instance.polymorphicDllSettings.codeGenerationSecretKey);
var opcodeMapping = Enumerable.Range(0, 248).Select(x => (byte)x).ToArray();
var rng = new System.Random((int)seed);
RandomUtil.Shuffle(opcodeMapping, rng);
DnlibPolymorphicContext.OpcodeMapping = opcodeMapping;
}
static void Finalizer()
{
DnlibPolymorphicContext.OpcodeMapping = null;
}
}
[HarmonyPatch(typeof(MethodBodyWriterBase), "WriteOpCode")]
static class WriteOpCodePatch
{
static bool Prefix(ref ArrayWriter writer, Instruction instr)
{
if (DnlibPolymorphicContext.OpcodeMapping is null)
return true;
WriteOpCode(ref writer, instr);
return false;
}
private static void WriteOpCode(ref ArrayWriter writer, Instruction instr)
{
var code = (int)instr.OpCode.Code;
int num = code >> 8;
if (code <= 255)
{
if (code < (int)dnlib.DotNet.Emit.Code.Prefix7)
{
code = DnlibPolymorphicContext.OpcodeMapping[code];
}
writer.WriteByte((byte)code);
return;
}
switch (num)
{
case 240:
case 241:
case 242:
case 243:
case 244:
case 245:
case 246:
case 247:
case 248:
case 249:
case 250:
case 251:
case 254:
writer.WriteByte((byte)num);
writer.WriteByte((byte)instr.OpCode.Code);
return;
}
switch (instr.OpCode.Code)
{
case dnlib.DotNet.Emit.Code.UNKNOWN1:
writer.WriteByte(0);
break;
case dnlib.DotNet.Emit.Code.UNKNOWN2:
writer.WriteUInt16(0);
break;
default:
throw new Exception("Unknown opcode");
}
}
}