重构 DataVirtualizationPass,移除重复代码
parent
7eb4b57b16
commit
b604810171
|
@ -37,8 +37,10 @@ namespace Obfuz.DynamicProxy
|
|||
return _dynamicProxyPolicy.NeedDynamicProxyCallInMethod(method);
|
||||
}
|
||||
|
||||
protected override bool TryObfuscateInstruction(MethodDef method, Instruction inst, IList<Instruction> instructions, int instructionIndex, List<Instruction> obfuscatedInstructions)
|
||||
protected override bool TryObfuscateInstruction(MethodDef method, Instruction inst, IList<Instruction> instructions, int instructionIndex,
|
||||
List<Instruction> outputInstructions, List<Instruction> totalFinalInstructions)
|
||||
{
|
||||
return false;
|
||||
switch (inst.OpCode.Code)
|
||||
{
|
||||
case Code.Call:
|
||||
|
@ -48,7 +50,7 @@ namespace Obfuz.DynamicProxy
|
|||
{
|
||||
return false;
|
||||
}
|
||||
_dynamicProxyObfuscator.Obfuscate(method, calledMethod, false, obfuscatedInstructions);
|
||||
_dynamicProxyObfuscator.Obfuscate(method, calledMethod, false, outputInstructions);
|
||||
return true;
|
||||
}
|
||||
case Code.Callvirt:
|
||||
|
@ -62,7 +64,7 @@ namespace Obfuz.DynamicProxy
|
|||
{
|
||||
return false;
|
||||
}
|
||||
_dynamicProxyObfuscator.Obfuscate(method, calledMethod, true, obfuscatedInstructions);
|
||||
_dynamicProxyObfuscator.Obfuscate(method, calledMethod, true, outputInstructions);
|
||||
return true;
|
||||
}
|
||||
default: return false;
|
||||
|
|
|
@ -27,7 +27,7 @@ namespace Obfuz.Emit
|
|||
|
||||
public DynamicProxyMethodData Allocate(IMethod method)
|
||||
{
|
||||
return null;
|
||||
return default;
|
||||
}
|
||||
|
||||
public void Done()
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
using System;
|
||||
using dnlib.DotNet;
|
||||
using dnlib.DotNet.Emit;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
@ -6,12 +8,9 @@ using System.Threading.Tasks;
|
|||
|
||||
namespace Obfuz.ExprObfuscation
|
||||
{
|
||||
public class ExprObfuscationPass : ObfuscationPassBase
|
||||
{
|
||||
public override void Process(ObfuscatorContext ctx)
|
||||
public class ExprObfuscationPass : MethodBodyObfuscationPassBase
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Start(ObfuscatorContext ctx)
|
||||
{
|
||||
|
@ -22,5 +21,15 @@ namespace Obfuz.ExprObfuscation
|
|||
{
|
||||
|
||||
}
|
||||
|
||||
protected override bool NeedObfuscateMethod(MethodDef method)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected override bool TryObfuscateInstruction(MethodDef callingMethod, Instruction inst, IList<Instruction> instructions, int instructionIndex, List<Instruction> outputInstructions, List<Instruction> totalFinalInstructions)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,8 @@ namespace Obfuz
|
|||
}
|
||||
|
||||
|
||||
protected abstract bool TryObfuscateInstruction(MethodDef callingMethod, Instruction inst, IList<Instruction> instructions, int instructionIndex, List<Instruction> outputInstructions);
|
||||
protected abstract bool TryObfuscateInstruction(MethodDef callingMethod, Instruction inst, IList<Instruction> instructions, int instructionIndex,
|
||||
List<Instruction> outputInstructions, List<Instruction> totalFinalInstructions);
|
||||
|
||||
private void ObfuscateData(MethodDef method)
|
||||
{
|
||||
|
@ -45,18 +46,23 @@ namespace Obfuz
|
|||
for (int i = 0; i < instructions.Count; i++)
|
||||
{
|
||||
Instruction inst = instructions[i];
|
||||
totalFinalInstructions.Add(inst);
|
||||
if (TryObfuscateInstruction(method, inst, instructions, i, outputInstructions))
|
||||
outputInstructions.Clear();
|
||||
if (TryObfuscateInstruction(method, inst, instructions, i, outputInstructions, totalFinalInstructions))
|
||||
{
|
||||
// current instruction may be the target of control flow instruction, so we can't remove it directly.
|
||||
// we replace it with nop now, then remove it in CleanUpInstructionPass
|
||||
inst.OpCode = outputInstructions[0].OpCode;
|
||||
inst.Operand = outputInstructions[0].Operand;
|
||||
totalFinalInstructions.Add(inst);
|
||||
for (int k = 1; k < outputInstructions.Count; k++)
|
||||
{
|
||||
totalFinalInstructions.Add(outputInstructions[k]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
totalFinalInstructions.Add(inst);
|
||||
}
|
||||
}
|
||||
|
||||
instructions.Clear();
|
||||
|
|
|
@ -11,7 +11,7 @@ using UnityEngine.Assertions;
|
|||
namespace Obfuz.Virtualization
|
||||
{
|
||||
|
||||
public class DataVirtualizationPass : ObfuscationPassBase
|
||||
public class DataVirtualizationPass : MethodBodyObfuscationPassBase
|
||||
{
|
||||
private IDataObfuscationPolicy _dataObfuscatorPolicy;
|
||||
private IDataObfuscator _dataObfuscator;
|
||||
|
@ -27,40 +27,14 @@ namespace Obfuz.Virtualization
|
|||
_dataObfuscator.Stop();
|
||||
}
|
||||
|
||||
public override void Process(ObfuscatorContext ctx)
|
||||
protected override bool NeedObfuscateMethod(MethodDef method)
|
||||
{
|
||||
foreach (var ass in ctx.assemblies)
|
||||
{
|
||||
// ToArray to avoid modify list exception
|
||||
foreach (TypeDef type in ass.module.GetTypes().ToArray())
|
||||
{
|
||||
if (type.Name.StartsWith("$Obfuz$"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// ToArray to avoid modify list exception
|
||||
foreach (MethodDef method in type.Methods.ToArray())
|
||||
{
|
||||
if (!method.HasBody || method.Name.StartsWith("$Obfuz$") || !_dataObfuscatorPolicy.NeedObfuscateMethod(method))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// TODO if isGeneratedBy Obfuscator, continue
|
||||
ObfuscateData(method);
|
||||
}
|
||||
}
|
||||
}
|
||||
return _dataObfuscatorPolicy.NeedObfuscateMethod(method);
|
||||
}
|
||||
|
||||
private void ObfuscateData(MethodDef method)
|
||||
protected override bool TryObfuscateInstruction(MethodDef method, Instruction inst, IList<Instruction> instructions, int instructionIndex,
|
||||
List<Instruction> outputInstructions, List<Instruction> totalFinalInstructions)
|
||||
{
|
||||
IList<Instruction> instructions = method.Body.Instructions;
|
||||
var obfuscatedInstructions = new List<Instruction>();
|
||||
var resultInstructions = new List<Instruction>();
|
||||
for (int i = 0; i < instructions.Count; i++)
|
||||
{
|
||||
Instruction inst = instructions[i];
|
||||
bool obfuscated = false;
|
||||
switch (inst.OpCode.OperandType)
|
||||
{
|
||||
case OperandType.InlineI:
|
||||
|
@ -69,15 +43,14 @@ namespace Obfuz.Virtualization
|
|||
case OperandType.ShortInlineR:
|
||||
case OperandType.InlineR:
|
||||
{
|
||||
obfuscatedInstructions.Clear();
|
||||
object operand = inst.Operand;
|
||||
if (operand is int)
|
||||
{
|
||||
int value = (int)operand;
|
||||
if (_dataObfuscatorPolicy.NeedObfuscateInt(method, value))
|
||||
{
|
||||
_dataObfuscator.ObfuscateInt(method, value, obfuscatedInstructions);
|
||||
obfuscated = true;
|
||||
_dataObfuscator.ObfuscateInt(method, value, outputInstructions);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (operand is sbyte)
|
||||
|
@ -85,8 +58,8 @@ namespace Obfuz.Virtualization
|
|||
int value = (sbyte)operand;
|
||||
if (_dataObfuscatorPolicy.NeedObfuscateInt(method, value))
|
||||
{
|
||||
_dataObfuscator.ObfuscateInt(method, value, obfuscatedInstructions);
|
||||
obfuscated = true;
|
||||
_dataObfuscator.ObfuscateInt(method, value, outputInstructions);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (operand is byte)
|
||||
|
@ -94,8 +67,8 @@ namespace Obfuz.Virtualization
|
|||
int value = (byte)operand;
|
||||
if (_dataObfuscatorPolicy.NeedObfuscateInt(method, value))
|
||||
{
|
||||
_dataObfuscator.ObfuscateInt(method, value, obfuscatedInstructions);
|
||||
obfuscated = true;
|
||||
_dataObfuscator.ObfuscateInt(method, value, outputInstructions);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (operand is long)
|
||||
|
@ -103,8 +76,8 @@ namespace Obfuz.Virtualization
|
|||
long value = (long)operand;
|
||||
if (_dataObfuscatorPolicy.NeedObfuscateLong(method, value))
|
||||
{
|
||||
_dataObfuscator.ObfuscateLong(method, value, obfuscatedInstructions);
|
||||
obfuscated = true;
|
||||
_dataObfuscator.ObfuscateLong(method, value, outputInstructions);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (operand is float)
|
||||
|
@ -112,8 +85,8 @@ namespace Obfuz.Virtualization
|
|||
float value = (float)operand;
|
||||
if (_dataObfuscatorPolicy.NeedObfuscateFloat(method, value))
|
||||
{
|
||||
_dataObfuscator.ObfuscateFloat(method, value, obfuscatedInstructions);
|
||||
obfuscated = true;
|
||||
_dataObfuscator.ObfuscateFloat(method, value, outputInstructions);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (operand is double)
|
||||
|
@ -121,29 +94,28 @@ namespace Obfuz.Virtualization
|
|||
double value = (double)operand;
|
||||
if (_dataObfuscatorPolicy.NeedObfuscateDouble(method, value))
|
||||
{
|
||||
_dataObfuscator.ObfuscateDouble(method, value, obfuscatedInstructions);
|
||||
obfuscated = true;
|
||||
_dataObfuscator.ObfuscateDouble(method, value, outputInstructions);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
return false;
|
||||
}
|
||||
case OperandType.InlineString:
|
||||
{
|
||||
obfuscatedInstructions.Clear();
|
||||
//RuntimeHelpers.InitializeArray
|
||||
string value = (string)inst.Operand;
|
||||
if (_dataObfuscatorPolicy.NeedObfuscateString(method, value))
|
||||
{
|
||||
_dataObfuscator.ObfuscateString(method, value, obfuscatedInstructions);
|
||||
obfuscated = true;
|
||||
_dataObfuscator.ObfuscateString(method, value, outputInstructions);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
return false;
|
||||
}
|
||||
case OperandType.InlineMethod:
|
||||
{
|
||||
if (((IMethod)inst.Operand).FullName == "System.Void System.Runtime.CompilerServices.RuntimeHelpers::InitializeArray(System.Array,System.RuntimeFieldHandle)")
|
||||
{
|
||||
Instruction prevInst = instructions[i - 1];
|
||||
Instruction prevInst = instructions[instructionIndex - 1];
|
||||
if (prevInst.OpCode.Code == Code.Ldtoken)
|
||||
{
|
||||
IField rvaField = (IField)prevInst.Operand;
|
||||
|
@ -152,34 +124,16 @@ namespace Obfuz.Virtualization
|
|||
if (data != null && _dataObfuscatorPolicy.NeedObfuscateArray(method, data))
|
||||
{
|
||||
// remove prev ldtoken instruction
|
||||
Assert.AreEqual(Code.Ldtoken, resultInstructions[resultInstructions.Count - 1].OpCode.Code);
|
||||
resultInstructions.RemoveAt(resultInstructions.Count - 1);
|
||||
_dataObfuscator.ObfuscateBytes(method, data, obfuscatedInstructions);
|
||||
obfuscated = true;
|
||||
Assert.AreEqual(Code.Ldtoken, totalFinalInstructions[totalFinalInstructions.Count - 1].OpCode.Code);
|
||||
totalFinalInstructions.RemoveAt(totalFinalInstructions.Count - 1);
|
||||
_dataObfuscator.ObfuscateBytes(method, data, outputInstructions);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
resultInstructions.Add(inst);
|
||||
if (obfuscated)
|
||||
{
|
||||
// current instruction may be the target of control flow instruction, so we can't remove it directly.
|
||||
// we replace it with nop now, then remove it in CleanUpInstructionPass
|
||||
inst.OpCode = obfuscatedInstructions[0].OpCode;
|
||||
inst.Operand = obfuscatedInstructions[0].Operand;
|
||||
for (int k = 1; k < obfuscatedInstructions.Count; k++)
|
||||
{
|
||||
resultInstructions.Add(obfuscatedInstructions[k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
instructions.Clear();
|
||||
foreach (var obInst in resultInstructions)
|
||||
{
|
||||
instructions.Add(obInst);
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue