Add generic type scrambling protection
This commit is contained in:
Sam Harwood 2018-07-17 23:40:51 +02:00
Родитель cbd2c7669c
Коммит d8a40d4e23
28 изменённых файлов: 990 добавлений и 4 удалений

Двоичные данные
.vs/Confuser2/DesignTimeBuild/.dtbcache Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -39,7 +39,7 @@ public static class Program {
Console.WriteLine("error when executing git describe.");
}
}
tag = tag ?? "v" + ver + "-custom";
tag = tag ?? "v" + ver;
string template = Path.Combine(dir, "GlobalAssemblyInfo.Template.cs");
string output = Path.Combine(dir, "GlobalAssemblyInfo.cs");

Просмотреть файл

@ -389,7 +389,7 @@ namespace Confuser.Core {
MemoryStream pdb = null, output = new MemoryStream();
if (context.CurrentModule.PdbState != null) {
if (context.CurrentModule.PdbState != null) {
pdb = new MemoryStream();
context.CurrentModuleWriterOptions.WritePdb = true;
context.CurrentModuleWriterOptions.PdbFileName = Path.ChangeExtension(Path.GetFileName(context.OutputPaths[context.CurrentModuleIndex]), "pdb");

Просмотреть файл

@ -117,6 +117,28 @@
<Compile Include="Resources\NormalMode.cs" />
<Compile Include="Resources\REContext.cs" />
<Compile Include="Resources\ResourceProtection.cs" />
<Compile Include="TypeScrambler\AnalyzePhase.cs" />
<Compile Include="TypeScrambler\ScramblePhase.cs" />
<Compile Include="TypeScrambler\Scrambler\Analyzers\ContextAnalyzer.cs" />
<Compile Include="TypeScrambler\Scrambler\Analyzers\ContextAnalyzerFactory.cs" />
<Compile Include="TypeScrambler\Scrambler\Analyzers\MemberRefAnalyzer.cs" />
<Compile Include="TypeScrambler\Scrambler\Analyzers\MethodDefAnalyzer.cs" />
<Compile Include="TypeScrambler\Scrambler\Analyzers\MethodSpecAnalyzer.cs" />
<Compile Include="TypeScrambler\Scrambler\Analyzers\TypeRefAnalyzer.cs" />
<Compile Include="TypeScrambler\Scrambler\Rewriter\EmbeddedCode\ObjectCreationFactory.cs" />
<Compile Include="TypeScrambler\Scrambler\Rewriter\Instructions\InstructionRewriter.cs" />
<Compile Include="TypeScrambler\Scrambler\Rewriter\Instructions\InstructionRewriterFactory.cs" />
<Compile Include="TypeScrambler\Scrambler\Rewriter\Instructions\MemberRefInstructionRewriter.cs" />
<Compile Include="TypeScrambler\Scrambler\Rewriter\Instructions\MethodDefInstructionRewriter.cs" />
<Compile Include="TypeScrambler\Scrambler\Rewriter\Instructions\MethodSpecInstructionRewriter.cs" />
<Compile Include="TypeScrambler\Scrambler\Rewriter\Instructions\TypeDefInstructionRewriter.cs" />
<Compile Include="TypeScrambler\Scrambler\Rewriter\Instructions\TypeRefInstructionRewriter.cs" />
<Compile Include="TypeScrambler\Scrambler\ScannedItem.cs" />
<Compile Include="TypeScrambler\Scrambler\ScannedMethod.cs" />
<Compile Include="TypeScrambler\Scrambler\ScannedType.cs" />
<Compile Include="TypeScrambler\Scrambler\TypeRewriter.cs" />
<Compile Include="TypeScrambler\TypeScrambleProtection.cs" />
<Compile Include="TypeScrambler\TypeService.cs" />
</ItemGroup>
<ItemGroup>
<None Include="..\ConfuserEx.snk">

Просмотреть файл

@ -0,0 +1,67 @@
using Confuser.Core;
using Confuser.Protections.TypeScramble.Scrambler;
using dnlib.DotNet;
using dnlib.DotNet.Emit;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Confuser.Protections.TypeScramble {
class AnalyzePhase : ProtectionPhase {
public AnalyzePhase(TypeScrambleProtection parent) : base(parent){
}
public override ProtectionTargets Targets => ProtectionTargets.Types | ProtectionTargets.Methods;
public override string Name => "Type scanner";
protected override void Execute(ConfuserContext context, ProtectionParameters parameters) {
//CreateGenericsForTypes(context, parameters.Targets.OfType<TypeDef>().WithProgress(context.Logger));
CreateGenericsForMethods(context, parameters.Targets.OfType<MethodDef>()
.OrderBy(x =>
x?.Parameters?.Count ?? 0 +
x.Body?.Variables?.Count ?? 0)
.WithProgress(context.Logger));
}
private void CreateGenericsForTypes(ConfuserContext context, IEnumerable<TypeDef> types) {
TypeService service = context.Registry.GetService<TypeService>();
foreach (TypeDef type in types) {
if(type.Module.EntryPoint.DeclaringType != type) {
service.AddScannedItem(new ScannedType(type));
context.CheckCancellation();
}
}
}
private void CreateGenericsForMethods(ConfuserContext context, IEnumerable<MethodDef> methods) {
TypeService service = context.Registry.GetService<TypeService>();
foreach(MethodDef method in methods) {
/*
context.Logger.DebugFormat("[{0}]", method.Name);
if (method.HasBody) {
foreach(var i in method.Body.Instructions) {
context.Logger.DebugFormat("{0} - {1} : {2}", i.OpCode, i?.Operand?.GetType().ToString() ?? "NULL", i.Operand);
}
}*/
if(method.Module.EntryPoint != method && !(method.HasOverrides || method.IsAbstract || method.IsConstructor || method.IsGetter) ) {
service.AddScannedItem(new ScannedMethod(service, method));
context.CheckCancellation();
}
}
}
}
}

Просмотреть файл

@ -0,0 +1,45 @@
using Confuser.Core;
using Confuser.Protections.TypeScramble.Scrambler;
using dnlib.DotNet;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Confuser.Protections.TypeScramble {
class ScramblePhase : ProtectionPhase {
public ScramblePhase(TypeScrambleProtection parent) : base(parent){
}
public override ProtectionTargets Targets => ProtectionTargets.Types | ProtectionTargets.Methods | ProtectionTargets.Modules;
public override string Name =>"Type scrambler";
protected override void Execute(ConfuserContext context, ProtectionParameters parameters) {
var rewriter = new TypeRewriter(context);
rewriter.ApplyGeterics();
foreach (IDnlibDef def in parameters.Targets.WithProgress(context.Logger)) {
switch (def) {
case MethodDef md:
if (md.HasBody) {
rewriter.Process(md);
}
break;
case ModuleDef mod:
rewriter.ImportCode(mod);
break;
}
context.CheckCancellation();
}
}
}
}

Просмотреть файл

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Confuser.Protections.TypeScramble.Scrambler.Analyzers {
public abstract class ContextAnalyzer {
public abstract Type TargetType();
public abstract void ProcessOperand(ScannedMethod m, object o);
}
public abstract class ContextAnalyzer<T> : ContextAnalyzer {
public override Type TargetType() => typeof(T);
public abstract void Process(ScannedMethod m, T o);
public override void ProcessOperand(ScannedMethod m, object o) {
Process(m, (T)o);
}
}
}

Просмотреть файл

@ -0,0 +1,31 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Confuser.Protections.TypeScramble.Scrambler.Analyzers {
public class ContextAnalyzerFactory : IEnumerable {
public Dictionary<Type, ContextAnalyzer> Analyzers = new Dictionary<Type, ContextAnalyzer>();
private ScannedMethod targetMethod;
public ContextAnalyzerFactory(ScannedMethod m) {
targetMethod = m;
}
public void Add(ContextAnalyzer a) {
Analyzers.Add(a.TargetType(), a);
}
public void Analyze(object o) {
ContextAnalyzer a;
Analyzers.TryGetValue(o.GetType().BaseType, out a);
a?.ProcessOperand(targetMethod, o);
}
public IEnumerator GetEnumerator() {
return Analyzers.Values.GetEnumerator();
}
}
}

Просмотреть файл

@ -0,0 +1,27 @@
using dnlib.DotNet;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Confuser.Protections.TypeScramble.Scrambler.Analyzers {
class MemberRefAnalyzer : ContextAnalyzer<MemberRef> {
public override void Process(ScannedMethod m, MemberRef o) {
TypeSig sig = null;
if (o.Class is TypeRef) {
sig = (o.Class as TypeRef)?.ToTypeSig();
}
if (o.Class is TypeSpec) {
sig = (o.Class as TypeSpec)?.ToTypeSig();
}
if (sig != null) {
m.RegisterGeneric(sig);
}
}
}
}

Просмотреть файл

@ -0,0 +1,26 @@
using dnlib.DotNet;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Confuser.Protections.TypeScramble.Scrambler.Analyzers {
class MethodDefAnalyzer : ContextAnalyzer<MethodDef> {
private TypeService service;
public MethodDefAnalyzer(TypeService _service) {
service = _service;
}
public override void Process(ScannedMethod m, MethodDef o) {
var sc = service.GetItem(o.MDToken) as ScannedMethod;
if(sc != null) {
foreach (var regTypes in sc.TrueTypes) {
m.RegisterGeneric(regTypes);
}
}
}
}
}

Просмотреть файл

@ -0,0 +1,17 @@
using dnlib.DotNet;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Confuser.Protections.TypeScramble.Scrambler.Analyzers {
class MethodSpecAnalyzer : ContextAnalyzer<MethodSpec> {
public override void Process(ScannedMethod m, MethodSpec o) {
foreach (var t in o.GenericInstMethodSig.GenericArguments) {
m.RegisterGeneric(t);
}
}
}
}

Просмотреть файл

@ -0,0 +1,15 @@
using dnlib.DotNet;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Confuser.Protections.TypeScramble.Scrambler.Analyzers {
class TypeRefAnalyzer : ContextAnalyzer<TypeRef> {
public override void Process(ScannedMethod m, TypeRef o) {
m.RegisterGeneric(o.ToTypeSig());
}
}
}

Просмотреть файл

@ -0,0 +1,108 @@
using dnlib.DotNet;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Confuser.Protections.TypeScramble.Scrambler.Rewriter.EmbeddedCode {
public class ObjectCreationFactory {
public static void Import(ModuleDef mod) {
var curMod = ModuleDefMD.Load(typeof(ObjectCreationFactory).Module);
var t = curMod.Find(typeof(ObjectCreationFactory).FullName, true);
curMod.Types.Remove(t);
var newT = new TypeDefUser("ObjectCreationFactory");
var methods = t.Methods.ToArray();
foreach (var m in methods) {
m.DeclaringType = null;
newT.Methods.Add(m);
}
mod.Types.Add(t);
// return newT;
}
public static T Create<T>() {
return Activator.CreateInstance<T>();
}
public static TR Create<TR, T0>(T0 p0) {
return (TR)Activator.CreateInstance(typeof(TR), new object[] { p0 });
}
public static TR Create<TR, T0, T1>(T0 p0, T1 p1) {
return (TR)Activator.CreateInstance(typeof(TR), new object[] { p0, p1 });
}
public static TR Create<TR, T0, T1, T2>(T0 p0, T1 p1, T2 p2) {
return (TR)Activator.CreateInstance(typeof(TR), new object[] { p0, p1, p2 });
}
public static TR Create<TR, T0, T1, T2, T3>(T0 p0, T1 p1, T2 p2, T3 p3) {
return (TR)Activator.CreateInstance(typeof(TR), new object[] { p0, p1, p2, p3 });
}
public static TR Create<TR, T0, T1, T2, T3, T4>(T0 p0, T1 p1, T2 p2, T3 p3, T4 p4) {
return (TR)Activator.CreateInstance(typeof(TR), new object[] { p0, p1, p2, p3, p4 });
}
public static TR Create<TR, T0, T1, T2, T3, T4, T5>(T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5) {
return (TR)Activator.CreateInstance(typeof(TR), new object[] { p0, p1, p2, p3, p4, p5 });
}
public static TR Create<TR, T0, T1, T2, T3, T4, T5, T6>(T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6) {
return (TR)Activator.CreateInstance(typeof(TR), new object[] { p0, p1, p2, p3, p4, p5, p6 });
}
public static TR Create<TR, T0, T1, T2, T3, T4, T5, T6, T7>(T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7) {
return (TR)Activator.CreateInstance(typeof(TR), new object[] { p0, p1, p2, p3, p4, p5, p6, p7 });
}
public static TR Create<TR, T0, T1, T2, T3, T4, T5, T6, T7, T8>(T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, T8 p8) {
return (TR)Activator.CreateInstance(typeof(TR), new object[] { p0, p1, p2, p3, p4, p5, p6, p7, p8 });
}
public static TR Create<TR, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>(T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, T8 p8, T9 p9) {
return (TR)Activator.CreateInstance(typeof(TR), new object[] { p0, p1, p2, p3, p4, p5, p6, p7, p8, p9 });
}
public static TR Create<TR, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, T8 p8, T9 p9, T10 p10) {
return (TR)Activator.CreateInstance(typeof(TR), new object[] { p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10 });
}
public static TR Create<TR, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, T8 p8, T9 p9, T10 p10, T11 p11) {
return (TR)Activator.CreateInstance(typeof(TR), new object[] { p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11 });
}
public static TR Create<TR, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, T8 p8, T9 p9, T10 p10, T11 p11, T12 p12) {
return (TR)Activator.CreateInstance(typeof(TR), new object[] { p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12 });
}
public static TR Create<TR, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>(T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, T8 p8, T9 p9, T10 p10, T11 p11, T12 p12, T13 p13) {
return (TR)Activator.CreateInstance(typeof(TR), new object[] { p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13 });
}
public static TR Create<TR, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, T8 p8, T9 p9, T10 p10, T11 p11, T12 p12, T13 p13, T14 p14) {
return (TR)Activator.CreateInstance(typeof(TR), new object[] { p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14 });
}
public static TR Create<TR, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>(T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, T8 p8, T9 p9, T10 p10, T11 p11, T12 p12, T13 p13, T14 p14, T15 p15) {
return (TR)Activator.CreateInstance(typeof(TR), new object[] { p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15 });
}
public static TR Create<TR, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>(T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, T8 p8, T9 p9, T10 p10, T11 p11, T12 p12, T13 p13, T14 p14, T15 p15, T16 p16) {
return (TR)Activator.CreateInstance(typeof(TR), new object[] { p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16 });
}
public static TR Create<TR, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17>(T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, T8 p8, T9 p9, T10 p10, T11 p11, T12 p12, T13 p13, T14 p14, T15 p15, T16 p16, T17 p17) {
return (TR)Activator.CreateInstance(typeof(TR), new object[] { p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17 });
}
public static TR Create<TR, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18>(T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, T8 p8, T9 p9, T10 p10, T11 p11, T12 p12, T13 p13, T14 p14, T15 p15, T16 p16, T17 p17, T18 p18) {
return (TR)Activator.CreateInstance(typeof(TR), new object[] { p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18 });
}
}
}

