调整和重构CallObfus的代码
parent
cf67f63066
commit
83c0b921e3
|
@ -268,7 +268,7 @@ namespace Obfuz.Data
|
|||
|
||||
private ModuleConstFieldAllocator GetModuleAllocator(ModuleDef mod)
|
||||
{
|
||||
return EmitManager.Ins.GetEmitManager<ModuleConstFieldAllocator>(mod, m => new ModuleConstFieldAllocator(_encryptor, _random, _rvaDataAllocator));
|
||||
return EmitManager.Ins.GetEmitManager<ModuleConstFieldAllocator>(mod, () => new ModuleConstFieldAllocator(_encryptor, _random, _rvaDataAllocator));
|
||||
}
|
||||
|
||||
public FieldDef Allocate(ModuleDef mod, int value)
|
||||
|
|
|
@ -28,9 +28,9 @@ namespace Obfuz.Data
|
|||
public class ModuleRvaDataAllocator : ModuleEmitManagerBase
|
||||
{
|
||||
// randomized
|
||||
const int maxRvaDataSize = 0x100;
|
||||
const int maxRvaDataSize = 0x1000;
|
||||
|
||||
private readonly ModuleDef _module;
|
||||
private ModuleDef _module;
|
||||
private readonly IRandom _random;
|
||||
private readonly IEncryptor _encryptor;
|
||||
|
||||
|
@ -69,16 +69,15 @@ namespace Obfuz.Data
|
|||
|
||||
private readonly Dictionary<int, TypeDef> _dataHolderTypeBySizes = new Dictionary<int, TypeDef>();
|
||||
|
||||
public ModuleRvaDataAllocator(ModuleDef mod, IRandom random, IEncryptor encryptor)
|
||||
public ModuleRvaDataAllocator(IRandom random, IEncryptor encryptor)
|
||||
{
|
||||
_module = mod;
|
||||
_random = random;
|
||||
_encryptor = encryptor;
|
||||
}
|
||||
|
||||
public override void Init(ModuleDef mod)
|
||||
{
|
||||
|
||||
_module = mod;
|
||||
}
|
||||
|
||||
private (FieldDef, FieldDef) CreateDataHolderRvaField(TypeDef dataHolderType)
|
||||
|
@ -297,7 +296,7 @@ namespace Obfuz.Data
|
|||
|
||||
private ModuleRvaDataAllocator GetModuleRvaDataAllocator(ModuleDef mod)
|
||||
{
|
||||
return EmitManager.Ins.GetEmitManager<ModuleRvaDataAllocator>(mod, mod => new ModuleRvaDataAllocator(mod, _random, _encryptor));
|
||||
return EmitManager.Ins.GetEmitManager<ModuleRvaDataAllocator>(mod, () => new ModuleRvaDataAllocator(_random, _encryptor));
|
||||
}
|
||||
|
||||
public RvaData Allocate(ModuleDef mod, int value)
|
||||
|
|
|
@ -29,7 +29,7 @@ namespace Obfuz.Emit
|
|||
Ins = new EmitManager();
|
||||
}
|
||||
|
||||
public T GetEmitManager<T>(ModuleDef mod, Func<ModuleDef, T> creator = null) where T : IModuleEmitManager
|
||||
public T GetEmitManager<T>(ModuleDef mod, Func<T> creator = null) where T : IModuleEmitManager
|
||||
{
|
||||
var key = (mod, typeof(T));
|
||||
if (_moduleEmitManagers.TryGetValue(key, out var emitManager))
|
||||
|
@ -41,7 +41,7 @@ namespace Obfuz.Emit
|
|||
T newEmitManager;
|
||||
if (creator != null)
|
||||
{
|
||||
newEmitManager = creator(mod);
|
||||
newEmitManager = creator();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -9,20 +9,23 @@ using System.Runtime.CompilerServices;
|
|||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine.Assertions;
|
||||
using Obfuz.Settings;
|
||||
|
||||
namespace Obfuz.ObfusPasses.CallObfus
|
||||
{
|
||||
public class ProxyCallPass : InstructionObfuscationPassBase
|
||||
public class CallObfusPass : InstructionObfuscationPassBase
|
||||
{
|
||||
private readonly IRandom _random;
|
||||
private readonly IProxyCallPolicy _dynamicProxyPolicy;
|
||||
private readonly IProxyCallObfuscator _dynamicProxyObfuscator;
|
||||
private readonly IEncryptor _encryptor;
|
||||
private readonly ICallObfusPolicy _dynamicProxyPolicy;
|
||||
private readonly ICallObfuscator _dynamicProxyObfuscator;
|
||||
|
||||
public ProxyCallPass()
|
||||
public CallObfusPass(CallObfusSettings settings)
|
||||
{
|
||||
_random = new RandomWithKey(new byte[] { 0x1, 0x2, 0x3, 0x4 }, 0x5);
|
||||
_dynamicProxyPolicy = new ConfigProxyCallPolicy();
|
||||
_dynamicProxyObfuscator = new DefaultProxyCallObfuscator(_random);
|
||||
_encryptor = new DefaultEncryptor(new byte[] { 0x1A, 0x2B, 0x3C, 0x4D });
|
||||
_dynamicProxyPolicy = new ConfigurableCallObfusPolicy();
|
||||
_dynamicProxyObfuscator = new DefaultProxyCallObfuscator(_random, _encryptor);
|
||||
}
|
||||
|
||||
public override void Stop(ObfuscationPassContext ctx)
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace Obfuz.ObfusPasses.CallObfus
|
||||
{
|
||||
public abstract class ProxyCallPolicyBase : IProxyCallPolicy
|
||||
public abstract class CallObfusPolicyBase : ICallObfusPolicy
|
||||
{
|
||||
public abstract bool NeedDynamicProxyCallInMethod(MethodDef method);
|
||||
|
|
@ -4,7 +4,7 @@ using System.Collections.Generic;
|
|||
|
||||
namespace Obfuz.ObfusPasses.CallObfus
|
||||
{
|
||||
public abstract class ProxyCallObfuscatorBase : IProxyCallObfuscator
|
||||
public abstract class CallObfuscatorBase : ICallObfuscator
|
||||
{
|
||||
public abstract void Obfuscate(MethodDef callingMethod, IMethod calledMethod, bool callVir, List<Instruction> obfuscatedInstructions);
|
||||
public abstract void Done();
|
|
@ -1,5 +1,6 @@
|
|||
using dnlib.DotNet;
|
||||
using dnlib.DotNet.Emit;
|
||||
using Obfuz.Emit;
|
||||
using Obfuz.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
@ -14,19 +15,24 @@ namespace Obfuz.ObfusPasses.CallObfus
|
|||
public struct ProxyCallMethodData
|
||||
{
|
||||
public readonly MethodDef proxyMethod;
|
||||
public readonly int secret;
|
||||
public readonly int encryptOps;
|
||||
public readonly int salt;
|
||||
public readonly int encryptedIndex;
|
||||
|
||||
public ProxyCallMethodData(MethodDef proxyMethod, int secret)
|
||||
public ProxyCallMethodData(MethodDef proxyMethod, int encryptOps, int salt, int encryptedIndex)
|
||||
{
|
||||
this.proxyMethod = proxyMethod;
|
||||
this.secret = secret;
|
||||
this.encryptOps = encryptOps;
|
||||
this.salt = salt;
|
||||
this.encryptedIndex = encryptedIndex;
|
||||
}
|
||||
}
|
||||
|
||||
class ModuleDynamicProxyMethodAllocator
|
||||
class ModuleCallProxyAllocator : IModuleEmitManager
|
||||
{
|
||||
private readonly ModuleDef _module;
|
||||
private ModuleDef _module;
|
||||
private readonly IRandom _random;
|
||||
private readonly IEncryptor _encryptor;
|
||||
|
||||
class MethodKey : IEquatable<MethodKey>
|
||||
{
|
||||
|
@ -55,7 +61,11 @@ namespace Obfuz.ObfusPasses.CallObfus
|
|||
class MethodProxyInfo
|
||||
{
|
||||
public MethodDef proxyMethod;
|
||||
public int secret;
|
||||
|
||||
public int index;
|
||||
public int encryptedOps;
|
||||
public int salt;
|
||||
public int encryptedIndex;
|
||||
}
|
||||
|
||||
private readonly Dictionary<MethodKey, MethodProxyInfo> _methodProxys = new Dictionary<MethodKey, MethodProxyInfo>();
|
||||
|
@ -72,7 +82,6 @@ namespace Obfuz.ObfusPasses.CallObfus
|
|||
class DispatchMethodInfo
|
||||
{
|
||||
public MethodDef methodDef;
|
||||
public int secret;
|
||||
public List<CallInfo> methods = new List<CallInfo>();
|
||||
}
|
||||
|
||||
|
@ -81,10 +90,15 @@ namespace Obfuz.ObfusPasses.CallObfus
|
|||
|
||||
private TypeDef _proxyTypeDef;
|
||||
|
||||
public ModuleDynamicProxyMethodAllocator(ModuleDef module, IRandom random)
|
||||
public ModuleCallProxyAllocator(IRandom random, IEncryptor encryptor)
|
||||
{
|
||||
_module = module;
|
||||
_random = random;
|
||||
_encryptor = encryptor;
|
||||
}
|
||||
|
||||
public void Init(ModuleDef mod)
|
||||
{
|
||||
_module = mod;
|
||||
}
|
||||
|
||||
private TypeDef CreateProxyTypeDef()
|
||||
|
@ -128,11 +142,21 @@ namespace Obfuz.ObfusPasses.CallObfus
|
|||
break;
|
||||
}
|
||||
}
|
||||
// extra param for secret
|
||||
// extra param for index
|
||||
methodSig.Params.Add(_module.CorLibTypes.Int32);
|
||||
return MethodSig.CreateStatic(methodSig.RetType, methodSig.Params.ToArray());
|
||||
}
|
||||
|
||||
private int GenerateSalt()
|
||||
{
|
||||
return _random.NextInt();
|
||||
}
|
||||
|
||||
private int GenerateEncryptOps()
|
||||
{
|
||||
return _random.NextInt();
|
||||
}
|
||||
|
||||
private DispatchMethodInfo GetDispatchMethod(IMethod method)
|
||||
{
|
||||
MethodSig methodSig = CreateDispatchMethodSig(method);
|
||||
|
@ -146,7 +170,6 @@ namespace Obfuz.ObfusPasses.CallObfus
|
|||
var newDispatchMethodInfo = new DispatchMethodInfo
|
||||
{
|
||||
methodDef = CreateDispatchMethodInfo(methodSig),
|
||||
secret = 0,
|
||||
};
|
||||
dispatchMethods.Add(newDispatchMethodInfo);
|
||||
}
|
||||
|
@ -159,15 +182,23 @@ namespace Obfuz.ObfusPasses.CallObfus
|
|||
if (!_methodProxys.TryGetValue(key, out var proxyInfo))
|
||||
{
|
||||
var methodDispatcher = GetDispatchMethod(method);
|
||||
|
||||
int index = methodDispatcher.methods.Count;
|
||||
int encryptOps = GenerateEncryptOps();
|
||||
int salt = GenerateSalt();
|
||||
int encryptedIndex = _encryptor.Encrypt(index, encryptOps, salt);
|
||||
proxyInfo = new MethodProxyInfo()
|
||||
{
|
||||
proxyMethod = methodDispatcher.methodDef,
|
||||
secret = methodDispatcher.methods.Count,
|
||||
index = index,
|
||||
encryptedOps = encryptOps,
|
||||
salt = salt,
|
||||
encryptedIndex = encryptedIndex,
|
||||
};
|
||||
methodDispatcher.methods.Add(new CallInfo { method = method, callVir = callVir});
|
||||
_methodProxys.Add(key, proxyInfo);
|
||||
}
|
||||
return new ProxyCallMethodData(proxyInfo.proxyMethod, proxyInfo.secret);
|
||||
return new ProxyCallMethodData(proxyInfo.proxyMethod, proxyInfo.encryptedOps, proxyInfo.salt, proxyInfo.encryptedIndex);
|
||||
}
|
||||
|
||||
public void Done()
|
||||
|
@ -175,7 +206,6 @@ namespace Obfuz.ObfusPasses.CallObfus
|
|||
foreach (DispatchMethodInfo dispatchMethod in _dispatchMethods.Values.SelectMany(ms => ms))
|
||||
{
|
||||
var methodDef = dispatchMethod.methodDef;
|
||||
var secret = dispatchMethod.secret;
|
||||
var methodSig = methodDef.MethodSig;
|
||||
|
||||
|
||||
|
@ -204,34 +234,34 @@ namespace Obfuz.ObfusPasses.CallObfus
|
|||
}
|
||||
}
|
||||
|
||||
public class ProxyCallAllocator
|
||||
public class CallProxyAllocator
|
||||
{
|
||||
private readonly IRandom _random;
|
||||
private readonly IEncryptor _encryptor;
|
||||
|
||||
private readonly Dictionary<ModuleDef, ModuleDynamicProxyMethodAllocator> _moduleAllocators = new Dictionary<ModuleDef, ModuleDynamicProxyMethodAllocator>();
|
||||
|
||||
public ProxyCallAllocator(IRandom random)
|
||||
public CallProxyAllocator(IRandom random, IEncryptor encryptor)
|
||||
{
|
||||
_random = random;
|
||||
_encryptor = encryptor;
|
||||
}
|
||||
|
||||
private ModuleCallProxyAllocator GetModuleAllocator(ModuleDef mod)
|
||||
{
|
||||
return EmitManager.Ins.GetEmitManager<ModuleCallProxyAllocator>(mod, () => new ModuleCallProxyAllocator(_random, _encryptor));
|
||||
}
|
||||
|
||||
public ProxyCallMethodData Allocate(ModuleDef mod, IMethod method, bool callVir)
|
||||
{
|
||||
if (!_moduleAllocators.TryGetValue(mod, out var allocator))
|
||||
{
|
||||
allocator = new ModuleDynamicProxyMethodAllocator(mod, _random);
|
||||
_moduleAllocators.Add(mod, allocator);
|
||||
}
|
||||
ModuleCallProxyAllocator allocator = GetModuleAllocator(mod);
|
||||
return allocator.Allocate(method, callVir);
|
||||
}
|
||||
|
||||
public void Done()
|
||||
{
|
||||
foreach (var allocator in _moduleAllocators.Values)
|
||||
foreach (var allocator in EmitManager.Ins.GetEmitManagers<ModuleCallProxyAllocator>())
|
||||
{
|
||||
allocator.Done();
|
||||
}
|
||||
_moduleAllocators.Clear();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,7 +7,7 @@ using System.Threading.Tasks;
|
|||
|
||||
namespace Obfuz.ObfusPasses.CallObfus
|
||||
{
|
||||
public class ConfigProxyCallPolicy : ProxyCallPolicyBase
|
||||
public class ConfigurableCallObfusPolicy : CallObfusPolicyBase
|
||||
{
|
||||
public override bool NeedDynamicProxyCallInMethod(MethodDef method)
|
||||
{
|
|
@ -6,15 +6,17 @@ using Obfuz.Emit;
|
|||
|
||||
namespace Obfuz.ObfusPasses.CallObfus
|
||||
{
|
||||
public class DefaultProxyCallObfuscator : ProxyCallObfuscatorBase
|
||||
public class DefaultProxyCallObfuscator : CallObfuscatorBase
|
||||
{
|
||||
private readonly IRandom _random;
|
||||
private readonly ProxyCallAllocator _proxyCallAllocator;
|
||||
private readonly IEncryptor _encryptor;
|
||||
private readonly CallProxyAllocator _proxyCallAllocator;
|
||||
|
||||
public DefaultProxyCallObfuscator(IRandom random)
|
||||
public DefaultProxyCallObfuscator(IRandom random, IEncryptor encryptor)
|
||||
{
|
||||
_random = random;
|
||||
_proxyCallAllocator = new ProxyCallAllocator(random);
|
||||
_encryptor = encryptor;
|
||||
_proxyCallAllocator = new CallProxyAllocator(random, _encryptor);
|
||||
}
|
||||
|
||||
public override void Done()
|
||||
|
@ -26,7 +28,11 @@ namespace Obfuz.ObfusPasses.CallObfus
|
|||
{
|
||||
MethodSig sharedMethodSig = MetaUtil.ToSharedMethodSig(calledMethod.Module.CorLibTypes, MetaUtil.GetInflatedMethodSig(calledMethod));
|
||||
ProxyCallMethodData proxyCallMethodData = _proxyCallAllocator.Allocate(callingMethod.Module, calledMethod, callVir);
|
||||
obfuscatedInstructions.Add(Instruction.CreateLdcI4(proxyCallMethodData.secret));
|
||||
DefaultModuleMetadataImporter importer = MetadataImporter.Instance.GetDefaultModuleMetadataImporter(callingMethod.Module);
|
||||
obfuscatedInstructions.Add(Instruction.CreateLdcI4(proxyCallMethodData.encryptedIndex));
|
||||
obfuscatedInstructions.Add(Instruction.CreateLdcI4(proxyCallMethodData.encryptOps));
|
||||
obfuscatedInstructions.Add(Instruction.CreateLdcI4(proxyCallMethodData.salt));
|
||||
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Call, importer.DecryptInt));
|
||||
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Call, proxyCallMethodData.proxyMethod));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ using System.Threading.Tasks;
|
|||
|
||||
namespace Obfuz.ObfusPasses.CallObfus
|
||||
{
|
||||
public interface IProxyCallPolicy
|
||||
public interface ICallObfusPolicy
|
||||
{
|
||||
bool NeedDynamicProxyCallInMethod(MethodDef method);
|
||||
|
|
@ -8,7 +8,7 @@ using System.Threading.Tasks;
|
|||
|
||||
namespace Obfuz.ObfusPasses.CallObfus
|
||||
{
|
||||
public interface IProxyCallObfuscator
|
||||
public interface ICallObfuscator
|
||||
{
|
||||
void Obfuscate(MethodDef callingMethod, IMethod calledMethod, bool callVir, List<Instruction> obfuscatedInstructions);
|
||||
|
|
@ -81,7 +81,7 @@ namespace Obfuz
|
|||
}
|
||||
if (obfuscationPasses.HasFlag(ObfuscationPassType.CallProxy))
|
||||
{
|
||||
builder.AddPass(new ProxyCallPass());
|
||||
builder.AddPass(new CallObfusPass(settings.callObfusSettings));
|
||||
}
|
||||
if (obfuscationPasses.HasFlag(ObfuscationPassType.ConstEncryption))
|
||||
{
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Obfuz.Settings
|
||||
{
|
||||
[Serializable]
|
||||
public class CallObfusSettings
|
||||
{
|
||||
}
|
||||
}
|
|
@ -32,6 +32,9 @@ namespace Obfuz.Settings
|
|||
[Tooltip("const encryption settings")]
|
||||
public ConstEncryptSettings constEncryptSettings;
|
||||
|
||||
[Tooltip("call obfuscation settings")]
|
||||
public CallObfusSettings callObfusSettings;
|
||||
|
||||
public string ObfuzRootDir => $"Library/Obfuz";
|
||||
|
||||
public string GetObfuscatedAssemblyOutputDir(BuildTarget target)
|
||||
|
|
|
@ -37,6 +37,7 @@ namespace Obfuz.Settings
|
|||
|
||||
private SerializedProperty _symbolObfusSettings;
|
||||
private SerializedProperty _constEncryptSettings;
|
||||
private SerializedProperty _callObfusSettings;
|
||||
|
||||
public ObfuzSettingsProvider() : base("Project/Obfuz", SettingsScope.Project)
|
||||
{
|
||||
|
@ -66,6 +67,7 @@ namespace Obfuz.Settings
|
|||
|
||||
_symbolObfusSettings = _serializedObject.FindProperty("symbolObfusSettings");
|
||||
_constEncryptSettings = _serializedObject.FindProperty("constEncryptSettings");
|
||||
_callObfusSettings = _serializedObject.FindProperty("callObfusSettings");
|
||||
}
|
||||
|
||||
public override void OnGUI(string searchContext)
|
||||
|
@ -85,6 +87,7 @@ namespace Obfuz.Settings
|
|||
|
||||
EditorGUILayout.PropertyField(_symbolObfusSettings);
|
||||
EditorGUILayout.PropertyField(_constEncryptSettings);
|
||||
EditorGUILayout.PropertyField(_callObfusSettings);
|
||||
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
|
|
Loading…
Reference in New Issue