-
-
Notifications
You must be signed in to change notification settings - Fork 3
/
ControlFlow.cs
92 lines (82 loc) · 3.97 KB
/
ControlFlow.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
using dnlib.DotNet;
using dnlib.DotNet.Emit;
using System;
using System.Collections.Generic;
using System.Linq;
namespace IP_Grabber
{
internal class ControlFlowObfuscation
{
public static void Execute(ModuleDefMD md)
{
foreach (var tDef in md.Types)
{
if (tDef == md.GlobalType) continue;
foreach (var mDef in tDef.Methods)
{
if (mDef.Name.StartsWith("get_") || mDef.Name.StartsWith("set_")) continue;
if (!mDef.HasBody || mDef.IsConstructor) continue;
mDef.Body.SimplifyBranches();
ExecuteMethod(mDef);
}
}
}
public static void ExecuteMethod(MethodDef method)
{
method.Body.SimplifyMacros(method.Parameters);
var blocks = BlockParser.ParseMethod(method);
blocks = Randomize(blocks);
method.Body.Instructions.Clear();
var local = new Local(method.Module.CorLibTypes.Int32);
method.Body.Variables.Add(local);
var target = Instruction.Create(OpCodes.Nop);
var instr = Instruction.Create(OpCodes.Br, target);
foreach (var instruction in Calc(0))
method.Body.Instructions.Add(instruction);
method.Body.Instructions.Add(Instruction.Create(OpCodes.Stloc, local));
method.Body.Instructions.Add(Instruction.Create(OpCodes.Br, instr));
method.Body.Instructions.Add(target);
foreach (var block in blocks.Where(block => block != blocks.Single(x => x.Number == blocks.Count - 1)))
{
method.Body.Instructions.Add(Instruction.Create(OpCodes.Ldloc, local));
foreach (var instruction in Calc(block.Number))
method.Body.Instructions.Add(instruction);
method.Body.Instructions.Add(Instruction.Create(OpCodes.Ceq));
var instruction4 = Instruction.Create(OpCodes.Nop);
method.Body.Instructions.Add(Instruction.Create(OpCodes.Brfalse, instruction4));
foreach (var instruction in block.Instructions)
method.Body.Instructions.Add(instruction);
foreach (var instruction in Calc(block.Number + 1))
method.Body.Instructions.Add(instruction);
method.Body.Instructions.Add(Instruction.Create(OpCodes.Stloc, local));
method.Body.Instructions.Add(instruction4);
}
method.Body.Instructions.Add(Instruction.Create(OpCodes.Ldloc, local));
foreach (var instruction in Calc(blocks.Count - 1))
method.Body.Instructions.Add(instruction);
method.Body.Instructions.Add(Instruction.Create(OpCodes.Ceq));
method.Body.Instructions.Add(Instruction.Create(OpCodes.Brfalse, instr));
method.Body.Instructions.Add(Instruction.Create(OpCodes.Br, blocks.Single(x => x.Number == blocks.Count - 1).Instructions[0]));
method.Body.Instructions.Add(instr);
foreach (var lastBlock in blocks.Single(x => x.Number == blocks.Count - 1).Instructions)
method.Body.Instructions.Add(lastBlock);
}
public static Random rnd = new Random();
public static List<Block> Randomize(List<Block> input)
{
var ret = new List<Block>();
foreach (var group in input)
ret.Insert(rnd.Next(0, ret.Count), group);
return ret;
}
public static List<Instruction> Calc(int value)
{
var instructions = new List<Instruction> { Instruction.Create(OpCodes.Ldc_I4, value) };
return instructions;
}
public void AddJump(IList<Instruction> instrs, Instruction target)
{
instrs.Add(Instruction.Create(OpCodes.Br, target));
}
}
}