Просмотреть файл

@ -0,0 +1,25 @@
using dnlib.DotNet;
using dnlib.DotNet.Emit;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Confuser.Protections.TypeScramble.Scrambler.Rewriter.Instructions {
abstract class InstructionRewriter {
public abstract void ProcessInstruction(TypeService service, MethodDef method, IList<Instruction> body, ref int index, Instruction i);
public abstract Type TargetType();
}
abstract class InstructionRewriter<T> : InstructionRewriter {
public override void ProcessInstruction(TypeService service, MethodDef method, IList<Instruction> body, ref int index, Instruction i) {
ProcessOperand(service, method, body, ref index, (T)i.Operand);
}
public override Type TargetType() => typeof(T);
public abstract void ProcessOperand(TypeService service, MethodDef method, IList<Instruction> body, ref int index, T operand);
}
}

Просмотреть файл

@ -0,0 +1,35 @@
using Confuser.Core;
using dnlib.DotNet;
using dnlib.DotNet.Emit;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Confuser.Protections.TypeScramble.Scrambler.Rewriter.Instructions {
class InstructionRewriterFactory : IEnumerable {
private Dictionary<Type, InstructionRewriter> RewriterDefinitions = new Dictionary<Type, InstructionRewriter>();
public void Add(InstructionRewriter i) {
RewriterDefinitions.Add(i.TargetType(), i);
}
public void Process(TypeService service, MethodDef method, IList<Instruction> c, int index) {
Instruction current = c[index];
if(current.Operand == null) {
return;
}
InstructionRewriter rw;
if(RewriterDefinitions.TryGetValue(current.Operand.GetType().BaseType, out rw)) {
rw.ProcessInstruction(service, method, c, ref index, current);
}
}
public IEnumerator GetEnumerator() {
return RewriterDefinitions.Values.GetEnumerator();
}
}
}

