支持FieldEncrypt
parent
f0bec3fab9
commit
18800f78c4
|
@ -0,0 +1,208 @@
|
|||
using dnlib.DotNet;
|
||||
using Obfuz.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
using UnityEditor.VersionControl;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Obfuz.Conf
|
||||
{
|
||||
|
||||
|
||||
|
||||
public class XmlFieldRuleParser<R> where R : class, new()
|
||||
{
|
||||
private readonly HashSet<string> _toObfuscatedAssemblyNames;
|
||||
private readonly Func<string, XmlElement, R> _ruleParser;
|
||||
private readonly Action<string, XmlElement> _unknownNodeTypeHandler;
|
||||
private readonly Dictionary<string, AssemblySpec> _assemblySpecs = new Dictionary<string, AssemblySpec>();
|
||||
|
||||
|
||||
private class FieldSpec
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public NameMatcher NameMatcher { get; set; }
|
||||
|
||||
public R Rule { get; set; }
|
||||
}
|
||||
|
||||
private class TypeSpec
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
||||
public NameMatcher NameMatcher { get; set; }
|
||||
|
||||
public List<FieldSpec> Fields { get; set; }
|
||||
}
|
||||
|
||||
private class AssemblySpec
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
||||
public List<TypeSpec> Types { get; set; }
|
||||
}
|
||||
|
||||
public XmlFieldRuleParser(IEnumerable<string> toObfuscatedAssemblyNames, Func<string, XmlElement, R> ruleParser, Action<string, XmlElement> unknownNodeTypeHandler)
|
||||
{
|
||||
_toObfuscatedAssemblyNames = new HashSet<string>(toObfuscatedAssemblyNames);
|
||||
_ruleParser = ruleParser;
|
||||
_unknownNodeTypeHandler = unknownNodeTypeHandler;
|
||||
}
|
||||
|
||||
public void LoadConfigs(IEnumerable<string> configFiles)
|
||||
{
|
||||
foreach (var configFile in configFiles)
|
||||
{
|
||||
LoadConfig(configFile);
|
||||
}
|
||||
}
|
||||
|
||||
public void LoadConfig(string configFile)
|
||||
{
|
||||
if (string.IsNullOrEmpty(configFile))
|
||||
{
|
||||
throw new Exception($"Invalid xml file {configFile}, file name is empty");
|
||||
}
|
||||
var doc = new XmlDocument();
|
||||
doc.Load(configFile);
|
||||
var root = doc.DocumentElement;
|
||||
if (root.Name != "obfuz")
|
||||
{
|
||||
throw new Exception($"Invalid xml file {configFile}, root name should be 'obfuz'");
|
||||
}
|
||||
foreach (XmlNode node in root.ChildNodes)
|
||||
{
|
||||
if (!(node is XmlElement ele))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
switch (ele.Name)
|
||||
{
|
||||
case "assembly":
|
||||
{
|
||||
AssemblySpec assSpec = ParseAssembly(configFile, ele);
|
||||
_assemblySpecs.Add(assSpec.Name, assSpec);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
if (_unknownNodeTypeHandler == null)
|
||||
{
|
||||
throw new Exception($"Invalid xml file {configFile}, unknown node {ele.Name}");
|
||||
}
|
||||
_unknownNodeTypeHandler(configFile, ele);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private AssemblySpec ParseAssembly(string configFile, XmlElement ele)
|
||||
{
|
||||
var assemblySpec = new AssemblySpec();
|
||||
string name = ele.GetAttribute("name");
|
||||
if (!_toObfuscatedAssemblyNames.Contains(name))
|
||||
{
|
||||
throw new Exception($"Invalid xml file {configFile}, assembly name {name} isn't in toObfuscatedAssemblyNames");
|
||||
}
|
||||
if (_assemblySpecs.ContainsKey(name))
|
||||
{
|
||||
throw new Exception($"Invalid xml file {configFile}, assembly name {name} is duplicated");
|
||||
}
|
||||
assemblySpec.Name = name;
|
||||
|
||||
var types = new List<TypeSpec>();
|
||||
assemblySpec.Types = types;
|
||||
foreach (XmlNode node in ele.ChildNodes)
|
||||
{
|
||||
if (!(node is XmlElement childEle))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
switch (childEle.Name)
|
||||
{
|
||||
case "type":
|
||||
{
|
||||
types.Add(ParseType(configFile, childEle));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
throw new Exception($"Invalid xml file, unknown node {childEle.Name}");
|
||||
}
|
||||
}
|
||||
}
|
||||
return assemblySpec;
|
||||
}
|
||||
|
||||
private TypeSpec ParseType(string configFile, XmlElement element)
|
||||
{
|
||||
var typeSpec = new TypeSpec();
|
||||
|
||||
string name = element.GetAttribute("name");
|
||||
typeSpec.Name = name;
|
||||
typeSpec.NameMatcher = new NameMatcher(name);
|
||||
|
||||
var fields = new List<FieldSpec>();
|
||||
typeSpec.Fields = fields;
|
||||
foreach (XmlNode node in element.ChildNodes)
|
||||
{
|
||||
if (!(node is XmlElement ele))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
switch (ele.Name)
|
||||
{
|
||||
case "field":
|
||||
{
|
||||
fields.Add(ParseField(configFile, ele));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
throw new Exception($"Invalid xml file, unknown node {ele.Name}");
|
||||
}
|
||||
}
|
||||
}
|
||||
return typeSpec;
|
||||
}
|
||||
|
||||
private FieldSpec ParseField(string configFile, XmlElement element)
|
||||
{
|
||||
var fieldSpec = new FieldSpec();
|
||||
string name = element.GetAttribute("name");
|
||||
fieldSpec.Name = name;
|
||||
fieldSpec.NameMatcher = new NameMatcher(name);
|
||||
fieldSpec.Rule = _ruleParser(configFile, element);
|
||||
return fieldSpec;
|
||||
}
|
||||
|
||||
public R GetFieldRule(FieldDef field)
|
||||
{
|
||||
var assemblyName = field.DeclaringType.Module.Assembly.Name;
|
||||
if (!_assemblySpecs.TryGetValue(assemblyName, out var assSpec))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
string declaringTypeName = field.DeclaringType.FullName;
|
||||
foreach (var typeSpec in assSpec.Types)
|
||||
{
|
||||
if (typeSpec.NameMatcher.IsMatch(declaringTypeName))
|
||||
{
|
||||
foreach (var fieldSpec in typeSpec.Fields)
|
||||
{
|
||||
if (fieldSpec.NameMatcher.IsMatch(field.Name))
|
||||
{
|
||||
return fieldSpec.Rule;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,19 +1,36 @@
|
|||
using dnlib.DotNet;
|
||||
using Obfuz.Conf;
|
||||
using Obfuz.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml;
|
||||
|
||||
namespace Obfuz.ObfusPasses.FieldEncrypt
|
||||
{
|
||||
public class ConfigurableEncryptPolicy : EncryptPolicyBase
|
||||
{
|
||||
class ObfuscationRule
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private readonly XmlFieldRuleParser<ObfuscationRule> _configParser;
|
||||
|
||||
public ConfigurableEncryptPolicy(List<string> toObfuscatedAssemblyNames, List<string> configFiles)
|
||||
{
|
||||
_configParser = new XmlFieldRuleParser<ObfuscationRule>(toObfuscatedAssemblyNames, ParseRule, null);
|
||||
_configParser.LoadConfigs(configFiles);
|
||||
}
|
||||
|
||||
private ObfuscationRule ParseRule(string configFile, XmlElement ele)
|
||||
{
|
||||
return new ObfuscationRule();
|
||||
}
|
||||
|
||||
public override bool NeedEncrypt(FieldDef field)
|
||||
{
|
||||
TypeDef type = field.DeclaringType;
|
||||
// TODO
|
||||
if (type.Name == "EncryptField" || type.Name == "EncryptProperty")
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
var rule = _configParser.GetFieldRule(field);
|
||||
return rule != null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
using dnlib.DotNet;
|
||||
using dnlib.DotNet.Emit;
|
||||
using Obfuz;
|
||||
using Obfuz.Settings;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Obfuz.ObfusPasses.FieldEncrypt
|
||||
|
@ -10,13 +12,21 @@ namespace Obfuz.ObfusPasses.FieldEncrypt
|
|||
|
||||
public class FieldEncryptPass : InstructionObfuscationPassBase
|
||||
{
|
||||
private readonly IEncryptPolicy _encryptionPolicy = new ConfigurableEncryptPolicy();
|
||||
private readonly List<string> _configFiles;
|
||||
private IEncryptPolicy _encryptionPolicy;
|
||||
private IFieldEncryptor _memoryEncryptor;
|
||||
|
||||
public FieldEncryptPass(FieldEncryptSettings settings)
|
||||
{
|
||||
_configFiles = settings.configFiles.ToList();
|
||||
}
|
||||
|
||||
protected override bool NeedProcessNotObfuscatedAssembly => true;
|
||||
|
||||
public override void Start(ObfuscationPassContext ctx)
|
||||
{
|
||||
_memoryEncryptor = new DefaultFieldEncryptor(ctx.random, ctx.encryptor);
|
||||
|
||||
_encryptionPolicy = new ConfigurableEncryptPolicy(ctx.toObfuscatedAssemblyNames, _configFiles);
|
||||
}
|
||||
|
||||
public override void Stop(ObfuscationPassContext ctx)
|
||||
|
@ -57,11 +67,6 @@ namespace Obfuz.ObfusPasses.FieldEncrypt
|
|||
{
|
||||
return false;
|
||||
}
|
||||
var ctx = new MemoryEncryptionContext
|
||||
{
|
||||
module = callingMethod.Module,
|
||||
currentInstruction = inst,
|
||||
};
|
||||
switch (code)
|
||||
{
|
||||
case Code.Ldfld:
|
||||
|
|
|
@ -7,11 +7,14 @@ namespace Obfuz.ObfusPasses
|
|||
{
|
||||
public abstract class InstructionObfuscationPassBase : ObfuscationPassBase
|
||||
{
|
||||
protected virtual bool NeedProcessNotObfuscatedAssembly => false;
|
||||
|
||||
protected abstract bool NeedObfuscateMethod(MethodDef method);
|
||||
|
||||
public override void Process(ObfuscationPassContext ctx)
|
||||
{
|
||||
foreach (ModuleDef mod in ctx.toObfuscatedModules)
|
||||
var modules = NeedProcessNotObfuscatedAssembly ? ctx.obfuscatedAndNotObfuscatedModules : ctx.toObfuscatedModules;
|
||||
foreach (ModuleDef mod in modules)
|
||||
{
|
||||
// ToArray to avoid modify list exception
|
||||
foreach (TypeDef type in mod.GetTypes().ToArray())
|
||||
|
|
|
@ -76,7 +76,7 @@ namespace Obfuz
|
|||
ObfuscationPassType obfuscationPasses = settings.enabledObfuscationPasses;
|
||||
if (obfuscationPasses.HasFlag(ObfuscationPassType.MemoryEncryption))
|
||||
{
|
||||
builder.AddPass(new FieldEncryptPass());
|
||||
builder.AddPass(new FieldEncryptPass(settings.fieldEncryptSettings));
|
||||
}
|
||||
if (obfuscationPasses.HasFlag(ObfuscationPassType.CallProxy))
|
||||
{
|
||||
|
|
|
@ -32,6 +32,9 @@ namespace Obfuz.Settings
|
|||
[Tooltip("const encryption settings")]
|
||||
public ConstEncryptSettings constEncryptSettings;
|
||||
|
||||
[Tooltip("field encryption settings")]
|
||||
public FieldEncryptSettings fieldEncryptSettings;
|
||||
|
||||
[Tooltip("call obfuscation settings")]
|
||||
public CallObfusSettings callObfusSettings;
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ namespace Obfuz.Settings
|
|||
|
||||
private SerializedProperty _symbolObfusSettings;
|
||||
private SerializedProperty _constEncryptSettings;
|
||||
private SerializedProperty _fieldEncryptSettings;
|
||||
private SerializedProperty _callObfusSettings;
|
||||
|
||||
public ObfuzSettingsProvider() : base("Project/Obfuz", SettingsScope.Project)
|
||||
|
@ -67,6 +68,7 @@ namespace Obfuz.Settings
|
|||
|
||||
_symbolObfusSettings = _serializedObject.FindProperty("symbolObfusSettings");
|
||||
_constEncryptSettings = _serializedObject.FindProperty("constEncryptSettings");
|
||||
_fieldEncryptSettings = _serializedObject.FindProperty("fieldEncryptSettings");
|
||||
_callObfusSettings = _serializedObject.FindProperty("callObfusSettings");
|
||||
}
|
||||
|
||||
|
@ -87,6 +89,7 @@ namespace Obfuz.Settings
|
|||
|
||||
EditorGUILayout.PropertyField(_symbolObfusSettings);
|
||||
EditorGUILayout.PropertyField(_constEncryptSettings);
|
||||
EditorGUILayout.PropertyField(_fieldEncryptSettings);
|
||||
EditorGUILayout.PropertyField(_callObfusSettings);
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue