添加ControlFlowObfus基础代码
parent
0ad96daa32
commit
0508421850
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 02fb097cf61874c41923b3ef23fee199
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,137 @@
|
||||||
|
using dnlib.DotNet;
|
||||||
|
using Obfuz.Conf;
|
||||||
|
using Obfuz.Settings;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Xml;
|
||||||
|
|
||||||
|
namespace Obfuz.ObfusPasses.ControlFlowObfus
|
||||||
|
{
|
||||||
|
struct ObfuscationRuleData
|
||||||
|
{
|
||||||
|
public readonly ObfuscationLevel obfuscationLevel;
|
||||||
|
public ObfuscationRuleData(ObfuscationLevel level)
|
||||||
|
{
|
||||||
|
obfuscationLevel = level;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IObfuscationPolicy
|
||||||
|
{
|
||||||
|
bool NeedObfuscate(MethodDef method);
|
||||||
|
|
||||||
|
ObfuscationRuleData GetObfuscationRuleData(MethodDef method);
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class ObfuscationPolicyBase : IObfuscationPolicy
|
||||||
|
{
|
||||||
|
public abstract bool NeedObfuscate(MethodDef method);
|
||||||
|
|
||||||
|
public abstract ObfuscationRuleData GetObfuscationRuleData(MethodDef method);
|
||||||
|
}
|
||||||
|
|
||||||
|
class ConfigurableObfuscationPolicy : ObfuscationPolicyBase
|
||||||
|
{
|
||||||
|
class ObfuscationRule : IRule<ObfuscationRule>
|
||||||
|
{
|
||||||
|
public ObfuscationLevel? obfuscationLevel;
|
||||||
|
|
||||||
|
public void InheritParent(ObfuscationRule parentRule)
|
||||||
|
{
|
||||||
|
if (obfuscationLevel == null)
|
||||||
|
obfuscationLevel = parentRule.obfuscationLevel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MethodSpec : MethodRuleBase<ObfuscationRule>
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
class TypeSpec : TypeRuleBase<MethodSpec, ObfuscationRule>
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
class AssemblySpec : AssemblyRuleBase<TypeSpec, MethodSpec, ObfuscationRule>
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private static readonly ObfuscationRule s_default = new ObfuscationRule()
|
||||||
|
{
|
||||||
|
obfuscationLevel = ObfuscationLevel.Basic,
|
||||||
|
};
|
||||||
|
|
||||||
|
private ObfuscationRule _global;
|
||||||
|
|
||||||
|
private readonly XmlAssemblyTypeMethodRuleParser<AssemblySpec, TypeSpec, MethodSpec, ObfuscationRule> _xmlParser;
|
||||||
|
|
||||||
|
private readonly Dictionary<MethodDef, ObfuscationRule> _methodRuleCache = new Dictionary<MethodDef, ObfuscationRule>();
|
||||||
|
|
||||||
|
public ConfigurableObfuscationPolicy(List<string> toObfuscatedAssemblyNames, List<string> xmlConfigFiles)
|
||||||
|
{
|
||||||
|
_xmlParser = new XmlAssemblyTypeMethodRuleParser<AssemblySpec, TypeSpec, MethodSpec, ObfuscationRule>(
|
||||||
|
toObfuscatedAssemblyNames, ParseObfuscationRule, ParseGlobal);
|
||||||
|
LoadConfigs(xmlConfigFiles);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadConfigs(List<string> configFiles)
|
||||||
|
{
|
||||||
|
_xmlParser.LoadConfigs(configFiles);
|
||||||
|
|
||||||
|
if (_global == null)
|
||||||
|
{
|
||||||
|
_global = s_default;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_global.InheritParent(s_default);
|
||||||
|
}
|
||||||
|
_xmlParser.InheritParentRules(_global);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ParseGlobal(string configFile, XmlElement ele)
|
||||||
|
{
|
||||||
|
switch (ele.Name)
|
||||||
|
{
|
||||||
|
case "global": _global = ParseObfuscationRule(configFile, ele); break;
|
||||||
|
default: throw new Exception($"Invalid xml file {configFile}, unknown node {ele.Name}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ObfuscationLevel ParseObfuscationLevel(string str)
|
||||||
|
{
|
||||||
|
return (ObfuscationLevel)Enum.Parse(typeof(ObfuscationLevel), str);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ObfuscationRule ParseObfuscationRule(string configFile, XmlElement ele)
|
||||||
|
{
|
||||||
|
var rule = new ObfuscationRule();
|
||||||
|
if (ele.HasAttribute("obfuscationLevel"))
|
||||||
|
{
|
||||||
|
rule.obfuscationLevel = ParseObfuscationLevel(ele.GetAttribute("obfuscationLevel"));
|
||||||
|
}
|
||||||
|
return rule;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ObfuscationRule GetMethodObfuscationRule(MethodDef method)
|
||||||
|
{
|
||||||
|
if (!_methodRuleCache.TryGetValue(method, out var rule))
|
||||||
|
{
|
||||||
|
rule = _xmlParser.GetMethodRule(method, s_default);
|
||||||
|
_methodRuleCache[method] = rule;
|
||||||
|
}
|
||||||
|
return rule;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool NeedObfuscate(MethodDef method)
|
||||||
|
{
|
||||||
|
ObfuscationRule rule = GetMethodObfuscationRule(method);
|
||||||
|
return rule.obfuscationLevel.Value > ObfuscationLevel.None;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ObfuscationRuleData GetObfuscationRuleData(MethodDef method)
|
||||||
|
{
|
||||||
|
var rule = GetMethodObfuscationRule(method);
|
||||||
|
return new ObfuscationRuleData(rule.obfuscationLevel.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f6983877d8859df4882c30f75be7a70e
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,73 @@
|
||||||
|
using dnlib.DotNet;
|
||||||
|
using Obfuz.Data;
|
||||||
|
using Obfuz.Emit;
|
||||||
|
using Obfuz.Settings;
|
||||||
|
using Obfuz.Utils;
|
||||||
|
|
||||||
|
namespace Obfuz.ObfusPasses.ControlFlowObfus
|
||||||
|
{
|
||||||
|
class ObfusMethodContext
|
||||||
|
{
|
||||||
|
public MethodDef method;
|
||||||
|
public LocalVariableAllocator localVariableAllocator;
|
||||||
|
public IRandom localRandom;
|
||||||
|
public EncryptionScopeInfo encryptionScope;
|
||||||
|
public DefaultMetadataImporter importer;
|
||||||
|
public ModuleConstFieldAllocator constFieldAllocator;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class ControlFlowObfusPass : ObfuscationMethodPassBase
|
||||||
|
{
|
||||||
|
private readonly ControlFlowObfuscationSettingsFacade _settings;
|
||||||
|
|
||||||
|
private IObfuscationPolicy _obfuscationPolicy;
|
||||||
|
private IObfuscator _obfuscator;
|
||||||
|
|
||||||
|
public ControlFlowObfusPass(ControlFlowObfuscationSettingsFacade settings)
|
||||||
|
{
|
||||||
|
_settings = settings;
|
||||||
|
_obfuscator = new DefaultObfuscator();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ObfuscationPassType Type => ObfuscationPassType.ControlFlowObfus;
|
||||||
|
|
||||||
|
public override void Start()
|
||||||
|
{
|
||||||
|
ObfuscationPassContext ctx = ObfuscationPassContext.Current;
|
||||||
|
_obfuscationPolicy = new ConfigurableObfuscationPolicy(
|
||||||
|
ctx.coreSettings.assembliesToObfuscate,
|
||||||
|
_settings.ruleFiles);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Stop()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool NeedObfuscateMethod(MethodDef method)
|
||||||
|
{
|
||||||
|
return _obfuscationPolicy.NeedObfuscate(method);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void ObfuscateData(MethodDef method)
|
||||||
|
{
|
||||||
|
//Debug.Log($"Obfuscating method: {method.FullName} with EvalStackObfusPass");
|
||||||
|
|
||||||
|
ObfuscationPassContext ctx = ObfuscationPassContext.Current;
|
||||||
|
var calc = new BasicBlockCollection(method, false);
|
||||||
|
var encryptionScope = ctx.encryptionScopeProvider.GetScope(method.Module);
|
||||||
|
var ruleData = _obfuscationPolicy.GetObfuscationRuleData(method);
|
||||||
|
var localRandom = encryptionScope.localRandomCreator(MethodEqualityComparer.CompareDeclaringTypes.GetHashCode(method));
|
||||||
|
var obfusMethodCtx = new ObfusMethodContext
|
||||||
|
{
|
||||||
|
method = method,
|
||||||
|
localVariableAllocator = new LocalVariableAllocator(method),
|
||||||
|
encryptionScope = encryptionScope,
|
||||||
|
constFieldAllocator = ctx.constFieldAllocator.GetModuleAllocator(method.Module),
|
||||||
|
localRandom = localRandom,
|
||||||
|
importer = ctx.moduleEntityManager.GetDefaultModuleMetadataImporter(method.Module, ctx.encryptionScopeProvider),
|
||||||
|
};
|
||||||
|
_obfuscator.Obfuscate(calc, obfusMethodCtx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: cf62db4d3137e6447bd5cb2a65f101d3
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,12 @@
|
||||||
|
using Obfuz.Emit;
|
||||||
|
|
||||||
|
namespace Obfuz.ObfusPasses.ControlFlowObfus
|
||||||
|
{
|
||||||
|
class DefaultObfuscator : ObfuscatorBase
|
||||||
|
{
|
||||||
|
public override bool Obfuscate(BasicBlockCollection basicBlocks, ObfusMethodContext ctx)
|
||||||
|
{
|
||||||
|
throw new System.NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 8aa2a2e43fa066541b982dbb63452458
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,14 @@
|
||||||
|
using Obfuz.Emit;
|
||||||
|
|
||||||
|
namespace Obfuz.ObfusPasses.ControlFlowObfus
|
||||||
|
{
|
||||||
|
interface IObfuscator
|
||||||
|
{
|
||||||
|
bool Obfuscate(BasicBlockCollection basicBlocks, ObfusMethodContext ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class ObfuscatorBase : IObfuscator
|
||||||
|
{
|
||||||
|
public abstract bool Obfuscate(BasicBlockCollection basicBlocks, ObfusMethodContext ctx);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 4ada5f6005768f745a18dc8b968e1684
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,27 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Obfuz.Settings
|
||||||
|
{
|
||||||
|
|
||||||
|
public class ControlFlowObfuscationSettingsFacade
|
||||||
|
{
|
||||||
|
public List<string> ruleFiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public class ControlFlowObfuscationSettings
|
||||||
|
{
|
||||||
|
[Tooltip("rule config xml files")]
|
||||||
|
public string[] ruleFiles;
|
||||||
|
|
||||||
|
public ControlFlowObfuscationSettingsFacade ToFacade()
|
||||||
|
{
|
||||||
|
return new ControlFlowObfuscationSettingsFacade
|
||||||
|
{
|
||||||
|
ruleFiles = new List<string>(ruleFiles ?? Array.Empty<string>()),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d40d2fb33f081b2458505c7566b1bc8f
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
Loading…
Reference in New Issue