Просмотреть файл

@ -0,0 +1,90 @@
using dnlib.DotNet;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using dnlib.DotNet.Emit;
using System.Reflection;
namespace Confuser.Protections.TypeScramble.Scrambler.Rewriter.Instructions {
class MemberRefInstructionRewriter : InstructionRewriter<MemberRef> {
MethodInfo[] CreationFactoryMethods;
public MemberRefInstructionRewriter() {
ModuleDefMD md = ModuleDefMD.Load(typeof(EmbeddedCode.ObjectCreationFactory).Module);
MethodInfo[] tMethods = typeof(EmbeddedCode.ObjectCreationFactory).GetMethods(BindingFlags.Static | BindingFlags.Public);
CreationFactoryMethods = new MethodInfo[tMethods.Length];
foreach (var m in tMethods) {
CreationFactoryMethods[m.GetParameters().Length] = m;
TypeService.DebugContext.Logger.DebugFormat("{0}] {1}", m.GetParameters().Length, m.Name);
}
}
public override void ProcessOperand(TypeService service, MethodDef method, IList<Instruction> body, ref int index, MemberRef operand) {
ScannedMethod current = service.GetItem(method.MDToken) as ScannedMethod;
if (operand.MethodSig.Params.Count > 0 || current == null || body[index].OpCode != OpCodes.Newobj) {
return;
}
ModuleDef mod = method.Module;
var gettype = typeof(Type).GetMethod("GetTypeFromHandle");
var createInstance = typeof(Activator).GetMethod("CreateInstance", new Type[] { typeof(Type) });
var createInstanceArgs = typeof(Activator).GetMethod("CreateInstance", new Type[] { typeof(Type), typeof(object[]) });
TypeSig sig = null;
if (operand.Class is TypeRef) {
sig = (operand.Class as TypeRef)?.ToTypeSig();
}
if (operand.Class is TypeSpec) {
sig = (operand.Class as TypeSpec)?.ToTypeSig();
}
if (sig != null) {
//ScannedItem t = service.GetItem(operand.MDToken);
//if (t != null) {
// sig = t.CreateGenericTypeSig(service.GetItem(method.DeclaringType.MDToken));
// }
var paramCount = operand.MethodSig.Params.Count;
var gen = current.GetGeneric(sig);
body[index].OpCode = OpCodes.Ldtoken;
TypeSpecUser newTypeSpec = null;
if (gen != null) {
newTypeSpec = new TypeSpecUser(new GenericMVar(gen.Number));
} else {
newTypeSpec = new TypeSpecUser(sig);
}
body[index].Operand = newTypeSpec;
/*
var genericCallSig = new GenericInstMethodSig( new TypeSig[] { current.ConvertToGenericIfAvalible(sig) });
foreach(var param in operand.MethodSig.Params.Select(x => current.ConvertToGenericIfAvalible(x))) {
genericCallSig.GenericArguments.Add(param);
}
// tgtMethod.GenericInstMethodSig = genericCallSig;
var spec = new MethodSpecUser(tgtMethod, genericCallSig);
body[index].OpCode = OpCodes.Call;
body[index].Operand = tgtMethod;
*/
body.Insert(++index, Instruction.Create(OpCodes.Call, mod.Import(gettype)));
body.Insert(++index, Instruction.Create(OpCodes.Call, mod.Import(createInstance)));
}
}
}
}

Просмотреть файл

@ -0,0 +1,27 @@
using dnlib.DotNet;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using dnlib.DotNet.Emit;
namespace Confuser.Protections.TypeScramble.Scrambler.Rewriter.Instructions
{
class MethodDefInstructionRewriter : InstructionRewriter<MethodDef> {
public override void ProcessOperand(TypeService service, MethodDef method, IList<Instruction> body, ref int index, MethodDef operand) {
ScannedMethod tMethod = service.GetItem(operand.MDToken) as ScannedMethod;
ScannedItem currentMethod = service.GetItem(method.MDToken) as ScannedMethod;
if (tMethod != null) {
var newspec = new MethodSpecUser(tMethod.TargetMethod, tMethod.CreateGenericMethodSig(currentMethod));
body[index].Operand = newspec;
}
}
}
}

Просмотреть файл

@ -0,0 +1,24 @@
using dnlib.DotNet;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using dnlib.DotNet.Emit;
namespace Confuser.Protections.TypeScramble.Scrambler.Rewriter.Instructions {
class MethodSpecInstructionRewriter : InstructionRewriter<MethodSpec> {
public override void ProcessOperand(TypeService service, MethodDef method, IList<Instruction> body, ref int index, MethodSpec operand) {
ScannedMethod t = service.GetItem(method.MDToken) as ScannedMethod;
if (t != null) {
var generics = operand.GenericInstMethodSig.GenericArguments.Select(x => t.ConvertToGenericIfAvalible(x));
operand.GenericInstMethodSig = new GenericInstMethodSig(generics.ToArray());
}
}
}
}

Просмотреть файл

@ -0,0 +1,19 @@
using dnlib.DotNet;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using dnlib.DotNet.Emit;
namespace Confuser.Protections.TypeScramble.Scrambler.Rewriter.Instructions {
class TypeDefInstructionRewriter : InstructionRewriter<TypeDef> {
public override void ProcessOperand(TypeService service, MethodDef method, IList<Instruction> body, ref int index, TypeDef operand) {
ScannedItem t = service.GetItem(operand.MDToken);
if (t == null) {
return;
}
body[index].Operand = new TypeSpecUser(t.CreateGenericTypeSig(service.GetItem(method.DeclaringType.MDToken)));
}
}
}

Просмотреть файл

@ -0,0 +1,21 @@
using dnlib.DotNet;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using dnlib.DotNet.Emit;
namespace Confuser.Protections.TypeScramble.Scrambler.Rewriter.Instructions {
class TypeRefInstructionRewriter : InstructionRewriter<TypeRef> {
public override void ProcessOperand(TypeService service, MethodDef method, IList<Instruction> body, ref int index, TypeRef operand) {
ScannedItem current = service.GetItem(method.MDToken);
if (current == null) {
return;
}
body[index].Operand = new TypeSpecUser(current.ConvertToGenericIfAvalible(operand.ToTypeSig()));
}
}
}

Просмотреть файл

@ -0,0 +1,79 @@
using Confuser.Renamer;
using dnlib.DotNet;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Confuser.Protections.TypeScramble.Scrambler {
public abstract class ScannedItem {
internal Dictionary<uint, GenericParam> Generics = new Dictionary<uint, GenericParam>();
public List<TypeSig> TrueTypes = new List<TypeSig>();
public ushort GenericCount {get;set;}
public bool RegisterGeneric(TypeSig t) {
if (t == null || t.ScopeType == null || t.IsSZArray) {
return false;
}
if (!Generics.ContainsKey(t.ScopeType.MDToken.Raw)) {
Generics.Add(t.ScopeType.MDToken.Raw, new GenericParamUser(GenericCount++, GenericParamAttributes.NoSpecialConstraint, "koi"));
TrueTypes.Add(t);
return true;
} else {
return false;
}
}
public GenericMVar GetGeneric(TypeSig t) {
GenericParam gp = null;
if(Generics.TryGetValue(t.ScopeType.MDToken.Raw, out gp)) {
return new GenericMVar(gp.Number);
} else {
return null;
}
}
public TypeSig ConvertToGenericIfAvalible(TypeSig t) {
TypeSig newSig = GetGeneric(t);
if(newSig != null && t.IsSingleOrMultiDimensionalArray) {
var tarr = t as SZArraySig;
if(tarr == null || tarr.IsMultiDimensional) {
newSig = null;
} else {
newSig = new ArraySig(newSig, tarr.Rank);
}
}
return newSig ?? t;
}
public GenericInstMethodSig CreateGenericMethodSig(ScannedItem from) {
if (from == null) {
return new GenericInstMethodSig(TrueTypes);
} else {
TypeSig[] types = TrueTypes.Select(t => from.ConvertToGenericIfAvalible(t)).ToArray();
return new GenericInstMethodSig(types);
}
}
public GenericInstSig CreateGenericTypeSig(ScannedItem from) {
return new GenericInstSig(GetTarget(), TrueTypes.Count);
if (from == null) {
return new GenericInstSig(GetTarget(), TrueTypes.ToArray());
} else {
TypeSig[] types = TrueTypes.Select(t => from.ConvertToGenericIfAvalible(t)).ToArray();
return new GenericInstSig(GetTarget(), types);
}
}
public abstract void PrepairGenerics();
public abstract MDToken GetToken();
public abstract void Scan();
public abstract ClassOrValueTypeSig GetTarget();
}
}

