Compare commits
No commits in common. "main" and "dev" have entirely different histories.
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet;
|
using dnlib.DotNet;
|
||||||
using Obfuz.Utils;
|
using Obfuz.Utils;
|
||||||
using System;
|
using System;
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet;
|
using dnlib.DotNet;
|
||||||
using Obfuz.Utils;
|
using Obfuz.Utils;
|
||||||
using System;
|
using System;
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet;
|
using dnlib.DotNet;
|
||||||
using Obfuz.ObfusPasses;
|
using Obfuz.ObfusPasses;
|
||||||
using Obfuz.Utils;
|
using Obfuz.Utils;
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
namespace Obfuz.Editor
|
namespace Obfuz.Editor
|
||||||
{
|
{
|
||||||
public static class ConstValues
|
public static class ConstValues
|
||||||
|
|
@ -31,7 +11,6 @@
|
||||||
public const string ObfuzScopeFullName = "Obfuz.ObfuzScope";
|
public const string ObfuzScopeFullName = "Obfuz.ObfuzScope";
|
||||||
|
|
||||||
public const string EncryptFieldAttributeFullName = "Obfuz.EncryptFieldAttribute";
|
public const string EncryptFieldAttributeFullName = "Obfuz.EncryptFieldAttribute";
|
||||||
public const string GeneratedEncryptionVirtualMachineFullName = "Obfuz.EncryptionVM.GeneratedEncryptionVirtualMachine";
|
|
||||||
|
|
||||||
public const string EmbeddedAttributeFullName = "Microsoft.CodeAnalysis.EmbeddedAttribute";
|
public const string EmbeddedAttributeFullName = "Microsoft.CodeAnalysis.EmbeddedAttribute";
|
||||||
|
|
||||||
|
|
@ -40,13 +19,5 @@
|
||||||
public const string ZluaLuaInvokeAttributeFullName = "Zlua.LuaInvokeAttribute";
|
public const string ZluaLuaInvokeAttributeFullName = "Zlua.LuaInvokeAttribute";
|
||||||
public const string ZluaLuaCallbackAttributeFullName = "Zlua.LuaCallbackAttribute";
|
public const string ZluaLuaCallbackAttributeFullName = "Zlua.LuaCallbackAttribute";
|
||||||
public const string ZluaLuaMarshalAsAttributeFullName = "Zlua.LuaMarshalAsAttribute";
|
public const string ZluaLuaMarshalAsAttributeFullName = "Zlua.LuaMarshalAsAttribute";
|
||||||
|
|
||||||
public const string BurstCompileFullName = "Unity.Burst.BurstCompileAttribute";
|
|
||||||
public const string DOTSCompilerGeneratedAttributeFullName = "Unity.Jobs.DOTSCompilerGeneratedAttribute";
|
|
||||||
|
|
||||||
public const string RuntimeInitializedOnLoadMethodAttributeFullName = "UnityEngine.RuntimeInitializeOnLoadMethodAttribute";
|
|
||||||
public const string BlackboardEnumAttributeFullName = "Unity.Behavior.BlackboardEnumAttribute";
|
|
||||||
|
|
||||||
public const string CompilerGeneratedAttributeFullName = "System.Runtime.CompilerServices.CompilerGeneratedAttribute";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet;
|
using dnlib.DotNet;
|
||||||
using dnlib.DotNet.Emit;
|
using dnlib.DotNet.Emit;
|
||||||
using Obfuz.Editor;
|
using Obfuz.Editor;
|
||||||
|
|
@ -30,8 +10,13 @@ using UnityEngine.Assertions;
|
||||||
|
|
||||||
namespace Obfuz.Data
|
namespace Obfuz.Data
|
||||||
{
|
{
|
||||||
public class ConstFieldAllocator : GroupByModuleEntityBase
|
public class ModuleConstFieldAllocator : IGroupByModuleEntity
|
||||||
{
|
{
|
||||||
|
private ModuleDef _module;
|
||||||
|
private readonly EncryptionScopeProvider _encryptionScopeProvider;
|
||||||
|
private readonly RvaDataAllocator _rvaDataAllocator;
|
||||||
|
private readonly GroupByModuleEntityManager _moduleEntityManager;
|
||||||
|
private EncryptionScopeInfo _encryptionScope;
|
||||||
private RandomCreator _randomCreator;
|
private RandomCreator _randomCreator;
|
||||||
private IEncryptor _encryptor;
|
private IEncryptor _encryptor;
|
||||||
|
|
||||||
|
|
@ -72,14 +57,19 @@ namespace Obfuz.Data
|
||||||
private bool _done;
|
private bool _done;
|
||||||
|
|
||||||
|
|
||||||
public ConstFieldAllocator()
|
public ModuleConstFieldAllocator(EncryptionScopeProvider encryptionScopeProvider, RvaDataAllocator rvaDataAllocator, GroupByModuleEntityManager moduleEntityManager)
|
||||||
{
|
{
|
||||||
|
_encryptionScopeProvider = encryptionScopeProvider;
|
||||||
|
_rvaDataAllocator = rvaDataAllocator;
|
||||||
|
_moduleEntityManager = moduleEntityManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Init()
|
public void Init(ModuleDef mod)
|
||||||
{
|
{
|
||||||
_randomCreator = EncryptionScope.localRandomCreator;
|
_module = mod;
|
||||||
_encryptor = EncryptionScope.encryptor;
|
_encryptionScope = _encryptionScopeProvider.GetScope(mod);
|
||||||
|
_randomCreator = _encryptionScope.localRandomCreator;
|
||||||
|
_encryptor = _encryptionScope.encryptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int maxFieldCount = 1000;
|
const int maxFieldCount = 1000;
|
||||||
|
|
@ -87,32 +77,30 @@ namespace Obfuz.Data
|
||||||
|
|
||||||
private TypeSig GetTypeSigOfValue(object value)
|
private TypeSig GetTypeSigOfValue(object value)
|
||||||
{
|
{
|
||||||
ModuleDef mod = Module;
|
|
||||||
if (value is int)
|
if (value is int)
|
||||||
return mod.CorLibTypes.Int32;
|
return _module.CorLibTypes.Int32;
|
||||||
if (value is long)
|
if (value is long)
|
||||||
return mod.CorLibTypes.Int64;
|
return _module.CorLibTypes.Int64;
|
||||||
if (value is float)
|
if (value is float)
|
||||||
return mod.CorLibTypes.Single;
|
return _module.CorLibTypes.Single;
|
||||||
if (value is double)
|
if (value is double)
|
||||||
return mod.CorLibTypes.Double;
|
return _module.CorLibTypes.Double;
|
||||||
if (value is string)
|
if (value is string)
|
||||||
return mod.CorLibTypes.String;
|
return _module.CorLibTypes.String;
|
||||||
if (value is byte[])
|
if (value is byte[])
|
||||||
return new SZArraySig(mod.CorLibTypes.Byte);
|
return new SZArraySig(_module.CorLibTypes.Byte);
|
||||||
throw new NotSupportedException($"Unsupported type: {value.GetType()}");
|
throw new NotSupportedException($"Unsupported type: {value.GetType()}");
|
||||||
}
|
}
|
||||||
|
|
||||||
private ConstFieldInfo CreateConstFieldInfo(object value)
|
private ConstFieldInfo CreateConstFieldInfo(object value)
|
||||||
{
|
{
|
||||||
ModuleDef mod = Module;
|
|
||||||
if (_holderTypeDef == null || _holderTypeDef.Fields.Count >= maxFieldCount)
|
if (_holderTypeDef == null || _holderTypeDef.Fields.Count >= maxFieldCount)
|
||||||
{
|
{
|
||||||
using (var scope = new DisableTypeDefFindCacheScope(mod))
|
using (var scope = new DisableTypeDefFindCacheScope(_module))
|
||||||
{
|
{
|
||||||
ITypeDefOrRef objectTypeRef = mod.Import(typeof(object));
|
ITypeDefOrRef objectTypeRef = _module.Import(typeof(object));
|
||||||
_holderTypeDef = new TypeDefUser($"{ConstValues.ObfuzInternalSymbolNamePrefix}ConstFieldHolder${_holderTypeDefs.Count}", objectTypeRef);
|
_holderTypeDef = new TypeDefUser($"{ConstValues.ObfuzInternalSymbolNamePrefix}ConstFieldHolder${_holderTypeDefs.Count}", objectTypeRef);
|
||||||
mod.Types.Add(_holderTypeDef);
|
_module.Types.Add(_holderTypeDef);
|
||||||
_holderTypeDefs.Add(_holderTypeDef);
|
_holderTypeDefs.Add(_holderTypeDef);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -171,35 +159,41 @@ namespace Obfuz.Data
|
||||||
return AllocateAny(value);
|
return AllocateAny(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private DefaultMetadataImporter GetModuleMetadataImporter()
|
||||||
|
{
|
||||||
|
return _moduleEntityManager.GetDefaultModuleMetadataImporter(_module, _encryptionScopeProvider);
|
||||||
|
}
|
||||||
|
|
||||||
private void CreateCCtorOfRvaTypeDef(TypeDef type)
|
private void CreateCCtorOfRvaTypeDef(TypeDef type)
|
||||||
{
|
{
|
||||||
ModuleDef mod = Module;
|
|
||||||
var cctor = new MethodDefUser(".cctor",
|
var cctor = new MethodDefUser(".cctor",
|
||||||
MethodSig.CreateStatic(mod.CorLibTypes.Void),
|
MethodSig.CreateStatic(_module.CorLibTypes.Void),
|
||||||
MethodImplAttributes.IL | MethodImplAttributes.Managed,
|
MethodImplAttributes.IL | MethodImplAttributes.Managed,
|
||||||
MethodAttributes.Static | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName | MethodAttributes.Private);
|
MethodAttributes.Static | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName | MethodAttributes.Private);
|
||||||
cctor.DeclaringType = type;
|
cctor.DeclaringType = type;
|
||||||
|
//_rvaTypeDef.Methods.Add(cctor);
|
||||||
var body = new CilBody();
|
var body = new CilBody();
|
||||||
cctor.Body = body;
|
cctor.Body = body;
|
||||||
var ins = body.Instructions;
|
var ins = body.Instructions;
|
||||||
|
|
||||||
|
//IMethod method = _module.Import(typeof(System.Runtime.CompilerServices.RuntimeHelpers).GetMethod("InitializeArray", new[] { typeof(Array), typeof(RuntimeFieldHandle) }));
|
||||||
|
//Assert.IsNotNull(method);
|
||||||
|
|
||||||
DefaultMetadataImporter importer = this.GetDefaultModuleMetadataImporter();
|
|
||||||
RvaDataAllocator rvaDataAllocator = GetEntity<RvaDataAllocator>();
|
DefaultMetadataImporter importer = GetModuleMetadataImporter();
|
||||||
// TODO. obfuscate init codes
|
// TODO. obfuscate init codes
|
||||||
foreach (var field in type.Fields)
|
foreach (var field in type.Fields)
|
||||||
{
|
{
|
||||||
ConstFieldInfo constInfo = _field2Fields[field];
|
ConstFieldInfo constInfo = _field2Fields[field];
|
||||||
IRandom localRandom = _randomCreator(HashUtil.ComputePrimitiveOrStringOrBytesHashCode(constInfo.value));
|
IRandom localRandom = _randomCreator(HashUtil.ComputePrimitiveOrStringOrBytesHashCode(constInfo.value));
|
||||||
int ops = EncryptionUtil.GenerateEncryptionOpCodes(localRandom, _encryptor, EncryptionScopeInfo.MaxEncryptionLevel, false);
|
int ops = EncryptionUtil.GenerateEncryptionOpCodes(localRandom, _encryptor, 4);
|
||||||
int salt = localRandom.NextInt();
|
int salt = localRandom.NextInt();
|
||||||
switch (constInfo.value)
|
switch (constInfo.value)
|
||||||
{
|
{
|
||||||
case int i:
|
case int i:
|
||||||
{
|
{
|
||||||
int encryptedValue = _encryptor.Encrypt(i, ops, salt);
|
int encryptedValue = _encryptor.Encrypt(i, ops, salt);
|
||||||
RvaData rvaData = rvaDataAllocator.Allocate(encryptedValue);
|
RvaData rvaData = _rvaDataAllocator.Allocate(_module, encryptedValue);
|
||||||
ins.Add(Instruction.Create(OpCodes.Ldsfld, rvaData.field));
|
ins.Add(Instruction.Create(OpCodes.Ldsfld, rvaData.field));
|
||||||
ins.Add(Instruction.CreateLdcI4(rvaData.offset));
|
ins.Add(Instruction.CreateLdcI4(rvaData.offset));
|
||||||
ins.Add(Instruction.CreateLdcI4(ops));
|
ins.Add(Instruction.CreateLdcI4(ops));
|
||||||
|
|
@ -210,7 +204,7 @@ namespace Obfuz.Data
|
||||||
case long l:
|
case long l:
|
||||||
{
|
{
|
||||||
long encryptedValue = _encryptor.Encrypt(l, ops, salt);
|
long encryptedValue = _encryptor.Encrypt(l, ops, salt);
|
||||||
RvaData rvaData = rvaDataAllocator.Allocate(encryptedValue);
|
RvaData rvaData = _rvaDataAllocator.Allocate(_module, encryptedValue);
|
||||||
ins.Add(Instruction.Create(OpCodes.Ldsfld, rvaData.field));
|
ins.Add(Instruction.Create(OpCodes.Ldsfld, rvaData.field));
|
||||||
ins.Add(Instruction.CreateLdcI4(rvaData.offset));
|
ins.Add(Instruction.CreateLdcI4(rvaData.offset));
|
||||||
ins.Add(Instruction.CreateLdcI4(ops));
|
ins.Add(Instruction.CreateLdcI4(ops));
|
||||||
|
|
@ -221,7 +215,7 @@ namespace Obfuz.Data
|
||||||
case float f:
|
case float f:
|
||||||
{
|
{
|
||||||
float encryptedValue = _encryptor.Encrypt(f, ops, salt);
|
float encryptedValue = _encryptor.Encrypt(f, ops, salt);
|
||||||
RvaData rvaData = rvaDataAllocator.Allocate(encryptedValue);
|
RvaData rvaData = _rvaDataAllocator.Allocate(_module, encryptedValue);
|
||||||
ins.Add(Instruction.Create(OpCodes.Ldsfld, rvaData.field));
|
ins.Add(Instruction.Create(OpCodes.Ldsfld, rvaData.field));
|
||||||
ins.Add(Instruction.CreateLdcI4(rvaData.offset));
|
ins.Add(Instruction.CreateLdcI4(rvaData.offset));
|
||||||
ins.Add(Instruction.CreateLdcI4(ops));
|
ins.Add(Instruction.CreateLdcI4(ops));
|
||||||
|
|
@ -232,7 +226,7 @@ namespace Obfuz.Data
|
||||||
case double d:
|
case double d:
|
||||||
{
|
{
|
||||||
double encryptedValue = _encryptor.Encrypt(d, ops, salt);
|
double encryptedValue = _encryptor.Encrypt(d, ops, salt);
|
||||||
RvaData rvaData = rvaDataAllocator.Allocate(encryptedValue);
|
RvaData rvaData = _rvaDataAllocator.Allocate(_module, encryptedValue);
|
||||||
ins.Add(Instruction.Create(OpCodes.Ldsfld, rvaData.field));
|
ins.Add(Instruction.Create(OpCodes.Ldsfld, rvaData.field));
|
||||||
ins.Add(Instruction.CreateLdcI4(rvaData.offset));
|
ins.Add(Instruction.CreateLdcI4(rvaData.offset));
|
||||||
ins.Add(Instruction.CreateLdcI4(ops));
|
ins.Add(Instruction.CreateLdcI4(ops));
|
||||||
|
|
@ -243,7 +237,7 @@ namespace Obfuz.Data
|
||||||
case string s:
|
case string s:
|
||||||
{
|
{
|
||||||
byte[] encryptedValue = _encryptor.Encrypt(s, ops, salt);
|
byte[] encryptedValue = _encryptor.Encrypt(s, ops, salt);
|
||||||
RvaData rvaData = rvaDataAllocator.Allocate(encryptedValue);
|
RvaData rvaData = _rvaDataAllocator.Allocate(_module, encryptedValue);
|
||||||
ins.Add(Instruction.Create(OpCodes.Ldsfld, rvaData.field));
|
ins.Add(Instruction.Create(OpCodes.Ldsfld, rvaData.field));
|
||||||
ins.Add(Instruction.CreateLdcI4(rvaData.offset));
|
ins.Add(Instruction.CreateLdcI4(rvaData.offset));
|
||||||
Assert.AreEqual(encryptedValue.Length, rvaData.size);
|
Assert.AreEqual(encryptedValue.Length, rvaData.size);
|
||||||
|
|
@ -257,7 +251,7 @@ namespace Obfuz.Data
|
||||||
{
|
{
|
||||||
byte[] encryptedValue = _encryptor.Encrypt(bs, 0, bs.Length, ops, salt);
|
byte[] encryptedValue = _encryptor.Encrypt(bs, 0, bs.Length, ops, salt);
|
||||||
Assert.AreEqual(encryptedValue.Length, bs.Length);
|
Assert.AreEqual(encryptedValue.Length, bs.Length);
|
||||||
RvaData rvaData = rvaDataAllocator.Allocate(encryptedValue);
|
RvaData rvaData = _rvaDataAllocator.Allocate(_module, encryptedValue);
|
||||||
ins.Add(Instruction.Create(OpCodes.Ldsfld, rvaData.field));
|
ins.Add(Instruction.Create(OpCodes.Ldsfld, rvaData.field));
|
||||||
ins.Add(Instruction.CreateLdcI4(rvaData.offset));
|
ins.Add(Instruction.CreateLdcI4(rvaData.offset));
|
||||||
ins.Add(Instruction.CreateLdcI4(bs.Length));
|
ins.Add(Instruction.CreateLdcI4(bs.Length));
|
||||||
|
|
@ -273,7 +267,7 @@ namespace Obfuz.Data
|
||||||
ins.Add(Instruction.Create(OpCodes.Ret));
|
ins.Add(Instruction.Create(OpCodes.Ret));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Done()
|
public void Done()
|
||||||
{
|
{
|
||||||
if (_done)
|
if (_done)
|
||||||
{
|
{
|
||||||
|
|
@ -286,4 +280,61 @@ namespace Obfuz.Data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class ConstFieldAllocator
|
||||||
|
{
|
||||||
|
private readonly EncryptionScopeProvider _encryptionScopeProvider;
|
||||||
|
private readonly RvaDataAllocator _rvaDataAllocator;
|
||||||
|
private readonly GroupByModuleEntityManager _moduleEntityManager;
|
||||||
|
|
||||||
|
public ConstFieldAllocator(EncryptionScopeProvider encryptionScopeProvider, RvaDataAllocator rvaDataAllocator, GroupByModuleEntityManager moduleEntityManager)
|
||||||
|
{
|
||||||
|
_encryptionScopeProvider = encryptionScopeProvider;
|
||||||
|
_rvaDataAllocator = rvaDataAllocator;
|
||||||
|
_moduleEntityManager = moduleEntityManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ModuleConstFieldAllocator GetModuleAllocator(ModuleDef mod)
|
||||||
|
{
|
||||||
|
return _moduleEntityManager.GetEntity<ModuleConstFieldAllocator>(mod, () => new ModuleConstFieldAllocator(_encryptionScopeProvider, _rvaDataAllocator, _moduleEntityManager));
|
||||||
|
}
|
||||||
|
|
||||||
|
public FieldDef Allocate(ModuleDef mod, int value)
|
||||||
|
{
|
||||||
|
return GetModuleAllocator(mod).Allocate(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FieldDef Allocate(ModuleDef mod, long value)
|
||||||
|
{
|
||||||
|
return GetModuleAllocator(mod).Allocate(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FieldDef Allocate(ModuleDef mod, float value)
|
||||||
|
{
|
||||||
|
return GetModuleAllocator(mod).Allocate(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FieldDef Allocate(ModuleDef mod, double value)
|
||||||
|
{
|
||||||
|
return GetModuleAllocator(mod).Allocate(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FieldDef Allocate(ModuleDef mod, byte[] value)
|
||||||
|
{
|
||||||
|
return GetModuleAllocator(mod).Allocate(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FieldDef Allocate(ModuleDef mod, string value)
|
||||||
|
{
|
||||||
|
return GetModuleAllocator(mod).Allocate(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Done()
|
||||||
|
{
|
||||||
|
foreach (var moduleAllocator in _moduleEntityManager.GetEntities<ModuleConstFieldAllocator>())
|
||||||
|
{
|
||||||
|
moduleAllocator.Done();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,30 +1,9 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet;
|
using dnlib.DotNet;
|
||||||
using dnlib.DotNet.Emit;
|
using dnlib.DotNet.Emit;
|
||||||
using Obfuz.Emit;
|
using Obfuz.Emit;
|
||||||
using Obfuz.Utils;
|
using Obfuz.Utils;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using UnityEngine.Assertions;
|
using UnityEngine.Assertions;
|
||||||
|
|
||||||
|
|
@ -44,13 +23,16 @@ namespace Obfuz.Data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class RvaDataAllocator : GroupByModuleEntityBase
|
public class ModuleRvaDataAllocator : GroupByModuleEntityBase
|
||||||
{
|
{
|
||||||
const int maxRvaDataSize = 2 * 1024;
|
// randomized
|
||||||
|
const int maxRvaDataSize = 0x1000;
|
||||||
|
|
||||||
// in HybridCLR version below 8.3.0, the max total static field size of a type is 16KB, so we limit the total size of RVA data to 16KB
|
private ModuleDef _module;
|
||||||
const int maxTotalRvaDataFieldSizeInHybridCLR = 16 * 1024;
|
private readonly EncryptionScopeProvider _encryptionScopeProvider;
|
||||||
|
private readonly GroupByModuleEntityManager _moduleEntityManager;
|
||||||
|
|
||||||
|
private EncryptionScopeInfo _encryptionScope;
|
||||||
private IRandom _random;
|
private IRandom _random;
|
||||||
|
|
||||||
class RvaField
|
class RvaField
|
||||||
|
|
@ -80,72 +62,64 @@ namespace Obfuz.Data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class RvaTypeDefInfo
|
private readonly List<RvaField> _rvaFields = new List<RvaField>();
|
||||||
{
|
|
||||||
public readonly TypeDef typeDef;
|
|
||||||
public readonly int index;
|
|
||||||
public readonly List<RvaField> rvaFields = new List<RvaField>();
|
|
||||||
|
|
||||||
public RvaTypeDefInfo(TypeDef typeDef, int index)
|
|
||||||
{
|
|
||||||
this.typeDef = typeDef;
|
|
||||||
this.index = index;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private RvaField _currentField;
|
private RvaField _currentField;
|
||||||
|
|
||||||
private RvaTypeDefInfo _currentRvaType;
|
|
||||||
private readonly List<RvaTypeDefInfo> _rvaTypeDefs = new List<RvaTypeDefInfo>();
|
private TypeDef _rvaTypeDef;
|
||||||
|
|
||||||
private readonly Dictionary<int, TypeDef> _dataHolderTypeBySizes = new Dictionary<int, TypeDef>();
|
private readonly Dictionary<int, TypeDef> _dataHolderTypeBySizes = new Dictionary<int, TypeDef>();
|
||||||
private bool _done;
|
private bool _done;
|
||||||
|
|
||||||
public RvaDataAllocator()
|
public ModuleRvaDataAllocator(EncryptionScopeProvider encryptionScopeProvider, GroupByModuleEntityManager moduleEntityManager)
|
||||||
{
|
{
|
||||||
|
_encryptionScopeProvider = encryptionScopeProvider;
|
||||||
|
_moduleEntityManager = moduleEntityManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Init()
|
public override void Init(ModuleDef mod)
|
||||||
{
|
{
|
||||||
_random = EncryptionScope.localRandomCreator(HashUtil.ComputeHash(Module.Name));
|
_module = mod;
|
||||||
|
_encryptionScope = _encryptionScopeProvider.GetScope(mod);
|
||||||
|
_random = _encryptionScope.localRandomCreator(HashUtil.ComputeHash(mod.Name));
|
||||||
}
|
}
|
||||||
|
|
||||||
private (FieldDef, FieldDef) CreateDataHolderRvaField(TypeDef dataHolderType)
|
private (FieldDef, FieldDef) CreateDataHolderRvaField(TypeDef dataHolderType)
|
||||||
{
|
{
|
||||||
if (_currentRvaType == null || _currentRvaType.rvaFields.Count >= maxTotalRvaDataFieldSizeInHybridCLR / maxRvaDataSize - 1)
|
if (_rvaTypeDef == null)
|
||||||
{
|
{
|
||||||
using (var scope = new DisableTypeDefFindCacheScope(Module))
|
using (var scope = new DisableTypeDefFindCacheScope(_module))
|
||||||
{
|
{
|
||||||
var rvaTypeDef = new TypeDefUser($"$Obfuz$RVA${_rvaTypeDefs.Count}", Module.CorLibTypes.Object.ToTypeDefOrRef());
|
ITypeDefOrRef objectTypeRef = _module.Import(typeof(object));
|
||||||
Module.Types.Add(rvaTypeDef);
|
_rvaTypeDef = new TypeDefUser("$Obfuz$RVA$", objectTypeRef);
|
||||||
_currentRvaType = new RvaTypeDefInfo(rvaTypeDef, _rvaTypeDefs.Count);
|
_module.Types.Add(_rvaTypeDef);
|
||||||
_rvaTypeDefs.Add(_currentRvaType);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var holderField = new FieldDefUser($"$RVA_Data{_currentRvaType.rvaFields.Count}", new FieldSig(dataHolderType.ToTypeSig()), FieldAttributes.InitOnly | FieldAttributes.Static | FieldAttributes.HasFieldRVA);
|
|
||||||
holderField.DeclaringType = _currentRvaType.typeDef;
|
|
||||||
|
|
||||||
var runtimeValueField = new FieldDefUser($"$RVA_Value{_currentRvaType.rvaFields.Count}", new FieldSig(new SZArraySig(Module.CorLibTypes.Byte)), FieldAttributes.Static | FieldAttributes.Public);
|
var holderField = new FieldDefUser($"$RVA_Data{_rvaFields.Count}", new FieldSig(dataHolderType.ToTypeSig()), FieldAttributes.InitOnly | FieldAttributes.Static | FieldAttributes.HasFieldRVA);
|
||||||
runtimeValueField.DeclaringType = _currentRvaType.typeDef;
|
holderField.DeclaringType = _rvaTypeDef;
|
||||||
|
|
||||||
|
var runtimeValueField = new FieldDefUser($"$RVA_Value{_rvaFields.Count}", new FieldSig(new SZArraySig(_module.CorLibTypes.Byte)), FieldAttributes.Static | FieldAttributes.Public);
|
||||||
|
runtimeValueField.DeclaringType = _rvaTypeDef;
|
||||||
return (holderField, runtimeValueField);
|
return (holderField, runtimeValueField);
|
||||||
}
|
}
|
||||||
|
|
||||||
private TypeDef GetDataHolderType(int size)
|
private TypeDef GetDataHolderType(int size)
|
||||||
{
|
{
|
||||||
size = (size + 15) & ~15; // align to 16 bytes
|
size = (size + 15) & ~15; // align to 6 bytes
|
||||||
if (_dataHolderTypeBySizes.TryGetValue(size, out var type))
|
if (_dataHolderTypeBySizes.TryGetValue(size, out var type))
|
||||||
return type;
|
return type;
|
||||||
|
|
||||||
using (var scope = new DisableTypeDefFindCacheScope(Module))
|
using (var scope = new DisableTypeDefFindCacheScope(_module))
|
||||||
{
|
{
|
||||||
var dataHolderType = new TypeDefUser($"$ObfuzRVA$DataHolder{size}", Module.Import(typeof(ValueType)));
|
var dataHolderType = new TypeDefUser($"$ObfuzRVA$DataHolder{size}", _module.Import(typeof(ValueType)));
|
||||||
dataHolderType.Attributes = TypeAttributes.Public | TypeAttributes.Sealed;
|
dataHolderType.Attributes = TypeAttributes.Public | TypeAttributes.Sealed;
|
||||||
dataHolderType.Layout = TypeAttributes.ExplicitLayout;
|
dataHolderType.Layout = TypeAttributes.ExplicitLayout;
|
||||||
dataHolderType.PackingSize = 1;
|
dataHolderType.PackingSize = 1;
|
||||||
dataHolderType.ClassSize = (uint)size;
|
dataHolderType.ClassSize = (uint)size;
|
||||||
_dataHolderTypeBySizes.Add(size, dataHolderType);
|
_dataHolderTypeBySizes.Add(size, dataHolderType);
|
||||||
Module.Types.Add(dataHolderType);
|
_module.Types.Add(dataHolderType);
|
||||||
return dataHolderType;
|
return dataHolderType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -168,7 +142,7 @@ namespace Obfuz.Data
|
||||||
encryptionOps = _random.NextInt(),
|
encryptionOps = _random.NextInt(),
|
||||||
salt = _random.NextInt(),
|
salt = _random.NextInt(),
|
||||||
};
|
};
|
||||||
_currentRvaType.rvaFields.Add(newRvaField);
|
_rvaFields.Add(newRvaField);
|
||||||
return newRvaField;
|
return newRvaField;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -256,11 +230,10 @@ namespace Obfuz.Data
|
||||||
private void AddVerifyCodes(IList<Instruction> insts, DefaultMetadataImporter importer)
|
private void AddVerifyCodes(IList<Instruction> insts, DefaultMetadataImporter importer)
|
||||||
{
|
{
|
||||||
int verifyIntValue = 0x12345678;
|
int verifyIntValue = 0x12345678;
|
||||||
EncryptionScopeInfo encryptionScope = this.EncryptionScope;
|
IRandom verifyRandom = _encryptionScope.localRandomCreator(verifyIntValue);
|
||||||
IRandom verifyRandom = encryptionScope.localRandomCreator(verifyIntValue);
|
int verifyOps = EncryptionUtil.GenerateEncryptionOpCodes(verifyRandom, _encryptionScope.encryptor, 4);
|
||||||
int verifyOps = EncryptionUtil.GenerateEncryptionOpCodes(verifyRandom, encryptionScope.encryptor, EncryptionScopeInfo.MaxEncryptionLevel, false);
|
|
||||||
int verifySalt = verifyRandom.NextInt();
|
int verifySalt = verifyRandom.NextInt();
|
||||||
int encryptedVerifyIntValue = encryptionScope.encryptor.Encrypt(verifyIntValue, verifyOps, verifySalt);
|
int encryptedVerifyIntValue = _encryptionScope.encryptor.Encrypt(verifyIntValue, verifyOps, verifySalt);
|
||||||
|
|
||||||
insts.Add(Instruction.Create(OpCodes.Ldc_I4, verifyIntValue));
|
insts.Add(Instruction.Create(OpCodes.Ldc_I4, verifyIntValue));
|
||||||
insts.Add(Instruction.CreateLdcI4(encryptedVerifyIntValue));
|
insts.Add(Instruction.CreateLdcI4(encryptedVerifyIntValue));
|
||||||
|
|
@ -273,22 +246,24 @@ namespace Obfuz.Data
|
||||||
|
|
||||||
private void CreateCCtorOfRvaTypeDef()
|
private void CreateCCtorOfRvaTypeDef()
|
||||||
{
|
{
|
||||||
foreach (RvaTypeDefInfo rvaTypeDef in _rvaTypeDefs)
|
if (_rvaTypeDef == null)
|
||||||
{
|
{
|
||||||
ModuleDef mod = rvaTypeDef.typeDef.Module;
|
return;
|
||||||
|
}
|
||||||
|
ModuleDef mod = _rvaTypeDef.Module;
|
||||||
var cctorMethod = new MethodDefUser(".cctor",
|
var cctorMethod = new MethodDefUser(".cctor",
|
||||||
MethodSig.CreateStatic(Module.CorLibTypes.Void),
|
MethodSig.CreateStatic(_module.CorLibTypes.Void),
|
||||||
MethodImplAttributes.IL | MethodImplAttributes.Managed,
|
MethodImplAttributes.IL | MethodImplAttributes.Managed,
|
||||||
MethodAttributes.Static | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName | MethodAttributes.Private);
|
MethodAttributes.Static | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName | MethodAttributes.Private);
|
||||||
cctorMethod.DeclaringType = rvaTypeDef.typeDef;
|
cctorMethod.DeclaringType = _rvaTypeDef;
|
||||||
//_rvaTypeDef.Methods.Add(cctor);
|
//_rvaTypeDef.Methods.Add(cctor);
|
||||||
var body = new CilBody();
|
var body = new CilBody();
|
||||||
cctorMethod.Body = body;
|
cctorMethod.Body = body;
|
||||||
var ins = body.Instructions;
|
var ins = body.Instructions;
|
||||||
|
|
||||||
DefaultMetadataImporter importer = this.GetDefaultModuleMetadataImporter();
|
DefaultMetadataImporter importer = _moduleEntityManager.GetDefaultModuleMetadataImporter(mod, _encryptionScopeProvider);
|
||||||
AddVerifyCodes(ins, importer);
|
AddVerifyCodes(ins, importer);
|
||||||
foreach (var field in rvaTypeDef.rvaFields)
|
foreach (var field in _rvaFields)
|
||||||
{
|
{
|
||||||
// ldc
|
// ldc
|
||||||
// newarr
|
// newarr
|
||||||
|
|
@ -312,11 +287,10 @@ namespace Obfuz.Data
|
||||||
}
|
}
|
||||||
ins.Add(Instruction.Create(OpCodes.Ret));
|
ins.Add(Instruction.Create(OpCodes.Ret));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private void SetFieldsRVA()
|
private void SetFieldsRVA()
|
||||||
{
|
{
|
||||||
foreach (var field in _rvaTypeDefs.SelectMany(t => t.rvaFields))
|
foreach (var field in _rvaFields)
|
||||||
{
|
{
|
||||||
Assert.IsTrue(field.bytes.Count <= field.size);
|
Assert.IsTrue(field.bytes.Count <= field.size);
|
||||||
if (field.bytes.Count < field.size)
|
if (field.bytes.Count < field.size)
|
||||||
|
|
@ -324,12 +298,12 @@ namespace Obfuz.Data
|
||||||
field.FillPaddingToEnd();
|
field.FillPaddingToEnd();
|
||||||
}
|
}
|
||||||
byte[] data = field.bytes.ToArray();
|
byte[] data = field.bytes.ToArray();
|
||||||
EncryptionScope.encryptor.EncryptBlock(data, field.encryptionOps, field.salt);
|
_encryptionScope.encryptor.EncryptBlock(data, field.encryptionOps, field.salt);
|
||||||
field.holderDataField.InitialValue = data;
|
field.holderDataField.InitialValue = data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Done()
|
public void Done()
|
||||||
{
|
{
|
||||||
if (_done)
|
if (_done)
|
||||||
{
|
{
|
||||||
|
|
@ -340,4 +314,59 @@ namespace Obfuz.Data
|
||||||
CreateCCtorOfRvaTypeDef();
|
CreateCCtorOfRvaTypeDef();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class RvaDataAllocator
|
||||||
|
{
|
||||||
|
private readonly EncryptionScopeProvider _encryptionScopeProvider;
|
||||||
|
private readonly GroupByModuleEntityManager _moduleEntityManager;
|
||||||
|
|
||||||
|
public RvaDataAllocator(EncryptionScopeProvider encryptionScopeProvider, GroupByModuleEntityManager moduleEntityManager)
|
||||||
|
{
|
||||||
|
_encryptionScopeProvider = encryptionScopeProvider;
|
||||||
|
_moduleEntityManager = moduleEntityManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ModuleRvaDataAllocator GetModuleRvaDataAllocator(ModuleDef mod)
|
||||||
|
{
|
||||||
|
return _moduleEntityManager.GetEntity<ModuleRvaDataAllocator>(mod, () => new ModuleRvaDataAllocator(_encryptionScopeProvider, _moduleEntityManager));
|
||||||
|
}
|
||||||
|
|
||||||
|
public RvaData Allocate(ModuleDef mod, int value)
|
||||||
|
{
|
||||||
|
return GetModuleRvaDataAllocator(mod).Allocate(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RvaData Allocate(ModuleDef mod, long value)
|
||||||
|
{
|
||||||
|
return GetModuleRvaDataAllocator(mod).Allocate(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RvaData Allocate(ModuleDef mod, float value)
|
||||||
|
{
|
||||||
|
return GetModuleRvaDataAllocator(mod).Allocate(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RvaData Allocate(ModuleDef mod, double value)
|
||||||
|
{
|
||||||
|
return GetModuleRvaDataAllocator(mod).Allocate(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RvaData Allocate(ModuleDef mod, string value)
|
||||||
|
{
|
||||||
|
return GetModuleRvaDataAllocator(mod).Allocate(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RvaData Allocate(ModuleDef mod, byte[] value)
|
||||||
|
{
|
||||||
|
return GetModuleRvaDataAllocator(mod).Allocate(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Done()
|
||||||
|
{
|
||||||
|
foreach (var allocator in _moduleEntityManager.GetEntities<ModuleRvaDataAllocator>())
|
||||||
|
{
|
||||||
|
allocator.Done();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet;
|
using dnlib.DotNet;
|
||||||
using dnlib.DotNet.Emit;
|
using dnlib.DotNet.Emit;
|
||||||
using System;
|
using System;
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet;
|
using dnlib.DotNet;
|
||||||
using System;
|
using System;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
@ -124,27 +104,30 @@ namespace Obfuz.Emit
|
||||||
Assert.IsNotNull(_decryptFromRvaBytes);
|
Assert.IsNotNull(_decryptFromRvaBytes);
|
||||||
_decryptFromRvaString = mod.Import(encryptionServiceType.GetMethod("DecryptFromRvaString", new[] { typeof(byte[]), typeof(int), typeof(int), typeof(int), typeof(int) }));
|
_decryptFromRvaString = mod.Import(encryptionServiceType.GetMethod("DecryptFromRvaString", new[] { typeof(byte[]), typeof(int), typeof(int), typeof(int), typeof(int) }));
|
||||||
Assert.IsNotNull(_decryptFromRvaString);
|
Assert.IsNotNull(_decryptFromRvaString);
|
||||||
_decryptInitializeArray = mod.Import(encryptionServiceType.GetMethod("DecryptInitializeArray", new[] { typeof(System.Array), typeof(byte[]), typeof(int), typeof(int), typeof(int), typeof(int) }));
|
_decryptInitializeArray = mod.Import(encryptionServiceType.GetMethod("DecryptInitializeArray", new[] { typeof(System.Array), typeof(System.RuntimeFieldHandle), typeof(int), typeof(int), typeof(int) }));
|
||||||
Assert.IsNotNull(_decryptInitializeArray);
|
Assert.IsNotNull(_decryptInitializeArray);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class DefaultMetadataImporter : GroupByModuleEntityBase
|
public class DefaultMetadataImporter : GroupByModuleEntityBase
|
||||||
{
|
{
|
||||||
|
private readonly EncryptionScopeProvider _encryptionScopeProvider;
|
||||||
|
private EncryptionScopeInfo _encryptionScope;
|
||||||
private EncryptionServiceMetadataImporter _defaultEncryptionServiceMetadataImporter;
|
private EncryptionServiceMetadataImporter _defaultEncryptionServiceMetadataImporter;
|
||||||
|
|
||||||
|
|
||||||
private EncryptionServiceMetadataImporter _staticDefaultEncryptionServiceMetadataImporter;
|
private EncryptionServiceMetadataImporter _staticDefaultEncryptionServiceMetadataImporter;
|
||||||
private EncryptionServiceMetadataImporter _dynamicDefaultEncryptionServiceMetadataImporter;
|
private EncryptionServiceMetadataImporter _dynamicDefaultEncryptionServiceMetadataImporter;
|
||||||
|
|
||||||
public DefaultMetadataImporter()
|
public DefaultMetadataImporter(EncryptionScopeProvider encryptionScopeProvider)
|
||||||
{
|
{
|
||||||
|
_encryptionScopeProvider = encryptionScopeProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Init()
|
public override void Init(ModuleDef mod)
|
||||||
{
|
{
|
||||||
ModuleDef mod = Module;
|
_module = mod;
|
||||||
|
_encryptionScope = _encryptionScopeProvider.GetScope(mod);
|
||||||
var constUtilityType = typeof(ConstUtility);
|
var constUtilityType = typeof(ConstUtility);
|
||||||
|
|
||||||
_castIntAsFloat = mod.Import(constUtilityType.GetMethod("CastIntAsFloat"));
|
_castIntAsFloat = mod.Import(constUtilityType.GetMethod("CastIntAsFloat"));
|
||||||
|
|
@ -158,7 +141,7 @@ namespace Obfuz.Emit
|
||||||
|
|
||||||
_initializeArray = mod.Import(typeof(System.Runtime.CompilerServices.RuntimeHelpers).GetMethod("InitializeArray", new[] { typeof(Array), typeof(RuntimeFieldHandle) }));
|
_initializeArray = mod.Import(typeof(System.Runtime.CompilerServices.RuntimeHelpers).GetMethod("InitializeArray", new[] { typeof(Array), typeof(RuntimeFieldHandle) }));
|
||||||
Assert.IsNotNull(_initializeArray);
|
Assert.IsNotNull(_initializeArray);
|
||||||
_verifySecretKey = mod.Import(typeof(AssertUtility).GetMethod("VerifySecretKey", new[] { typeof(int), typeof(int) }));
|
_verifySecretKey = mod.Import(typeof(AssetUtility).GetMethod("VerifySecretKey", new[] { typeof(int), typeof(int) }));
|
||||||
Assert.IsNotNull(_verifySecretKey, "VerifySecretKey not found");
|
Assert.IsNotNull(_verifySecretKey, "VerifySecretKey not found");
|
||||||
|
|
||||||
_obfuscationTypeMapperRegisterType = mod.Import(typeof(ObfuscationTypeMapper).GetMethod("RegisterType", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static, null, new[] { typeof(string) }, null));
|
_obfuscationTypeMapperRegisterType = mod.Import(typeof(ObfuscationTypeMapper).GetMethod("RegisterType", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static, null, new[] { typeof(string) }, null));
|
||||||
|
|
@ -173,11 +156,6 @@ namespace Obfuz.Emit
|
||||||
Assert.IsNotNull(_addFloat, "ExprUtility.Add(float, float) not found");
|
Assert.IsNotNull(_addFloat, "ExprUtility.Add(float, float) not found");
|
||||||
_addDouble = mod.Import(exprUtilityType.GetMethod("Add", new[] { typeof(double), typeof(double) }));
|
_addDouble = mod.Import(exprUtilityType.GetMethod("Add", new[] { typeof(double), typeof(double) }));
|
||||||
Assert.IsNotNull(_addDouble, "ExprUtility.Add(double, double) not found");
|
Assert.IsNotNull(_addDouble, "ExprUtility.Add(double, double) not found");
|
||||||
_addIntPtr = mod.Import(exprUtilityType.GetMethod("Add", new[] { typeof(IntPtr), typeof(IntPtr) }));
|
|
||||||
Assert.IsNotNull(_addIntPtr, "ExprUtility.Add(IntPtr, IntPtr) not found");
|
|
||||||
_addIntPtrInt = mod.Import(exprUtilityType.GetMethod("Add", new[] { typeof(IntPtr), typeof(int) }));
|
|
||||||
Assert.IsNotNull(_addIntPtrInt, "ExprUtility.Add(IntPtr, int) not found");
|
|
||||||
|
|
||||||
_subtractInt = mod.Import(exprUtilityType.GetMethod("Subtract", new[] { typeof(int), typeof(int) }));
|
_subtractInt = mod.Import(exprUtilityType.GetMethod("Subtract", new[] { typeof(int), typeof(int) }));
|
||||||
Assert.IsNotNull(_subtractInt, "ExprUtility.Subtract(int, int) not found");
|
Assert.IsNotNull(_subtractInt, "ExprUtility.Subtract(int, int) not found");
|
||||||
_subtractLong = mod.Import(exprUtilityType.GetMethod("Subtract", new[] { typeof(long), typeof(long) }));
|
_subtractLong = mod.Import(exprUtilityType.GetMethod("Subtract", new[] { typeof(long), typeof(long) }));
|
||||||
|
|
@ -186,11 +164,6 @@ namespace Obfuz.Emit
|
||||||
Assert.IsNotNull(_subtractFloat, "ExprUtility.Subtract(float, float) not found");
|
Assert.IsNotNull(_subtractFloat, "ExprUtility.Subtract(float, float) not found");
|
||||||
_subtractDouble = mod.Import(exprUtilityType.GetMethod("Subtract", new[] { typeof(double), typeof(double) }));
|
_subtractDouble = mod.Import(exprUtilityType.GetMethod("Subtract", new[] { typeof(double), typeof(double) }));
|
||||||
Assert.IsNotNull(_subtractDouble, "ExprUtility.Subtract(double, double) not found");
|
Assert.IsNotNull(_subtractDouble, "ExprUtility.Subtract(double, double) not found");
|
||||||
_subtractIntPtr = mod.Import(exprUtilityType.GetMethod("Subtract", new[] { typeof(IntPtr), typeof(IntPtr) }));
|
|
||||||
Assert.IsNotNull(_subtractIntPtr, "ExprUtility.Subtract(IntPtr, IntPtr) not found");
|
|
||||||
_subtractIntPtrInt = mod.Import(exprUtilityType.GetMethod("Subtract", new[] { typeof(IntPtr), typeof(int) }));
|
|
||||||
Assert.IsNotNull(_subtractIntPtrInt, "ExprUtility.Subtract(IntPtr, int) not found");
|
|
||||||
|
|
||||||
_multiplyInt = mod.Import(exprUtilityType.GetMethod("Multiply", new[] { typeof(int), typeof(int) }));
|
_multiplyInt = mod.Import(exprUtilityType.GetMethod("Multiply", new[] { typeof(int), typeof(int) }));
|
||||||
Assert.IsNotNull(_multiplyInt, "ExprUtility.Multiply(int, int) not found");
|
Assert.IsNotNull(_multiplyInt, "ExprUtility.Multiply(int, int) not found");
|
||||||
_multiplyLong = mod.Import(exprUtilityType.GetMethod("Multiply", new[] { typeof(long), typeof(long) }));
|
_multiplyLong = mod.Import(exprUtilityType.GetMethod("Multiply", new[] { typeof(long), typeof(long) }));
|
||||||
|
|
@ -199,11 +172,6 @@ namespace Obfuz.Emit
|
||||||
Assert.IsNotNull(_multiplyFloat, "ExprUtility.Multiply(float, float) not found");
|
Assert.IsNotNull(_multiplyFloat, "ExprUtility.Multiply(float, float) not found");
|
||||||
_multiplyDouble = mod.Import(exprUtilityType.GetMethod("Multiply", new[] { typeof(double), typeof(double) }));
|
_multiplyDouble = mod.Import(exprUtilityType.GetMethod("Multiply", new[] { typeof(double), typeof(double) }));
|
||||||
Assert.IsNotNull(_multiplyDouble, "ExprUtility.Multiply(double, double) not found");
|
Assert.IsNotNull(_multiplyDouble, "ExprUtility.Multiply(double, double) not found");
|
||||||
_multiplyIntPtr = mod.Import(exprUtilityType.GetMethod("Multiply", new[] { typeof(IntPtr), typeof(IntPtr) }));
|
|
||||||
Assert.IsNotNull(_multiplyIntPtr, "ExprUtility.Multiply(IntPtr, IntPtr) not found");
|
|
||||||
_multiplyIntPtrInt = mod.Import(exprUtilityType.GetMethod("Multiply", new[] { typeof(IntPtr), typeof(int) }));
|
|
||||||
Assert.IsNotNull(_multiplyIntPtrInt, "ExprUtility.Multiply(IntPtr, int) not found");
|
|
||||||
|
|
||||||
_divideInt = mod.Import(exprUtilityType.GetMethod("Divide", new[] { typeof(int), typeof(int) }));
|
_divideInt = mod.Import(exprUtilityType.GetMethod("Divide", new[] { typeof(int), typeof(int) }));
|
||||||
Assert.IsNotNull(_divideInt, "ExprUtility.Divide(int, int) not found");
|
Assert.IsNotNull(_divideInt, "ExprUtility.Divide(int, int) not found");
|
||||||
_divideLong = mod.Import(exprUtilityType.GetMethod("Divide", new[] { typeof(long), typeof(long) }));
|
_divideLong = mod.Import(exprUtilityType.GetMethod("Divide", new[] { typeof(long), typeof(long) }));
|
||||||
|
|
@ -270,7 +238,7 @@ namespace Obfuz.Emit
|
||||||
|
|
||||||
_staticDefaultEncryptionServiceMetadataImporter = new EncryptionServiceMetadataImporter(mod, typeof(EncryptionService<DefaultStaticEncryptionScope>));
|
_staticDefaultEncryptionServiceMetadataImporter = new EncryptionServiceMetadataImporter(mod, typeof(EncryptionService<DefaultStaticEncryptionScope>));
|
||||||
_dynamicDefaultEncryptionServiceMetadataImporter = new EncryptionServiceMetadataImporter(mod, typeof(EncryptionService<DefaultDynamicEncryptionScope>));
|
_dynamicDefaultEncryptionServiceMetadataImporter = new EncryptionServiceMetadataImporter(mod, typeof(EncryptionService<DefaultDynamicEncryptionScope>));
|
||||||
if (EncryptionScopeProvider.IsDynamicSecretAssembly(mod))
|
if (_encryptionScopeProvider.IsDynamicSecretAssembly(mod))
|
||||||
{
|
{
|
||||||
_defaultEncryptionServiceMetadataImporter = _dynamicDefaultEncryptionServiceMetadataImporter;
|
_defaultEncryptionServiceMetadataImporter = _dynamicDefaultEncryptionServiceMetadataImporter;
|
||||||
}
|
}
|
||||||
|
|
@ -280,14 +248,9 @@ namespace Obfuz.Emit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Done()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public EncryptionServiceMetadataImporter GetEncryptionServiceMetadataImporterOfModule(ModuleDef mod)
|
public EncryptionServiceMetadataImporter GetEncryptionServiceMetadataImporterOfModule(ModuleDef mod)
|
||||||
{
|
{
|
||||||
return EncryptionScopeProvider.IsDynamicSecretAssembly(mod) ? _dynamicDefaultEncryptionServiceMetadataImporter : _staticDefaultEncryptionServiceMetadataImporter;
|
return _encryptionScopeProvider.IsDynamicSecretAssembly(mod) ? _dynamicDefaultEncryptionServiceMetadataImporter : _staticDefaultEncryptionServiceMetadataImporter;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ModuleDef _module;
|
private ModuleDef _module;
|
||||||
|
|
@ -304,20 +267,14 @@ namespace Obfuz.Emit
|
||||||
private IMethod _addLong;
|
private IMethod _addLong;
|
||||||
private IMethod _addFloat;
|
private IMethod _addFloat;
|
||||||
private IMethod _addDouble;
|
private IMethod _addDouble;
|
||||||
private IMethod _addIntPtr;
|
|
||||||
private IMethod _addIntPtrInt;
|
|
||||||
private IMethod _subtractInt;
|
private IMethod _subtractInt;
|
||||||
private IMethod _subtractLong;
|
private IMethod _subtractLong;
|
||||||
private IMethod _subtractFloat;
|
private IMethod _subtractFloat;
|
||||||
private IMethod _subtractDouble;
|
private IMethod _subtractDouble;
|
||||||
private IMethod _subtractIntPtr;
|
|
||||||
private IMethod _subtractIntPtrInt;
|
|
||||||
private IMethod _multiplyInt;
|
private IMethod _multiplyInt;
|
||||||
private IMethod _multiplyLong;
|
private IMethod _multiplyLong;
|
||||||
private IMethod _multiplyFloat;
|
private IMethod _multiplyFloat;
|
||||||
private IMethod _multiplyDouble;
|
private IMethod _multiplyDouble;
|
||||||
private IMethod _multiplyIntPtr;
|
|
||||||
private IMethod _multiplyIntPtrInt;
|
|
||||||
private IMethod _divideInt;
|
private IMethod _divideInt;
|
||||||
private IMethod _divideLong;
|
private IMethod _divideLong;
|
||||||
private IMethod _divideFloat;
|
private IMethod _divideFloat;
|
||||||
|
|
@ -391,22 +348,14 @@ namespace Obfuz.Emit
|
||||||
public IMethod AddLong => _addLong;
|
public IMethod AddLong => _addLong;
|
||||||
public IMethod AddFloat => _addFloat;
|
public IMethod AddFloat => _addFloat;
|
||||||
public IMethod AddDouble => _addDouble;
|
public IMethod AddDouble => _addDouble;
|
||||||
public IMethod AddIntPtr => _addIntPtr;
|
|
||||||
public IMethod AddIntPtrInt => _addIntPtrInt;
|
|
||||||
public IMethod SubtractInt => _subtractInt;
|
public IMethod SubtractInt => _subtractInt;
|
||||||
public IMethod SubtractLong => _subtractLong;
|
public IMethod SubtractLong => _subtractLong;
|
||||||
public IMethod SubtractFloat => _subtractFloat;
|
public IMethod SubtractFloat => _subtractFloat;
|
||||||
public IMethod SubtractDouble => _subtractDouble;
|
public IMethod SubtractDouble => _subtractDouble;
|
||||||
public IMethod SubtractIntPtr => _subtractIntPtr;
|
|
||||||
public IMethod SubtractIntPtrInt => _subtractIntPtrInt;
|
|
||||||
|
|
||||||
public IMethod MultiplyInt => _multiplyInt;
|
public IMethod MultiplyInt => _multiplyInt;
|
||||||
public IMethod MultiplyLong => _multiplyLong;
|
public IMethod MultiplyLong => _multiplyLong;
|
||||||
public IMethod MultiplyFloat => _multiplyFloat;
|
public IMethod MultiplyFloat => _multiplyFloat;
|
||||||
public IMethod MultiplyDouble => _multiplyDouble;
|
public IMethod MultiplyDouble => _multiplyDouble;
|
||||||
public IMethod MultiplyIntPtr => _multiplyIntPtr;
|
|
||||||
public IMethod MultiplyIntPtrInt => _multiplyIntPtrInt;
|
|
||||||
|
|
||||||
public IMethod DivideInt => _divideInt;
|
public IMethod DivideInt => _divideInt;
|
||||||
public IMethod DivideLong => _divideLong;
|
public IMethod DivideLong => _divideLong;
|
||||||
public IMethod DivideFloat => _divideFloat;
|
public IMethod DivideFloat => _divideFloat;
|
||||||
|
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
namespace Obfuz.Emit
|
|
||||||
{
|
|
||||||
public static class EntityExtensions
|
|
||||||
{
|
|
||||||
public static T GetEntity<T>(this IGroupByModuleEntity entity) where T : IGroupByModuleEntity, new()
|
|
||||||
{
|
|
||||||
return entity.Manager.GetEntity<T>(entity.Module);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static DefaultMetadataImporter GetDefaultModuleMetadataImporter(this IGroupByModuleEntity entity)
|
|
||||||
{
|
|
||||||
return entity.GetEntity<DefaultMetadataImporter>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: 6e9557733f180764692756653eb60f88
|
|
||||||
MonoImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 2
|
|
||||||
defaultReferences: []
|
|
||||||
executionOrder: 0
|
|
||||||
icon: {instanceID: 0}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
|
|
@ -1,29 +1,9 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet;
|
using dnlib.DotNet;
|
||||||
using dnlib.DotNet.Emit;
|
using dnlib.DotNet.Emit;
|
||||||
using Obfuz.Utils;
|
using Obfuz.Utils;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using UnityEngine.Assertions;
|
using UnityEngine.Assertions;
|
||||||
|
|
||||||
|
|
@ -83,7 +63,6 @@ namespace Obfuz.Emit
|
||||||
class EvalStackCalculator
|
class EvalStackCalculator
|
||||||
{
|
{
|
||||||
private readonly MethodDef _method;
|
private readonly MethodDef _method;
|
||||||
private readonly ICorLibTypes _corLibTypes;
|
|
||||||
private readonly BasicBlockCollection _basicBlocks;
|
private readonly BasicBlockCollection _basicBlocks;
|
||||||
private readonly Dictionary<Instruction, InstructionParameterInfo> _instructionParameterInfos = new Dictionary<Instruction, InstructionParameterInfo>();
|
private readonly Dictionary<Instruction, InstructionParameterInfo> _instructionParameterInfos = new Dictionary<Instruction, InstructionParameterInfo>();
|
||||||
private readonly Dictionary<Instruction, EvalDataType> _evalStackTopDataTypeAfterInstructions = new Dictionary<Instruction, EvalDataType>();
|
private readonly Dictionary<Instruction, EvalDataType> _evalStackTopDataTypeAfterInstructions = new Dictionary<Instruction, EvalDataType>();
|
||||||
|
|
@ -92,7 +71,6 @@ namespace Obfuz.Emit
|
||||||
public EvalStackCalculator(MethodDef method)
|
public EvalStackCalculator(MethodDef method)
|
||||||
{
|
{
|
||||||
_method = method;
|
_method = method;
|
||||||
_corLibTypes = method.Module.CorLibTypes;
|
|
||||||
_basicBlocks = new BasicBlockCollection(method, false);
|
_basicBlocks = new BasicBlockCollection(method, false);
|
||||||
_blockEvalStackStates = _basicBlocks.Blocks.ToDictionary(b => b, b => new EvalStackState());
|
_blockEvalStackStates = _basicBlocks.Blocks.ToDictionary(b => b, b => new EvalStackState());
|
||||||
|
|
||||||
|
|
@ -147,7 +125,7 @@ namespace Obfuz.Emit
|
||||||
case ElementType.Ptr:
|
case ElementType.Ptr:
|
||||||
case ElementType.FnPtr:
|
case ElementType.FnPtr:
|
||||||
case ElementType.ByRef:
|
case ElementType.ByRef:
|
||||||
datas.Add(new EvalDataTypeWithSig(EvalDataType.I, type));
|
datas.Add(new EvalDataTypeWithSig(EvalDataType.I, null));
|
||||||
break;
|
break;
|
||||||
case ElementType.String:
|
case ElementType.String:
|
||||||
case ElementType.Class:
|
case ElementType.Class:
|
||||||
|
|
@ -228,21 +206,11 @@ namespace Obfuz.Emit
|
||||||
datas.Add(type);
|
datas.Add(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PushStackObject(List<EvalDataTypeWithSig> datas, TypeSig type)
|
private void PushStackObject(List<EvalDataTypeWithSig> datas)
|
||||||
{
|
{
|
||||||
PushStack(datas, new EvalDataTypeWithSig(EvalDataType.Ref, type));
|
datas.Add(new EvalDataTypeWithSig(EvalDataType.Ref, _method.Module.CorLibTypes.Object));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PushStackPointer(List<EvalDataTypeWithSig> datas, TypeSig type)
|
|
||||||
{
|
|
||||||
PushStack(datas, new EvalDataTypeWithSig(EvalDataType.I, type));
|
|
||||||
}
|
|
||||||
|
|
||||||
//private void PushStackObject(List<EvalDataTypeWithSig> datas)
|
|
||||||
//{
|
|
||||||
// datas.Add(new EvalDataTypeWithSig(EvalDataType.Ref, _method.Module.CorLibTypes.Object));
|
|
||||||
//}
|
|
||||||
|
|
||||||
private EvalDataType CalcBasicBinOpRetType(EvalDataType op1, EvalDataType op2)
|
private EvalDataType CalcBasicBinOpRetType(EvalDataType op1, EvalDataType op2)
|
||||||
{
|
{
|
||||||
switch (op1)
|
switch (op1)
|
||||||
|
|
@ -302,7 +270,7 @@ namespace Obfuz.Emit
|
||||||
|
|
||||||
private void SimulateRunAllBlocks()
|
private void SimulateRunAllBlocks()
|
||||||
{
|
{
|
||||||
bool methodHasReturnValue = !MetaUtil.IsVoidType(_method.ReturnType);
|
bool methodHasReturnValue = _method.ReturnType.RemovePinnedAndModifiers().ElementType != ElementType.Void;
|
||||||
|
|
||||||
CilBody body = _method.Body;
|
CilBody body = _method.Body;
|
||||||
if (body.HasExceptionHandlers)
|
if (body.HasExceptionHandlers)
|
||||||
|
|
@ -315,7 +283,7 @@ namespace Obfuz.Emit
|
||||||
var inputStackDatas = _blockEvalStackStates[bb].inputStackDatas;
|
var inputStackDatas = _blockEvalStackStates[bb].inputStackDatas;
|
||||||
if (inputStackDatas.Count == 0)
|
if (inputStackDatas.Count == 0)
|
||||||
{
|
{
|
||||||
PushStackObject(inputStackDatas, handler.CatchType.ToTypeSig());
|
inputStackDatas.Add(new EvalDataTypeWithSig(EvalDataType.Ref, handler.CatchType.ToTypeSig()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (handler.IsCatch || handler.IsFilter)
|
if (handler.IsCatch || handler.IsFilter)
|
||||||
|
|
@ -324,7 +292,7 @@ namespace Obfuz.Emit
|
||||||
var inputStackDatas = _blockEvalStackStates[bb].inputStackDatas;
|
var inputStackDatas = _blockEvalStackStates[bb].inputStackDatas;
|
||||||
if (inputStackDatas.Count == 0)
|
if (inputStackDatas.Count == 0)
|
||||||
{
|
{
|
||||||
PushStackObject(inputStackDatas, handler.CatchType.ToTypeSig());
|
inputStackDatas.Add(new EvalDataTypeWithSig(EvalDataType.Ref, handler.CatchType.ToTypeSig()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -371,7 +339,7 @@ namespace Obfuz.Emit
|
||||||
case Code.Ldarga:
|
case Code.Ldarga:
|
||||||
case Code.Ldarga_S:
|
case Code.Ldarga_S:
|
||||||
{
|
{
|
||||||
PushStackPointer(newPushedDatas, new ByRefSig(inst.GetParameter(_method.Parameters).Type));
|
PushStack(newPushedDatas, EvalDataType.I);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Code.Ldloc_0:
|
case Code.Ldloc_0:
|
||||||
|
|
@ -387,7 +355,7 @@ namespace Obfuz.Emit
|
||||||
case Code.Ldloca:
|
case Code.Ldloca:
|
||||||
case Code.Ldloca_S:
|
case Code.Ldloca_S:
|
||||||
{
|
{
|
||||||
PushStackPointer(newPushedDatas, new ByRefSig(inst.GetLocal(body.Variables).Type));
|
PushStack(newPushedDatas, EvalDataType.I);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Code.Stloc_0:
|
case Code.Stloc_0:
|
||||||
|
|
@ -408,7 +376,7 @@ namespace Obfuz.Emit
|
||||||
}
|
}
|
||||||
case Code.Ldnull:
|
case Code.Ldnull:
|
||||||
{
|
{
|
||||||
PushStackObject(newPushedDatas, corLibTypes.Object);
|
PushStackObject(newPushedDatas);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Code.Ldc_I4_M1:
|
case Code.Ldc_I4_M1:
|
||||||
|
|
@ -545,13 +513,13 @@ namespace Obfuz.Emit
|
||||||
case Code.Ldind_I:
|
case Code.Ldind_I:
|
||||||
{
|
{
|
||||||
Assert.IsTrue(stackSize > 0);
|
Assert.IsTrue(stackSize > 0);
|
||||||
PushStackPointer(newPushedDatas, corLibTypes.IntPtr);
|
PushStack(newPushedDatas, EvalDataType.I);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Code.Ldind_Ref:
|
case Code.Ldind_Ref:
|
||||||
{
|
{
|
||||||
Assert.IsTrue(stackSize > 0);
|
Assert.IsTrue(stackSize > 0);
|
||||||
PushStackObject(newPushedDatas, stackDatas[stackSize - 1].typeSig?.RemovePinnedAndModifiers().Next ?? corLibTypes.Object);
|
PushStackObject(newPushedDatas);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Code.Ldind_R4:
|
case Code.Ldind_R4:
|
||||||
|
|
@ -671,7 +639,7 @@ namespace Obfuz.Emit
|
||||||
case Code.Conv_I:
|
case Code.Conv_I:
|
||||||
case Code.Conv_U:
|
case Code.Conv_U:
|
||||||
{
|
{
|
||||||
PushStackPointer(newPushedDatas, corLibTypes.IntPtr);
|
PushStack(newPushedDatas, EvalDataType.I);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Code.Conv_R4:
|
case Code.Conv_R4:
|
||||||
|
|
@ -713,7 +681,7 @@ namespace Obfuz.Emit
|
||||||
case Code.Conv_Ovf_U:
|
case Code.Conv_Ovf_U:
|
||||||
case Code.Conv_Ovf_U_Un:
|
case Code.Conv_Ovf_U_Un:
|
||||||
{
|
{
|
||||||
PushStackPointer(newPushedDatas, corLibTypes.IntPtr);
|
PushStack(newPushedDatas, EvalDataType.I);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Code.Conv_R_Un:
|
case Code.Conv_R_Un:
|
||||||
|
|
@ -734,7 +702,7 @@ namespace Obfuz.Emit
|
||||||
}
|
}
|
||||||
case Code.Ldstr:
|
case Code.Ldstr:
|
||||||
{
|
{
|
||||||
PushStackObject(newPushedDatas, corLibTypes.String);
|
PushStack(newPushedDatas, new EvalDataTypeWithSig(EvalDataType.Ref, corLibTypes.String));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Code.Newobj:
|
case Code.Newobj:
|
||||||
|
|
@ -745,24 +713,21 @@ namespace Obfuz.Emit
|
||||||
}
|
}
|
||||||
case Code.Castclass:
|
case Code.Castclass:
|
||||||
{
|
{
|
||||||
Assert.IsTrue(stackSize > 0);
|
PushStack(newPushedDatas, (ITypeDefOrRef)inst.Operand);
|
||||||
var obj = stackDatas[stackSize - 1];
|
|
||||||
//Assert.IsTrue(obj.type == EvalDataType.Ref);
|
|
||||||
PushStackObject(newPushedDatas, ((ITypeDefOrRef)inst.Operand).ToTypeSig());
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Code.Isinst:
|
case Code.Isinst:
|
||||||
{
|
{
|
||||||
Assert.IsTrue(stackSize > 0);
|
Assert.IsTrue(stackSize > 0);
|
||||||
var obj = stackDatas[stackSize - 1];
|
var obj = stackDatas[stackSize - 1];
|
||||||
//Assert.IsTrue(obj.type == EvalDataType.Ref);
|
Assert.IsTrue(obj.type == EvalDataType.Ref);
|
||||||
PushStackObject(newPushedDatas, ((ITypeDefOrRef)inst.Operand).ToTypeSig());
|
PushStack(newPushedDatas, obj);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Code.Unbox:
|
case Code.Unbox:
|
||||||
{
|
{
|
||||||
Assert.IsTrue(stackSize > 0);
|
Assert.IsTrue(stackSize > 0);
|
||||||
PushStackPointer(newPushedDatas, corLibTypes.IntPtr);
|
PushStack(newPushedDatas, EvalDataType.I);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Code.Unbox_Any:
|
case Code.Unbox_Any:
|
||||||
|
|
@ -774,8 +739,7 @@ namespace Obfuz.Emit
|
||||||
case Code.Box:
|
case Code.Box:
|
||||||
{
|
{
|
||||||
Assert.IsTrue(stackSize > 0);
|
Assert.IsTrue(stackSize > 0);
|
||||||
//PushStack(newPushedDatas, (ITypeDefOrRef)inst.Operand);
|
PushStackObject(newPushedDatas);
|
||||||
PushStackObject(newPushedDatas, ((ITypeDefOrRef)inst.Operand).ToTypeSig());
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Code.Throw:
|
case Code.Throw:
|
||||||
|
|
@ -799,9 +763,7 @@ namespace Obfuz.Emit
|
||||||
case Code.Ldflda:
|
case Code.Ldflda:
|
||||||
case Code.Ldsflda:
|
case Code.Ldsflda:
|
||||||
{
|
{
|
||||||
IField field = (IField)inst.Operand;
|
PushStack(newPushedDatas, EvalDataType.I);
|
||||||
TypeSig fieldType = MetaUtil.InflateFieldSig(field, gac);
|
|
||||||
PushStackPointer(newPushedDatas, new ByRefSig(fieldType));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Code.Stfld:
|
case Code.Stfld:
|
||||||
|
|
@ -847,7 +809,7 @@ namespace Obfuz.Emit
|
||||||
case Code.Ldelem_I:
|
case Code.Ldelem_I:
|
||||||
{
|
{
|
||||||
Assert.IsTrue(stackSize >= 2);
|
Assert.IsTrue(stackSize >= 2);
|
||||||
PushStackPointer(newPushedDatas, corLibTypes.IntPtr);
|
PushStack(newPushedDatas, EvalDataType.I);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Code.Ldelem_R4:
|
case Code.Ldelem_R4:
|
||||||
|
|
@ -865,7 +827,7 @@ namespace Obfuz.Emit
|
||||||
case Code.Ldelem_Ref:
|
case Code.Ldelem_Ref:
|
||||||
{
|
{
|
||||||
Assert.IsTrue(stackSize >= 2);
|
Assert.IsTrue(stackSize >= 2);
|
||||||
PushStackObject(newPushedDatas, stackDatas[stackSize - 2].typeSig.RemovePinnedAndModifiers().Next ?? corLibTypes.Object);
|
PushStackObject(newPushedDatas);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Code.Ldelem:
|
case Code.Ldelem:
|
||||||
|
|
@ -900,7 +862,7 @@ namespace Obfuz.Emit
|
||||||
case Code.Refanyval:
|
case Code.Refanyval:
|
||||||
{
|
{
|
||||||
Assert.IsTrue(stackSize > 0);
|
Assert.IsTrue(stackSize > 0);
|
||||||
PushStackPointer(newPushedDatas, corLibTypes.IntPtr);
|
PushStack(newPushedDatas, EvalDataType.I);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Code.Ldtoken:
|
case Code.Ldtoken:
|
||||||
|
|
@ -930,7 +892,7 @@ namespace Obfuz.Emit
|
||||||
}
|
}
|
||||||
case Code.Localloc:
|
case Code.Localloc:
|
||||||
{
|
{
|
||||||
PushStackPointer(newPushedDatas, corLibTypes.IntPtr);
|
PushStack(newPushedDatas, EvalDataType.I);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Code.Unaligned:
|
case Code.Unaligned:
|
||||||
|
|
@ -979,468 +941,27 @@ namespace Obfuz.Emit
|
||||||
_evalStackTopDataTypeAfterInstructions[inst] = stackDatas.Last().type;
|
_evalStackTopDataTypeAfterInstructions[inst] = stackDatas.Last().type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ReduceOutputArgsToBaseType(block, stackDatas);
|
|
||||||
|
|
||||||
foreach (BasicBlock outBb in block.outBlocks)
|
foreach (BasicBlock outBb in block.outBlocks)
|
||||||
{
|
{
|
||||||
EvalStackState outState = _blockEvalStackStates[outBb];
|
EvalStackState outState = _blockEvalStackStates[outBb];
|
||||||
if (!outState.visited)
|
if (outState.visited)
|
||||||
{
|
{
|
||||||
|
if (stackDatas.Count != outState.inputStackDatas.Count)
|
||||||
|
{
|
||||||
|
throw new Exception($"Block {block} in method {_method.FullName} has inconsistent stack data. Expected {outState.inputStackDatas.Count}, but got {stackDatas.Count}.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (outState.inputStackDatas.Count != stackDatas.Count)
|
||||||
|
{
|
||||||
|
if (outState.inputStackDatas.Count > 0)
|
||||||
|
{
|
||||||
|
throw new Exception($"Block {outBb} in method {_method.FullName} has inconsistent stack data. Expected {outState.inputStackDatas.Count}, but got {stackDatas.Count}.");
|
||||||
|
}
|
||||||
|
outState.inputStackDatas.AddRange(stackDatas);
|
||||||
blockWalkStack.Push(outBb);
|
blockWalkStack.Push(outBb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ReduceOutputArgsToBaseType(BasicBlock block, List<EvalDataTypeWithSig> stackDatas)
|
|
||||||
{
|
|
||||||
foreach (BasicBlock outBb in block.outBlocks)
|
|
||||||
{
|
|
||||||
if (outBb == block)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
EvalStackState outState = _blockEvalStackStates[outBb];
|
|
||||||
if (outState.inputStackDatas.Count == stackDatas.Count)
|
|
||||||
{
|
|
||||||
ReduceOutputArgsToBaseType(stackDatas, outState.inputStackDatas);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (outState.inputStackDatas.Count > 0 || outState.visited)
|
|
||||||
{
|
|
||||||
throw new Exception($"Block {outBb} in method {_method.FullName} has inconsistent stack data. Expected {outState.inputStackDatas.Count}, but got {stackDatas.Count}.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
foreach (BasicBlock outBb in block.outBlocks)
|
|
||||||
{
|
|
||||||
if (outBb == block)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
EvalStackState outState = _blockEvalStackStates[outBb];
|
|
||||||
outState.inputStackDatas.Clear();
|
|
||||||
outState.inputStackDatas.AddRange(stackDatas);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private TypeSig ReduceBaseType(TypeSig type1, TypeSig type2, bool forceRefType)
|
|
||||||
{
|
|
||||||
if (TypeEqualityComparer.Instance.Equals(type1, type2))
|
|
||||||
{
|
|
||||||
return type1;
|
|
||||||
}
|
|
||||||
type1 = type1.RemovePinnedAndModifiers();
|
|
||||||
type2 = type2.RemovePinnedAndModifiers();
|
|
||||||
|
|
||||||
ElementType t1 = type1.ElementType;
|
|
||||||
ElementType t2 = type2.ElementType;
|
|
||||||
if (t1 > t2)
|
|
||||||
{
|
|
||||||
(t1, t2) = (t2, t1);
|
|
||||||
(type1, type2) = (type2, type1);
|
|
||||||
}
|
|
||||||
switch (t1)
|
|
||||||
{
|
|
||||||
case ElementType.Void:
|
|
||||||
case ElementType.TypedByRef:
|
|
||||||
case ElementType.ValueArray:
|
|
||||||
{
|
|
||||||
if (t1 != t2)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return type1;
|
|
||||||
}
|
|
||||||
case ElementType.R4:
|
|
||||||
case ElementType.R8:
|
|
||||||
case ElementType.R:
|
|
||||||
{
|
|
||||||
if (t1 == t2)
|
|
||||||
{
|
|
||||||
return type1;
|
|
||||||
}
|
|
||||||
if (forceRefType)
|
|
||||||
{
|
|
||||||
switch (t2)
|
|
||||||
{
|
|
||||||
case ElementType.Class:
|
|
||||||
case ElementType.GenericInst:
|
|
||||||
return type2;
|
|
||||||
default: return _corLibTypes.Object;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ElementType.Boolean:
|
|
||||||
case ElementType.Char:
|
|
||||||
case ElementType.I1:
|
|
||||||
case ElementType.U1:
|
|
||||||
case ElementType.I2:
|
|
||||||
case ElementType.U2:
|
|
||||||
case ElementType.I4:
|
|
||||||
case ElementType.U4:
|
|
||||||
{
|
|
||||||
switch (t2)
|
|
||||||
{
|
|
||||||
case ElementType.Boolean:
|
|
||||||
case ElementType.Char:
|
|
||||||
case ElementType.I1:
|
|
||||||
case ElementType.U1:
|
|
||||||
case ElementType.I2:
|
|
||||||
case ElementType.U2:
|
|
||||||
case ElementType.I4:
|
|
||||||
case ElementType.U4:
|
|
||||||
{
|
|
||||||
return _corLibTypes.Int32;
|
|
||||||
}
|
|
||||||
case ElementType.I:
|
|
||||||
case ElementType.U:
|
|
||||||
case ElementType.I8:
|
|
||||||
case ElementType.U8:
|
|
||||||
{
|
|
||||||
return type2;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
if (forceRefType)
|
|
||||||
{
|
|
||||||
switch (t2)
|
|
||||||
{
|
|
||||||
case ElementType.Class:
|
|
||||||
case ElementType.GenericInst:
|
|
||||||
return type2;
|
|
||||||
default: return _corLibTypes.Object;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ElementType.I8:
|
|
||||||
case ElementType.U8:
|
|
||||||
{
|
|
||||||
switch (t2)
|
|
||||||
{
|
|
||||||
case ElementType.I:
|
|
||||||
case ElementType.U:
|
|
||||||
case ElementType.I8:
|
|
||||||
case ElementType.U8:
|
|
||||||
{
|
|
||||||
return type1;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
if (forceRefType)
|
|
||||||
{
|
|
||||||
switch (t2)
|
|
||||||
{
|
|
||||||
case ElementType.Class:
|
|
||||||
case ElementType.GenericInst:
|
|
||||||
return type2;
|
|
||||||
default: return _corLibTypes.Object;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ElementType.I:
|
|
||||||
case ElementType.U:
|
|
||||||
{
|
|
||||||
switch (t2)
|
|
||||||
{
|
|
||||||
case ElementType.I:
|
|
||||||
case ElementType.U:
|
|
||||||
{
|
|
||||||
return type1;
|
|
||||||
}
|
|
||||||
case ElementType.FnPtr:
|
|
||||||
{
|
|
||||||
return type2;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
if (forceRefType)
|
|
||||||
{
|
|
||||||
switch (t2)
|
|
||||||
{
|
|
||||||
case ElementType.Class:
|
|
||||||
case ElementType.GenericInst:
|
|
||||||
return type2;
|
|
||||||
default: return _corLibTypes.Object;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ElementType.String:
|
|
||||||
{
|
|
||||||
if (t1 == t2)
|
|
||||||
{
|
|
||||||
return type1;
|
|
||||||
}
|
|
||||||
return _corLibTypes.Object;
|
|
||||||
}
|
|
||||||
case ElementType.Ptr:
|
|
||||||
{
|
|
||||||
switch (t2)
|
|
||||||
{
|
|
||||||
case ElementType.Ptr: return new PtrSig(ReduceBaseType(type1.Next, type2.Next, false));
|
|
||||||
case ElementType.ByRef: return new ByRefSig(ReduceBaseType(type1.Next, type2.Next, false));
|
|
||||||
case ElementType.I:
|
|
||||||
case ElementType.U: return type1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ElementType.ByRef:
|
|
||||||
{
|
|
||||||
switch (t2)
|
|
||||||
{
|
|
||||||
case ElementType.ByRef: return new ByRefSig(ReduceBaseType(type1.Next, type2.Next, false));
|
|
||||||
case ElementType.I:
|
|
||||||
case ElementType.U: return type1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ElementType.ValueType:
|
|
||||||
{
|
|
||||||
if (forceRefType)
|
|
||||||
{
|
|
||||||
return type2;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ElementType.Class:
|
|
||||||
{
|
|
||||||
switch (t2)
|
|
||||||
{
|
|
||||||
case ElementType.Class:
|
|
||||||
{
|
|
||||||
TypeDef typeDef1 = type1.ToTypeDefOrRef().ResolveTypeDefThrow();
|
|
||||||
TypeDef typeDef2 = type2.ToTypeDefOrRef().ResolveTypeDefThrow();
|
|
||||||
while (typeDef2 != null)
|
|
||||||
{
|
|
||||||
if (MetaUtil.IsAssignableFrom(typeDef1, typeDef2))
|
|
||||||
{
|
|
||||||
return _method.Module.Import(typeDef2).ToTypeSig();
|
|
||||||
}
|
|
||||||
typeDef2 = typeDef2.BaseType?.ResolveTypeDefThrow();
|
|
||||||
}
|
|
||||||
return _corLibTypes.Object;
|
|
||||||
}
|
|
||||||
case ElementType.Array:
|
|
||||||
case ElementType.SZArray:
|
|
||||||
{
|
|
||||||
TypeDef typeDef1 = type1.ToTypeDefOrRef().ResolveTypeDefThrow();
|
|
||||||
if (typeDef1.Namespace.StartsWith("System"))
|
|
||||||
{
|
|
||||||
switch (typeDef1.Name.ToString())
|
|
||||||
{
|
|
||||||
case "Array":
|
|
||||||
case "ICloneable":
|
|
||||||
case "IList":
|
|
||||||
case "IList`1":
|
|
||||||
case "ICollection":
|
|
||||||
case "ICollection`1":
|
|
||||||
case "IEnumerable":
|
|
||||||
case "IEnumerable`1":
|
|
||||||
case "IStructuralComparable":
|
|
||||||
case "IStructuralEquatable":
|
|
||||||
{
|
|
||||||
return type1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return _corLibTypes.Object;
|
|
||||||
}
|
|
||||||
case ElementType.GenericInst:
|
|
||||||
{
|
|
||||||
return type2;
|
|
||||||
}
|
|
||||||
case ElementType.Var:
|
|
||||||
case ElementType.Object:
|
|
||||||
case ElementType.MVar:
|
|
||||||
{
|
|
||||||
return _corLibTypes.Object;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ElementType.Array:
|
|
||||||
{
|
|
||||||
switch (t2)
|
|
||||||
{
|
|
||||||
case ElementType.Array:
|
|
||||||
return new ArraySig(ReduceBaseType(type1.Next, type2.Next, false));
|
|
||||||
case ElementType.SZArray:
|
|
||||||
return _method.Module.ImportAsTypeSig(typeof(Array));
|
|
||||||
case ElementType.GenericInst:
|
|
||||||
{
|
|
||||||
var gis = (GenericInstSig)type2;
|
|
||||||
switch (gis.GenericType.GetName())
|
|
||||||
{
|
|
||||||
case "IList`1":
|
|
||||||
case "ICollection`1":
|
|
||||||
return type2;
|
|
||||||
}
|
|
||||||
return _corLibTypes.Object;
|
|
||||||
}
|
|
||||||
case ElementType.Object:
|
|
||||||
{
|
|
||||||
return _corLibTypes.Object;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ElementType.GenericInst:
|
|
||||||
{
|
|
||||||
var gis = (GenericInstSig)type1;
|
|
||||||
switch (t2)
|
|
||||||
{
|
|
||||||
case ElementType.Object:
|
|
||||||
{
|
|
||||||
return _corLibTypes.Object;
|
|
||||||
}
|
|
||||||
case ElementType.MVar:
|
|
||||||
{
|
|
||||||
return type2;
|
|
||||||
}
|
|
||||||
case ElementType.SZArray:
|
|
||||||
{
|
|
||||||
switch (gis.GenericType.GetName())
|
|
||||||
{
|
|
||||||
case "IList`1":
|
|
||||||
case "ICollection`1":
|
|
||||||
{
|
|
||||||
return type1;
|
|
||||||
}
|
|
||||||
// FIXME
|
|
||||||
default: return _corLibTypes.Object;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case ElementType.GenericInst:
|
|
||||||
{
|
|
||||||
// FIXME
|
|
||||||
return type1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ElementType.FnPtr:
|
|
||||||
{
|
|
||||||
switch (t2)
|
|
||||||
{
|
|
||||||
case ElementType.FnPtr:
|
|
||||||
{
|
|
||||||
// FIXME
|
|
||||||
return type1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ElementType.Object:
|
|
||||||
{
|
|
||||||
return type1;
|
|
||||||
}
|
|
||||||
case ElementType.SZArray:
|
|
||||||
{
|
|
||||||
switch (t2)
|
|
||||||
{
|
|
||||||
case ElementType.SZArray:
|
|
||||||
return new SZArraySig(ReduceBaseType(type1.Next, type2.Next, false));
|
|
||||||
case ElementType.MVar:
|
|
||||||
return _corLibTypes.Object;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ElementType.Var:
|
|
||||||
case ElementType.MVar:
|
|
||||||
{
|
|
||||||
if (t1 == t2)
|
|
||||||
{
|
|
||||||
// FIXME!!!
|
|
||||||
return type1;
|
|
||||||
}
|
|
||||||
if (t2 == ElementType.Class || t2 == ElementType.GenericInst)
|
|
||||||
{
|
|
||||||
return type2;
|
|
||||||
}
|
|
||||||
return _corLibTypes.Object;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
UnityEngine.Debug.LogError($"reduce base type of {type1} and {type2} is unsupported");
|
|
||||||
return type1;
|
|
||||||
}
|
|
||||||
|
|
||||||
private EvalDataTypeWithSig ReduceBaseType(EvalDataTypeWithSig type1, EvalDataTypeWithSig type2)
|
|
||||||
{
|
|
||||||
if (type1.type != type2.type)
|
|
||||||
{
|
|
||||||
throw new Exception($"Method {_method.FullName} has inconsistent stack data. Expected {type1.type}, but got {type2.type}.");
|
|
||||||
}
|
|
||||||
switch (type1.type)
|
|
||||||
{
|
|
||||||
case EvalDataType.Int32:
|
|
||||||
case EvalDataType.Int64:
|
|
||||||
case EvalDataType.Float:
|
|
||||||
case EvalDataType.Double:
|
|
||||||
case EvalDataType.Token:
|
|
||||||
case EvalDataType.Unknown:
|
|
||||||
{
|
|
||||||
return type1;
|
|
||||||
}
|
|
||||||
case EvalDataType.I:
|
|
||||||
case EvalDataType.Ref:
|
|
||||||
{
|
|
||||||
if (type1.typeSig == null)
|
|
||||||
{
|
|
||||||
return type2;
|
|
||||||
}
|
|
||||||
if (type2.typeSig == null)
|
|
||||||
{
|
|
||||||
return type1;
|
|
||||||
}
|
|
||||||
if (TypeEqualityComparer.Instance.Equals(type1.typeSig, type2.typeSig))
|
|
||||||
{
|
|
||||||
return type1;
|
|
||||||
}
|
|
||||||
return new EvalDataTypeWithSig(type1.type, ReduceBaseType(type1.typeSig, type2.typeSig, type1.type == EvalDataType.Ref));
|
|
||||||
}
|
|
||||||
case EvalDataType.ValueType:
|
|
||||||
{
|
|
||||||
if (!TypeEqualityComparer.Instance.Equals(type1.typeSig, type2.typeSig))
|
|
||||||
{
|
|
||||||
throw new Exception($"Method {_method.FullName} has inconsistent stack data. Expected {type1.typeSig}, but got {type2.typeSig}.");
|
|
||||||
}
|
|
||||||
return type1;
|
|
||||||
}
|
|
||||||
default: throw new Exception($"not supported EvalDataType: {type1.type} in method: {_method.FullName}.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ReduceOutputArgsToBaseType(List<EvalDataTypeWithSig> stackDatasRet, List<EvalDataTypeWithSig> stackDatasNew)
|
|
||||||
{
|
|
||||||
if (stackDatasNew.Count == 0)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (stackDatasRet.Count != stackDatasNew.Count)
|
|
||||||
{
|
|
||||||
throw new Exception($"Method {_method.FullName} has inconsistent stack data. Expected {stackDatasRet.Count}, but got {stackDatasNew.Count}.");
|
|
||||||
}
|
|
||||||
for (int i = 0; i < stackDatasRet.Count; i++)
|
|
||||||
{
|
|
||||||
EvalDataTypeWithSig oldType = stackDatasRet[i];
|
|
||||||
EvalDataTypeWithSig newType = stackDatasNew[i];
|
|
||||||
stackDatasRet[i] = ReduceBaseType(oldType, newType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet;
|
using dnlib.DotNet;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
@ -26,46 +6,19 @@ namespace Obfuz.Emit
|
||||||
{
|
{
|
||||||
public interface IGroupByModuleEntity
|
public interface IGroupByModuleEntity
|
||||||
{
|
{
|
||||||
GroupByModuleEntityManager Manager { get; set; }
|
void Init(ModuleDef mod);
|
||||||
|
|
||||||
ModuleDef Module { get; set; }
|
|
||||||
|
|
||||||
EncryptionScopeProvider EncryptionScopeProvider { get; }
|
|
||||||
|
|
||||||
EncryptionScopeInfo EncryptionScope { get; set; }
|
|
||||||
|
|
||||||
void Init();
|
|
||||||
|
|
||||||
void Done();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class GroupByModuleEntityBase : IGroupByModuleEntity
|
public abstract class GroupByModuleEntityBase : IGroupByModuleEntity
|
||||||
{
|
{
|
||||||
public GroupByModuleEntityManager Manager { get; set; }
|
public abstract void Init(ModuleDef mod);
|
||||||
|
|
||||||
public ModuleDef Module { get; set; }
|
|
||||||
|
|
||||||
public EncryptionScopeInfo EncryptionScope { get; set; }
|
|
||||||
|
|
||||||
public EncryptionScopeProvider EncryptionScopeProvider => Manager.EncryptionScopeProvider;
|
|
||||||
|
|
||||||
public T GetEntity<T>() where T : IGroupByModuleEntity, new()
|
|
||||||
{
|
|
||||||
return Manager.GetEntity<T>(Module);
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract void Init();
|
|
||||||
|
|
||||||
public abstract void Done();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class GroupByModuleEntityManager
|
public class GroupByModuleEntityManager
|
||||||
{
|
{
|
||||||
private readonly Dictionary<(ModuleDef, Type), IGroupByModuleEntity> _moduleEntityManagers = new Dictionary<(ModuleDef, Type), IGroupByModuleEntity>();
|
private readonly Dictionary<(ModuleDef, Type), IGroupByModuleEntity> _moduleEntityManagers = new Dictionary<(ModuleDef, Type), IGroupByModuleEntity>();
|
||||||
|
|
||||||
public EncryptionScopeProvider EncryptionScopeProvider { get; set; }
|
public T GetEntity<T>(ModuleDef mod, Func<T> creator = null) where T : IGroupByModuleEntity
|
||||||
|
|
||||||
public T GetEntity<T>(ModuleDef mod) where T : IGroupByModuleEntity, new()
|
|
||||||
{
|
{
|
||||||
var key = (mod, typeof(T));
|
var key = (mod, typeof(T));
|
||||||
if (_moduleEntityManagers.TryGetValue(key, out var emitManager))
|
if (_moduleEntityManagers.TryGetValue(key, out var emitManager))
|
||||||
|
|
@ -74,17 +27,22 @@ namespace Obfuz.Emit
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
T newEmitManager = new T();
|
T newEmitManager;
|
||||||
newEmitManager.Manager = this;
|
if (creator != null)
|
||||||
newEmitManager.Module = mod;
|
{
|
||||||
newEmitManager.EncryptionScope = EncryptionScopeProvider.GetScope(mod);
|
newEmitManager = creator();
|
||||||
newEmitManager.Init();
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
newEmitManager = (T)Activator.CreateInstance(typeof(T));
|
||||||
|
}
|
||||||
|
newEmitManager.Init(mod);
|
||||||
_moduleEntityManagers[key] = newEmitManager;
|
_moduleEntityManagers[key] = newEmitManager;
|
||||||
return newEmitManager;
|
return newEmitManager;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<T> GetEntities<T>() where T : IGroupByModuleEntity, new()
|
public List<T> GetEntities<T>() where T : IGroupByModuleEntity
|
||||||
{
|
{
|
||||||
var managers = new List<T>();
|
var managers = new List<T>();
|
||||||
foreach (var kv in _moduleEntityManagers)
|
foreach (var kv in _moduleEntityManagers)
|
||||||
|
|
@ -97,13 +55,9 @@ namespace Obfuz.Emit
|
||||||
return managers;
|
return managers;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Done<T>() where T : IGroupByModuleEntity, new()
|
public DefaultMetadataImporter GetDefaultModuleMetadataImporter(ModuleDef module, EncryptionScopeProvider encryptionScopeProvider)
|
||||||
{
|
{
|
||||||
var managers = GetEntities<T>();
|
return GetEntity<DefaultMetadataImporter>(module, () => new DefaultMetadataImporter(encryptionScopeProvider));
|
||||||
foreach (var manager in managers)
|
|
||||||
{
|
|
||||||
manager.Done();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet;
|
using dnlib.DotNet;
|
||||||
using dnlib.DotNet.Emit;
|
using dnlib.DotNet.Emit;
|
||||||
using System;
|
using System;
|
||||||
|
|
@ -31,8 +11,6 @@ namespace Obfuz.Emit
|
||||||
|
|
||||||
private readonly List<Local> _allocatedVars = new List<Local>();
|
private readonly List<Local> _allocatedVars = new List<Local>();
|
||||||
|
|
||||||
public IReadOnlyList<Local> AllocatedLocals => _allocatedVars;
|
|
||||||
|
|
||||||
|
|
||||||
public ScopeLocalVariables(LocalVariableAllocator localVariableAllocator)
|
public ScopeLocalVariables(LocalVariableAllocator localVariableAllocator)
|
||||||
{
|
{
|
||||||
|
|
@ -85,10 +63,5 @@ namespace Obfuz.Emit
|
||||||
{
|
{
|
||||||
_freeLocals.Add(local);
|
_freeLocals.Add(local);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ScopeLocalVariables CreateScope()
|
|
||||||
{
|
|
||||||
return new ScopeLocalVariables(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
namespace Obfuz.EncryptionVM
|
namespace Obfuz.EncryptionVM
|
||||||
{
|
{
|
||||||
public class EncryptionInstructionWithOpCode
|
public class EncryptionInstructionWithOpCode
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Obfuz.EncryptionVM
|
namespace Obfuz.EncryptionVM
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Obfuz.EncryptionVM.Instructions
|
namespace Obfuz.EncryptionVM.Instructions
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Obfuz.EncryptionVM.Instructions
|
namespace Obfuz.EncryptionVM.Instructions
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Obfuz.EncryptionVM.Instructions
|
namespace Obfuz.EncryptionVM.Instructions
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Obfuz.EncryptionVM.Instructions
|
namespace Obfuz.EncryptionVM.Instructions
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,5 @@
|
||||||
// Copyright 2025 Code Philosophy
|
using NUnit.Framework;
|
||||||
//
|
using Obfuz.Utils;
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using Obfuz.Utils;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Obfuz.EncryptionVM.Instructions
|
namespace Obfuz.EncryptionVM.Instructions
|
||||||
|
|
@ -40,7 +21,7 @@ namespace Obfuz.EncryptionVM.Instructions
|
||||||
private void Verify()
|
private void Verify()
|
||||||
{
|
{
|
||||||
int a = 1122334;
|
int a = 1122334;
|
||||||
UnityEngine.Assertions.Assert.AreEqual(a, a * _multiValue * _revertMultiValue);
|
Assert.AreEqual(a, a * _multiValue * _revertMultiValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int Encrypt(int value, int[] secretKey, int salt)
|
public override int Encrypt(int value, int[] secretKey, int salt)
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using Obfuz.Utils;
|
using Obfuz.Utils;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using Obfuz.Utils;
|
using Obfuz.Utils;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Obfuz.EncryptionVM.Instructions
|
namespace Obfuz.EncryptionVM.Instructions
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Obfuz.EncryptionVM.Instructions
|
namespace Obfuz.EncryptionVM.Instructions
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using Obfuz.Utils;
|
using Obfuz.Utils;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
namespace Obfuz.EncryptionVM
|
namespace Obfuz.EncryptionVM
|
||||||
{
|
{
|
||||||
public class VirtualMachine
|
public class VirtualMachine
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using Obfuz.Utils;
|
using Obfuz.Utils;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
@ -102,7 +82,8 @@ namespace Obfuz.EncryptionVM
|
||||||
}
|
}
|
||||||
|
|
||||||
lines.Add(@"
|
lines.Add(@"
|
||||||
default: throw new System.Exception($""Invalid opCode:{opCode}"");
|
default:
|
||||||
|
throw new System.Exception($""Invalid opCode:{opCode}"");
|
||||||
}
|
}
|
||||||
}");
|
}");
|
||||||
}
|
}
|
||||||
|
|
@ -125,7 +106,8 @@ namespace Obfuz.EncryptionVM
|
||||||
}
|
}
|
||||||
|
|
||||||
lines.Add(@"
|
lines.Add(@"
|
||||||
default: throw new System.Exception($""Invalid opCode:{opCode}"");
|
default:
|
||||||
|
throw new System.Exception($""Invalid opCode:{opCode}"");
|
||||||
}
|
}
|
||||||
}");
|
}");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using Obfuz.EncryptionVM.Instructions;
|
using Obfuz.EncryptionVM.Instructions;
|
||||||
using Obfuz.Utils;
|
using Obfuz.Utils;
|
||||||
using System;
|
using System;
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using Obfuz.Utils;
|
using Obfuz.Utils;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using UnityEngine.Assertions;
|
using UnityEngine.Assertions;
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,9 @@
|
||||||
// Copyright 2025 Code Philosophy
|
using dnlib.DotNet;
|
||||||
//
|
using NUnit.Framework;
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
using Obfuz.Settings;
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
using Obfuz.Utils;
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using Obfuz.Utils;
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,26 +1,10 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using Obfuz.Settings;
|
using Obfuz.Settings;
|
||||||
using Obfuz.Utils;
|
using Obfuz.Utils;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Obfuz.GarbageCodeGeneration
|
namespace Obfuz.GarbageCodeGeneration
|
||||||
|
|
@ -30,10 +14,10 @@ namespace Obfuz.GarbageCodeGeneration
|
||||||
{
|
{
|
||||||
private const int CodeGenerationSecretKeyLength = 1024;
|
private const int CodeGenerationSecretKeyLength = 1024;
|
||||||
|
|
||||||
private readonly GarbageCodeGenerationSettings _settings;
|
private readonly GarbageCodeGeneratorSettings _settings;
|
||||||
private readonly int[] _intGenerationSecretKey;
|
private readonly int[] _intGenerationSecretKey;
|
||||||
|
|
||||||
public GarbageCodeGenerator(GarbageCodeGenerationSettings settings)
|
public GarbageCodeGenerator(GarbageCodeGeneratorSettings settings)
|
||||||
{
|
{
|
||||||
_settings = settings;
|
_settings = settings;
|
||||||
|
|
||||||
|
|
@ -71,14 +55,14 @@ namespace Obfuz.GarbageCodeGeneration
|
||||||
|
|
||||||
private void GenerateTask(GarbageCodeGenerationTask task)
|
private void GenerateTask(GarbageCodeGenerationTask task)
|
||||||
{
|
{
|
||||||
Debug.Log($"Generating garbage code with seed: {task.codeGenerationRandomSeed}, class count: {task.classCount}, method count per class: {task.methodCountPerClass}, types: {task.garbageCodeType}, output path: {task.outputPath}");
|
Debug.Log($"Generating garbage code with seed: {task.codeGenerationRandomSeed}, class count: {task.classCount}, method count per class: {task.methodCountPerClass}, types: {task.garbageCodeTypes}, output path: {task.outputPath}");
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(task.outputPath))
|
if (string.IsNullOrWhiteSpace(task.outputPath))
|
||||||
{
|
{
|
||||||
throw new Exception("outputPath of GarbageCodeGenerationTask is empty!");
|
throw new Exception("outputPath of GarbageCodeGenerationTask is empty!");
|
||||||
}
|
}
|
||||||
|
|
||||||
var generator = CreateSpecificCodeGenerator(task.garbageCodeType);
|
var generator = CreateSpecificCodeGenerator(task.garbageCodeTypes);
|
||||||
|
|
||||||
var parameters = new GenerationParameters
|
var parameters = new GenerationParameters
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,5 @@
|
||||||
// Copyright 2025 Code Philosophy
|
using Obfuz.Settings;
|
||||||
//
|
using Obfuz.Utils;
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using Obfuz.Utils;
|
|
||||||
|
|
||||||
namespace Obfuz.GarbageCodeGeneration
|
namespace Obfuz.GarbageCodeGeneration
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using Obfuz.Utils;
|
using Obfuz.Utils;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,9 @@
|
||||||
// Copyright 2025 Code Philosophy
|
using dnlib.DotNet;
|
||||||
//
|
using NUnit.Framework;
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
using Obfuz.Settings;
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
using Obfuz.Utils;
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using Obfuz.Utils;
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using Obfuz.ObfusPasses;
|
using Obfuz.ObfusPasses;
|
||||||
|
|
||||||
namespace Obfuz
|
namespace Obfuz
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet;
|
using dnlib.DotNet;
|
||||||
using dnlib.DotNet.Emit;
|
using dnlib.DotNet.Emit;
|
||||||
using Obfuz.Emit;
|
using Obfuz.Emit;
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet;
|
using dnlib.DotNet;
|
||||||
using dnlib.DotNet.Emit;
|
using dnlib.DotNet.Emit;
|
||||||
using Obfuz.Emit;
|
using Obfuz.Emit;
|
||||||
|
|
@ -27,30 +7,19 @@ using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Obfuz.ObfusPasses.CallObfus
|
namespace Obfuz.ObfusPasses.CallObfus
|
||||||
{
|
{
|
||||||
class ObfusMethodContext
|
public class CallObfusPass : BasicBlockObfuscationPassBase
|
||||||
{
|
{
|
||||||
public MethodDef method;
|
|
||||||
public LocalVariableAllocator localVariableAllocator;
|
|
||||||
public IRandom localRandom;
|
|
||||||
public EncryptionScopeInfo encryptionScope;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class CallObfusPass : ObfuscationMethodPassBase
|
|
||||||
{
|
|
||||||
public static CallObfuscationSettingsFacade CurrentSettings { get; private set; }
|
|
||||||
|
|
||||||
private readonly CallObfuscationSettingsFacade _settings;
|
private readonly CallObfuscationSettingsFacade _settings;
|
||||||
private SpecialWhiteListMethodCalculator _specialWhiteListMethodCache;
|
|
||||||
|
|
||||||
private IObfuscator _dynamicProxyObfuscator;
|
private IObfuscator _dynamicProxyObfuscator;
|
||||||
private IObfuscationPolicy _dynamicProxyPolicy;
|
private IObfuscationPolicy _dynamicProxyPolicy;
|
||||||
|
private readonly CachedDictionary<IMethod, bool> _specialwhiteListMethodCache;
|
||||||
|
|
||||||
public override ObfuscationPassType Type => ObfuscationPassType.CallObfus;
|
public override ObfuscationPassType Type => ObfuscationPassType.CallObfus;
|
||||||
|
|
||||||
public CallObfusPass(CallObfuscationSettingsFacade settings)
|
public CallObfusPass(CallObfuscationSettingsFacade settings)
|
||||||
{
|
{
|
||||||
_settings = settings;
|
_settings = settings;
|
||||||
CurrentSettings = settings;
|
_specialwhiteListMethodCache = new CachedDictionary<IMethod, bool>(MethodEqualityComparer.CompareDeclaringTypes, this.ComputeIsInWhiteList);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Stop()
|
public override void Stop()
|
||||||
|
|
@ -61,82 +30,117 @@ namespace Obfuz.ObfusPasses.CallObfus
|
||||||
public override void Start()
|
public override void Start()
|
||||||
{
|
{
|
||||||
var ctx = ObfuscationPassContext.Current;
|
var ctx = ObfuscationPassContext.Current;
|
||||||
|
_dynamicProxyObfuscator = new DefaultCallProxyObfuscator(ctx.encryptionScopeProvider, ctx.constFieldAllocator, ctx.moduleEntityManager, _settings);
|
||||||
_specialWhiteListMethodCache = new SpecialWhiteListMethodCalculator(ctx.coreSettings.targetRuntime, _settings.obfuscateCallToMethodInMscorlib);
|
|
||||||
_dynamicProxyObfuscator = CreateObfuscator(ctx, _settings.proxyMode);
|
|
||||||
_dynamicProxyPolicy = new ConfigurableObfuscationPolicy(ctx.coreSettings.assembliesToObfuscate, _settings.ruleFiles);
|
_dynamicProxyPolicy = new ConfigurableObfuscationPolicy(ctx.coreSettings.assembliesToObfuscate, _settings.ruleFiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
private IObfuscator CreateObfuscator(ObfuscationPassContext ctx, ProxyMode mode)
|
|
||||||
{
|
|
||||||
switch (mode)
|
|
||||||
{
|
|
||||||
case ProxyMode.Dispatch:
|
|
||||||
return new DispatchProxyObfuscator(ctx.moduleEntityManager);
|
|
||||||
case ProxyMode.Delegate:
|
|
||||||
return new DelegateProxyObfuscator(ctx.moduleEntityManager);
|
|
||||||
default:
|
|
||||||
throw new System.NotSupportedException($"Unsupported proxy mode: {mode}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void ObfuscateData(MethodDef method)
|
|
||||||
{
|
|
||||||
BasicBlockCollection bbc = new BasicBlockCollection(method, false);
|
|
||||||
|
|
||||||
IList<Instruction> instructions = method.Body.Instructions;
|
|
||||||
|
|
||||||
var outputInstructions = new List<Instruction>();
|
|
||||||
var totalFinalInstructions = new List<Instruction>();
|
|
||||||
|
|
||||||
ObfuscationPassContext ctx = ObfuscationPassContext.Current;
|
|
||||||
var encryptionScope = ctx.moduleEntityManager.EncryptionScopeProvider.GetScope(method.Module);
|
|
||||||
var localRandom = encryptionScope.localRandomCreator(MethodEqualityComparer.CompareDeclaringTypes.GetHashCode(method));
|
|
||||||
var omc = new ObfusMethodContext
|
|
||||||
{
|
|
||||||
method = method,
|
|
||||||
localVariableAllocator = new LocalVariableAllocator(method),
|
|
||||||
localRandom = localRandom,
|
|
||||||
encryptionScope = encryptionScope,
|
|
||||||
};
|
|
||||||
Instruction lastInst = null;
|
|
||||||
for (int i = 0; i < instructions.Count; i++)
|
|
||||||
{
|
|
||||||
Instruction inst = instructions[i];
|
|
||||||
BasicBlock block = bbc.GetBasicBlockByInstruction(inst);
|
|
||||||
outputInstructions.Clear();
|
|
||||||
if (TryObfuscateInstruction(method, lastInst, inst, outputInstructions, omc))
|
|
||||||
{
|
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
lastInst = inst;
|
|
||||||
}
|
|
||||||
|
|
||||||
instructions.Clear();
|
|
||||||
foreach (var obInst in totalFinalInstructions)
|
|
||||||
{
|
|
||||||
instructions.Add(obInst);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool NeedObfuscateMethod(MethodDef method)
|
protected override bool NeedObfuscateMethod(MethodDef method)
|
||||||
{
|
{
|
||||||
return _dynamicProxyPolicy.NeedObfuscateCallInMethod(method);
|
return _dynamicProxyPolicy.NeedObfuscateCallInMethod(method);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool TryObfuscateInstruction(MethodDef callerMethod, Instruction lastInst, Instruction inst, List<Instruction> outputInstructions, ObfusMethodContext ctx)
|
|
||||||
|
private static readonly HashSet<string> _specialTypeFullNames = new HashSet<string>
|
||||||
|
{
|
||||||
|
"System.Enum",
|
||||||
|
"System.Delegate",
|
||||||
|
"System.MulticastDelegate",
|
||||||
|
"Obfuz.EncryptionService`1",
|
||||||
|
};
|
||||||
|
|
||||||
|
private static readonly HashSet<string> _specialMethodNames = new HashSet<string>
|
||||||
|
{
|
||||||
|
"GetEnumerator", // List<T>.Enumerator.GetEnumerator()
|
||||||
|
".ctor", // constructor
|
||||||
|
};
|
||||||
|
|
||||||
|
private static readonly HashSet<string> _specialMethodFullNames = new HashSet<string>
|
||||||
|
{
|
||||||
|
"System.Reflection.MethodBase.GetCurrentMethod",
|
||||||
|
"System.Reflection.Assembly.GetCallingAssembly",
|
||||||
|
"System.Reflection.Assembly.GetExecutingAssembly",
|
||||||
|
"System.Reflection.Assembly.GetEntryAssembly",
|
||||||
|
};
|
||||||
|
|
||||||
|
private bool ComputeIsInWhiteList(IMethod calledMethod)
|
||||||
|
{
|
||||||
|
MethodDef calledMethodDef = calledMethod.ResolveMethodDef();
|
||||||
|
// mono has more strict access control, calls non-public method will raise exception.
|
||||||
|
if (PlatformUtil.IsMonoBackend())
|
||||||
|
{
|
||||||
|
if (calledMethodDef != null && (!calledMethodDef.IsPublic || !IsTypeSelfAndParentPublic(calledMethodDef.DeclaringType)))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ITypeDefOrRef declaringType = calledMethod.DeclaringType;
|
||||||
|
TypeSig declaringTypeSig = calledMethod.DeclaringType.ToTypeSig();
|
||||||
|
declaringTypeSig = declaringTypeSig.RemovePinnedAndModifiers();
|
||||||
|
switch (declaringTypeSig.ElementType)
|
||||||
|
{
|
||||||
|
case ElementType.ValueType:
|
||||||
|
case ElementType.Class:
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ElementType.GenericInst:
|
||||||
|
{
|
||||||
|
if (MetaUtil.ContainsContainsGenericParameter(calledMethod))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
TypeDef typeDef = declaringType.ResolveTypeDef();
|
||||||
|
|
||||||
|
if (!_settings.obfuscateCallToMethodInMscorlib && typeDef.Module.IsCoreLibraryModule == true)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeDef.IsDelegate || typeDef.IsEnum)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
string fullName = typeDef.FullName;
|
||||||
|
if (_specialTypeFullNames.Contains(fullName))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
//if (fullName.StartsWith("System.Runtime.CompilerServices."))
|
||||||
|
//{
|
||||||
|
// return true;
|
||||||
|
//}
|
||||||
|
|
||||||
|
string methodName = calledMethod.Name;
|
||||||
|
if (_specialMethodNames.Contains(methodName))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
string methodFullName = $"{fullName}.{methodName}";
|
||||||
|
if (_specialMethodFullNames.Contains(methodFullName))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool IsTypeSelfAndParentPublic(TypeDef type)
|
||||||
|
{
|
||||||
|
if (type.DeclaringType != null && !IsTypeSelfAndParentPublic(type.DeclaringType))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return type.IsPublic;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool TryObfuscateInstruction(MethodDef callerMethod, Instruction inst, BasicBlock block,
|
||||||
|
int instructionIndex, IList<Instruction> globalInstructions, List<Instruction> outputInstructions, List<Instruction> totalFinalInstructions)
|
||||||
{
|
{
|
||||||
IMethod calledMethod = inst.Operand as IMethod;
|
IMethod calledMethod = inst.Operand as IMethod;
|
||||||
if (calledMethod == null || !calledMethod.IsMethod)
|
if (calledMethod == null || !calledMethod.IsMethod)
|
||||||
|
|
@ -158,7 +162,7 @@ namespace Obfuz.ObfusPasses.CallObfus
|
||||||
}
|
}
|
||||||
case Code.Callvirt:
|
case Code.Callvirt:
|
||||||
{
|
{
|
||||||
if (lastInst != null && lastInst.OpCode.Code == Code.Constrained)
|
if (instructionIndex > 0 && globalInstructions[instructionIndex - 1].OpCode.Code == Code.Constrained)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -169,18 +173,21 @@ namespace Obfuz.ObfusPasses.CallObfus
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (_specialWhiteListMethodCache.IsInWhiteList(calledMethod))
|
if (_specialwhiteListMethodCache.GetValue(calledMethod))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!_dynamicProxyPolicy.NeedObfuscateCalledMethod(callerMethod, calledMethod, callVir))
|
if (!_dynamicProxyPolicy.NeedObfuscateCalledMethod(callerMethod, calledMethod, callVir, block.inLoop))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return _dynamicProxyObfuscator.Obfuscate(callerMethod, calledMethod, callVir, outputInstructions);
|
ObfuscationCachePolicy cachePolicy = _dynamicProxyPolicy.GetMethodObfuscationCachePolicy(callerMethod);
|
||||||
|
bool cachedCallIndex = block.inLoop ? cachePolicy.cacheInLoop : cachePolicy.cacheNotInLoop;
|
||||||
|
_dynamicProxyObfuscator.Obfuscate(callerMethod, calledMethod, callVir, cachedCallIndex, outputInstructions);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet;
|
using dnlib.DotNet;
|
||||||
using dnlib.DotNet.Emit;
|
using dnlib.DotNet.Emit;
|
||||||
using Obfuz.Editor;
|
using Obfuz.Editor;
|
||||||
|
|
@ -32,7 +12,6 @@ using TypeAttributes = dnlib.DotNet.TypeAttributes;
|
||||||
|
|
||||||
namespace Obfuz.ObfusPasses.CallObfus
|
namespace Obfuz.ObfusPasses.CallObfus
|
||||||
{
|
{
|
||||||
|
|
||||||
public struct ProxyCallMethodData
|
public struct ProxyCallMethodData
|
||||||
{
|
{
|
||||||
public readonly MethodDef proxyMethod;
|
public readonly MethodDef proxyMethod;
|
||||||
|
|
@ -51,11 +30,38 @@ namespace Obfuz.ObfusPasses.CallObfus
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ModuleDispatchProxyAllocator : GroupByModuleEntityBase
|
class ModuleCallProxyAllocator : IGroupByModuleEntity
|
||||||
{
|
{
|
||||||
private bool _done;
|
private ModuleDef _module;
|
||||||
private CallObfuscationSettingsFacade _settings;
|
private readonly EncryptionScopeProvider _encryptionScopeProvider;
|
||||||
|
private readonly CallObfuscationSettingsFacade _settings;
|
||||||
|
|
||||||
|
private EncryptionScopeInfo _encryptionScope;
|
||||||
|
private bool _done;
|
||||||
|
|
||||||
|
class MethodKey : IEquatable<MethodKey>
|
||||||
|
{
|
||||||
|
public readonly IMethod _method;
|
||||||
|
public readonly bool _callVir;
|
||||||
|
private readonly int _hashCode;
|
||||||
|
|
||||||
|
public MethodKey(IMethod method, bool callVir)
|
||||||
|
{
|
||||||
|
_method = method;
|
||||||
|
_callVir = callVir;
|
||||||
|
_hashCode = HashUtil.CombineHash(MethodEqualityComparer.CompareDeclaringTypes.GetHashCode(method), callVir ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
return _hashCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Equals(MethodKey other)
|
||||||
|
{
|
||||||
|
return MethodEqualityComparer.CompareDeclaringTypes.Equals(_method, other._method) && _callVir == other._callVir;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class MethodProxyInfo
|
class MethodProxyInfo
|
||||||
{
|
{
|
||||||
|
|
@ -87,23 +93,25 @@ namespace Obfuz.ObfusPasses.CallObfus
|
||||||
|
|
||||||
private TypeDef _proxyTypeDef;
|
private TypeDef _proxyTypeDef;
|
||||||
|
|
||||||
public ModuleDispatchProxyAllocator()
|
public ModuleCallProxyAllocator(EncryptionScopeProvider encryptionScopeProvider, CallObfuscationSettingsFacade settings)
|
||||||
{
|
{
|
||||||
|
_encryptionScopeProvider = encryptionScopeProvider;
|
||||||
|
_settings = settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Init()
|
public void Init(ModuleDef mod)
|
||||||
{
|
{
|
||||||
_settings = CallObfusPass.CurrentSettings;
|
_module = mod;
|
||||||
|
_encryptionScope = _encryptionScopeProvider.GetScope(mod);
|
||||||
}
|
}
|
||||||
|
|
||||||
private TypeDef CreateProxyTypeDef()
|
private TypeDef CreateProxyTypeDef()
|
||||||
{
|
{
|
||||||
ModuleDef mod = Module;
|
using (var scope = new DisableTypeDefFindCacheScope(_module))
|
||||||
using (var scope = new DisableTypeDefFindCacheScope(mod))
|
|
||||||
{
|
{
|
||||||
var typeDef = new TypeDefUser($"{ConstValues.ObfuzInternalSymbolNamePrefix}ProxyCall", mod.CorLibTypes.Object.ToTypeDefOrRef());
|
var typeDef = new TypeDefUser($"{ConstValues.ObfuzInternalSymbolNamePrefix}ProxyCall", _module.CorLibTypes.Object.ToTypeDefOrRef());
|
||||||
typeDef.Attributes = TypeAttributes.NotPublic | TypeAttributes.Sealed;
|
typeDef.Attributes = TypeAttributes.NotPublic | TypeAttributes.Sealed;
|
||||||
mod.Types.Add(typeDef);
|
_module.Types.Add(typeDef);
|
||||||
return typeDef;
|
return typeDef;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -149,25 +157,24 @@ namespace Obfuz.ObfusPasses.CallObfus
|
||||||
|
|
||||||
private MethodSig CreateDispatchMethodSig(IMethod method)
|
private MethodSig CreateDispatchMethodSig(IMethod method)
|
||||||
{
|
{
|
||||||
ModuleDef mod = Module;
|
MethodSig methodSig = MetaUtil.ToSharedMethodSig(_module.CorLibTypes, MetaUtil.GetInflatedMethodSig(method, null));
|
||||||
MethodSig methodSig = MetaUtil.ToSharedMethodSig(mod.CorLibTypes, MetaUtil.GetInflatedMethodSig(method, null));
|
|
||||||
//MethodSig methodSig = MetaUtil.GetInflatedMethodSig(method).Clone();
|
//MethodSig methodSig = MetaUtil.GetInflatedMethodSig(method).Clone();
|
||||||
//methodSig.Params
|
//methodSig.Params
|
||||||
switch (MetaUtil.GetThisArgType(method))
|
switch (MetaUtil.GetThisArgType(method))
|
||||||
{
|
{
|
||||||
case ThisArgType.Class:
|
case ThisArgType.Class:
|
||||||
{
|
{
|
||||||
methodSig.Params.Insert(0, mod.CorLibTypes.Object);
|
methodSig.Params.Insert(0, _module.CorLibTypes.Object);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ThisArgType.ValueType:
|
case ThisArgType.ValueType:
|
||||||
{
|
{
|
||||||
methodSig.Params.Insert(0, mod.CorLibTypes.IntPtr);
|
methodSig.Params.Insert(0, _module.CorLibTypes.IntPtr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// extra param for index
|
// extra param for index
|
||||||
methodSig.Params.Add(mod.CorLibTypes.Int32);
|
methodSig.Params.Add(_module.CorLibTypes.Int32);
|
||||||
return MethodSig.CreateStatic(methodSig.RetType, methodSig.Params.ToArray());
|
return MethodSig.CreateStatic(methodSig.RetType, methodSig.Params.ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -178,7 +185,7 @@ namespace Obfuz.ObfusPasses.CallObfus
|
||||||
|
|
||||||
private int GenerateEncryptOps(IRandom random)
|
private int GenerateEncryptOps(IRandom random)
|
||||||
{
|
{
|
||||||
return EncryptionUtil.GenerateEncryptionOpCodes(random, EncryptionScope.encryptor, _settings.obfuscationLevel);
|
return EncryptionUtil.GenerateEncryptionOpCodes(random, _encryptionScope.encryptor, _settings.obfuscationLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
private DispatchMethodInfo GetDispatchMethod(IMethod method)
|
private DispatchMethodInfo GetDispatchMethod(IMethod method)
|
||||||
|
|
@ -203,7 +210,7 @@ namespace Obfuz.ObfusPasses.CallObfus
|
||||||
private IRandom CreateRandomForMethod(IMethod method, bool callVir)
|
private IRandom CreateRandomForMethod(IMethod method, bool callVir)
|
||||||
{
|
{
|
||||||
int seed = MethodEqualityComparer.CompareDeclaringTypes.GetHashCode(method);
|
int seed = MethodEqualityComparer.CompareDeclaringTypes.GetHashCode(method);
|
||||||
return EncryptionScope.localRandomCreator(seed);
|
return _encryptionScope.localRandomCreator(seed);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProxyCallMethodData Allocate(IMethod method, bool callVir)
|
public ProxyCallMethodData Allocate(IMethod method, bool callVir)
|
||||||
|
|
@ -221,7 +228,7 @@ namespace Obfuz.ObfusPasses.CallObfus
|
||||||
IRandom localRandom = CreateRandomForMethod(method, callVir);
|
IRandom localRandom = CreateRandomForMethod(method, callVir);
|
||||||
int encryptOps = GenerateEncryptOps(localRandom);
|
int encryptOps = GenerateEncryptOps(localRandom);
|
||||||
int salt = GenerateSalt(localRandom);
|
int salt = GenerateSalt(localRandom);
|
||||||
int encryptedIndex = EncryptionScope.encryptor.Encrypt(index, encryptOps, salt);
|
int encryptedIndex = _encryptionScope.encryptor.Encrypt(index, encryptOps, salt);
|
||||||
proxyInfo = new MethodProxyInfo()
|
proxyInfo = new MethodProxyInfo()
|
||||||
{
|
{
|
||||||
proxyMethod = methodDispatcher.methodDef,
|
proxyMethod = methodDispatcher.methodDef,
|
||||||
|
|
@ -236,7 +243,7 @@ namespace Obfuz.ObfusPasses.CallObfus
|
||||||
return new ProxyCallMethodData(proxyInfo.proxyMethod, proxyInfo.encryptedOps, proxyInfo.salt, proxyInfo.encryptedIndex, proxyInfo.index);
|
return new ProxyCallMethodData(proxyInfo.proxyMethod, proxyInfo.encryptedOps, proxyInfo.salt, proxyInfo.encryptedIndex, proxyInfo.index);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Done()
|
public void Done()
|
||||||
{
|
{
|
||||||
if (_done)
|
if (_done)
|
||||||
{
|
{
|
||||||
|
|
@ -290,4 +297,37 @@ namespace Obfuz.ObfusPasses.CallObfus
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class CallProxyAllocator
|
||||||
|
{
|
||||||
|
private readonly EncryptionScopeProvider _encryptionScopeProvider;
|
||||||
|
private GroupByModuleEntityManager _moduleEntityManager;
|
||||||
|
private readonly CallObfuscationSettingsFacade _settings;
|
||||||
|
|
||||||
|
public CallProxyAllocator(EncryptionScopeProvider encryptionScopeProvider, GroupByModuleEntityManager moduleEntityManager, CallObfuscationSettingsFacade settings)
|
||||||
|
{
|
||||||
|
_encryptionScopeProvider = encryptionScopeProvider;
|
||||||
|
_moduleEntityManager = moduleEntityManager;
|
||||||
|
_settings = settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ModuleCallProxyAllocator GetModuleAllocator(ModuleDef mod)
|
||||||
|
{
|
||||||
|
return _moduleEntityManager.GetEntity<ModuleCallProxyAllocator>(mod, () => new ModuleCallProxyAllocator(_encryptionScopeProvider, _settings));
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProxyCallMethodData Allocate(ModuleDef mod, IMethod method, bool callVir)
|
||||||
|
{
|
||||||
|
ModuleCallProxyAllocator allocator = GetModuleAllocator(mod);
|
||||||
|
return allocator.Allocate(method, callVir);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Done()
|
||||||
|
{
|
||||||
|
foreach (var allocator in _moduleEntityManager.GetEntities<ModuleCallProxyAllocator>())
|
||||||
|
{
|
||||||
|
allocator.Done();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,26 +1,5 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet;
|
using dnlib.DotNet;
|
||||||
using Obfuz.Conf;
|
using Obfuz.Conf;
|
||||||
using Obfuz.Settings;
|
|
||||||
using Obfuz.Utils;
|
using Obfuz.Utils;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
@ -55,12 +34,29 @@ namespace Obfuz.ObfusPasses.CallObfus
|
||||||
|
|
||||||
class ObfuscationRule : IRule<ObfuscationRule>
|
class ObfuscationRule : IRule<ObfuscationRule>
|
||||||
{
|
{
|
||||||
public ObfuscationLevel? obfuscationLevel;
|
public bool? disableObfuscation;
|
||||||
|
public bool? obfuscateCallInLoop;
|
||||||
|
public bool? cacheCallIndexInLoop;
|
||||||
|
public bool? cacheCallIndexNotLoop;
|
||||||
|
|
||||||
public void InheritParent(ObfuscationRule parentRule)
|
public void InheritParent(ObfuscationRule parentRule)
|
||||||
{
|
{
|
||||||
if (obfuscationLevel == null)
|
if (disableObfuscation == null)
|
||||||
obfuscationLevel = parentRule.obfuscationLevel;
|
{
|
||||||
|
disableObfuscation = parentRule.disableObfuscation;
|
||||||
|
}
|
||||||
|
if (obfuscateCallInLoop == null)
|
||||||
|
{
|
||||||
|
obfuscateCallInLoop = parentRule.obfuscateCallInLoop;
|
||||||
|
}
|
||||||
|
if (cacheCallIndexInLoop == null)
|
||||||
|
{
|
||||||
|
cacheCallIndexInLoop = parentRule.cacheCallIndexInLoop;
|
||||||
|
}
|
||||||
|
if (cacheCallIndexNotLoop == null)
|
||||||
|
{
|
||||||
|
cacheCallIndexNotLoop = parentRule.cacheCallIndexNotLoop;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -79,7 +75,10 @@ namespace Obfuz.ObfusPasses.CallObfus
|
||||||
|
|
||||||
private static readonly ObfuscationRule s_default = new ObfuscationRule()
|
private static readonly ObfuscationRule s_default = new ObfuscationRule()
|
||||||
{
|
{
|
||||||
obfuscationLevel = ObfuscationLevel.Basic,
|
disableObfuscation = false,
|
||||||
|
obfuscateCallInLoop = true,
|
||||||
|
cacheCallIndexInLoop = true,
|
||||||
|
cacheCallIndexNotLoop = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
private readonly XmlAssemblyTypeMethodRuleParser<AssemblySpec, TypeSpec, MethodSpec, ObfuscationRule> _configParser;
|
private readonly XmlAssemblyTypeMethodRuleParser<AssemblySpec, TypeSpec, MethodSpec, ObfuscationRule> _configParser;
|
||||||
|
|
@ -148,9 +147,21 @@ namespace Obfuz.ObfusPasses.CallObfus
|
||||||
private ObfuscationRule ParseObfuscationRule(string configFile, XmlElement ele)
|
private ObfuscationRule ParseObfuscationRule(string configFile, XmlElement ele)
|
||||||
{
|
{
|
||||||
var rule = new ObfuscationRule();
|
var rule = new ObfuscationRule();
|
||||||
if (ele.HasAttribute("obfuscationLevel"))
|
if (ele.HasAttribute("disableObfuscation"))
|
||||||
{
|
{
|
||||||
rule.obfuscationLevel = ConfigUtil.ParseObfuscationLevel(ele.GetAttribute("obfuscationLevel"));
|
rule.disableObfuscation = ConfigUtil.ParseBool(ele.GetAttribute("disableObfuscation"));
|
||||||
|
}
|
||||||
|
if (ele.HasAttribute("obfuscateCallInLoop"))
|
||||||
|
{
|
||||||
|
rule.obfuscateCallInLoop = ConfigUtil.ParseBool(ele.GetAttribute("obfuscateCallInLoop"));
|
||||||
|
}
|
||||||
|
if (ele.HasAttribute("cacheCallIndexInLoop"))
|
||||||
|
{
|
||||||
|
rule.cacheCallIndexInLoop = ConfigUtil.ParseBool(ele.GetAttribute("cacheCallIndexInLoop"));
|
||||||
|
}
|
||||||
|
if (ele.HasAttribute("cacheCallIndexNotLoop"))
|
||||||
|
{
|
||||||
|
rule.cacheCallIndexNotLoop = ConfigUtil.ParseBool(ele.GetAttribute("cacheCallIndexNotLoop"));
|
||||||
}
|
}
|
||||||
return rule;
|
return rule;
|
||||||
}
|
}
|
||||||
|
|
@ -251,7 +262,17 @@ namespace Obfuz.ObfusPasses.CallObfus
|
||||||
public override bool NeedObfuscateCallInMethod(MethodDef method)
|
public override bool NeedObfuscateCallInMethod(MethodDef method)
|
||||||
{
|
{
|
||||||
ObfuscationRule rule = GetMethodObfuscationRule(method);
|
ObfuscationRule rule = GetMethodObfuscationRule(method);
|
||||||
return rule.obfuscationLevel != null && rule.obfuscationLevel.Value >= ObfuscationLevel.Basic;
|
return rule.disableObfuscation != true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ObfuscationCachePolicy GetMethodObfuscationCachePolicy(MethodDef method)
|
||||||
|
{
|
||||||
|
ObfuscationRule rule = GetMethodObfuscationRule(method);
|
||||||
|
return new ObfuscationCachePolicy()
|
||||||
|
{
|
||||||
|
cacheInLoop = rule.cacheCallIndexInLoop.Value,
|
||||||
|
cacheNotInLoop = rule.cacheCallIndexNotLoop.Value,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool ComputeIsInWhiteList(IMethod calledMethod)
|
private bool ComputeIsInWhiteList(IMethod calledMethod)
|
||||||
|
|
@ -308,12 +329,18 @@ namespace Obfuz.ObfusPasses.CallObfus
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool NeedObfuscateCalledMethod(MethodDef callerMethod, IMethod calledMethod, bool callVir)
|
public override bool NeedObfuscateCalledMethod(MethodDef callerMethod, IMethod calledMethod, bool callVir, bool currentInLoop)
|
||||||
{
|
{
|
||||||
if (_whiteListMethodCache.GetValue(calledMethod))
|
if (_whiteListMethodCache.GetValue(calledMethod))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ObfuscationRule rule = GetMethodObfuscationRule(callerMethod);
|
||||||
|
if (currentInLoop && rule.obfuscateCallInLoop == false)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
using dnlib.DotNet;
|
||||||
|
using dnlib.DotNet.Emit;
|
||||||
|
using Obfuz.Data;
|
||||||
|
using Obfuz.Emit;
|
||||||
|
using Obfuz.Settings;
|
||||||
|
using Obfuz.Utils;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Obfuz.ObfusPasses.CallObfus
|
||||||
|
{
|
||||||
|
public class DefaultCallProxyObfuscator : ObfuscatorBase
|
||||||
|
{
|
||||||
|
private readonly EncryptionScopeProvider _encryptionScopeProvider;
|
||||||
|
private readonly ConstFieldAllocator _constFieldAllocator;
|
||||||
|
private readonly CallProxyAllocator _proxyCallAllocator;
|
||||||
|
private readonly GroupByModuleEntityManager _moduleEntityManager;
|
||||||
|
|
||||||
|
public DefaultCallProxyObfuscator(EncryptionScopeProvider encryptionScopeProvider, ConstFieldAllocator constFieldAllocator, GroupByModuleEntityManager moduleEntityManager, CallObfuscationSettingsFacade settings)
|
||||||
|
{
|
||||||
|
_encryptionScopeProvider = encryptionScopeProvider;
|
||||||
|
_constFieldAllocator = constFieldAllocator;
|
||||||
|
_moduleEntityManager = moduleEntityManager;
|
||||||
|
_proxyCallAllocator = new CallProxyAllocator(encryptionScopeProvider, moduleEntityManager, settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Done()
|
||||||
|
{
|
||||||
|
_proxyCallAllocator.Done();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Obfuscate(MethodDef callerMethod, IMethod calledMethod, bool callVir, bool needCacheCall, List<Instruction> obfuscatedInstructions)
|
||||||
|
{
|
||||||
|
|
||||||
|
MethodSig sharedMethodSig = MetaUtil.ToSharedMethodSig(calledMethod.Module.CorLibTypes, MetaUtil.GetInflatedMethodSig(calledMethod, null));
|
||||||
|
ProxyCallMethodData proxyCallMethodData = _proxyCallAllocator.Allocate(callerMethod.Module, calledMethod, callVir);
|
||||||
|
DefaultMetadataImporter importer = _moduleEntityManager.GetDefaultModuleMetadataImporter(callerMethod.Module, _encryptionScopeProvider);
|
||||||
|
|
||||||
|
if (needCacheCall)
|
||||||
|
{
|
||||||
|
FieldDef cacheField = _constFieldAllocator.Allocate(callerMethod.Module, proxyCallMethodData.index);
|
||||||
|
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Ldsfld, cacheField));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,285 +0,0 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet;
|
|
||||||
using dnlib.DotNet.Emit;
|
|
||||||
using Obfuz.Data;
|
|
||||||
using Obfuz.Emit;
|
|
||||||
using Obfuz.Settings;
|
|
||||||
using Obfuz.Utils;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace Obfuz.ObfusPasses.CallObfus
|
|
||||||
{
|
|
||||||
|
|
||||||
struct DelegateProxyMethodData
|
|
||||||
{
|
|
||||||
public readonly FieldDef delegateInstanceField;
|
|
||||||
public readonly MethodDef delegateInvokeMethod;
|
|
||||||
|
|
||||||
public DelegateProxyMethodData(FieldDef delegateInstanceField, MethodDef delegateInvokeMethod)
|
|
||||||
{
|
|
||||||
this.delegateInstanceField = delegateInstanceField;
|
|
||||||
this.delegateInvokeMethod = delegateInvokeMethod;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class DelegateProxyAllocator : GroupByModuleEntityBase
|
|
||||||
{
|
|
||||||
private readonly CachedDictionary<MethodSig, TypeDef> _delegateTypes;
|
|
||||||
private readonly HashSet<string> _allocatedDelegateNames = new HashSet<string>();
|
|
||||||
|
|
||||||
private TypeDef _delegateInstanceHolderType;
|
|
||||||
private bool _done;
|
|
||||||
|
|
||||||
class CallInfo
|
|
||||||
{
|
|
||||||
public string key1;
|
|
||||||
public int key2;
|
|
||||||
public IMethod method;
|
|
||||||
public bool callVir;
|
|
||||||
|
|
||||||
public int index;
|
|
||||||
public TypeDef delegateType;
|
|
||||||
public FieldDef delegateInstanceField;
|
|
||||||
public MethodDef delegateInvokeMethod;
|
|
||||||
public MethodDef proxyMethod;
|
|
||||||
}
|
|
||||||
private readonly Dictionary<MethodKey, CallInfo> _callMethods = new Dictionary<MethodKey, CallInfo>();
|
|
||||||
private CallObfuscationSettingsFacade _settings;
|
|
||||||
|
|
||||||
public DelegateProxyAllocator()
|
|
||||||
{
|
|
||||||
_delegateTypes = new CachedDictionary<MethodSig, TypeDef>(SignatureEqualityComparer.Instance, CreateDelegateForSignature);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Init()
|
|
||||||
{
|
|
||||||
_delegateInstanceHolderType = CreateDelegateInstanceHolderTypeDef();
|
|
||||||
_settings = CallObfusPass.CurrentSettings;
|
|
||||||
}
|
|
||||||
|
|
||||||
private string AllocateDelegateTypeName(MethodSig delegateInvokeSig)
|
|
||||||
{
|
|
||||||
uint hashCode = (uint)SignatureEqualityComparer.Instance.GetHashCode(delegateInvokeSig);
|
|
||||||
string typeName = $"$Obfuz$Delegate_{hashCode}";
|
|
||||||
if (_allocatedDelegateNames.Add(typeName))
|
|
||||||
{
|
|
||||||
return typeName;
|
|
||||||
}
|
|
||||||
for (int i = 0; ; i++)
|
|
||||||
{
|
|
||||||
typeName = $"$Obfuz$Delegate_{hashCode}_{i}";
|
|
||||||
if (_allocatedDelegateNames.Add(typeName))
|
|
||||||
{
|
|
||||||
return typeName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private TypeDef CreateDelegateForSignature(MethodSig delegateInvokeSig)
|
|
||||||
{
|
|
||||||
ModuleDef mod = Module;
|
|
||||||
using (var scope = new DisableTypeDefFindCacheScope(mod))
|
|
||||||
{
|
|
||||||
|
|
||||||
string typeName = AllocateDelegateTypeName(delegateInvokeSig);
|
|
||||||
mod.Import(typeof(MulticastDelegate));
|
|
||||||
|
|
||||||
TypeDef delegateType = new TypeDefUser("", typeName, mod.CorLibTypes.GetTypeRef("System", "MulticastDelegate"));
|
|
||||||
delegateType.Attributes = TypeAttributes.Class | TypeAttributes.Sealed | TypeAttributes.Public;
|
|
||||||
mod.Types.Add(delegateType);
|
|
||||||
|
|
||||||
MethodDef ctor = new MethodDefUser(
|
|
||||||
".ctor",
|
|
||||||
MethodSig.CreateInstance(mod.CorLibTypes.Void, mod.CorLibTypes.Object, mod.CorLibTypes.IntPtr),
|
|
||||||
MethodImplAttributes.Runtime,
|
|
||||||
MethodAttributes.RTSpecialName | MethodAttributes.SpecialName | MethodAttributes.HideBySig | MethodAttributes.Public
|
|
||||||
);
|
|
||||||
ctor.DeclaringType = delegateType;
|
|
||||||
|
|
||||||
|
|
||||||
MethodDef invokeMethod = new MethodDefUser(
|
|
||||||
"Invoke",
|
|
||||||
MethodSig.CreateInstance(delegateInvokeSig.RetType, delegateInvokeSig.Params.ToArray()),
|
|
||||||
MethodImplAttributes.Runtime,
|
|
||||||
MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.NewSlot | MethodAttributes.Virtual
|
|
||||||
);
|
|
||||||
invokeMethod.DeclaringType = delegateType;
|
|
||||||
return delegateType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private TypeDef CreateDelegateInstanceHolderTypeDef()
|
|
||||||
{
|
|
||||||
ModuleDef mod = Module;
|
|
||||||
using (var scope = new DisableTypeDefFindCacheScope(mod))
|
|
||||||
{
|
|
||||||
string typeName = "$Obfuz$DelegateInstanceHolder";
|
|
||||||
TypeDef holderType = new TypeDefUser("", typeName, mod.CorLibTypes.Object.ToTypeDefOrRef());
|
|
||||||
holderType.Attributes = TypeAttributes.Class | TypeAttributes.Public;
|
|
||||||
mod.Types.Add(holderType);
|
|
||||||
return holderType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private string AllocateFieldName(IMethod method, bool callVir)
|
|
||||||
{
|
|
||||||
uint hashCode = (uint)MethodEqualityComparer.CompareDeclaringTypes.GetHashCode(method);
|
|
||||||
string typeName = $"$Obfuz$Delegate$Field_{hashCode}_{callVir}";
|
|
||||||
if (_allocatedDelegateNames.Add(typeName))
|
|
||||||
{
|
|
||||||
return typeName;
|
|
||||||
}
|
|
||||||
for (int i = 0; ; i++)
|
|
||||||
{
|
|
||||||
typeName = $"$Obfuz$Delegate$Field_{hashCode}_{callVir}_{i}";
|
|
||||||
if (_allocatedDelegateNames.Add(typeName))
|
|
||||||
{
|
|
||||||
return typeName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private MethodDef CreateProxyMethod(string name, IMethod calledMethod, bool callVir, MethodSig delegateInvokeSig)
|
|
||||||
{
|
|
||||||
var proxyMethod = new MethodDefUser(name, delegateInvokeSig, MethodImplAttributes.Managed, MethodAttributes.Public | MethodAttributes.Static);
|
|
||||||
var body = new CilBody();
|
|
||||||
proxyMethod.Body = body;
|
|
||||||
var ins = body.Instructions;
|
|
||||||
|
|
||||||
foreach (Parameter param in proxyMethod.Parameters)
|
|
||||||
{
|
|
||||||
ins.Add(Instruction.Create(OpCodes.Ldarg, param));
|
|
||||||
}
|
|
||||||
|
|
||||||
ins.Add(Instruction.Create(callVir ? OpCodes.Callvirt : OpCodes.Call, calledMethod));
|
|
||||||
ins.Add(Instruction.Create(OpCodes.Ret));
|
|
||||||
return proxyMethod;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DelegateProxyMethodData Allocate(IMethod method, bool callVir, MethodSig delegateInvokeSig)
|
|
||||||
{
|
|
||||||
var key = new MethodKey(method, callVir);
|
|
||||||
if (!_callMethods.TryGetValue(key, out var callInfo))
|
|
||||||
{
|
|
||||||
TypeDef delegateType = _delegateTypes.GetValue(delegateInvokeSig);
|
|
||||||
MethodDef delegateInvokeMethod = delegateType.FindMethod("Invoke");
|
|
||||||
string fieldName = AllocateFieldName(method, callVir);
|
|
||||||
FieldDef delegateInstanceField = new FieldDefUser(fieldName, new FieldSig(delegateType.ToTypeSig()), FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.InitOnly);
|
|
||||||
string key1 = $"{method.FullName}_{callVir}";
|
|
||||||
callInfo = new CallInfo
|
|
||||||
{
|
|
||||||
key1 = key1,
|
|
||||||
key2 = HashUtil.ComputePrimitiveOrStringOrBytesHashCode(key1) * 33445566,
|
|
||||||
method = method,
|
|
||||||
callVir = callVir,
|
|
||||||
delegateType = delegateType,
|
|
||||||
delegateInstanceField = delegateInstanceField,
|
|
||||||
delegateInvokeMethod = delegateInvokeMethod,
|
|
||||||
proxyMethod = CreateProxyMethod($"{fieldName}$Proxy", method, callVir, delegateInvokeSig),
|
|
||||||
};
|
|
||||||
_callMethods.Add(key, callInfo);
|
|
||||||
}
|
|
||||||
return new DelegateProxyMethodData(callInfo.delegateInstanceField, callInfo.delegateInvokeMethod);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Done()
|
|
||||||
{
|
|
||||||
if (_done)
|
|
||||||
{
|
|
||||||
throw new Exception("Already done");
|
|
||||||
}
|
|
||||||
_done = true;
|
|
||||||
|
|
||||||
ModuleDef mod = Module;
|
|
||||||
|
|
||||||
// for stable order, we sort methods by name
|
|
||||||
List<CallInfo> callMethodList = _callMethods.Values.ToList();
|
|
||||||
callMethodList.Sort((a, b) => a.key1.CompareTo(b.key1));
|
|
||||||
|
|
||||||
var cctor = new MethodDefUser(".cctor",
|
|
||||||
MethodSig.CreateStatic(mod.CorLibTypes.Void),
|
|
||||||
MethodImplAttributes.IL | MethodImplAttributes.Managed,
|
|
||||||
MethodAttributes.Static | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName | MethodAttributes.Private);
|
|
||||||
cctor.DeclaringType = _delegateInstanceHolderType;
|
|
||||||
//_rvaTypeDef.Methods.Add(cctor);
|
|
||||||
var body = new CilBody();
|
|
||||||
cctor.Body = body;
|
|
||||||
var ins = body.Instructions;
|
|
||||||
|
|
||||||
// var arr = new array[];
|
|
||||||
// var d = new delegate;
|
|
||||||
// arr[index] = d;
|
|
||||||
int index = 0;
|
|
||||||
ins.Add(Instruction.CreateLdcI4(callMethodList.Count));
|
|
||||||
ins.Add(Instruction.Create(OpCodes.Newarr, mod.CorLibTypes.Object));
|
|
||||||
foreach (CallInfo ci in callMethodList)
|
|
||||||
{
|
|
||||||
ci.index = index;
|
|
||||||
_delegateInstanceHolderType.Methods.Add(ci.proxyMethod);
|
|
||||||
ins.Add(Instruction.Create(OpCodes.Dup));
|
|
||||||
ins.Add(Instruction.CreateLdcI4(index));
|
|
||||||
ins.Add(Instruction.Create(OpCodes.Ldnull));
|
|
||||||
ins.Add(Instruction.Create(OpCodes.Ldftn, ci.proxyMethod));
|
|
||||||
MethodDef ctor = ci.delegateType.FindMethod(".ctor");
|
|
||||||
UnityEngine.Assertions.Assert.IsNotNull(ctor, $"Delegate type {ci.delegateType.FullName} does not have a constructor.");
|
|
||||||
ins.Add(Instruction.Create(OpCodes.Newobj, ctor));
|
|
||||||
ins.Add(Instruction.Create(OpCodes.Stelem_Ref));
|
|
||||||
++index;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
List<CallInfo> callMethodList2 = callMethodList.ToList();
|
|
||||||
callMethodList2.Sort((a, b) => a.key2.CompareTo(b.key2));
|
|
||||||
|
|
||||||
EncryptionScopeInfo encryptionScope = EncryptionScope;
|
|
||||||
DefaultMetadataImporter importer = this.GetDefaultModuleMetadataImporter();
|
|
||||||
RvaDataAllocator rvaDataAllocator = this.GetEntity<RvaDataAllocator>();
|
|
||||||
foreach (CallInfo ci in callMethodList2)
|
|
||||||
{
|
|
||||||
_delegateInstanceHolderType.Fields.Add(ci.delegateInstanceField);
|
|
||||||
|
|
||||||
|
|
||||||
ins.Add(Instruction.Create(OpCodes.Dup));
|
|
||||||
|
|
||||||
IRandom localRandom = encryptionScope.localRandomCreator(HashUtil.ComputePrimitiveOrStringOrBytesHashCode(ci.key1));
|
|
||||||
int ops = EncryptionUtil.GenerateEncryptionOpCodes(localRandom, encryptionScope.encryptor, _settings.obfuscationLevel);
|
|
||||||
int salt = localRandom.NextInt();
|
|
||||||
|
|
||||||
int encryptedValue = encryptionScope.encryptor.Encrypt(ci.index, ops, salt);
|
|
||||||
RvaData rvaData = rvaDataAllocator.Allocate(encryptedValue);
|
|
||||||
ins.Add(Instruction.Create(OpCodes.Ldsfld, rvaData.field));
|
|
||||||
ins.Add(Instruction.CreateLdcI4(rvaData.offset));
|
|
||||||
ins.Add(Instruction.CreateLdcI4(ops));
|
|
||||||
ins.Add(Instruction.CreateLdcI4(salt));
|
|
||||||
ins.Add(Instruction.Create(OpCodes.Call, importer.DecryptFromRvaInt));
|
|
||||||
ins.Add(Instruction.Create(OpCodes.Ldelem_Ref));
|
|
||||||
ins.Add(Instruction.Create(OpCodes.Stsfld, ci.delegateInstanceField));
|
|
||||||
}
|
|
||||||
|
|
||||||
ins.Add(Instruction.Create(OpCodes.Pop));
|
|
||||||
ins.Add(Instruction.Create(OpCodes.Ret));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: 02761bacbed8a8b489ae3e7f49f0f84a
|
|
||||||
MonoImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 2
|
|
||||||
defaultReferences: []
|
|
||||||
executionOrder: 0
|
|
||||||
icon: {instanceID: 0}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
|
|
@ -1,101 +0,0 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet;
|
|
||||||
using dnlib.DotNet.Emit;
|
|
||||||
using Obfuz.Emit;
|
|
||||||
using Obfuz.Utils;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace Obfuz.ObfusPasses.CallObfus
|
|
||||||
{
|
|
||||||
|
|
||||||
public class DelegateProxyObfuscator : ObfuscatorBase
|
|
||||||
{
|
|
||||||
private readonly GroupByModuleEntityManager _entityManager;
|
|
||||||
|
|
||||||
public DelegateProxyObfuscator(GroupByModuleEntityManager moduleEntityManager)
|
|
||||||
{
|
|
||||||
_entityManager = moduleEntityManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Done()
|
|
||||||
{
|
|
||||||
_entityManager.Done<DelegateProxyAllocator>();
|
|
||||||
}
|
|
||||||
|
|
||||||
private MethodSig CreateProxyMethodSig(ModuleDef module, IMethod method)
|
|
||||||
{
|
|
||||||
MethodSig methodSig = MetaUtil.ToSharedMethodSig(module.CorLibTypes, MetaUtil.GetInflatedMethodSig(method, null));
|
|
||||||
//MethodSig methodSig = MetaUtil.GetInflatedMethodSig(method).Clone();
|
|
||||||
//methodSig.Params
|
|
||||||
switch (MetaUtil.GetThisArgType(method))
|
|
||||||
{
|
|
||||||
case ThisArgType.Class:
|
|
||||||
{
|
|
||||||
methodSig.Params.Insert(0, module.CorLibTypes.Object);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ThisArgType.ValueType:
|
|
||||||
{
|
|
||||||
methodSig.Params.Insert(0, module.CorLibTypes.IntPtr);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return MethodSig.CreateStatic(methodSig.RetType, methodSig.Params.ToArray());
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool Obfuscate(MethodDef callingMethod, IMethod calledMethod, bool callVir, List<Instruction> obfuscatedInstructions)
|
|
||||||
{
|
|
||||||
DelegateProxyAllocator allocator = _entityManager.GetEntity<DelegateProxyAllocator>(callingMethod.Module);
|
|
||||||
LocalVariableAllocator localVarAllocator = new LocalVariableAllocator(callingMethod);
|
|
||||||
MethodSig methodSig = CreateProxyMethodSig(callingMethod.Module, calledMethod);
|
|
||||||
DelegateProxyMethodData proxyData = allocator.Allocate(calledMethod, callVir, methodSig);
|
|
||||||
bool isVoidReturn = MetaUtil.IsVoidType(methodSig.RetType);
|
|
||||||
|
|
||||||
using (var varScope = localVarAllocator.CreateScope())
|
|
||||||
{
|
|
||||||
List<Local> localVars = new List<Local>();
|
|
||||||
if (!isVoidReturn)
|
|
||||||
{
|
|
||||||
varScope.AllocateLocal(methodSig.RetType);
|
|
||||||
}
|
|
||||||
foreach (var p in methodSig.Params)
|
|
||||||
{
|
|
||||||
localVars.Add(varScope.AllocateLocal(p));
|
|
||||||
}
|
|
||||||
// save args
|
|
||||||
for (int i = localVars.Count - 1; i >= 0; i--)
|
|
||||||
{
|
|
||||||
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Stloc, localVars[i]));
|
|
||||||
}
|
|
||||||
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Ldsfld, proxyData.delegateInstanceField));
|
|
||||||
foreach (var local in localVars)
|
|
||||||
{
|
|
||||||
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Ldloc, local));
|
|
||||||
}
|
|
||||||
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Callvirt, proxyData.delegateInvokeMethod));
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: 1102cd9f03de27c4b9fde3d6a87277c7
|
|
||||||
MonoImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 2
|
|
||||||
defaultReferences: []
|
|
||||||
executionOrder: 0
|
|
||||||
icon: {instanceID: 0}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
|
|
@ -1,72 +0,0 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet;
|
|
||||||
using dnlib.DotNet.Emit;
|
|
||||||
using Obfuz.Data;
|
|
||||||
using Obfuz.Emit;
|
|
||||||
using Obfuz.Utils;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace Obfuz.ObfusPasses.CallObfus
|
|
||||||
{
|
|
||||||
|
|
||||||
public class DispatchProxyObfuscator : ObfuscatorBase
|
|
||||||
{
|
|
||||||
private readonly GroupByModuleEntityManager _moduleEntityManager;
|
|
||||||
|
|
||||||
public DispatchProxyObfuscator(GroupByModuleEntityManager moduleEntityManager)
|
|
||||||
{
|
|
||||||
_moduleEntityManager = moduleEntityManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Done()
|
|
||||||
{
|
|
||||||
_moduleEntityManager.Done<ModuleDispatchProxyAllocator>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool Obfuscate(MethodDef callerMethod, IMethod calledMethod, bool callVir, List<Instruction> obfuscatedInstructions)
|
|
||||||
{
|
|
||||||
ModuleDispatchProxyAllocator proxyCallAllocator = _moduleEntityManager.GetEntity<ModuleDispatchProxyAllocator>(callerMethod.Module);
|
|
||||||
MethodSig sharedMethodSig = MetaUtil.ToSharedMethodSig(calledMethod.Module.CorLibTypes, MetaUtil.GetInflatedMethodSig(calledMethod, null));
|
|
||||||
ProxyCallMethodData proxyCallMethodData = proxyCallAllocator.Allocate(calledMethod, callVir);
|
|
||||||
DefaultMetadataImporter importer = proxyCallAllocator.GetDefaultModuleMetadataImporter();
|
|
||||||
|
|
||||||
//if (needCacheCall)
|
|
||||||
//{
|
|
||||||
// FieldDef cacheField = _constFieldAllocator.Allocate(callerMethod.Module, proxyCallMethodData.index);
|
|
||||||
// obfuscatedInstructions.Add(Instruction.Create(OpCodes.Ldsfld, cacheField));
|
|
||||||
//}
|
|
||||||
//else
|
|
||||||
//{
|
|
||||||
// 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));
|
|
||||||
//}
|
|
||||||
|
|
||||||
ConstFieldAllocator constFieldAllocator = proxyCallAllocator.GetEntity<ConstFieldAllocator>();
|
|
||||||
FieldDef cacheField = constFieldAllocator.Allocate(proxyCallMethodData.index);
|
|
||||||
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Ldsfld, cacheField));
|
|
||||||
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Call, proxyCallMethodData.proxyMethod));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,39 +1,29 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet;
|
using dnlib.DotNet;
|
||||||
|
|
||||||
namespace Obfuz.ObfusPasses.CallObfus
|
namespace Obfuz.ObfusPasses.CallObfus
|
||||||
{
|
{
|
||||||
|
|
||||||
|
public struct ObfuscationCachePolicy
|
||||||
|
{
|
||||||
|
public bool cacheInLoop;
|
||||||
|
public bool cacheNotInLoop;
|
||||||
|
}
|
||||||
|
|
||||||
public interface IObfuscationPolicy
|
public interface IObfuscationPolicy
|
||||||
{
|
{
|
||||||
bool NeedObfuscateCallInMethod(MethodDef method);
|
bool NeedObfuscateCallInMethod(MethodDef method);
|
||||||
|
|
||||||
bool NeedObfuscateCalledMethod(MethodDef callerMethod, IMethod calledMethod, bool callVir);
|
ObfuscationCachePolicy GetMethodObfuscationCachePolicy(MethodDef method);
|
||||||
|
|
||||||
|
bool NeedObfuscateCalledMethod(MethodDef callerMethod, IMethod calledMethod, bool callVir, bool currentInLoop);
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class ObfuscationPolicyBase : IObfuscationPolicy
|
public abstract class ObfuscationPolicyBase : IObfuscationPolicy
|
||||||
{
|
{
|
||||||
public abstract bool NeedObfuscateCallInMethod(MethodDef method);
|
public abstract bool NeedObfuscateCallInMethod(MethodDef method);
|
||||||
|
|
||||||
public abstract bool NeedObfuscateCalledMethod(MethodDef callerMethod, IMethod calledMethod, bool callVir);
|
public abstract ObfuscationCachePolicy GetMethodObfuscationCachePolicy(MethodDef method);
|
||||||
|
|
||||||
|
public abstract bool NeedObfuscateCalledMethod(MethodDef callerMethod, IMethod calledMethod, bool callVir, bool currentInLoop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet;
|
using dnlib.DotNet;
|
||||||
using dnlib.DotNet.Emit;
|
using dnlib.DotNet.Emit;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
@ -26,15 +6,14 @@ namespace Obfuz.ObfusPasses.CallObfus
|
||||||
{
|
{
|
||||||
public interface IObfuscator
|
public interface IObfuscator
|
||||||
{
|
{
|
||||||
bool Obfuscate(MethodDef callingMethod, IMethod calledMethod, bool callVir, List<Instruction> obfuscatedInstructions);
|
void Obfuscate(MethodDef callingMethod, IMethod calledMethod, bool callVir, bool needCacheCall, List<Instruction> obfuscatedInstructions);
|
||||||
|
|
||||||
void Done();
|
void Done();
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class ObfuscatorBase : IObfuscator
|
public abstract class ObfuscatorBase : IObfuscator
|
||||||
{
|
{
|
||||||
public abstract bool Obfuscate(MethodDef callingMethod, IMethod calledMethod, bool callVir, List<Instruction> obfuscatedInstructions);
|
public abstract void Obfuscate(MethodDef callingMethod, IMethod calledMethod, bool callVir, bool needCacheCall, List<Instruction> obfuscatedInstructions);
|
||||||
|
|
||||||
public abstract void Done();
|
public abstract void Done();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,50 +0,0 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet;
|
|
||||||
using Obfuz.Utils;
|
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace Obfuz.ObfusPasses.CallObfus
|
|
||||||
{
|
|
||||||
class MethodKey : IEquatable<MethodKey>
|
|
||||||
{
|
|
||||||
public readonly IMethod _method;
|
|
||||||
public readonly bool _callVir;
|
|
||||||
private readonly int _hashCode;
|
|
||||||
|
|
||||||
public MethodKey(IMethod method, bool callVir)
|
|
||||||
{
|
|
||||||
_method = method;
|
|
||||||
_callVir = callVir;
|
|
||||||
_hashCode = HashUtil.CombineHash(MethodEqualityComparer.CompareDeclaringTypes.GetHashCode(method), callVir ? 1 : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int GetHashCode()
|
|
||||||
{
|
|
||||||
return _hashCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Equals(MethodKey other)
|
|
||||||
{
|
|
||||||
return MethodEqualityComparer.CompareDeclaringTypes.Equals(_method, other._method) && _callVir == other._callVir;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: 1193647b317b56f4b83aa080d0a17f7a
|
|
||||||
MonoImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 2
|
|
||||||
defaultReferences: []
|
|
||||||
executionOrder: 0
|
|
||||||
icon: {instanceID: 0}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
|
|
@ -1,145 +0,0 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet;
|
|
||||||
using Obfuz.Settings;
|
|
||||||
using Obfuz.Utils;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace Obfuz.ObfusPasses.CallObfus
|
|
||||||
{
|
|
||||||
class SpecialWhiteListMethodCalculator
|
|
||||||
{
|
|
||||||
private readonly RuntimeType _targetRuntime;
|
|
||||||
private readonly bool _obfuscateCallToMethodInMscorlib;
|
|
||||||
private readonly CachedDictionary<IMethod, bool> _specialWhiteListMethodCache;
|
|
||||||
|
|
||||||
public SpecialWhiteListMethodCalculator(RuntimeType targetRuntime, bool obfuscateCallToMethodInMscorlib)
|
|
||||||
{
|
|
||||||
_targetRuntime = targetRuntime;
|
|
||||||
_obfuscateCallToMethodInMscorlib = obfuscateCallToMethodInMscorlib;
|
|
||||||
_specialWhiteListMethodCache = new CachedDictionary<IMethod, bool>(MethodEqualityComparer.CompareDeclaringTypes, this.ComputeIsInWhiteList);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsInWhiteList(IMethod calledMethod)
|
|
||||||
{
|
|
||||||
return _specialWhiteListMethodCache.GetValue(calledMethod);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static readonly HashSet<string> _specialTypeFullNames = new HashSet<string>
|
|
||||||
{
|
|
||||||
"System.Enum",
|
|
||||||
"System.Delegate",
|
|
||||||
"System.MulticastDelegate",
|
|
||||||
"Obfuz.EncryptionService`1",
|
|
||||||
};
|
|
||||||
|
|
||||||
private static readonly HashSet<string> _specialMethodNames = new HashSet<string>
|
|
||||||
{
|
|
||||||
"GetEnumerator", // List<T>.Enumerator.GetEnumerator()
|
|
||||||
".ctor", // constructor
|
|
||||||
};
|
|
||||||
|
|
||||||
private static readonly HashSet<string> _specialMethodFullNames = new HashSet<string>
|
|
||||||
{
|
|
||||||
"System.Reflection.MethodBase.GetCurrentMethod",
|
|
||||||
"System.Reflection.Assembly.GetCallingAssembly",
|
|
||||||
"System.Reflection.Assembly.GetExecutingAssembly",
|
|
||||||
"System.Reflection.Assembly.GetEntryAssembly",
|
|
||||||
};
|
|
||||||
|
|
||||||
private bool ComputeIsInWhiteList(IMethod calledMethod)
|
|
||||||
{
|
|
||||||
MethodDef calledMethodDef = calledMethod.ResolveMethodDef();
|
|
||||||
// mono has more strict access control, calls non-public method will raise exception.
|
|
||||||
if (_targetRuntime == RuntimeType.Mono)
|
|
||||||
{
|
|
||||||
if (calledMethodDef != null && (!calledMethodDef.IsPublic || !IsTypeSelfAndParentPublic(calledMethodDef.DeclaringType)))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ITypeDefOrRef declaringType = calledMethod.DeclaringType;
|
|
||||||
TypeSig declaringTypeSig = calledMethod.DeclaringType.ToTypeSig();
|
|
||||||
declaringTypeSig = declaringTypeSig.RemovePinnedAndModifiers();
|
|
||||||
switch (declaringTypeSig.ElementType)
|
|
||||||
{
|
|
||||||
case ElementType.ValueType:
|
|
||||||
case ElementType.Class:
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ElementType.GenericInst:
|
|
||||||
{
|
|
||||||
if (MetaUtil.ContainsContainsGenericParameter(calledMethod))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
TypeDef typeDef = declaringType.ResolveTypeDef();
|
|
||||||
|
|
||||||
if (!_obfuscateCallToMethodInMscorlib && typeDef.Module.IsCoreLibraryModule == true)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeDef.IsDelegate || typeDef.IsEnum)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
string fullName = typeDef.FullName;
|
|
||||||
if (_specialTypeFullNames.Contains(fullName))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
//if (fullName.StartsWith("System.Runtime.CompilerServices."))
|
|
||||||
//{
|
|
||||||
// return true;
|
|
||||||
//}
|
|
||||||
|
|
||||||
string methodName = calledMethod.Name;
|
|
||||||
if (_specialMethodNames.Contains(methodName))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
string methodFullName = $"{fullName}.{methodName}";
|
|
||||||
if (_specialMethodFullNames.Contains(methodFullName))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool IsTypeSelfAndParentPublic(TypeDef type)
|
|
||||||
{
|
|
||||||
if (type.DeclaringType != null && !IsTypeSelfAndParentPublic(type.DeclaringType))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return type.IsPublic;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: 904e80c4b98911c40b6a9173ca24f3ee
|
|
||||||
MonoImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 2
|
|
||||||
defaultReferences: []
|
|
||||||
executionOrder: 0
|
|
||||||
icon: {instanceID: 0}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet;
|
using dnlib.DotNet;
|
||||||
using dnlib.DotNet.Emit;
|
using dnlib.DotNet.Emit;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet;
|
using dnlib.DotNet;
|
||||||
using Obfuz.Editor;
|
using Obfuz.Editor;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet;
|
using dnlib.DotNet;
|
||||||
using Obfuz.Conf;
|
using Obfuz.Conf;
|
||||||
using Obfuz.Utils;
|
using Obfuz.Utils;
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet;
|
using dnlib.DotNet;
|
||||||
using dnlib.DotNet.Emit;
|
using dnlib.DotNet.Emit;
|
||||||
using Obfuz.Emit;
|
using Obfuz.Emit;
|
||||||
|
|
@ -43,7 +23,7 @@ namespace Obfuz.ObfusPasses.ConstEncrypt
|
||||||
{
|
{
|
||||||
var ctx = ObfuscationPassContext.Current;
|
var ctx = ObfuscationPassContext.Current;
|
||||||
_dataObfuscatorPolicy = new ConfigurableEncryptPolicy(ctx.coreSettings.assembliesToObfuscate, _settings.ruleFiles);
|
_dataObfuscatorPolicy = new ConfigurableEncryptPolicy(ctx.coreSettings.assembliesToObfuscate, _settings.ruleFiles);
|
||||||
_dataObfuscator = new DefaultConstEncryptor(ctx.moduleEntityManager, _settings);
|
_dataObfuscator = new DefaultConstEncryptor(ctx.encryptionScopeProvider, ctx.rvaDataAllocator, ctx.constFieldAllocator, ctx.moduleEntityManager, _settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Stop()
|
public override void Stop()
|
||||||
|
|
@ -143,9 +123,6 @@ namespace Obfuz.ObfusPasses.ConstEncrypt
|
||||||
{
|
{
|
||||||
// don't need cache for byte array obfuscation
|
// don't need cache for byte array obfuscation
|
||||||
needCache = false;
|
needCache = false;
|
||||||
// Drop ldtoken RuntimeFieldHandle; DecryptInitializeArray now loads from RvaDataAllocator byte[].
|
|
||||||
prevInst.OpCode = OpCodes.Nop;
|
|
||||||
prevInst.Operand = null;
|
|
||||||
_dataObfuscator.ObfuscateBytes(method, needCache, ravFieldDef, data, outputInstructions);
|
_dataObfuscator.ObfuscateBytes(method, needCache, ravFieldDef, data, outputInstructions);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,42 +1,28 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet;
|
using dnlib.DotNet;
|
||||||
using dnlib.DotNet.Emit;
|
using dnlib.DotNet.Emit;
|
||||||
|
using NUnit.Framework;
|
||||||
using Obfuz.Data;
|
using Obfuz.Data;
|
||||||
using Obfuz.Emit;
|
using Obfuz.Emit;
|
||||||
using Obfuz.Settings;
|
using Obfuz.Settings;
|
||||||
using Obfuz.Utils;
|
using Obfuz.Utils;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using UnityEngine.Assertions;
|
|
||||||
|
|
||||||
namespace Obfuz.ObfusPasses.ConstEncrypt
|
namespace Obfuz.ObfusPasses.ConstEncrypt
|
||||||
{
|
{
|
||||||
public class DefaultConstEncryptor : IConstEncryptor
|
public class DefaultConstEncryptor : IConstEncryptor
|
||||||
{
|
{
|
||||||
|
private readonly EncryptionScopeProvider _encryptionScopeProvider;
|
||||||
|
private readonly RvaDataAllocator _rvaDataAllocator;
|
||||||
|
private readonly ConstFieldAllocator _constFieldAllocator;
|
||||||
private readonly GroupByModuleEntityManager _moduleEntityManager;
|
private readonly GroupByModuleEntityManager _moduleEntityManager;
|
||||||
private readonly ConstEncryptionSettingsFacade _settings;
|
private readonly ConstEncryptionSettingsFacade _settings;
|
||||||
|
|
||||||
public DefaultConstEncryptor(GroupByModuleEntityManager moduleEntityManager, ConstEncryptionSettingsFacade settings)
|
public DefaultConstEncryptor(EncryptionScopeProvider encryptionScopeProvider, RvaDataAllocator rvaDataAllocator, ConstFieldAllocator constFieldAllocator, GroupByModuleEntityManager moduleEntityManager, ConstEncryptionSettingsFacade settings)
|
||||||
{
|
{
|
||||||
|
_encryptionScopeProvider = encryptionScopeProvider;
|
||||||
|
_rvaDataAllocator = rvaDataAllocator;
|
||||||
|
_constFieldAllocator = constFieldAllocator;
|
||||||
_moduleEntityManager = moduleEntityManager;
|
_moduleEntityManager = moduleEntityManager;
|
||||||
_settings = settings;
|
_settings = settings;
|
||||||
}
|
}
|
||||||
|
|
@ -58,23 +44,20 @@ namespace Obfuz.ObfusPasses.ConstEncrypt
|
||||||
|
|
||||||
private DefaultMetadataImporter GetModuleMetadataImporter(MethodDef method)
|
private DefaultMetadataImporter GetModuleMetadataImporter(MethodDef method)
|
||||||
{
|
{
|
||||||
return _moduleEntityManager.GetEntity<DefaultMetadataImporter>(method.Module);
|
return _moduleEntityManager.GetDefaultModuleMetadataImporter(method.Module, _encryptionScopeProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ObfuscateInt(MethodDef method, bool needCacheValue, int value, List<Instruction> obfuscatedInstructions)
|
public void ObfuscateInt(MethodDef method, bool needCacheValue, int value, List<Instruction> obfuscatedInstructions)
|
||||||
{
|
{
|
||||||
EncryptionScopeInfo encryptionScope = _moduleEntityManager.EncryptionScopeProvider.GetScope(method.Module);
|
EncryptionScopeInfo encryptionScope = _encryptionScopeProvider.GetScope(method.Module);
|
||||||
IRandom random = CreateRandomForValue(encryptionScope, value.GetHashCode());
|
IRandom random = CreateRandomForValue(encryptionScope, value.GetHashCode());
|
||||||
ConstFieldAllocator constFieldAllocator = _moduleEntityManager.GetEntity<ConstFieldAllocator>(method.Module);
|
ModuleConstFieldAllocator moduleConstFieldAllocator = _constFieldAllocator.GetModuleAllocator(method.Module);
|
||||||
RvaDataAllocator rvaDataAllocator = _moduleEntityManager.GetEntity<RvaDataAllocator>(method.Module);
|
|
||||||
DefaultMetadataImporter importer = GetModuleMetadataImporter(method);
|
|
||||||
|
|
||||||
switch (random.NextInt(5))
|
switch (random.NextInt(5))
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
{
|
{
|
||||||
// = c = encrypted static field
|
// = c = encrypted static field
|
||||||
FieldDef cacheField = constFieldAllocator.Allocate(value);
|
FieldDef cacheField = _constFieldAllocator.Allocate(method.Module, value);
|
||||||
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Ldsfld, cacheField));
|
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Ldsfld, cacheField));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -84,7 +67,7 @@ namespace Obfuz.ObfusPasses.ConstEncrypt
|
||||||
int a = random.NextInt();
|
int a = random.NextInt();
|
||||||
int b = value - a;
|
int b = value - a;
|
||||||
float constProbability = 0.5f;
|
float constProbability = 0.5f;
|
||||||
ConstObfusUtil.LoadConstTwoInt(a, b, random, constProbability, constFieldAllocator, obfuscatedInstructions);
|
ConstObfusUtil.LoadConstTwoInt(a, b, random, constProbability, moduleConstFieldAllocator, obfuscatedInstructions);
|
||||||
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Add));
|
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Add));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -95,7 +78,7 @@ namespace Obfuz.ObfusPasses.ConstEncrypt
|
||||||
int ra = MathUtil.ModInverse32(a);
|
int ra = MathUtil.ModInverse32(a);
|
||||||
int b = ra * value;
|
int b = ra * value;
|
||||||
float constProbability = 0.5f;
|
float constProbability = 0.5f;
|
||||||
ConstObfusUtil.LoadConstTwoInt(a, b, random, constProbability, constFieldAllocator, obfuscatedInstructions);
|
ConstObfusUtil.LoadConstTwoInt(a, b, random, constProbability, moduleConstFieldAllocator, obfuscatedInstructions);
|
||||||
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Mul));
|
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Mul));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -105,7 +88,7 @@ namespace Obfuz.ObfusPasses.ConstEncrypt
|
||||||
int a = random.NextInt();
|
int a = random.NextInt();
|
||||||
int b = a ^ value;
|
int b = a ^ value;
|
||||||
float constProbability = 0.5f;
|
float constProbability = 0.5f;
|
||||||
ConstObfusUtil.LoadConstTwoInt(a, b, random, constProbability, constFieldAllocator, obfuscatedInstructions);
|
ConstObfusUtil.LoadConstTwoInt(a, b, random, constProbability, moduleConstFieldAllocator, obfuscatedInstructions);
|
||||||
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Xor));
|
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Xor));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -113,14 +96,16 @@ namespace Obfuz.ObfusPasses.ConstEncrypt
|
||||||
{
|
{
|
||||||
if (needCacheValue)
|
if (needCacheValue)
|
||||||
{
|
{
|
||||||
FieldDef cacheField = constFieldAllocator.Allocate(value);
|
FieldDef cacheField = moduleConstFieldAllocator.Allocate(value);
|
||||||
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Ldsfld, cacheField));
|
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Ldsfld, cacheField));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int ops = GenerateEncryptionOperations(encryptionScope, random);
|
int ops = GenerateEncryptionOperations(encryptionScope, random);
|
||||||
int salt = GenerateSalt(random);
|
int salt = GenerateSalt(random);
|
||||||
int encryptedValue = encryptionScope.encryptor.Encrypt(value, ops, salt);
|
int encryptedValue = encryptionScope.encryptor.Encrypt(value, ops, salt);
|
||||||
RvaData rvaData = rvaDataAllocator.Allocate(encryptedValue);
|
RvaData rvaData = _rvaDataAllocator.Allocate(method.Module, encryptedValue);
|
||||||
|
|
||||||
|
DefaultMetadataImporter importer = GetModuleMetadataImporter(method);
|
||||||
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Ldsfld, rvaData.field));
|
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Ldsfld, rvaData.field));
|
||||||
obfuscatedInstructions.Add(Instruction.CreateLdcI4(rvaData.offset));
|
obfuscatedInstructions.Add(Instruction.CreateLdcI4(rvaData.offset));
|
||||||
obfuscatedInstructions.Add(Instruction.CreateLdcI4(ops));
|
obfuscatedInstructions.Add(Instruction.CreateLdcI4(ops));
|
||||||
|
|
@ -135,18 +120,16 @@ namespace Obfuz.ObfusPasses.ConstEncrypt
|
||||||
|
|
||||||
public void ObfuscateLong(MethodDef method, bool needCacheValue, long value, List<Instruction> obfuscatedInstructions)
|
public void ObfuscateLong(MethodDef method, bool needCacheValue, long value, List<Instruction> obfuscatedInstructions)
|
||||||
{
|
{
|
||||||
EncryptionScopeInfo encryptionScope = _moduleEntityManager.EncryptionScopeProvider.GetScope(method.Module);
|
EncryptionScopeInfo encryptionScope = _encryptionScopeProvider.GetScope(method.Module);
|
||||||
IRandom random = CreateRandomForValue(encryptionScope, value.GetHashCode());
|
IRandom random = CreateRandomForValue(encryptionScope, value.GetHashCode());
|
||||||
ConstFieldAllocator constFieldAllocator = _moduleEntityManager.GetEntity<ConstFieldAllocator>(method.Module);
|
ModuleConstFieldAllocator moduleConstFieldAllocator = _constFieldAllocator.GetModuleAllocator(method.Module);
|
||||||
RvaDataAllocator rvaDataAllocator = _moduleEntityManager.GetEntity<RvaDataAllocator>(method.Module);
|
|
||||||
DefaultMetadataImporter importer = GetModuleMetadataImporter(method);
|
|
||||||
|
|
||||||
switch (random.NextInt(5))
|
switch (random.NextInt(5))
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
{
|
{
|
||||||
// c = encrypted static field
|
// c = encrypted static field
|
||||||
FieldDef cacheField = constFieldAllocator.Allocate(value);
|
FieldDef cacheField = _constFieldAllocator.Allocate(method.Module, value);
|
||||||
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Ldsfld, cacheField));
|
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Ldsfld, cacheField));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -156,7 +139,7 @@ namespace Obfuz.ObfusPasses.ConstEncrypt
|
||||||
long a = random.NextLong();
|
long a = random.NextLong();
|
||||||
long b = value - a;
|
long b = value - a;
|
||||||
float constProbability = 0.5f;
|
float constProbability = 0.5f;
|
||||||
ConstObfusUtil.LoadConstTwoLong(a, b, random, constProbability, constFieldAllocator, obfuscatedInstructions);
|
ConstObfusUtil.LoadConstTwoLong(a, b, random, constProbability, moduleConstFieldAllocator, obfuscatedInstructions);
|
||||||
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Add));
|
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Add));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -167,7 +150,7 @@ namespace Obfuz.ObfusPasses.ConstEncrypt
|
||||||
long ra = MathUtil.ModInverse64(a);
|
long ra = MathUtil.ModInverse64(a);
|
||||||
long b = ra * value;
|
long b = ra * value;
|
||||||
float constProbability = 0.5f;
|
float constProbability = 0.5f;
|
||||||
ConstObfusUtil.LoadConstTwoLong(a, b, random, constProbability, constFieldAllocator, obfuscatedInstructions);
|
ConstObfusUtil.LoadConstTwoLong(a, b, random, constProbability, moduleConstFieldAllocator, obfuscatedInstructions);
|
||||||
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Mul));
|
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Mul));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -177,7 +160,7 @@ namespace Obfuz.ObfusPasses.ConstEncrypt
|
||||||
long a = random.NextLong();
|
long a = random.NextLong();
|
||||||
long b = a ^ value;
|
long b = a ^ value;
|
||||||
float constProbability = 0.5f;
|
float constProbability = 0.5f;
|
||||||
ConstObfusUtil.LoadConstTwoLong(a, b, random, constProbability, constFieldAllocator, obfuscatedInstructions);
|
ConstObfusUtil.LoadConstTwoLong(a, b, random, constProbability, moduleConstFieldAllocator, obfuscatedInstructions);
|
||||||
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Xor));
|
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Xor));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -185,7 +168,7 @@ namespace Obfuz.ObfusPasses.ConstEncrypt
|
||||||
{
|
{
|
||||||
if (needCacheValue)
|
if (needCacheValue)
|
||||||
{
|
{
|
||||||
FieldDef cacheField = constFieldAllocator.Allocate(value);
|
FieldDef cacheField = _constFieldAllocator.Allocate(method.Module, value);
|
||||||
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Ldsfld, cacheField));
|
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Ldsfld, cacheField));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -193,8 +176,9 @@ namespace Obfuz.ObfusPasses.ConstEncrypt
|
||||||
int ops = GenerateEncryptionOperations(encryptionScope, random);
|
int ops = GenerateEncryptionOperations(encryptionScope, random);
|
||||||
int salt = GenerateSalt(random);
|
int salt = GenerateSalt(random);
|
||||||
long encryptedValue = encryptionScope.encryptor.Encrypt(value, ops, salt);
|
long encryptedValue = encryptionScope.encryptor.Encrypt(value, ops, salt);
|
||||||
RvaData rvaData = rvaDataAllocator.Allocate(encryptedValue);
|
RvaData rvaData = _rvaDataAllocator.Allocate(method.Module, encryptedValue);
|
||||||
|
|
||||||
|
DefaultMetadataImporter importer = GetModuleMetadataImporter(method);
|
||||||
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Ldsfld, rvaData.field));
|
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Ldsfld, rvaData.field));
|
||||||
obfuscatedInstructions.Add(Instruction.CreateLdcI4(rvaData.offset));
|
obfuscatedInstructions.Add(Instruction.CreateLdcI4(rvaData.offset));
|
||||||
obfuscatedInstructions.Add(Instruction.CreateLdcI4(ops));
|
obfuscatedInstructions.Add(Instruction.CreateLdcI4(ops));
|
||||||
|
|
@ -209,25 +193,21 @@ namespace Obfuz.ObfusPasses.ConstEncrypt
|
||||||
|
|
||||||
public void ObfuscateFloat(MethodDef method, bool needCacheValue, float value, List<Instruction> obfuscatedInstructions)
|
public void ObfuscateFloat(MethodDef method, bool needCacheValue, float value, List<Instruction> obfuscatedInstructions)
|
||||||
{
|
{
|
||||||
EncryptionScopeInfo encryptionScope = _moduleEntityManager.EncryptionScopeProvider.GetScope(method.Module);
|
|
||||||
IRandom random = CreateRandomForValue(encryptionScope, value.GetHashCode());
|
|
||||||
ConstFieldAllocator constFieldAllocator = _moduleEntityManager.GetEntity<ConstFieldAllocator>(method.Module);
|
|
||||||
RvaDataAllocator rvaDataAllocator = _moduleEntityManager.GetEntity<RvaDataAllocator>(method.Module);
|
|
||||||
DefaultMetadataImporter importer = GetModuleMetadataImporter(method);
|
|
||||||
|
|
||||||
if (needCacheValue)
|
if (needCacheValue)
|
||||||
{
|
{
|
||||||
FieldDef cacheField = constFieldAllocator.Allocate(value);
|
FieldDef cacheField = _constFieldAllocator.Allocate(method.Module, value);
|
||||||
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Ldsfld, cacheField));
|
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Ldsfld, cacheField));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EncryptionScopeInfo encryptionScope = _encryptionScopeProvider.GetScope(method.Module);
|
||||||
|
IRandom random = CreateRandomForValue(encryptionScope, value.GetHashCode());
|
||||||
int ops = GenerateEncryptionOperations(encryptionScope, random);
|
int ops = GenerateEncryptionOperations(encryptionScope, random);
|
||||||
int salt = GenerateSalt(random);
|
int salt = GenerateSalt(random);
|
||||||
float encryptedValue = encryptionScope.encryptor.Encrypt(value, ops, salt);
|
float encryptedValue = encryptionScope.encryptor.Encrypt(value, ops, salt);
|
||||||
RvaData rvaData = rvaDataAllocator.Allocate(encryptedValue);
|
RvaData rvaData = _rvaDataAllocator.Allocate(method.Module, encryptedValue);
|
||||||
|
|
||||||
|
DefaultMetadataImporter importer = GetModuleMetadataImporter(method);
|
||||||
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Ldsfld, rvaData.field));
|
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Ldsfld, rvaData.field));
|
||||||
obfuscatedInstructions.Add(Instruction.CreateLdcI4(rvaData.offset));
|
obfuscatedInstructions.Add(Instruction.CreateLdcI4(rvaData.offset));
|
||||||
obfuscatedInstructions.Add(Instruction.CreateLdcI4(ops));
|
obfuscatedInstructions.Add(Instruction.CreateLdcI4(ops));
|
||||||
|
|
@ -237,25 +217,21 @@ namespace Obfuz.ObfusPasses.ConstEncrypt
|
||||||
|
|
||||||
public void ObfuscateDouble(MethodDef method, bool needCacheValue, double value, List<Instruction> obfuscatedInstructions)
|
public void ObfuscateDouble(MethodDef method, bool needCacheValue, double value, List<Instruction> obfuscatedInstructions)
|
||||||
{
|
{
|
||||||
EncryptionScopeInfo encryptionScope = _moduleEntityManager.EncryptionScopeProvider.GetScope(method.Module);
|
|
||||||
IRandom random = CreateRandomForValue(encryptionScope, value.GetHashCode());
|
|
||||||
ConstFieldAllocator constFieldAllocator = _moduleEntityManager.GetEntity<ConstFieldAllocator>(method.Module);
|
|
||||||
RvaDataAllocator rvaDataAllocator = _moduleEntityManager.GetEntity<RvaDataAllocator>(method.Module);
|
|
||||||
DefaultMetadataImporter importer = GetModuleMetadataImporter(method);
|
|
||||||
|
|
||||||
if (needCacheValue)
|
if (needCacheValue)
|
||||||
{
|
{
|
||||||
FieldDef cacheField = constFieldAllocator.Allocate(value);
|
FieldDef cacheField = _constFieldAllocator.Allocate(method.Module, value);
|
||||||
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Ldsfld, cacheField));
|
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Ldsfld, cacheField));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EncryptionScopeInfo encryptionScope = _encryptionScopeProvider.GetScope(method.Module);
|
||||||
|
IRandom random = CreateRandomForValue(encryptionScope, value.GetHashCode());
|
||||||
int ops = GenerateEncryptionOperations(encryptionScope, random);
|
int ops = GenerateEncryptionOperations(encryptionScope, random);
|
||||||
int salt = GenerateSalt(random);
|
int salt = GenerateSalt(random);
|
||||||
double encryptedValue = encryptionScope.encryptor.Encrypt(value, ops, salt);
|
double encryptedValue = encryptionScope.encryptor.Encrypt(value, ops, salt);
|
||||||
RvaData rvaData = rvaDataAllocator.Allocate(encryptedValue);
|
RvaData rvaData = _rvaDataAllocator.Allocate(method.Module, encryptedValue);
|
||||||
|
|
||||||
|
DefaultMetadataImporter importer = GetModuleMetadataImporter(method);
|
||||||
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Ldsfld, rvaData.field));
|
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Ldsfld, rvaData.field));
|
||||||
obfuscatedInstructions.Add(Instruction.CreateLdcI4(rvaData.offset));
|
obfuscatedInstructions.Add(Instruction.CreateLdcI4(rvaData.offset));
|
||||||
obfuscatedInstructions.Add(Instruction.CreateLdcI4(ops));
|
obfuscatedInstructions.Add(Instruction.CreateLdcI4(ops));
|
||||||
|
|
@ -266,15 +242,15 @@ namespace Obfuz.ObfusPasses.ConstEncrypt
|
||||||
|
|
||||||
class EncryptedRvaDataInfo
|
class EncryptedRvaDataInfo
|
||||||
{
|
{
|
||||||
public readonly RvaData rvaData;
|
public readonly FieldDef fieldDef;
|
||||||
public readonly byte[] originalBytes;
|
public readonly byte[] originalBytes;
|
||||||
public readonly byte[] encryptedBytes;
|
public readonly byte[] encryptedBytes;
|
||||||
public readonly int opts;
|
public readonly int opts;
|
||||||
public readonly int salt;
|
public readonly int salt;
|
||||||
|
|
||||||
public EncryptedRvaDataInfo(RvaData rvaData, byte[] originalBytes, byte[] encryptedBytes, int opts, int salt)
|
public EncryptedRvaDataInfo(FieldDef fieldDef, byte[] originalBytes, byte[] encryptedBytes, int opts, int salt)
|
||||||
{
|
{
|
||||||
this.rvaData = rvaData;
|
this.fieldDef = fieldDef;
|
||||||
this.originalBytes = originalBytes;
|
this.originalBytes = originalBytes;
|
||||||
this.encryptedBytes = encryptedBytes;
|
this.encryptedBytes = encryptedBytes;
|
||||||
this.opts = opts;
|
this.opts = opts;
|
||||||
|
|
@ -288,7 +264,7 @@ namespace Obfuz.ObfusPasses.ConstEncrypt
|
||||||
{
|
{
|
||||||
if (!_encryptedRvaFields.TryGetValue(fieldDef, out var encryptedRvaData))
|
if (!_encryptedRvaFields.TryGetValue(fieldDef, out var encryptedRvaData))
|
||||||
{
|
{
|
||||||
EncryptionScopeInfo encryptionScope = _moduleEntityManager.EncryptionScopeProvider.GetScope(fieldDef.Module);
|
EncryptionScopeInfo encryptionScope = _encryptionScopeProvider.GetScope(fieldDef.Module);
|
||||||
IRandom random = CreateRandomForValue(encryptionScope, FieldEqualityComparer.CompareDeclaringTypes.GetHashCode(fieldDef));
|
IRandom random = CreateRandomForValue(encryptionScope, FieldEqualityComparer.CompareDeclaringTypes.GetHashCode(fieldDef));
|
||||||
int ops = GenerateEncryptionOperations(encryptionScope, random);
|
int ops = GenerateEncryptionOperations(encryptionScope, random);
|
||||||
int salt = GenerateSalt(random);
|
int salt = GenerateSalt(random);
|
||||||
|
|
@ -296,15 +272,12 @@ namespace Obfuz.ObfusPasses.ConstEncrypt
|
||||||
byte[] encryptedBytes = (byte[])originalBytes.Clone();
|
byte[] encryptedBytes = (byte[])originalBytes.Clone();
|
||||||
encryptionScope.encryptor.EncryptBlock(encryptedBytes, ops, salt);
|
encryptionScope.encryptor.EncryptBlock(encryptedBytes, ops, salt);
|
||||||
Assert.AreNotEqual(originalBytes, encryptedBytes, "Original bytes should not be the same as encrypted bytes.");
|
Assert.AreNotEqual(originalBytes, encryptedBytes, "Original bytes should not be the same as encrypted bytes.");
|
||||||
RvaDataAllocator rvaDataAllocator = _moduleEntityManager.GetEntity<RvaDataAllocator>(fieldDef.Module);
|
encryptedRvaData = new EncryptedRvaDataInfo(fieldDef, originalBytes, encryptedBytes, ops, salt);
|
||||||
RvaData rvaData = rvaDataAllocator.Allocate(encryptedBytes);
|
|
||||||
encryptedRvaData = new EncryptedRvaDataInfo(rvaData, originalBytes, encryptedBytes, ops, salt);
|
|
||||||
_encryptedRvaFields.Add(fieldDef, encryptedRvaData);
|
_encryptedRvaFields.Add(fieldDef, encryptedRvaData);
|
||||||
// Keep ciphertext in the original RVA field so plaintext is not shipped; runtime loads via RvaDataAllocator.
|
|
||||||
fieldDef.InitialValue = encryptedBytes;
|
fieldDef.InitialValue = encryptedBytes;
|
||||||
byte[] decryptedBytes = (byte[])encryptedBytes.Clone();
|
byte[] decryptedBytes = (byte[])encryptedBytes.Clone();
|
||||||
encryptionScope.encryptor.DecryptBlock(decryptedBytes, ops, salt);
|
encryptionScope.encryptor.DecryptBlock(decryptedBytes, ops, salt);
|
||||||
AssertUtil.AreArrayEqual(originalBytes, decryptedBytes, "Decrypted bytes should match the original bytes after encryption and decryption.");
|
Assert.AreEqual(originalBytes, decryptedBytes, "Decrypted bytes should match the original bytes after encryption and decryption.");
|
||||||
}
|
}
|
||||||
return encryptedRvaData;
|
return encryptedRvaData;
|
||||||
}
|
}
|
||||||
|
|
@ -316,8 +289,6 @@ namespace Obfuz.ObfusPasses.ConstEncrypt
|
||||||
Assert.AreEqual(value.Length, encryptedData.encryptedBytes.Length);
|
Assert.AreEqual(value.Length, encryptedData.encryptedBytes.Length);
|
||||||
|
|
||||||
DefaultMetadataImporter importer = GetModuleMetadataImporter(method);
|
DefaultMetadataImporter importer = GetModuleMetadataImporter(method);
|
||||||
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Ldsfld, encryptedData.rvaData.field));
|
|
||||||
obfuscatedInstructions.Add(Instruction.CreateLdcI4(encryptedData.rvaData.offset));
|
|
||||||
obfuscatedInstructions.Add(Instruction.CreateLdcI4(encryptedData.encryptedBytes.Length));
|
obfuscatedInstructions.Add(Instruction.CreateLdcI4(encryptedData.encryptedBytes.Length));
|
||||||
obfuscatedInstructions.Add(Instruction.CreateLdcI4(encryptedData.opts));
|
obfuscatedInstructions.Add(Instruction.CreateLdcI4(encryptedData.opts));
|
||||||
obfuscatedInstructions.Add(Instruction.CreateLdcI4(encryptedData.salt));
|
obfuscatedInstructions.Add(Instruction.CreateLdcI4(encryptedData.salt));
|
||||||
|
|
@ -326,26 +297,23 @@ namespace Obfuz.ObfusPasses.ConstEncrypt
|
||||||
|
|
||||||
public void ObfuscateString(MethodDef method, bool needCacheValue, string value, List<Instruction> obfuscatedInstructions)
|
public void ObfuscateString(MethodDef method, bool needCacheValue, string value, List<Instruction> obfuscatedInstructions)
|
||||||
{
|
{
|
||||||
EncryptionScopeInfo encryptionScope = _moduleEntityManager.EncryptionScopeProvider.GetScope(method.Module);
|
|
||||||
IRandom random = CreateRandomForValue(encryptionScope, value.GetHashCode());
|
|
||||||
ConstFieldAllocator constFieldAllocator = _moduleEntityManager.GetEntity<ConstFieldAllocator>(method.Module);
|
|
||||||
RvaDataAllocator rvaDataAllocator = _moduleEntityManager.GetEntity<RvaDataAllocator>(method.Module);
|
|
||||||
DefaultMetadataImporter importer = GetModuleMetadataImporter(method);
|
|
||||||
|
|
||||||
if (needCacheValue)
|
if (needCacheValue)
|
||||||
{
|
{
|
||||||
FieldDef cacheField = constFieldAllocator.Allocate(value);
|
FieldDef cacheField = _constFieldAllocator.Allocate(method.Module, value);
|
||||||
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Ldsfld, cacheField));
|
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Ldsfld, cacheField));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EncryptionScopeInfo encryptionScope = _encryptionScopeProvider.GetScope(method.Module);
|
||||||
|
IRandom random = CreateRandomForValue(encryptionScope, value.GetHashCode());
|
||||||
int ops = GenerateEncryptionOperations(encryptionScope, random);
|
int ops = GenerateEncryptionOperations(encryptionScope, random);
|
||||||
int salt = GenerateSalt(random);
|
int salt = GenerateSalt(random);
|
||||||
int stringByteLength = Encoding.UTF8.GetByteCount(value);
|
int stringByteLength = Encoding.UTF8.GetByteCount(value);
|
||||||
byte[] encryptedValue = encryptionScope.encryptor.Encrypt(value, ops, salt);
|
byte[] encryptedValue = encryptionScope.encryptor.Encrypt(value, ops, salt);
|
||||||
Assert.AreEqual(stringByteLength, encryptedValue.Length);
|
Assert.AreEqual(stringByteLength, encryptedValue.Length);
|
||||||
RvaData rvaData = rvaDataAllocator.Allocate(encryptedValue);
|
RvaData rvaData = _rvaDataAllocator.Allocate(method.Module, encryptedValue);
|
||||||
|
|
||||||
|
DefaultMetadataImporter importer = GetModuleMetadataImporter(method);
|
||||||
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Ldsfld, rvaData.field));
|
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Ldsfld, rvaData.field));
|
||||||
obfuscatedInstructions.Add(Instruction.CreateLdcI4(rvaData.offset));
|
obfuscatedInstructions.Add(Instruction.CreateLdcI4(rvaData.offset));
|
||||||
// should use stringByteLength, can't use rvaData.size, because rvaData.size is align to 4, it's not the actual length.
|
// should use stringByteLength, can't use rvaData.size, because rvaData.size is align to 4, it's not the actual length.
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet;
|
using dnlib.DotNet;
|
||||||
using dnlib.DotNet.Emit;
|
using dnlib.DotNet.Emit;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet;
|
using dnlib.DotNet;
|
||||||
|
|
||||||
namespace Obfuz.ObfusPasses.ConstEncrypt
|
namespace Obfuz.ObfusPasses.ConstEncrypt
|
||||||
|
|
|
||||||
|
|
@ -1,27 +1,6 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet;
|
using dnlib.DotNet;
|
||||||
using Obfuz.Conf;
|
using Obfuz.Conf;
|
||||||
using Obfuz.Settings;
|
using Obfuz.Settings;
|
||||||
using Obfuz.Utils;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
|
|
@ -118,12 +97,17 @@ namespace Obfuz.ObfusPasses.ControlFlowObfus
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ObfuscationLevel ParseObfuscationLevel(string str)
|
||||||
|
{
|
||||||
|
return (ObfuscationLevel)Enum.Parse(typeof(ObfuscationLevel), str);
|
||||||
|
}
|
||||||
|
|
||||||
private ObfuscationRule ParseObfuscationRule(string configFile, XmlElement ele)
|
private ObfuscationRule ParseObfuscationRule(string configFile, XmlElement ele)
|
||||||
{
|
{
|
||||||
var rule = new ObfuscationRule();
|
var rule = new ObfuscationRule();
|
||||||
if (ele.HasAttribute("obfuscationLevel"))
|
if (ele.HasAttribute("obfuscationLevel"))
|
||||||
{
|
{
|
||||||
rule.obfuscationLevel = ConfigUtil.ParseObfuscationLevel(ele.GetAttribute("obfuscationLevel"));
|
rule.obfuscationLevel = ParseObfuscationLevel(ele.GetAttribute("obfuscationLevel"));
|
||||||
}
|
}
|
||||||
return rule;
|
return rule;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet;
|
using dnlib.DotNet;
|
||||||
using Obfuz.Data;
|
using Obfuz.Data;
|
||||||
using Obfuz.Emit;
|
using Obfuz.Emit;
|
||||||
|
|
@ -33,7 +13,7 @@ namespace Obfuz.ObfusPasses.ControlFlowObfus
|
||||||
public IRandom localRandom;
|
public IRandom localRandom;
|
||||||
public EncryptionScopeInfo encryptionScope;
|
public EncryptionScopeInfo encryptionScope;
|
||||||
public DefaultMetadataImporter importer;
|
public DefaultMetadataImporter importer;
|
||||||
public ConstFieldAllocator constFieldAllocator;
|
public ModuleConstFieldAllocator constFieldAllocator;
|
||||||
public int minInstructionCountOfBasicBlockToObfuscate;
|
public int minInstructionCountOfBasicBlockToObfuscate;
|
||||||
|
|
||||||
public IRandom CreateRandom()
|
public IRandom CreateRandom()
|
||||||
|
|
@ -80,8 +60,7 @@ namespace Obfuz.ObfusPasses.ControlFlowObfus
|
||||||
//Debug.Log($"Obfuscating method: {method.FullName} with EvalStackObfusPass");
|
//Debug.Log($"Obfuscating method: {method.FullName} with EvalStackObfusPass");
|
||||||
|
|
||||||
ObfuscationPassContext ctx = ObfuscationPassContext.Current;
|
ObfuscationPassContext ctx = ObfuscationPassContext.Current;
|
||||||
GroupByModuleEntityManager moduleEntityManager = ctx.moduleEntityManager;
|
var encryptionScope = ctx.encryptionScopeProvider.GetScope(method.Module);
|
||||||
var encryptionScope = moduleEntityManager.EncryptionScopeProvider.GetScope(method.Module);
|
|
||||||
var ruleData = _obfuscationPolicy.GetObfuscationRuleData(method);
|
var ruleData = _obfuscationPolicy.GetObfuscationRuleData(method);
|
||||||
var localRandom = encryptionScope.localRandomCreator(MethodEqualityComparer.CompareDeclaringTypes.GetHashCode(method));
|
var localRandom = encryptionScope.localRandomCreator(MethodEqualityComparer.CompareDeclaringTypes.GetHashCode(method));
|
||||||
var obfusMethodCtx = new ObfusMethodContext
|
var obfusMethodCtx = new ObfusMethodContext
|
||||||
|
|
@ -89,9 +68,9 @@ namespace Obfuz.ObfusPasses.ControlFlowObfus
|
||||||
method = method,
|
method = method,
|
||||||
localVariableAllocator = new LocalVariableAllocator(method),
|
localVariableAllocator = new LocalVariableAllocator(method),
|
||||||
encryptionScope = encryptionScope,
|
encryptionScope = encryptionScope,
|
||||||
constFieldAllocator = moduleEntityManager.GetEntity<ConstFieldAllocator>(method.Module),
|
constFieldAllocator = ctx.constFieldAllocator.GetModuleAllocator(method.Module),
|
||||||
localRandom = localRandom,
|
localRandom = localRandom,
|
||||||
importer = moduleEntityManager.GetEntity<DefaultMetadataImporter>(method.Module),
|
importer = ctx.moduleEntityManager.GetDefaultModuleMetadataImporter(method.Module, ctx.encryptionScopeProvider),
|
||||||
minInstructionCountOfBasicBlockToObfuscate = _settings.minInstructionCountOfBasicBlockToObfuscate,
|
minInstructionCountOfBasicBlockToObfuscate = _settings.minInstructionCountOfBasicBlockToObfuscate,
|
||||||
};
|
};
|
||||||
_obfuscator.Obfuscate(method, obfusMethodCtx);
|
_obfuscator.Obfuscate(method, obfusMethodCtx);
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,5 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet;
|
using dnlib.DotNet;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Obfuz.ObfusPasses.ControlFlowObfus
|
namespace Obfuz.ObfusPasses.ControlFlowObfus
|
||||||
{
|
{
|
||||||
|
|
@ -30,7 +11,7 @@ namespace Obfuz.ObfusPasses.ControlFlowObfus
|
||||||
var mcfc = new MethodControlFlowCalculator(method, ctx.CreateRandom(), ctx.constFieldAllocator, ctx.minInstructionCountOfBasicBlockToObfuscate);
|
var mcfc = new MethodControlFlowCalculator(method, ctx.CreateRandom(), ctx.constFieldAllocator, ctx.minInstructionCountOfBasicBlockToObfuscate);
|
||||||
if (!mcfc.TryObfus())
|
if (!mcfc.TryObfus())
|
||||||
{
|
{
|
||||||
//Debug.LogWarning($"not obfuscate method: {method.FullName}");
|
Debug.LogWarning($"not obfuscate method: {method.FullName}");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,5 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet;
|
using dnlib.DotNet;
|
||||||
|
using Obfuz.Emit;
|
||||||
|
|
||||||
namespace Obfuz.ObfusPasses.ControlFlowObfus
|
namespace Obfuz.ObfusPasses.ControlFlowObfus
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet;
|
using dnlib.DotNet;
|
||||||
using dnlib.DotNet.Emit;
|
using dnlib.DotNet.Emit;
|
||||||
using Obfuz.Data;
|
using Obfuz.Data;
|
||||||
|
|
@ -26,6 +6,7 @@ using Obfuz.Utils;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Runtime.ConstrainedExecution;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.Assertions;
|
using UnityEngine.Assertions;
|
||||||
|
|
||||||
|
|
@ -54,16 +35,15 @@ namespace Obfuz.ObfusPasses.ControlFlowObfus
|
||||||
|
|
||||||
private TypeSig GetLocalTypeSig(ICorLibTypes corLibTypes, EvalDataTypeWithSig type)
|
private TypeSig GetLocalTypeSig(ICorLibTypes corLibTypes, EvalDataTypeWithSig type)
|
||||||
{
|
{
|
||||||
TypeSig typeSig = type.typeSig;
|
|
||||||
switch (type.type)
|
switch (type.type)
|
||||||
{
|
{
|
||||||
case EvalDataType.Int32: return corLibTypes.Int32;
|
case EvalDataType.Int32: return corLibTypes.Int32;
|
||||||
case EvalDataType.Int64: return corLibTypes.Int64;
|
case EvalDataType.Int64: return corLibTypes.Int64;
|
||||||
case EvalDataType.Float: return corLibTypes.Single;
|
case EvalDataType.Float: return corLibTypes.Single;
|
||||||
case EvalDataType.Double: return corLibTypes.Double;
|
case EvalDataType.Double: return corLibTypes.Double;
|
||||||
case EvalDataType.I: return typeSig ?? corLibTypes.IntPtr;
|
case EvalDataType.I: return corLibTypes.IntPtr;
|
||||||
case EvalDataType.Ref: return typeSig == null || MetaUtil.IsValueType(typeSig) ? corLibTypes.Object : typeSig;
|
case EvalDataType.Ref: Assert.IsNotNull(type.typeSig); return type.typeSig;
|
||||||
case EvalDataType.ValueType: Assert.IsNotNull(typeSig); return typeSig;
|
case EvalDataType.ValueType: Assert.IsNotNull(type.typeSig); return type.typeSig;
|
||||||
case EvalDataType.Token: throw new System.NotSupportedException("Token type is not supported in BasicBlockInputOutputArguments");
|
case EvalDataType.Token: throw new System.NotSupportedException("Token type is not supported in BasicBlockInputOutputArguments");
|
||||||
default: throw new System.NotSupportedException("not supported EvalDataType");
|
default: throw new System.NotSupportedException("not supported EvalDataType");
|
||||||
}
|
}
|
||||||
|
|
@ -175,11 +155,11 @@ namespace Obfuz.ObfusPasses.ControlFlowObfus
|
||||||
|
|
||||||
private readonly MethodDef _method;
|
private readonly MethodDef _method;
|
||||||
private readonly IRandom _random;
|
private readonly IRandom _random;
|
||||||
private readonly ConstFieldAllocator _constFieldAllocator;
|
private readonly ModuleConstFieldAllocator _constFieldAllocator;
|
||||||
private readonly int _minInstructionCountOfBasicBlockToObfuscate;
|
private readonly int _minInstructionCountOfBasicBlockToObfuscate;
|
||||||
private readonly BasicBlockInfo _bbHead;
|
private readonly BasicBlockInfo _bbHead;
|
||||||
|
|
||||||
public MethodControlFlowCalculator(MethodDef method, IRandom random, ConstFieldAllocator constFieldAllocator, int minInstructionCountOfBasicBlockToObfuscate)
|
public MethodControlFlowCalculator(MethodDef method, IRandom random, ModuleConstFieldAllocator constFieldAllocator, int minInstructionCountOfBasicBlockToObfuscate)
|
||||||
{
|
{
|
||||||
_method = method;
|
_method = method;
|
||||||
_random = random;
|
_random = random;
|
||||||
|
|
@ -349,10 +329,9 @@ namespace Obfuz.ObfusPasses.ControlFlowObfus
|
||||||
|
|
||||||
BlockGroup group = to.group;
|
BlockGroup group = to.group;
|
||||||
group.basicBlocks.Insert(group.basicBlocks.IndexOf(to), saveLocalBasicBlock);
|
group.basicBlocks.Insert(group.basicBlocks.IndexOf(to), saveLocalBasicBlock);
|
||||||
group.switchMachineCases.Add(new SwitchMachineCase { index = -1, prepareBlock = saveLocalBasicBlock, targetBlock = to });
|
group.switchMachineCases.Add(new SwitchMachineCase { index = -1, prepareBlock = saveLocalBasicBlock, targetBlock = to});
|
||||||
saveLocalBasicBlock.instructions.Add(Instruction.Create(OpCodes.Ldsfld, (FieldDef)null));
|
saveLocalBasicBlock.instructions.Add(Instruction.Create(OpCodes.Ldsfld, (FieldDef)null));
|
||||||
saveLocalBasicBlock.instructions.Add(Instruction.Create(OpCodes.Stloc, GlobalSwitchIndexLocal));
|
saveLocalBasicBlock.instructions.Add(Instruction.Create(OpCodes.Br, group.switchMachineInst));
|
||||||
saveLocalBasicBlock.instructions.Add(Instruction.Create(OpCodes.Br, group.switchMachineEntryInst));
|
|
||||||
|
|
||||||
|
|
||||||
return saveLocalBasicBlock;
|
return saveLocalBasicBlock;
|
||||||
|
|
@ -383,46 +362,19 @@ namespace Obfuz.ObfusPasses.ControlFlowObfus
|
||||||
InsertSwitchMachineBasicBlockForGroup(rootGroup, inst2bb);
|
InsertSwitchMachineBasicBlockForGroup(rootGroup, inst2bb);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ShuffleBasicBlocks0(List<BasicBlockInfo> bbs)
|
//private void ShuffleBasicBlocks0(List<BasicBlockInfo> bbs)
|
||||||
{
|
|
||||||
if (bbs.Count <= 2)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var subBlocksExcludeFirstLast = bbs.GetRange(1, bbs.Count - 2);
|
|
||||||
|
|
||||||
var blocksInputArgsCountZero = new List<BasicBlockInfo>();
|
|
||||||
var blocksInputArgsCountNonZero = new List<BasicBlockInfo>();
|
|
||||||
foreach (var bb in subBlocksExcludeFirstLast)
|
|
||||||
{
|
|
||||||
if (bb.inputArgs.locals.Count == 0)
|
|
||||||
{
|
|
||||||
blocksInputArgsCountZero.Add(bb);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
blocksInputArgsCountNonZero.Add(bb);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
RandomUtil.ShuffleList(blocksInputArgsCountZero, _random);
|
|
||||||
|
|
||||||
int index = 1;
|
|
||||||
foreach (var bb in blocksInputArgsCountZero)
|
|
||||||
{
|
|
||||||
bbs[index++] = bb;
|
|
||||||
}
|
|
||||||
foreach (var bb in blocksInputArgsCountNonZero)
|
|
||||||
{
|
|
||||||
bbs[index++] = bb;
|
|
||||||
}
|
|
||||||
Assert.AreEqual(bbs.Count - 1, index, "Shuffled basic blocks count should be the same as original count minus first and last blocks");
|
|
||||||
|
|
||||||
//var firstSection = new List<BasicBlockInfo>() { bbs[0] };
|
|
||||||
//var sectionsExcludeFirstLast = new List<List<BasicBlockInfo>>();
|
|
||||||
//List<BasicBlockInfo> currentSection = firstSection;
|
|
||||||
//for (int i = 1; i < n; i++)
|
|
||||||
//{
|
//{
|
||||||
|
// int n = bbs.Count;
|
||||||
|
// if (n <= 1)
|
||||||
|
// {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// var firstSection = new List<BasicBlockInfo>() { bbs[0] };
|
||||||
|
// var sectionsExcludeFirstLast = new List<List<BasicBlockInfo>>();
|
||||||
|
// List<BasicBlockInfo> currentSection = firstSection;
|
||||||
|
// for (int i = 1; i < n; i++)
|
||||||
|
// {
|
||||||
// BasicBlockInfo cur = bbs[i];
|
// BasicBlockInfo cur = bbs[i];
|
||||||
// if (cur.inputArgs.locals.Count == 0)
|
// if (cur.inputArgs.locals.Count == 0)
|
||||||
// {
|
// {
|
||||||
|
|
@ -433,61 +385,46 @@ namespace Obfuz.ObfusPasses.ControlFlowObfus
|
||||||
// {
|
// {
|
||||||
// currentSection.Add(cur);
|
// currentSection.Add(cur);
|
||||||
// }
|
// }
|
||||||
//}
|
// }
|
||||||
//if (sectionsExcludeFirstLast.Count <= 1)
|
// if (sectionsExcludeFirstLast.Count <= 1)
|
||||||
//{
|
// {
|
||||||
// return;
|
// return;
|
||||||
|
// }
|
||||||
|
// var lastSection = sectionsExcludeFirstLast.Last();
|
||||||
|
// sectionsExcludeFirstLast.RemoveAt(sectionsExcludeFirstLast.Count - 1);
|
||||||
|
|
||||||
|
|
||||||
|
// RandomUtil.ShuffleList(sectionsExcludeFirstLast, _random);
|
||||||
|
|
||||||
|
// bbs.Clear();
|
||||||
|
// bbs.AddRange(firstSection);
|
||||||
|
// bbs.AddRange(sectionsExcludeFirstLast.SelectMany(section => section));
|
||||||
|
// bbs.AddRange(lastSection);
|
||||||
|
// Assert.AreEqual(n, bbs.Count, "Shuffled basic blocks count should be the same as original count");
|
||||||
//}
|
//}
|
||||||
//var lastSection = sectionsExcludeFirstLast.Last();
|
|
||||||
//sectionsExcludeFirstLast.RemoveAt(sectionsExcludeFirstLast.Count - 1);
|
|
||||||
|
|
||||||
|
|
||||||
//RandomUtil.ShuffleList(sectionsExcludeFirstLast, _random);
|
|
||||||
|
|
||||||
//bbs.Clear();
|
|
||||||
//bbs.AddRange(firstSection);
|
|
||||||
//bbs.AddRange(sectionsExcludeFirstLast.SelectMany(section => section));
|
|
||||||
//bbs.AddRange(lastSection);
|
|
||||||
//Assert.AreEqual(n, bbs.Count, "Shuffled basic blocks count should be the same as original count");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ShuffleBasicBlocks(List<BasicBlockInfo> bbs)
|
private void ShuffleBasicBlocks(List<BasicBlockInfo> bbs)
|
||||||
{
|
{
|
||||||
// TODO
|
// TODO
|
||||||
|
|
||||||
int n = bbs.Count;
|
//int n = bbs.Count;
|
||||||
BasicBlockInfo groupPrev = bbs[0].prev;
|
//BasicBlockInfo groupPrev = bbs[0].prev;
|
||||||
BasicBlockInfo groupNext = bbs[n - 1].next;
|
//BasicBlockInfo groupNext = bbs[n - 1].next;
|
||||||
//RandomUtil.ShuffleList(bbs, _random);
|
////RandomUtil.ShuffleList(bbs, _random);
|
||||||
ShuffleBasicBlocks0(bbs);
|
//ShuffleBasicBlocks0(bbs);
|
||||||
BasicBlockInfo prev = groupPrev;
|
//BasicBlockInfo prev = groupPrev;
|
||||||
for (int i = 0; i < n; i++)
|
//for (int i = 0; i < n; i++)
|
||||||
{
|
//{
|
||||||
BasicBlockInfo cur = bbs[i];
|
// BasicBlockInfo cur = bbs[i];
|
||||||
cur.prev = prev;
|
// cur.prev = prev;
|
||||||
prev.next = cur;
|
// prev.next = cur;
|
||||||
prev = cur;
|
// prev = cur;
|
||||||
}
|
//}
|
||||||
prev.next = groupNext;
|
//prev.next = groupNext;
|
||||||
if (groupNext != null)
|
//if (groupNext != null)
|
||||||
{
|
//{
|
||||||
groupNext.prev = prev;
|
// groupNext.prev = prev;
|
||||||
}
|
//}
|
||||||
}
|
|
||||||
|
|
||||||
private Local _globalSwitchIndexLocal;
|
|
||||||
|
|
||||||
Local GlobalSwitchIndexLocal
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_globalSwitchIndexLocal == null)
|
|
||||||
{
|
|
||||||
_globalSwitchIndexLocal = new Local(_method.Module.CorLibTypes.Int32);
|
|
||||||
_method.Body.Variables.Add(_globalSwitchIndexLocal);
|
|
||||||
}
|
|
||||||
return _globalSwitchIndexLocal;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InsertSwitchMachineBasicBlockForGroup(BlockGroup group, Dictionary<Instruction, BasicBlockInfo> inst2bb)
|
private void InsertSwitchMachineBasicBlockForGroup(BlockGroup group, Dictionary<Instruction, BasicBlockInfo> inst2bb)
|
||||||
|
|
@ -513,8 +450,6 @@ namespace Obfuz.ObfusPasses.ControlFlowObfus
|
||||||
var instructions = new List<Instruction>()
|
var instructions = new List<Instruction>()
|
||||||
{
|
{
|
||||||
Instruction.Create(OpCodes.Ldsfld, (FieldDef)null),
|
Instruction.Create(OpCodes.Ldsfld, (FieldDef)null),
|
||||||
Instruction.Create(OpCodes.Stloc, GlobalSwitchIndexLocal),
|
|
||||||
group.switchMachineEntryInst,
|
|
||||||
group.switchMachineInst,
|
group.switchMachineInst,
|
||||||
Instruction.Create(OpCodes.Br, firstCase.targetBlock.FirstInstruction),
|
Instruction.Create(OpCodes.Br, firstCase.targetBlock.FirstInstruction),
|
||||||
};
|
};
|
||||||
|
|
@ -546,7 +481,7 @@ namespace Obfuz.ObfusPasses.ControlFlowObfus
|
||||||
switchMachineCase.index = i;
|
switchMachineCase.index = i;
|
||||||
List<Instruction> prepareBlockInstructions = switchMachineCase.prepareBlock.instructions;
|
List<Instruction> prepareBlockInstructions = switchMachineCase.prepareBlock.instructions;
|
||||||
|
|
||||||
Instruction setBranchIndexInst = prepareBlockInstructions[prepareBlockInstructions.Count - 3];
|
Instruction setBranchIndexInst = prepareBlockInstructions[prepareBlockInstructions.Count - 2];
|
||||||
Assert.AreEqual(setBranchIndexInst.OpCode, OpCodes.Ldsfld, "first instruction of prepareBlock should be Ldsfld");
|
Assert.AreEqual(setBranchIndexInst.OpCode, OpCodes.Ldsfld, "first instruction of prepareBlock should be Ldsfld");
|
||||||
//setBranchIndexInst.Operand = i;
|
//setBranchIndexInst.Operand = i;
|
||||||
var indexField = _constFieldAllocator.Allocate(i);
|
var indexField = _constFieldAllocator.Allocate(i);
|
||||||
|
|
@ -555,10 +490,9 @@ namespace Obfuz.ObfusPasses.ControlFlowObfus
|
||||||
}
|
}
|
||||||
|
|
||||||
// after shuffle
|
// after shuffle
|
||||||
//Assert.IsTrue(instructions.Count == 4 || instructions.Count == 5, "Switch machine basic block should contain 4 or 5 instructions");
|
Assert.IsTrue(instructions.Count == 3 || instructions.Count == 4, "Switch machine basic block should contain 3 or 4 instructions");
|
||||||
Instruction loadFirstIndex = instructions[instructions.Count - 5];
|
Assert.AreEqual(Code.Ldsfld, instructions[instructions.Count - 3].OpCode.Code, "First instruction should be Ldsfld");
|
||||||
Assert.AreEqual(Code.Ldsfld, loadFirstIndex.OpCode.Code, "First instruction should be Ldsfld");
|
instructions[instructions.Count - 3].Operand = _constFieldAllocator.Allocate(firstCase.index);
|
||||||
loadFirstIndex.Operand = _constFieldAllocator.Allocate(firstCase.index);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -620,7 +554,6 @@ namespace Obfuz.ObfusPasses.ControlFlowObfus
|
||||||
|
|
||||||
public List<BasicBlockInfo> basicBlocks;
|
public List<BasicBlockInfo> basicBlocks;
|
||||||
|
|
||||||
public Instruction switchMachineEntryInst;
|
|
||||||
public Instruction switchMachineInst;
|
public Instruction switchMachineInst;
|
||||||
public List<SwitchMachineCase> switchMachineCases;
|
public List<SwitchMachineCase> switchMachineCases;
|
||||||
|
|
||||||
|
|
@ -731,7 +664,7 @@ namespace Obfuz.ObfusPasses.ControlFlowObfus
|
||||||
this.subGroups = finalGroupList;
|
this.subGroups = finalGroupList;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ComputeBasicBlocks(Dictionary<Instruction, BasicBlockInfo> inst2bb, Func<Local> switchIndexLocalGetter)
|
public void ComputeBasicBlocks(Dictionary<Instruction, BasicBlockInfo> inst2bb)
|
||||||
{
|
{
|
||||||
if (subGroups == null || subGroups.Count == 0)
|
if (subGroups == null || subGroups.Count == 0)
|
||||||
{
|
{
|
||||||
|
|
@ -752,14 +685,13 @@ namespace Obfuz.ObfusPasses.ControlFlowObfus
|
||||||
basicBlocks.Add(block);
|
basicBlocks.Add(block);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
switchMachineEntryInst = Instruction.Create(OpCodes.Ldloc, switchIndexLocalGetter());
|
|
||||||
switchMachineInst = Instruction.Create(OpCodes.Switch, new List<Instruction>());
|
switchMachineInst = Instruction.Create(OpCodes.Switch, new List<Instruction>());
|
||||||
switchMachineCases = new List<SwitchMachineCase>();
|
switchMachineCases = new List<SwitchMachineCase>();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
foreach (var subGroup in subGroups)
|
foreach (var subGroup in subGroups)
|
||||||
{
|
{
|
||||||
subGroup.ComputeBasicBlocks(inst2bb, switchIndexLocalGetter);
|
subGroup.ComputeBasicBlocks(inst2bb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -794,13 +726,13 @@ namespace Obfuz.ObfusPasses.ControlFlowObfus
|
||||||
private class ExceptionHandlerWithFilterGroup : BlockGroup
|
private class ExceptionHandlerWithFilterGroup : BlockGroup
|
||||||
{
|
{
|
||||||
public readonly ExceptionHandler exceptionHandler;
|
public readonly ExceptionHandler exceptionHandler;
|
||||||
public readonly ExceptionFilterGroup filterGroup;
|
//public readonly ExceptionFilterGroup filterGroup;
|
||||||
public readonly ExceptionHandlerGroup handlerGroup;
|
//public readonly ExceptionHandlerGroup handlerGroup;
|
||||||
public ExceptionHandlerWithFilterGroup(ExceptionHandler exceptionHandler, ExceptionFilterGroup filterGroup, ExceptionHandlerGroup handlerGroup, List<Instruction> instructions, Dictionary<Instruction, BlockGroup> inst2group) : base(instructions, inst2group)
|
public ExceptionHandlerWithFilterGroup(ExceptionHandler exceptionHandler, List<Instruction> filterInstructions, List<Instruction> handlerInstructions, List<Instruction> allInstructions, Dictionary<Instruction, BlockGroup> inst2group) : base(allInstructions, inst2group)
|
||||||
{
|
{
|
||||||
this.exceptionHandler = exceptionHandler;
|
this.exceptionHandler = exceptionHandler;
|
||||||
this.filterGroup = filterGroup;
|
var filterGroup = new ExceptionFilterGroup(exceptionHandler, filterInstructions, inst2group);
|
||||||
this.handlerGroup = handlerGroup;
|
var handlerGroup = new ExceptionHandlerGroup(exceptionHandler, handlerInstructions, inst2group);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -833,7 +765,7 @@ namespace Obfuz.ObfusPasses.ControlFlowObfus
|
||||||
var tryBlocks = new List<TryBlockInfo>();
|
var tryBlocks = new List<TryBlockInfo>();
|
||||||
foreach (var ex in _method.Body.ExceptionHandlers)
|
foreach (var ex in _method.Body.ExceptionHandlers)
|
||||||
{
|
{
|
||||||
TryBlockInfo tryBlock = tryBlocks.Find(block => block.tryStart == ex.TryStart && block.tryEnd == ex.TryEnd);
|
TryBlockInfo tryBlock = tryBlocks.Find(tryBlocks => tryBlocks.tryStart == ex.TryStart && tryBlocks.tryEnd == ex.TryEnd);
|
||||||
if (tryBlock == null)
|
if (tryBlock == null)
|
||||||
{
|
{
|
||||||
int startIndex = inst2Index[ex.TryStart];
|
int startIndex = inst2Index[ex.TryStart];
|
||||||
|
|
@ -853,10 +785,9 @@ namespace Obfuz.ObfusPasses.ControlFlowObfus
|
||||||
int filterEndIndex = ex.HandlerStart != null ? inst2Index[ex.HandlerStart] : inst2Index.Count;
|
int filterEndIndex = ex.HandlerStart != null ? inst2Index[ex.HandlerStart] : inst2Index.Count;
|
||||||
int handlerStartIndex = filterEndIndex;
|
int handlerStartIndex = filterEndIndex;
|
||||||
int handlerEndIndex = ex.HandlerEnd != null ? inst2Index[ex.HandlerEnd] : inst2Index.Count;
|
int handlerEndIndex = ex.HandlerEnd != null ? inst2Index[ex.HandlerEnd] : inst2Index.Count;
|
||||||
|
var filterHandlerGroup = new ExceptionHandlerWithFilterGroup(ex,
|
||||||
var filterGroup = new ExceptionFilterGroup(ex, instructions.GetRange(filterStartIndex, filterEndIndex - filterStartIndex), inst2blockGroup);
|
instructions.GetRange(filterStartIndex, filterEndIndex - filterStartIndex),
|
||||||
var handlerGroup = new ExceptionHandlerGroup(ex, instructions.GetRange(handlerStartIndex, handlerEndIndex - handlerStartIndex), inst2blockGroup);
|
instructions.GetRange(handlerStartIndex, handlerEndIndex - handlerStartIndex),
|
||||||
var filterHandlerGroup = new ExceptionHandlerWithFilterGroup(ex, filterGroup, handlerGroup,
|
|
||||||
instructions.GetRange(filterStartIndex, handlerEndIndex - filterStartIndex), inst2blockGroup);
|
instructions.GetRange(filterStartIndex, handlerEndIndex - filterStartIndex), inst2blockGroup);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -869,7 +800,7 @@ namespace Obfuz.ObfusPasses.ControlFlowObfus
|
||||||
var rootGroup = new BlockGroup(new List<Instruction>(instructions), inst2blockGroup);
|
var rootGroup = new BlockGroup(new List<Instruction>(instructions), inst2blockGroup);
|
||||||
rootGroup.SplitInstructionsNotInAnySubGroupsToIndividualGroups(inst2blockGroup);
|
rootGroup.SplitInstructionsNotInAnySubGroupsToIndividualGroups(inst2blockGroup);
|
||||||
|
|
||||||
rootGroup.ComputeBasicBlocks(BuildInstructionToBasicBlockInfoDic(), () => GlobalSwitchIndexLocal);
|
rootGroup.ComputeBasicBlocks(BuildInstructionToBasicBlockInfoDic());
|
||||||
return rootGroup;
|
return rootGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -939,10 +870,6 @@ namespace Obfuz.ObfusPasses.ControlFlowObfus
|
||||||
//{
|
//{
|
||||||
// return false;
|
// return false;
|
||||||
//}
|
//}
|
||||||
if (_method.HasGenericParameters || _method.DeclaringType.HasGenericParameters)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
var evc = new EvalStackCalculator(_method);
|
var evc = new EvalStackCalculator(_method);
|
||||||
BuildBasicBlockLink(evc);
|
BuildBasicBlockLink(evc);
|
||||||
if (!CheckNotContainsNotSupportedEvalStackData())
|
if (!CheckNotContainsNotSupportedEvalStackData())
|
||||||
|
|
|
||||||
|
|
@ -1,27 +1,6 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet;
|
using dnlib.DotNet;
|
||||||
using Obfuz.Conf;
|
using Obfuz.Conf;
|
||||||
using Obfuz.Settings;
|
using Obfuz.Settings;
|
||||||
using Obfuz.Utils;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
|
|
@ -84,7 +63,7 @@ namespace Obfuz.ObfusPasses.EvalStackObfus
|
||||||
private static readonly ObfuscationRule s_default = new ObfuscationRule()
|
private static readonly ObfuscationRule s_default = new ObfuscationRule()
|
||||||
{
|
{
|
||||||
obfuscationLevel = ObfuscationLevel.Basic,
|
obfuscationLevel = ObfuscationLevel.Basic,
|
||||||
obfuscationPercentage = 0.05f,
|
obfuscationPercentage = 0.5f,
|
||||||
};
|
};
|
||||||
|
|
||||||
private ObfuscationRule _global;
|
private ObfuscationRule _global;
|
||||||
|
|
@ -112,10 +91,6 @@ namespace Obfuz.ObfusPasses.EvalStackObfus
|
||||||
{
|
{
|
||||||
_global.InheritParent(s_default);
|
_global.InheritParent(s_default);
|
||||||
}
|
}
|
||||||
if (_global.obfuscationPercentage.Value > 0.1f)
|
|
||||||
{
|
|
||||||
UnityEngine.Debug.LogWarning($"EvalStackObfus significantly increases the size of the obfuscated hot-update DLL. It is recommended to keep the obfuscationPercentage ≤ 0.1 (currently set to {_global.obfuscationPercentage.Value}).");
|
|
||||||
}
|
|
||||||
_xmlParser.InheritParentRules(_global);
|
_xmlParser.InheritParentRules(_global);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -128,12 +103,17 @@ namespace Obfuz.ObfusPasses.EvalStackObfus
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ObfuscationLevel ParseObfuscationLevel(string str)
|
||||||
|
{
|
||||||
|
return (ObfuscationLevel)Enum.Parse(typeof(ObfuscationLevel), str);
|
||||||
|
}
|
||||||
|
|
||||||
private ObfuscationRule ParseObfuscationRule(string configFile, XmlElement ele)
|
private ObfuscationRule ParseObfuscationRule(string configFile, XmlElement ele)
|
||||||
{
|
{
|
||||||
var rule = new ObfuscationRule();
|
var rule = new ObfuscationRule();
|
||||||
if (ele.HasAttribute("obfuscationLevel"))
|
if (ele.HasAttribute("obfuscationLevel"))
|
||||||
{
|
{
|
||||||
rule.obfuscationLevel = ConfigUtil.ParseObfuscationLevel(ele.GetAttribute("obfuscationLevel"));
|
rule.obfuscationLevel = ParseObfuscationLevel(ele.GetAttribute("obfuscationLevel"));
|
||||||
}
|
}
|
||||||
if (ele.HasAttribute("obfuscationPercentage"))
|
if (ele.HasAttribute("obfuscationPercentage"))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet.Emit;
|
using dnlib.DotNet.Emit;
|
||||||
using Obfuz.Utils;
|
using Obfuz.Utils;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet;
|
using dnlib.DotNet;
|
||||||
using dnlib.DotNet.Emit;
|
using dnlib.DotNet.Emit;
|
||||||
using Obfuz.Data;
|
using Obfuz.Data;
|
||||||
|
|
@ -36,7 +16,7 @@ namespace Obfuz.ObfusPasses.EvalStackObfus
|
||||||
public IRandom localRandom;
|
public IRandom localRandom;
|
||||||
public EncryptionScopeInfo encryptionScope;
|
public EncryptionScopeInfo encryptionScope;
|
||||||
public DefaultMetadataImporter importer;
|
public DefaultMetadataImporter importer;
|
||||||
public ConstFieldAllocator constFieldAllocator;
|
public ModuleConstFieldAllocator constFieldAllocator;
|
||||||
public float obfuscationPercentage;
|
public float obfuscationPercentage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -94,9 +74,7 @@ namespace Obfuz.ObfusPasses.EvalStackObfus
|
||||||
|
|
||||||
ObfuscationPassContext ctx = ObfuscationPassContext.Current;
|
ObfuscationPassContext ctx = ObfuscationPassContext.Current;
|
||||||
var calc = new EvalStackCalculator(method);
|
var calc = new EvalStackCalculator(method);
|
||||||
|
var encryptionScope = ctx.encryptionScopeProvider.GetScope(method.Module);
|
||||||
GroupByModuleEntityManager moduleEntityManager = ctx.moduleEntityManager;
|
|
||||||
var encryptionScope = moduleEntityManager.EncryptionScopeProvider.GetScope(method.Module);
|
|
||||||
var ruleData = _obfuscationPolicy.GetObfuscationRuleData(method);
|
var ruleData = _obfuscationPolicy.GetObfuscationRuleData(method);
|
||||||
var localRandom = encryptionScope.localRandomCreator(MethodEqualityComparer.CompareDeclaringTypes.GetHashCode(method));
|
var localRandom = encryptionScope.localRandomCreator(MethodEqualityComparer.CompareDeclaringTypes.GetHashCode(method));
|
||||||
var obfusMethodCtx = new ObfusMethodContext
|
var obfusMethodCtx = new ObfusMethodContext
|
||||||
|
|
@ -105,9 +83,9 @@ namespace Obfuz.ObfusPasses.EvalStackObfus
|
||||||
evalStackCalculator = calc,
|
evalStackCalculator = calc,
|
||||||
localVariableAllocator = new LocalVariableAllocator(method),
|
localVariableAllocator = new LocalVariableAllocator(method),
|
||||||
encryptionScope = encryptionScope,
|
encryptionScope = encryptionScope,
|
||||||
constFieldAllocator = moduleEntityManager.GetEntity<ConstFieldAllocator>(method.Module),
|
constFieldAllocator = ctx.constFieldAllocator.GetModuleAllocator(method.Module),
|
||||||
localRandom = localRandom,
|
localRandom = localRandom,
|
||||||
importer = moduleEntityManager.GetEntity<DefaultMetadataImporter>(method.Module),
|
importer = ctx.moduleEntityManager.GetDefaultModuleMetadataImporter(method.Module, ctx.encryptionScopeProvider),
|
||||||
obfuscationPercentage = ruleData.obfuscationPercentage,
|
obfuscationPercentage = ruleData.obfuscationPercentage,
|
||||||
};
|
};
|
||||||
for (int i = 0; i < instructions.Count; i++)
|
for (int i = 0; i < instructions.Count; i++)
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet.Emit;
|
using dnlib.DotNet.Emit;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,27 +1,6 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet;
|
using dnlib.DotNet;
|
||||||
using Obfuz.Conf;
|
using Obfuz.Conf;
|
||||||
using Obfuz.Settings;
|
using Obfuz.Settings;
|
||||||
using Obfuz.Utils;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
|
|
@ -124,12 +103,17 @@ namespace Obfuz.ObfusPasses.ExprObfus
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ObfuscationLevel ParseObfuscationLevel(string str)
|
||||||
|
{
|
||||||
|
return (ObfuscationLevel)Enum.Parse(typeof(ObfuscationLevel), str);
|
||||||
|
}
|
||||||
|
|
||||||
private ObfuscationRule ParseObfuscationRule(string configFile, XmlElement ele)
|
private ObfuscationRule ParseObfuscationRule(string configFile, XmlElement ele)
|
||||||
{
|
{
|
||||||
var rule = new ObfuscationRule();
|
var rule = new ObfuscationRule();
|
||||||
if (ele.HasAttribute("obfuscationLevel"))
|
if (ele.HasAttribute("obfuscationLevel"))
|
||||||
{
|
{
|
||||||
rule.obfuscationLevel = ConfigUtil.ParseObfuscationLevel(ele.GetAttribute("obfuscationLevel"));
|
rule.obfuscationLevel = ParseObfuscationLevel(ele.GetAttribute("obfuscationLevel"));
|
||||||
}
|
}
|
||||||
if (ele.HasAttribute("obfuscationPercentage"))
|
if (ele.HasAttribute("obfuscationPercentage"))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet;
|
using dnlib.DotNet;
|
||||||
using dnlib.DotNet.Emit;
|
using dnlib.DotNet.Emit;
|
||||||
using Obfuz.Data;
|
using Obfuz.Data;
|
||||||
|
|
@ -37,7 +17,7 @@ namespace Obfuz.ObfusPasses.ExprObfus
|
||||||
public IRandom localRandom;
|
public IRandom localRandom;
|
||||||
public EncryptionScopeInfo encryptionScope;
|
public EncryptionScopeInfo encryptionScope;
|
||||||
public DefaultMetadataImporter importer;
|
public DefaultMetadataImporter importer;
|
||||||
public ConstFieldAllocator constFieldAllocator;
|
public ModuleConstFieldAllocator constFieldAllocator;
|
||||||
public float obfuscationPercentage;
|
public float obfuscationPercentage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -140,9 +120,7 @@ namespace Obfuz.ObfusPasses.ExprObfus
|
||||||
|
|
||||||
ObfuscationPassContext ctx = ObfuscationPassContext.Current;
|
ObfuscationPassContext ctx = ObfuscationPassContext.Current;
|
||||||
var calc = new EvalStackCalculator(method);
|
var calc = new EvalStackCalculator(method);
|
||||||
|
var encryptionScope = ctx.encryptionScopeProvider.GetScope(method.Module);
|
||||||
GroupByModuleEntityManager moduleEntityManager = ctx.moduleEntityManager;
|
|
||||||
var encryptionScope = moduleEntityManager.EncryptionScopeProvider.GetScope(method.Module);
|
|
||||||
var ruleData = _obfuscationPolicy.GetObfuscationRuleData(method);
|
var ruleData = _obfuscationPolicy.GetObfuscationRuleData(method);
|
||||||
var obfuscator = GetObfuscator(ruleData.obfuscationLevel);
|
var obfuscator = GetObfuscator(ruleData.obfuscationLevel);
|
||||||
var obfusMethodCtx = new ObfusMethodContext
|
var obfusMethodCtx = new ObfusMethodContext
|
||||||
|
|
@ -151,9 +129,9 @@ namespace Obfuz.ObfusPasses.ExprObfus
|
||||||
evalStackCalculator = calc,
|
evalStackCalculator = calc,
|
||||||
localVariableAllocator = new LocalVariableAllocator(method),
|
localVariableAllocator = new LocalVariableAllocator(method),
|
||||||
encryptionScope = encryptionScope,
|
encryptionScope = encryptionScope,
|
||||||
constFieldAllocator = moduleEntityManager.GetEntity<ConstFieldAllocator>(method.Module),
|
constFieldAllocator = ctx.constFieldAllocator.GetModuleAllocator(method.Module),
|
||||||
localRandom = encryptionScope.localRandomCreator(MethodEqualityComparer.CompareDeclaringTypes.GetHashCode(method)),
|
localRandom = encryptionScope.localRandomCreator(MethodEqualityComparer.CompareDeclaringTypes.GetHashCode(method)),
|
||||||
importer = moduleEntityManager.GetEntity<DefaultMetadataImporter>(method.Module),
|
importer = ctx.moduleEntityManager.GetDefaultModuleMetadataImporter(method.Module, ctx.encryptionScopeProvider),
|
||||||
obfuscationPercentage = ruleData.obfuscationPercentage,
|
obfuscationPercentage = ruleData.obfuscationPercentage,
|
||||||
};
|
};
|
||||||
for (int i = 0; i < instructions.Count; i++)
|
for (int i = 0; i < instructions.Count; i++)
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet.Emit;
|
using dnlib.DotNet.Emit;
|
||||||
using Obfuz.Emit;
|
using Obfuz.Emit;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet.Emit;
|
using dnlib.DotNet.Emit;
|
||||||
using Obfuz.Data;
|
using Obfuz.Data;
|
||||||
using Obfuz.Emit;
|
using Obfuz.Emit;
|
||||||
|
|
@ -31,7 +11,7 @@ namespace Obfuz.ObfusPasses.ExprObfus.Obfuscators
|
||||||
protected bool GenerateIdentityTransformForArgument(Instruction inst, EvalDataType op, List<Instruction> outputInsts, ObfusMethodContext ctx)
|
protected bool GenerateIdentityTransformForArgument(Instruction inst, EvalDataType op, List<Instruction> outputInsts, ObfusMethodContext ctx)
|
||||||
{
|
{
|
||||||
IRandom random = ctx.localRandom;
|
IRandom random = ctx.localRandom;
|
||||||
ConstFieldAllocator constFieldAllocator = ctx.constFieldAllocator;
|
ModuleConstFieldAllocator constFieldAllocator = ctx.constFieldAllocator;
|
||||||
switch (op)
|
switch (op)
|
||||||
{
|
{
|
||||||
case EvalDataType.Int32:
|
case EvalDataType.Int32:
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet;
|
using dnlib.DotNet;
|
||||||
using dnlib.DotNet.Emit;
|
using dnlib.DotNet.Emit;
|
||||||
using Obfuz.Emit;
|
using Obfuz.Emit;
|
||||||
|
|
@ -29,35 +9,7 @@ namespace Obfuz.ObfusPasses.ExprObfus.Obfuscators
|
||||||
|
|
||||||
class BasicObfuscator : ObfuscatorBase
|
class BasicObfuscator : ObfuscatorBase
|
||||||
{
|
{
|
||||||
private IMethod GetUnaryOpMethod(DefaultMetadataImporter importer, Code code, EvalDataType op1)
|
private IMethod GetMethod(DefaultMetadataImporter importer, Code code, EvalDataType op1)
|
||||||
{
|
|
||||||
switch (code)
|
|
||||||
{
|
|
||||||
case Code.Neg:
|
|
||||||
{
|
|
||||||
switch (op1)
|
|
||||||
{
|
|
||||||
case EvalDataType.Int32: return importer.NegInt;
|
|
||||||
case EvalDataType.Int64: return importer.NegLong;
|
|
||||||
case EvalDataType.Float: return importer.NegFloat;
|
|
||||||
case EvalDataType.Double: return importer.NegDouble;
|
|
||||||
default: return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case Code.Not:
|
|
||||||
{
|
|
||||||
switch (op1)
|
|
||||||
{
|
|
||||||
case EvalDataType.Int32: return importer.NotInt;
|
|
||||||
case EvalDataType.Int64: return importer.NotLong;
|
|
||||||
default: return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default: return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private IMethod GetBinaryOpMethod(DefaultMetadataImporter importer, Code code, EvalDataType op1, EvalDataType op2)
|
|
||||||
{
|
{
|
||||||
switch (code)
|
switch (code)
|
||||||
{
|
{
|
||||||
|
|
@ -65,19 +17,10 @@ namespace Obfuz.ObfusPasses.ExprObfus.Obfuscators
|
||||||
{
|
{
|
||||||
switch (op1)
|
switch (op1)
|
||||||
{
|
{
|
||||||
case EvalDataType.Int32: return op2 == op1 ? importer.AddInt : null;
|
case EvalDataType.Int32: return importer.AddInt;
|
||||||
case EvalDataType.Int64: return op2 == op1 ? importer.AddLong : null;
|
case EvalDataType.Int64: return importer.AddLong;
|
||||||
case EvalDataType.Float: return op2 == op1 ? importer.AddFloat : null;
|
case EvalDataType.Float: return importer.AddFloat;
|
||||||
case EvalDataType.Double: return op2 == op1 ? importer.AddDouble : null;
|
case EvalDataType.Double: return importer.AddDouble;
|
||||||
case EvalDataType.I:
|
|
||||||
{
|
|
||||||
switch (op2)
|
|
||||||
{
|
|
||||||
case EvalDataType.I: return importer.AddIntPtr;
|
|
||||||
case EvalDataType.Int32: return importer.AddIntPtrInt;
|
|
||||||
default: return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default: return null;
|
default: return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -85,19 +28,10 @@ namespace Obfuz.ObfusPasses.ExprObfus.Obfuscators
|
||||||
{
|
{
|
||||||
switch (op1)
|
switch (op1)
|
||||||
{
|
{
|
||||||
case EvalDataType.Int32: return op2 == op1 ? importer.SubtractInt : null;
|
case EvalDataType.Int32: return importer.SubtractInt;
|
||||||
case EvalDataType.Int64: return op2 == op1 ? importer.SubtractLong : null;
|
case EvalDataType.Int64: return importer.SubtractLong;
|
||||||
case EvalDataType.Float: return op2 == op1 ? importer.SubtractFloat : null;
|
case EvalDataType.Float: return importer.SubtractFloat;
|
||||||
case EvalDataType.Double: return op2 == op1 ? importer.SubtractDouble : null;
|
case EvalDataType.Double: return importer.SubtractDouble;
|
||||||
case EvalDataType.I:
|
|
||||||
{
|
|
||||||
switch (op2)
|
|
||||||
{
|
|
||||||
case EvalDataType.I: return importer.SubtractIntPtr;
|
|
||||||
case EvalDataType.Int32: return importer.SubtractIntPtrInt;
|
|
||||||
default: return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default: return null;
|
default: return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -105,19 +39,10 @@ namespace Obfuz.ObfusPasses.ExprObfus.Obfuscators
|
||||||
{
|
{
|
||||||
switch (op1)
|
switch (op1)
|
||||||
{
|
{
|
||||||
case EvalDataType.Int32: return op2 == op1 ? importer.MultiplyInt : null;
|
case EvalDataType.Int32: return importer.MultiplyInt;
|
||||||
case EvalDataType.Int64: return op2 == op1 ? importer.MultiplyLong : null;
|
case EvalDataType.Int64: return importer.MultiplyLong;
|
||||||
case EvalDataType.Float: return op2 == op1 ? importer.MultiplyFloat : null;
|
case EvalDataType.Float: return importer.MultiplyFloat;
|
||||||
case EvalDataType.Double: return op2 == op1 ? importer.MultiplyDouble : null;
|
case EvalDataType.Double: return importer.MultiplyDouble;
|
||||||
case EvalDataType.I:
|
|
||||||
{
|
|
||||||
switch (op2)
|
|
||||||
{
|
|
||||||
case EvalDataType.I: return importer.MultiplyIntPtr;
|
|
||||||
case EvalDataType.Int32: return importer.MultiplyIntPtrInt;
|
|
||||||
default: return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default: return null;
|
default: return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -241,10 +166,9 @@ namespace Obfuz.ObfusPasses.ExprObfus.Obfuscators
|
||||||
|
|
||||||
public override bool ObfuscateBasicUnaryOp(Instruction inst, EvalDataType op, EvalDataType ret, List<Instruction> outputInsts, ObfusMethodContext ctx)
|
public override bool ObfuscateBasicUnaryOp(Instruction inst, EvalDataType op, EvalDataType ret, List<Instruction> outputInsts, ObfusMethodContext ctx)
|
||||||
{
|
{
|
||||||
IMethod opMethod = GetUnaryOpMethod(ctx.importer, inst.OpCode.Code, op);
|
IMethod opMethod = GetMethod(ctx.importer, inst.OpCode.Code, op);
|
||||||
if (opMethod == null)
|
if (opMethod == null)
|
||||||
{
|
{
|
||||||
Debug.LogWarning($"BasicObfuscator: Cannot obfuscate unary operation {inst.OpCode.Code} with different operand types: op={op}. This is a limitation of the BasicObfuscator.");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
outputInsts.Add(Instruction.Create(OpCodes.Call, opMethod));
|
outputInsts.Add(Instruction.Create(OpCodes.Call, opMethod));
|
||||||
|
|
@ -253,22 +177,25 @@ namespace Obfuz.ObfusPasses.ExprObfus.Obfuscators
|
||||||
|
|
||||||
public override bool ObfuscateBasicBinOp(Instruction inst, EvalDataType op1, EvalDataType op2, EvalDataType ret, List<Instruction> outputInsts, ObfusMethodContext ctx)
|
public override bool ObfuscateBasicBinOp(Instruction inst, EvalDataType op1, EvalDataType op2, EvalDataType ret, List<Instruction> outputInsts, ObfusMethodContext ctx)
|
||||||
{
|
{
|
||||||
IMethod opMethod = GetBinaryOpMethod(ctx.importer, inst.OpCode.Code, op1, op2);
|
if (op1 != op2)
|
||||||
if (opMethod == null)
|
|
||||||
{
|
{
|
||||||
Debug.LogWarning($"BasicObfuscator: Cannot obfuscate binary operation {inst.OpCode.Code} with different operand types: op1={op1}, op2={op2}, ret={ret}. This is a limitation of the BasicObfuscator.");
|
Debug.LogWarning($"BasicObfuscator: Cannot obfuscate binary operation {inst.OpCode.Code} with different operand types: op1={op1}, op2={op2}, ret={ret}. This is a limitation of the BasicObfuscator.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
IMethod opMethod = GetMethod(ctx.importer, inst.OpCode.Code, op1);
|
||||||
|
if (opMethod == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
outputInsts.Add(Instruction.Create(OpCodes.Call, opMethod));
|
outputInsts.Add(Instruction.Create(OpCodes.Call, opMethod));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool ObfuscateUnaryBitwiseOp(Instruction inst, EvalDataType op, EvalDataType ret, List<Instruction> outputInsts, ObfusMethodContext ctx)
|
public override bool ObfuscateUnaryBitwiseOp(Instruction inst, EvalDataType op, EvalDataType ret, List<Instruction> outputInsts, ObfusMethodContext ctx)
|
||||||
{
|
{
|
||||||
IMethod opMethod = GetUnaryOpMethod(ctx.importer, inst.OpCode.Code, op);
|
IMethod opMethod = GetMethod(ctx.importer, inst.OpCode.Code, op);
|
||||||
if (opMethod == null)
|
if (opMethod == null)
|
||||||
{
|
{
|
||||||
Debug.LogWarning($"BasicObfuscator: Cannot obfuscate unary operation {inst.OpCode.Code} with different operand types: op={op}. This is a limitation of the BasicObfuscator.");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
outputInsts.Add(Instruction.Create(OpCodes.Call, opMethod));
|
outputInsts.Add(Instruction.Create(OpCodes.Call, opMethod));
|
||||||
|
|
@ -277,24 +204,32 @@ namespace Obfuz.ObfusPasses.ExprObfus.Obfuscators
|
||||||
|
|
||||||
public override bool ObfuscateBinBitwiseOp(Instruction inst, EvalDataType op1, EvalDataType op2, EvalDataType ret, List<Instruction> outputInsts, ObfusMethodContext ctx)
|
public override bool ObfuscateBinBitwiseOp(Instruction inst, EvalDataType op1, EvalDataType op2, EvalDataType ret, List<Instruction> outputInsts, ObfusMethodContext ctx)
|
||||||
{
|
{
|
||||||
IMethod opMethod = GetBinaryOpMethod(ctx.importer, inst.OpCode.Code, op1, op2);
|
if (op1 != op2)
|
||||||
if (opMethod == null)
|
|
||||||
{
|
{
|
||||||
Debug.LogWarning($"BasicObfuscator: Cannot obfuscate binary operation {inst.OpCode.Code} with different operand types: op1={op1}, op2={op2}, ret={ret}. This is a limitation of the BasicObfuscator.");
|
Debug.LogWarning($"BasicObfuscator: Cannot obfuscate binary operation {inst.OpCode.Code} with different operand types: op1={op1}, op2={op2}, ret={ret}. This is a limitation of the BasicObfuscator.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
IMethod opMethod = GetMethod(ctx.importer, inst.OpCode.Code, op1);
|
||||||
|
if (opMethod == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
outputInsts.Add(Instruction.Create(OpCodes.Call, opMethod));
|
outputInsts.Add(Instruction.Create(OpCodes.Call, opMethod));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool ObfuscateBitShiftOp(Instruction inst, EvalDataType op1, EvalDataType op2, EvalDataType ret, List<Instruction> outputInsts, ObfusMethodContext ctx)
|
public override bool ObfuscateBitShiftOp(Instruction inst, EvalDataType op1, EvalDataType op2, EvalDataType ret, List<Instruction> outputInsts, ObfusMethodContext ctx)
|
||||||
{
|
{
|
||||||
IMethod opMethod = GetBinaryOpMethod(ctx.importer, inst.OpCode.Code, op1, op2);
|
if (op2 != EvalDataType.Int32)
|
||||||
if (opMethod == null)
|
|
||||||
{
|
{
|
||||||
Debug.LogWarning($"BasicObfuscator: Cannot obfuscate binary operation {inst.OpCode.Code} with operand type {op2}. This is a limitation of the BasicObfuscator.");
|
Debug.LogWarning($"BasicObfuscator: Cannot obfuscate binary operation {inst.OpCode.Code} with operand type {op2}. This is a limitation of the BasicObfuscator.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
IMethod opMethod = GetMethod(ctx.importer, inst.OpCode.Code, op1);
|
||||||
|
if (opMethod == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
outputInsts.Add(Instruction.Create(OpCodes.Call, opMethod));
|
outputInsts.Add(Instruction.Create(OpCodes.Call, opMethod));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet.Emit;
|
using dnlib.DotNet.Emit;
|
||||||
using Obfuz.Emit;
|
using Obfuz.Emit;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet;
|
using dnlib.DotNet;
|
||||||
using Obfuz.Conf;
|
using Obfuz.Conf;
|
||||||
using Obfuz.Utils;
|
using Obfuz.Utils;
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet;
|
using dnlib.DotNet;
|
||||||
using dnlib.DotNet.Emit;
|
using dnlib.DotNet.Emit;
|
||||||
using Obfuz.Emit;
|
using Obfuz.Emit;
|
||||||
|
|
@ -31,15 +11,22 @@ namespace Obfuz.ObfusPasses.FieldEncrypt
|
||||||
{
|
{
|
||||||
public class DefaultFieldEncryptor : FieldEncryptorBase
|
public class DefaultFieldEncryptor : FieldEncryptorBase
|
||||||
{
|
{
|
||||||
|
private readonly EncryptionScopeProvider _encryptionScopeProvider;
|
||||||
private readonly GroupByModuleEntityManager _moduleEntityManager;
|
private readonly GroupByModuleEntityManager _moduleEntityManager;
|
||||||
private readonly FieldEncryptionSettingsFacade _settings;
|
private readonly FieldEncryptionSettingsFacade _settings;
|
||||||
|
|
||||||
public DefaultFieldEncryptor(GroupByModuleEntityManager moduleEntityManager, FieldEncryptionSettingsFacade settings)
|
public DefaultFieldEncryptor(EncryptionScopeProvider encryptionScopeProvider, GroupByModuleEntityManager moduleEntityManager, FieldEncryptionSettingsFacade settings)
|
||||||
{
|
{
|
||||||
|
_encryptionScopeProvider = encryptionScopeProvider;
|
||||||
_moduleEntityManager = moduleEntityManager;
|
_moduleEntityManager = moduleEntityManager;
|
||||||
_settings = settings;
|
_settings = settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private DefaultMetadataImporter GetMetadataImporter(MethodDef method)
|
||||||
|
{
|
||||||
|
return _moduleEntityManager.GetDefaultModuleMetadataImporter(method.Module, _encryptionScopeProvider);
|
||||||
|
}
|
||||||
|
|
||||||
class FieldEncryptInfo
|
class FieldEncryptInfo
|
||||||
{
|
{
|
||||||
public int encryptOps;
|
public int encryptOps;
|
||||||
|
|
@ -90,7 +77,7 @@ namespace Obfuz.ObfusPasses.FieldEncrypt
|
||||||
{
|
{
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
EncryptionScopeInfo encryptionScope = _moduleEntityManager.EncryptionScopeProvider.GetScope(field.Module);
|
EncryptionScopeInfo encryptionScope = _encryptionScopeProvider.GetScope(field.Module);
|
||||||
|
|
||||||
IRandom random = CreateRandomForField(encryptionScope.localRandomCreator, field);
|
IRandom random = CreateRandomForField(encryptionScope.localRandomCreator, field);
|
||||||
IEncryptor encryptor = encryptionScope.encryptor;
|
IEncryptor encryptor = encryptionScope.encryptor;
|
||||||
|
|
@ -112,7 +99,7 @@ namespace Obfuz.ObfusPasses.FieldEncrypt
|
||||||
|
|
||||||
public override void Encrypt(MethodDef method, FieldDef field, List<Instruction> outputInstructions, Instruction currentInstruction)
|
public override void Encrypt(MethodDef method, FieldDef field, List<Instruction> outputInstructions, Instruction currentInstruction)
|
||||||
{
|
{
|
||||||
DefaultMetadataImporter importer = _moduleEntityManager.GetEntity<DefaultMetadataImporter>(method.Module);
|
DefaultMetadataImporter importer = GetMetadataImporter(method);
|
||||||
EncryptionServiceMetadataImporter encryptionServiceMetadataImporter = importer.GetEncryptionServiceMetadataImporterOfModule(field.Module);
|
EncryptionServiceMetadataImporter encryptionServiceMetadataImporter = importer.GetEncryptionServiceMetadataImporterOfModule(field.Module);
|
||||||
FieldEncryptInfo fei = GetFieldEncryptInfo(field);
|
FieldEncryptInfo fei = GetFieldEncryptInfo(field);
|
||||||
if (fei.fieldType == ElementType.I4 || fei.fieldType == ElementType.U4 || fei.fieldType == ElementType.R4)
|
if (fei.fieldType == ElementType.I4 || fei.fieldType == ElementType.U4 || fei.fieldType == ElementType.R4)
|
||||||
|
|
@ -167,7 +154,7 @@ namespace Obfuz.ObfusPasses.FieldEncrypt
|
||||||
public override void Decrypt(MethodDef method, FieldDef field, List<Instruction> outputInstructions, Instruction currentInstruction)
|
public override void Decrypt(MethodDef method, FieldDef field, List<Instruction> outputInstructions, Instruction currentInstruction)
|
||||||
{
|
{
|
||||||
outputInstructions.Add(currentInstruction.Clone());
|
outputInstructions.Add(currentInstruction.Clone());
|
||||||
DefaultMetadataImporter importer = _moduleEntityManager.GetEntity<DefaultMetadataImporter>(method.Module);
|
DefaultMetadataImporter importer = GetMetadataImporter(method);
|
||||||
EncryptionServiceMetadataImporter encryptionServiceMetadataImporter = importer.GetEncryptionServiceMetadataImporterOfModule(field.Module);
|
EncryptionServiceMetadataImporter encryptionServiceMetadataImporter = importer.GetEncryptionServiceMetadataImporterOfModule(field.Module);
|
||||||
FieldEncryptInfo fei = GetFieldEncryptInfo(field);
|
FieldEncryptInfo fei = GetFieldEncryptInfo(field);
|
||||||
if (fei.fieldType == ElementType.I4 || fei.fieldType == ElementType.U4 || fei.fieldType == ElementType.R4)
|
if (fei.fieldType == ElementType.I4 || fei.fieldType == ElementType.U4 || fei.fieldType == ElementType.R4)
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet;
|
using dnlib.DotNet;
|
||||||
using dnlib.DotNet.Emit;
|
using dnlib.DotNet.Emit;
|
||||||
using Obfuz.Settings;
|
using Obfuz.Settings;
|
||||||
|
|
@ -44,7 +24,7 @@ namespace Obfuz.ObfusPasses.FieldEncrypt
|
||||||
public override void Start()
|
public override void Start()
|
||||||
{
|
{
|
||||||
var ctx = ObfuscationPassContext.Current;
|
var ctx = ObfuscationPassContext.Current;
|
||||||
_memoryEncryptor = new DefaultFieldEncryptor(ctx.moduleEntityManager, _settings);
|
_memoryEncryptor = new DefaultFieldEncryptor(ctx.encryptionScopeProvider, ctx.moduleEntityManager, _settings);
|
||||||
_encryptionPolicy = new ConfigurableEncryptPolicy(ctx.obfuzIgnoreScopeComputeCache, ctx.coreSettings.assembliesToObfuscate, _settings.ruleFiles);
|
_encryptionPolicy = new ConfigurableEncryptPolicy(ctx.obfuzIgnoreScopeComputeCache, ctx.coreSettings.assembliesToObfuscate, _settings.ruleFiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet;
|
using dnlib.DotNet;
|
||||||
|
|
||||||
namespace Obfuz.ObfusPasses.FieldEncrypt
|
namespace Obfuz.ObfusPasses.FieldEncrypt
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet;
|
using dnlib.DotNet;
|
||||||
using dnlib.DotNet.Emit;
|
using dnlib.DotNet.Emit;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
|
||||||
|
|
@ -1,27 +1,6 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet;
|
using dnlib.DotNet;
|
||||||
using dnlib.DotNet.Emit;
|
using dnlib.DotNet.Emit;
|
||||||
using Obfuz.Editor;
|
using Obfuz.Editor;
|
||||||
using Obfuz.Emit;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
@ -110,7 +89,7 @@ namespace Obfuz.ObfusPasses.Instinct
|
||||||
}
|
}
|
||||||
|
|
||||||
ObfuscationPassContext ctx = ObfuscationPassContext.Current;
|
ObfuscationPassContext ctx = ObfuscationPassContext.Current;
|
||||||
var importer = ctx.moduleEntityManager.GetEntity<DefaultMetadataImporter>(callingMethod.Module);
|
var importer = ctx.moduleEntityManager.GetDefaultModuleMetadataImporter(callingMethod.Module, ctx.encryptionScopeProvider);
|
||||||
|
|
||||||
string methodName = methodDef.Name;
|
string methodName = methodDef.Name;
|
||||||
switch (methodName)
|
switch (methodName)
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet;
|
using dnlib.DotNet;
|
||||||
using dnlib.DotNet.Emit;
|
using dnlib.DotNet.Emit;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet;
|
using dnlib.DotNet;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
namespace Obfuz.ObfusPasses
|
namespace Obfuz.ObfusPasses
|
||||||
{
|
{
|
||||||
public abstract class ObfuscationPassBase : IObfuscationPass
|
public abstract class ObfuscationPassBase : IObfuscationPass
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Obfuz.ObfusPasses
|
namespace Obfuz.ObfusPasses
|
||||||
|
|
@ -36,9 +16,6 @@ namespace Obfuz.ObfusPasses
|
||||||
ControlFlowObfus = 0x800,
|
ControlFlowObfus = 0x800,
|
||||||
EvalStackObfus = 0x1000,
|
EvalStackObfus = 0x1000,
|
||||||
|
|
||||||
RemoveConstField = 0x100000,
|
|
||||||
WaterMark = 0x200000,
|
|
||||||
|
|
||||||
AllObfus = SymbolObfus | CallObfus | ExprObfus | ControlFlowObfus | EvalStackObfus,
|
AllObfus = SymbolObfus | CallObfus | ExprObfus | ControlFlowObfus | EvalStackObfus,
|
||||||
AllEncrypt = ConstEncrypt | FieldEncrypt,
|
AllEncrypt = ConstEncrypt | FieldEncrypt,
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: d2c28a04d2997bc4d91a4c7693983d12
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
|
|
@ -1,54 +0,0 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet;
|
|
||||||
using Obfuz.Conf;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Xml;
|
|
||||||
|
|
||||||
namespace Obfuz.ObfusPasses.RemoveConstField
|
|
||||||
{
|
|
||||||
public class ConfigurableRemoveConstFieldPolicy : RemoveConstFieldBase
|
|
||||||
{
|
|
||||||
class ObfuscationRule
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private readonly XmlFieldRuleParser<ObfuscationRule> _configParser;
|
|
||||||
|
|
||||||
public ConfigurableRemoveConstFieldPolicy(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 NeedPreserved(FieldDef field)
|
|
||||||
{
|
|
||||||
var rule = _configParser.GetFieldRule(field);
|
|
||||||
return rule != null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: e3b708559fbf755419d7daf4ddce72f2
|
|
||||||
MonoImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 2
|
|
||||||
defaultReferences: []
|
|
||||||
executionOrder: 0
|
|
||||||
icon: {instanceID: 0}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet;
|
|
||||||
|
|
||||||
namespace Obfuz.ObfusPasses.RemoveConstField
|
|
||||||
{
|
|
||||||
public interface IRemoveConstFieldPolicy
|
|
||||||
{
|
|
||||||
bool NeedPreserved(FieldDef field);
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract class RemoveConstFieldBase : IRemoveConstFieldPolicy
|
|
||||||
{
|
|
||||||
public abstract bool NeedPreserved(FieldDef field);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: 5fad0b7ef9225b24cacc94f8dcaee26d
|
|
||||||
MonoImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 2
|
|
||||||
defaultReferences: []
|
|
||||||
executionOrder: 0
|
|
||||||
icon: {instanceID: 0}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
|
|
@ -1,93 +0,0 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet;
|
|
||||||
using Obfuz.Settings;
|
|
||||||
using Obfuz.Utils;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace Obfuz.ObfusPasses.RemoveConstField
|
|
||||||
{
|
|
||||||
|
|
||||||
public class RemoveConstFieldPass : ObfuscationPassBase
|
|
||||||
{
|
|
||||||
private RemoveConstFieldSettingsFacade _settings;
|
|
||||||
private ObfuzIgnoreScopeComputeCache _obfuzIgnoreScopeComputeCache;
|
|
||||||
private IRemoveConstFieldPolicy _removeConstFieldPolicy;
|
|
||||||
|
|
||||||
public override ObfuscationPassType Type => ObfuscationPassType.RemoveConstField;
|
|
||||||
|
|
||||||
public RemoveConstFieldPass(RemoveConstFieldSettingsFacade settings)
|
|
||||||
{
|
|
||||||
_settings = settings;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Start()
|
|
||||||
{
|
|
||||||
var ctx = ObfuscationPassContext.Current;
|
|
||||||
_obfuzIgnoreScopeComputeCache = ctx.obfuzIgnoreScopeComputeCache;
|
|
||||||
_removeConstFieldPolicy = new ConfigurableRemoveConstFieldPolicy(ctx.coreSettings.assembliesToObfuscate, _settings.ruleFiles);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Stop()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Process()
|
|
||||||
{
|
|
||||||
var ctx = ObfuscationPassContext.Current;
|
|
||||||
var modules = ctx.modulesToObfuscate;
|
|
||||||
ConfigurablePassPolicy passPolicy = ctx.passPolicy;
|
|
||||||
foreach (ModuleDef mod in modules)
|
|
||||||
{
|
|
||||||
// ToArray to avoid modify list exception
|
|
||||||
foreach (TypeDef type in mod.GetTypes())
|
|
||||||
{
|
|
||||||
if (type.IsEnum)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
foreach (FieldDef field in type.Fields.ToArray())
|
|
||||||
{
|
|
||||||
if (!field.IsLiteral)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!Support(passPolicy.GetFieldObfuscationPasses(field)))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (_obfuzIgnoreScopeComputeCache.HasSelfOrDeclaringOrEnclosingOrInheritObfuzIgnoreScope(field, field.DeclaringType, ObfuzScope.Field))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (_removeConstFieldPolicy.NeedPreserved(field))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
field.DeclaringType = null;
|
|
||||||
//Debug.Log($"Remove const field {field.FullName} in type {type.FullName} in module {mod.Name}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: 3188de094ab4cdd47b55c2f622251cf5
|
|
||||||
MonoImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 2
|
|
||||||
defaultReferences: []
|
|
||||||
executionOrder: 0
|
|
||||||
icon: {instanceID: 0}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet;
|
using dnlib.DotNet;
|
||||||
|
|
||||||
namespace Obfuz.ObfusPasses.SymbolObfus
|
namespace Obfuz.ObfusPasses.SymbolObfus
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet;
|
using dnlib.DotNet;
|
||||||
|
|
||||||
namespace Obfuz.ObfusPasses.SymbolObfus
|
namespace Obfuz.ObfusPasses.SymbolObfus
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,6 @@
|
||||||
// Copyright 2025 Code Philosophy
|
using System.Text;
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
namespace Obfuz.ObfusPasses.SymbolObfus.NameMakers
|
namespace Obfuz.ObfusPasses.SymbolObfus.NameMakers
|
||||||
{
|
{
|
||||||
public class DebugNameMaker : NameMakerBase
|
public class DebugNameMaker : NameMakerBase
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
namespace Obfuz.ObfusPasses.SymbolObfus.NameMakers
|
namespace Obfuz.ObfusPasses.SymbolObfus.NameMakers
|
||||||
{
|
{
|
||||||
public interface INameScope
|
public interface INameScope
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using dnlib.DotNet;
|
using dnlib.DotNet;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using UnityEngine.Assertions;
|
using UnityEngine.Assertions;
|
||||||
|
|
@ -115,7 +95,7 @@ namespace Obfuz.ObfusPasses.SymbolObfus.NameMakers
|
||||||
|
|
||||||
public virtual string GetNewName(ParamDef param, string originalName)
|
public virtual string GetNewName(ParamDef param, string originalName)
|
||||||
{
|
{
|
||||||
return $"_{param.Sequence}";
|
return "1";
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetNewName(FieldDef fieldDef, string originalName)
|
public string GetNewName(FieldDef fieldDef, string originalName)
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Obfuz.ObfusPasses.SymbolObfus.NameMakers
|
namespace Obfuz.ObfusPasses.SymbolObfus.NameMakers
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,3 @@
|
||||||
// Copyright 2025 Code Philosophy
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue