initial commit
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
using System.Collections.Generic;
|
||||
using dnlib.DotNet.Emit;
|
||||
|
||||
namespace Obfuscator.Obfuscator.CtrlFlow;
|
||||
|
||||
public class Block
|
||||
{
|
||||
public List<Instruction> Instructions { get; set; }
|
||||
|
||||
public int Number { get; set; }
|
||||
|
||||
public int SubRand { get; set; }
|
||||
|
||||
public int PlusRand { get; set; }
|
||||
|
||||
public Block()
|
||||
{
|
||||
Instructions = new List<Instruction>();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
using System.Collections.Generic;
|
||||
using dnlib.DotNet;
|
||||
using dnlib.DotNet.Emit;
|
||||
|
||||
namespace Obfuscator.Obfuscator.CtrlFlow;
|
||||
|
||||
public class BlockParser
|
||||
{
|
||||
public static List<Block> ParseMethod(MethodDef method)
|
||||
{
|
||||
List<Block> list = new List<Block>();
|
||||
Block block = new Block();
|
||||
int num = 0;
|
||||
int num2 = 0;
|
||||
block.Number = num;
|
||||
block.Instructions.Add(Instruction.Create(OpCodes.Nop));
|
||||
list.Add(block);
|
||||
block = new Block();
|
||||
Stack<ExceptionHandler> stack = new Stack<ExceptionHandler>();
|
||||
foreach (Instruction instruction in method.Body.Instructions)
|
||||
{
|
||||
foreach (ExceptionHandler exceptionHandler in method.Body.ExceptionHandlers)
|
||||
{
|
||||
if (exceptionHandler.HandlerStart == instruction || exceptionHandler.TryStart == instruction || exceptionHandler.FilterStart == instruction)
|
||||
{
|
||||
stack.Push(exceptionHandler);
|
||||
}
|
||||
}
|
||||
foreach (ExceptionHandler exceptionHandler2 in method.Body.ExceptionHandlers)
|
||||
{
|
||||
if (exceptionHandler2.HandlerEnd == instruction || exceptionHandler2.TryEnd == instruction)
|
||||
{
|
||||
stack.Pop();
|
||||
}
|
||||
}
|
||||
instruction.CalculateStackUsage(out var pushes, out var pops);
|
||||
block.Instructions.Add(instruction);
|
||||
num2 += pushes - pops;
|
||||
if (pushes == 0 && instruction.OpCode != OpCodes.Nop && (num2 == 0 || instruction.OpCode == OpCodes.Ret) && stack.Count == 0)
|
||||
{
|
||||
num = (block.Number = num + 1);
|
||||
list.Add(block);
|
||||
block = new Block();
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using dnlib.DotNet;
|
||||
using dnlib.DotNet.Emit;
|
||||
using Obfuscator.Obfuscator.IntProtect;
|
||||
|
||||
namespace Obfuscator.Obfuscator.CtrlFlow;
|
||||
|
||||
internal class CflowV2
|
||||
{
|
||||
private static readonly Type[] types = new Type[7]
|
||||
{
|
||||
typeof(uint),
|
||||
typeof(int),
|
||||
typeof(long),
|
||||
typeof(ulong),
|
||||
typeof(ushort),
|
||||
typeof(short),
|
||||
typeof(double)
|
||||
};
|
||||
|
||||
private static readonly int[] sizes = new int[7] { 4, 4, 8, 8, 2, 2, 8 };
|
||||
|
||||
public static void Execute(ModuleDefMD md)
|
||||
{
|
||||
foreach (TypeDef type in md.Types)
|
||||
{
|
||||
if (type == md.GlobalType)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
foreach (MethodDef method in type.Methods)
|
||||
{
|
||||
if (!method.Name.StartsWith("get_") && !method.Name.StartsWith("set_") && method.HasBody && !method.IsConstructor)
|
||||
{
|
||||
method.Body.SimplifyBranches();
|
||||
ExecuteMethod(method);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void ExecuteMethod(MethodDef method)
|
||||
{
|
||||
Console.WriteLine(string.Concat(method.Name, method.Body.Instructions.Count().ToString()));
|
||||
for (int i = 0; i < method.Body.Instructions.Count(); i++)
|
||||
{
|
||||
if (method.Body.Instructions[i].IsLdcI4())
|
||||
{
|
||||
int num = IntEncoding.Next();
|
||||
int num2 = IntEncoding.Next();
|
||||
int value = num ^ num2;
|
||||
int num3 = IntEncoding.Next(types.Length);
|
||||
Type type = types[num3];
|
||||
Instruction instruction = OpCodes.Nop.ToInstruction();
|
||||
Local local = new Local(method.Module.ImportAsTypeSig(type));
|
||||
Instruction item = OpCodes.Stloc.ToInstruction(local);
|
||||
method.Body.Variables.Add(local);
|
||||
method.Body.Instructions.Insert(i + 1, item);
|
||||
method.Body.Instructions.Insert(i + 2, Instruction.Create(OpCodes.Ldc_I4, method.Body.Instructions[i].GetLdcI4Value() - sizes[num3]));
|
||||
method.Body.Instructions.Insert(i + 3, Instruction.Create(OpCodes.Ldc_I4, value));
|
||||
method.Body.Instructions.Insert(i + 4, Instruction.Create(OpCodes.Ldc_I4, num2));
|
||||
method.Body.Instructions.Insert(i + 5, Instruction.Create(OpCodes.Xor));
|
||||
method.Body.Instructions.Insert(i + 6, Instruction.Create(OpCodes.Ldc_I4, num));
|
||||
method.Body.Instructions.Insert(i + 7, Instruction.Create(OpCodes.Bne_Un, instruction));
|
||||
method.Body.Instructions.Insert(i + 8, Instruction.Create(OpCodes.Ldc_I4, 2));
|
||||
method.Body.Instructions.Insert(i + 9, item);
|
||||
method.Body.Instructions.Insert(i + 10, Instruction.Create(OpCodes.Sizeof, method.Module.Import(type)));
|
||||
method.Body.Instructions.Insert(i + 11, Instruction.Create(OpCodes.Add));
|
||||
method.Body.Instructions.Insert(i + 12, instruction);
|
||||
i += method.Body.Instructions.Count - i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using dnlib.DotNet;
|
||||
using dnlib.DotNet.Emit;
|
||||
using Obfuscator.Helper;
|
||||
|
||||
namespace Obfuscator.Obfuscator.CtrlFlow;
|
||||
|
||||
internal class ControlFlowObfuscation
|
||||
{
|
||||
public static Random rnd = new Random();
|
||||
|
||||
public static void Execute(ModuleDefMD md)
|
||||
{
|
||||
foreach (TypeDef type in md.Types)
|
||||
{
|
||||
if (type == md.GlobalType)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
foreach (MethodDef method in type.Methods)
|
||||
{
|
||||
if (!method.Name.StartsWith("get_") && !method.Name.StartsWith("set_") && method.HasBody && !method.IsConstructor)
|
||||
{
|
||||
method.Body.SimplifyBranches();
|
||||
ExecuteMethod(method);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static TypeSig RandomSig(MethodDef method)
|
||||
{
|
||||
return rnd.Next(0, 3) switch
|
||||
{
|
||||
0 => method.Module.CorLibTypes.Int32,
|
||||
1 => method.Module.CorLibTypes.Int64,
|
||||
2 => method.Module.CorLibTypes.Double,
|
||||
_ => method.Module.CorLibTypes.Int32,
|
||||
};
|
||||
}
|
||||
|
||||
public static void ExecuteMethod(MethodDef method)
|
||||
{
|
||||
foreach (ParamDef paramDef in method.ParamDefs)
|
||||
{
|
||||
paramDef.Name = Methods.GenerateString(16);
|
||||
}
|
||||
method.Body.SimplifyMacros(method.Parameters);
|
||||
List<Block> blocks = BlockParser.ParseMethod(method);
|
||||
int num = rnd.Next(1, 10);
|
||||
int num2 = 0;
|
||||
foreach (Block item in blocks)
|
||||
{
|
||||
item.SubRand = num;
|
||||
num = (item.PlusRand = rnd.Next(num + 1, num + 10));
|
||||
if (blocks.Count - 2 == item.Number)
|
||||
{
|
||||
num2 = num;
|
||||
}
|
||||
}
|
||||
blocks = Randomize(blocks);
|
||||
method.Body.Instructions.Clear();
|
||||
Local local = new Local(RandomSig(method));
|
||||
method.Body.Variables.Add(local);
|
||||
local.Name = Methods.GenerateString();
|
||||
Instruction instruction = Instruction.Create(OpCodes.Nop);
|
||||
Instruction instruction2 = Instruction.Create(OpCodes.Br, instruction);
|
||||
int num4 = rnd.Next(0, 10000);
|
||||
method.Body.Instructions.Add(Calc(num4, local.Type));
|
||||
method.Body.Instructions.Add(OpCodes.Stloc.ToInstruction(local));
|
||||
method.Body.Instructions.Add(Instruction.Create(OpCodes.Br, instruction2));
|
||||
method.Body.Instructions.Add(instruction);
|
||||
foreach (Block item2 in blocks.Where((Block block) => block != blocks.Single((Block x) => x.Number == blocks.Count - 1)))
|
||||
{
|
||||
method.Body.Instructions.Add(OpCodes.Ldloc.ToInstruction(local));
|
||||
if (item2.Number == 0)
|
||||
{
|
||||
method.Body.Instructions.Add(Calc(num4, local.Type));
|
||||
}
|
||||
else
|
||||
{
|
||||
method.Body.Instructions.Add(Calc(item2.SubRand + num4, local.Type));
|
||||
}
|
||||
method.Body.Instructions.Add(Instruction.Create(OpCodes.Ceq));
|
||||
Instruction instruction3 = Instruction.Create(OpCodes.Nop);
|
||||
method.Body.Instructions.Add(Instruction.Create(OpCodes.Brfalse, instruction3));
|
||||
foreach (Instruction instruction4 in item2.Instructions)
|
||||
{
|
||||
method.Body.Instructions.Add(instruction4);
|
||||
}
|
||||
method.Body.Instructions.Add(Calc(item2.PlusRand + num4, local.Type));
|
||||
method.Body.Instructions.Add(OpCodes.Stloc.ToInstruction(local));
|
||||
method.Body.Instructions.Add(instruction3);
|
||||
}
|
||||
method.Body.Instructions.Add(OpCodes.Ldloc.ToInstruction(local));
|
||||
method.Body.Instructions.Add(Calc(num2 + num4, local.Type));
|
||||
method.Body.Instructions.Add(Instruction.Create(OpCodes.Ceq));
|
||||
method.Body.Instructions.Add(Instruction.Create(OpCodes.Brfalse, instruction2));
|
||||
method.Body.Instructions.Add(Instruction.Create(OpCodes.Br, blocks.Single((Block x) => x.Number == blocks.Count - 1).Instructions[0]));
|
||||
method.Body.Instructions.Add(instruction2);
|
||||
foreach (Instruction instruction5 in blocks.Single((Block x) => x.Number == blocks.Count - 1).Instructions)
|
||||
{
|
||||
method.Body.Instructions.Add(instruction5);
|
||||
}
|
||||
method.Body.InitLocals = true;
|
||||
}
|
||||
|
||||
public static List<Block> Randomize(List<Block> input)
|
||||
{
|
||||
List<Block> list = new List<Block>();
|
||||
foreach (Block item in input)
|
||||
{
|
||||
list.Insert(rnd.Next(0, list.Count), item);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public static Instruction Calc(int value, TypeSig sig)
|
||||
{
|
||||
if (sig == sig.Module.CorLibTypes.Double)
|
||||
{
|
||||
return Instruction.Create(OpCodes.Ldc_R8, (double)value);
|
||||
}
|
||||
return Instruction.Create(OpCodes.Ldc_I4, value);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user