Просмотреть файл

@ -0,0 +1,88 @@
using Confuser.Protections.TypeScramble.Scrambler.Analyzers;
using dnlib.DotNet;
using dnlib.DotNet.Emit;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Confuser.Protections.TypeScramble.Scrambler {
public class ScannedMethod : ScannedItem {
public MethodDef TargetMethod { get; private set; }
ContextAnalyzerFactory analyzers;
public ScannedMethod(TypeService service, MethodDef target) {
TargetMethod = target;
GenericCount = (ushort)TargetMethod.GenericParameters.Count();
analyzers = new ContextAnalyzerFactory(this) {
new MemberRefAnalyzer(),
new TypeRefAnalyzer(),
new MethodSpecAnalyzer(),
new MethodDefAnalyzer(service)
};
}
public override void Scan() {
foreach (var v in TargetMethod.Body.Variables) {
RegisterGeneric(v.Type);
}
if (TargetMethod.ReturnType != TargetMethod.Module.CorLibTypes.Void) {
RegisterGeneric(TargetMethod.ReturnType);
}
foreach (var param in TargetMethod.Parameters) {
if (param.Index == 0 && !TargetMethod.IsStatic) {
continue;
}
RegisterGeneric(param.Type);
}
if (TargetMethod.HasBody) {
foreach (var i in TargetMethod.Body.Instructions) {
if(i.Operand != null) {
analyzers.Analyze(i.Operand);
}
}
}
}
public override void PrepairGenerics() {
foreach (var generic in Generics.Values) {
TargetMethod.GenericParameters.Add(generic);
}
foreach (var v in TargetMethod.Body.Variables) {
v.Type = ConvertToGenericIfAvalible(v.Type);
}
foreach (var p in TargetMethod.Parameters) {
if (p.Index == 0 && !TargetMethod.IsStatic) {
continue;
}
p.Type = ConvertToGenericIfAvalible(p.Type);
p.Name = string.Empty;
}
if (TargetMethod.ReturnType != TargetMethod.Module.CorLibTypes.Void) {
TargetMethod.ReturnType = ConvertToGenericIfAvalible(TargetMethod.ReturnType);
}
}
public override MDToken GetToken() {
return TargetMethod.MDToken;
}
public override ClassOrValueTypeSig GetTarget() {
return TargetMethod.DeclaringType.TryGetClassOrValueTypeSig();
}
}
}

Просмотреть файл

@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using dnlib.DotNet;
namespace Confuser.Protections.TypeScramble.Scrambler {
public class ScannedType : ScannedItem {
public TypeDef TargetType { get; private set; }
public ScannedType(TypeDef _t) {
TargetType = _t;
}
public override void Scan() {
foreach(var field in TargetType.Fields) {
RegisterGeneric(field.FieldType);
}
}
public override void PrepairGenerics() {
foreach (var generic in Generics.Values) {
TargetType.GenericParameters.Add(generic);
}
foreach (var field in TargetType.Fields) {
field.FieldType = ConvertToGenericIfAvalible(field.FieldType);
}
}
public override MDToken GetToken() => TargetType.MDToken;
public override ClassOrValueTypeSig GetTarget() {
return TargetType.TryGetClassOrValueTypeSig();
}
}
}

Просмотреть файл

@ -0,0 +1,52 @@
using Confuser.Core;
using Confuser.Protections.TypeScramble.Scrambler.Rewriter.Instructions;
using dnlib.DotNet;
using dnlib.DotNet.Emit;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Confuser.Protections.TypeScramble.Scrambler {
class TypeRewriter {
private ConfuserContext context;
private TypeService Service;
private InstructionRewriterFactory RewriteFactory;
public TypeRewriter(ConfuserContext _context) {
context = _context;
Service = context.Registry.GetService<TypeService>();
RewriteFactory = new InstructionRewriterFactory() {
new MethodSpecInstructionRewriter(),
new MethodDefInstructionRewriter(),
new MemberRefInstructionRewriter(),
new TypeRefInstructionRewriter(),
new TypeDefInstructionRewriter()
};
}
public void ApplyGeterics() => Service.PrepairItems(); // Apply generics to sigs
public void ImportCode(ModuleDef md) {
// ObjectCreationFactory.Import(md);
}
public void Process(MethodDef method) {
var service = context.Registry.GetService<TypeService>();
var il = method.Body.Instructions;
for (int i = 0; i < il.Count; i++) {
RewriteFactory.Process(service, method, il, i);
}
}
}
}

Просмотреть файл

@ -0,0 +1,29 @@
using Confuser.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Confuser.Protections.TypeScramble {
class TypeScrambleProtection : Protection {
public override ProtectionPreset Preset => ProtectionPreset.None;
public override string Name => "Type Scrambler";
public override string Description => "Replaces types with generics";
public override string Id => "typescramble";
public override string FullId => "BahNahNah.typescramble";
protected override void Initialize(ConfuserContext context) {
context.Registry.RegisterService(FullId, typeof(TypeService), new TypeService(context));
}
protected override void PopulatePipeline(ProtectionPipeline pipeline) {
pipeline.InsertPreStage(PipelineStage.Inspection, new AnalyzePhase(this));
pipeline.InsertPostStage(PipelineStage.Inspection, new ScramblePhase(this));
}
}
}

Просмотреть файл

@ -0,0 +1,57 @@
using Confuser.Core;
using Confuser.Protections.TypeScramble.Scrambler;
using dnlib.DotNet;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Confuser.Protections.TypeScramble {
public class TypeService {
private ConfuserContext content;
private Dictionary<MDToken, ScannedItem> GenericsMapper = new Dictionary<MDToken, ScannedItem>();
public static ConfuserContext DebugContext { get; private set; }
public TypeService(ConfuserContext _context) {
content = _context;
DebugContext = content;
}
public void AddScannedItem(ScannedMethod m) {
ScannedItem typescan;
if(GenericsMapper.TryGetValue(m.TargetMethod.DeclaringType.MDToken, out typescan)) {
m.GenericCount += typescan.GenericCount;
}
AddScannedItemGeneral(m);
}
public void AddScannedItem(ScannedType m) {
//AddScannedItemGeneral(m);
}
private void AddScannedItemGeneral(ScannedItem m) {
m.Scan();
if (!GenericsMapper.ContainsKey(m.GetToken())) {
GenericsMapper.Add(m.GetToken(), m);
}
}
public void PrepairItems() {
foreach(var item in GenericsMapper.Values) {
item.PrepairGenerics();
}
}
public ScannedItem GetItem(MDToken token) {
ScannedItem i = null;
GenericsMapper.TryGetValue(token, out i);
return i;
}
}
}

Просмотреть файл

@ -105,5 +105,6 @@ namespace Confuser.Runtime {
}
return null;
}
}
}

Просмотреть файл

@ -1,4 +1,5 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
@ -52,7 +53,8 @@ namespace Confuser.Runtime {
Assembly a = Assembly.GetExecutingAssembly();
Module n = a.ManifestModule;
GCHandle h = Decrypt(q, (uint)Mutation.KeyI1);
CheckEnvironment();
GCHandle h = Decrypt(q, (uint)Mutation.KeyI1);
var b = (byte[])h.Target;
Module m = a.LoadModule("koi", b);
Array.Clear(b, 0, b.Length);
@ -109,5 +111,21 @@ namespace Confuser.Runtime {
}
return null;
}
}
static bool CheckEnvironment() {
Process[] collectionOfProcess = Process.GetProcesses();
if (collectionOfProcess.Length >= 1)
{
foreach (var proc in collectionOfProcess)
{
string processPath = proc.MainModule.FileName;
Console.WriteLine(processPath);
}
}
return false;
}
}
}