diff --git a/Editor/Emit/DefaultMetadataImporter.cs b/Editor/Emit/DefaultMetadataImporter.cs index 3d7a7e5..6399b42 100644 --- a/Editor/Emit/DefaultMetadataImporter.cs +++ b/Editor/Emit/DefaultMetadataImporter.cs @@ -153,6 +153,11 @@ namespace Obfuz.Emit Assert.IsNotNull(_addFloat, "ExprUtility.Add(float, float) not found"); _addDouble = mod.Import(exprUtilityType.GetMethod("Add", new[] { typeof(double), typeof(double) })); 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) })); Assert.IsNotNull(_subtractInt, "ExprUtility.Subtract(int, int) not found"); _subtractLong = mod.Import(exprUtilityType.GetMethod("Subtract", new[] { typeof(long), typeof(long) })); @@ -161,6 +166,11 @@ namespace Obfuz.Emit Assert.IsNotNull(_subtractFloat, "ExprUtility.Subtract(float, float) not found"); _subtractDouble = mod.Import(exprUtilityType.GetMethod("Subtract", new[] { typeof(double), typeof(double) })); 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) })); Assert.IsNotNull(_multiplyInt, "ExprUtility.Multiply(int, int) not found"); _multiplyLong = mod.Import(exprUtilityType.GetMethod("Multiply", new[] { typeof(long), typeof(long) })); @@ -169,6 +179,11 @@ namespace Obfuz.Emit Assert.IsNotNull(_multiplyFloat, "ExprUtility.Multiply(float, float) not found"); _multiplyDouble = mod.Import(exprUtilityType.GetMethod("Multiply", new[] { typeof(double), typeof(double) })); 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) })); Assert.IsNotNull(_divideInt, "ExprUtility.Divide(int, int) not found"); _divideLong = mod.Import(exprUtilityType.GetMethod("Divide", new[] { typeof(long), typeof(long) })); @@ -269,14 +284,20 @@ namespace Obfuz.Emit private IMethod _addLong; private IMethod _addFloat; private IMethod _addDouble; + private IMethod _addIntPtr; + private IMethod _addIntPtrInt; private IMethod _subtractInt; private IMethod _subtractLong; private IMethod _subtractFloat; private IMethod _subtractDouble; + private IMethod _subtractIntPtr; + private IMethod _subtractIntPtrInt; private IMethod _multiplyInt; private IMethod _multiplyLong; private IMethod _multiplyFloat; private IMethod _multiplyDouble; + private IMethod _multiplyIntPtr; + private IMethod _multiplyIntPtrInt; private IMethod _divideInt; private IMethod _divideLong; private IMethod _divideFloat; @@ -350,14 +371,22 @@ namespace Obfuz.Emit public IMethod AddLong => _addLong; public IMethod AddFloat => _addFloat; public IMethod AddDouble => _addDouble; + public IMethod AddIntPtr => _addIntPtr; + public IMethod AddIntPtrInt => _addIntPtrInt; public IMethod SubtractInt => _subtractInt; public IMethod SubtractLong => _subtractLong; public IMethod SubtractFloat => _subtractFloat; public IMethod SubtractDouble => _subtractDouble; + public IMethod SubtractIntPtr => _subtractIntPtr; + public IMethod SubtractIntPtrInt => _subtractIntPtrInt; + public IMethod MultiplyInt => _multiplyInt; public IMethod MultiplyLong => _multiplyLong; public IMethod MultiplyFloat => _multiplyFloat; public IMethod MultiplyDouble => _multiplyDouble; + public IMethod MultiplyIntPtr => _multiplyIntPtr; + public IMethod MultiplyIntPtrInt => _multiplyIntPtrInt; + public IMethod DivideInt => _divideInt; public IMethod DivideLong => _divideLong; public IMethod DivideFloat => _divideFloat; diff --git a/Editor/ObfusPasses/ExprObfus/Obfuscators/BasicObfuscator.cs b/Editor/ObfusPasses/ExprObfus/Obfuscators/BasicObfuscator.cs index 5d55289..56e110e 100644 --- a/Editor/ObfusPasses/ExprObfus/Obfuscators/BasicObfuscator.cs +++ b/Editor/ObfusPasses/ExprObfus/Obfuscators/BasicObfuscator.cs @@ -9,7 +9,35 @@ namespace Obfuz.ObfusPasses.ExprObfus.Obfuscators class BasicObfuscator : ObfuscatorBase { - private IMethod GetMethod(DefaultMetadataImporter importer, Code code, EvalDataType op1) + private IMethod GetUnaryOpMethod(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) { @@ -17,10 +45,19 @@ namespace Obfuz.ObfusPasses.ExprObfus.Obfuscators { switch (op1) { - case EvalDataType.Int32: return importer.AddInt; - case EvalDataType.Int64: return importer.AddLong; - case EvalDataType.Float: return importer.AddFloat; - case EvalDataType.Double: return importer.AddDouble; + case EvalDataType.Int32: return op2 == op1 ? importer.AddInt : null; + case EvalDataType.Int64: return op2 == op1 ? importer.AddLong : null; + case EvalDataType.Float: return op2 == op1 ? importer.AddFloat : null; + case EvalDataType.Double: return op2 == op1 ? importer.AddDouble : null; + case EvalDataType.I: + { + switch (op2) + { + case EvalDataType.I: return importer.AddIntPtr; + case EvalDataType.Int32: return importer.AddIntPtrInt; + default: return null; + } + } default: return null; } } @@ -28,10 +65,19 @@ namespace Obfuz.ObfusPasses.ExprObfus.Obfuscators { switch (op1) { - case EvalDataType.Int32: return importer.SubtractInt; - case EvalDataType.Int64: return importer.SubtractLong; - case EvalDataType.Float: return importer.SubtractFloat; - case EvalDataType.Double: return importer.SubtractDouble; + case EvalDataType.Int32: return op2 == op1 ? importer.SubtractInt : null; + case EvalDataType.Int64: return op2 == op1 ? importer.SubtractLong : null; + case EvalDataType.Float: return op2 == op1 ? importer.SubtractFloat : null; + case EvalDataType.Double: return op2 == op1 ? importer.SubtractDouble : null; + case EvalDataType.I: + { + switch (op2) + { + case EvalDataType.I: return importer.SubtractIntPtr; + case EvalDataType.Int32: return importer.SubtractIntPtrInt; + default: return null; + } + } default: return null; } } @@ -39,10 +85,19 @@ namespace Obfuz.ObfusPasses.ExprObfus.Obfuscators { switch (op1) { - case EvalDataType.Int32: return importer.MultiplyInt; - case EvalDataType.Int64: return importer.MultiplyLong; - case EvalDataType.Float: return importer.MultiplyFloat; - case EvalDataType.Double: return importer.MultiplyDouble; + case EvalDataType.Int32: return op2 == op1 ? importer.MultiplyInt : null; + case EvalDataType.Int64: return op2 == op1 ? importer.MultiplyLong : null; + case EvalDataType.Float: return op2 == op1 ? importer.MultiplyFloat : null; + case EvalDataType.Double: return op2 == op1 ? importer.MultiplyDouble : null; + case EvalDataType.I: + { + switch (op2) + { + case EvalDataType.I: return importer.MultiplyIntPtr; + case EvalDataType.Int32: return importer.MultiplyIntPtrInt; + default: return null; + } + } default: return null; } } @@ -166,9 +221,10 @@ namespace Obfuz.ObfusPasses.ExprObfus.Obfuscators public override bool ObfuscateBasicUnaryOp(Instruction inst, EvalDataType op, EvalDataType ret, List outputInsts, ObfusMethodContext ctx) { - IMethod opMethod = GetMethod(ctx.importer, inst.OpCode.Code, op); + IMethod opMethod = GetUnaryOpMethod(ctx.importer, inst.OpCode.Code, op); 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; } outputInsts.Add(Instruction.Create(OpCodes.Call, opMethod)); @@ -177,14 +233,10 @@ namespace Obfuz.ObfusPasses.ExprObfus.Obfuscators public override bool ObfuscateBasicBinOp(Instruction inst, EvalDataType op1, EvalDataType op2, EvalDataType ret, List outputInsts, ObfusMethodContext ctx) { - if (op1 != op2) - { - 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; - } - IMethod opMethod = GetMethod(ctx.importer, inst.OpCode.Code, op1); + IMethod opMethod = GetBinaryOpMethod(ctx.importer, inst.OpCode.Code, 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."); return false; } outputInsts.Add(Instruction.Create(OpCodes.Call, opMethod)); @@ -193,9 +245,10 @@ namespace Obfuz.ObfusPasses.ExprObfus.Obfuscators public override bool ObfuscateUnaryBitwiseOp(Instruction inst, EvalDataType op, EvalDataType ret, List outputInsts, ObfusMethodContext ctx) { - IMethod opMethod = GetMethod(ctx.importer, inst.OpCode.Code, op); + IMethod opMethod = GetUnaryOpMethod(ctx.importer, inst.OpCode.Code, op); 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; } outputInsts.Add(Instruction.Create(OpCodes.Call, opMethod)); @@ -204,14 +257,10 @@ namespace Obfuz.ObfusPasses.ExprObfus.Obfuscators public override bool ObfuscateBinBitwiseOp(Instruction inst, EvalDataType op1, EvalDataType op2, EvalDataType ret, List outputInsts, ObfusMethodContext ctx) { - if (op1 != op2) - { - 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; - } - IMethod opMethod = GetMethod(ctx.importer, inst.OpCode.Code, op1); + IMethod opMethod = GetBinaryOpMethod(ctx.importer, inst.OpCode.Code, 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."); return false; } outputInsts.Add(Instruction.Create(OpCodes.Call, opMethod)); @@ -220,14 +269,10 @@ namespace Obfuz.ObfusPasses.ExprObfus.Obfuscators public override bool ObfuscateBitShiftOp(Instruction inst, EvalDataType op1, EvalDataType op2, EvalDataType ret, List outputInsts, ObfusMethodContext ctx) { - if (op2 != EvalDataType.Int32) - { - Debug.LogWarning($"BasicObfuscator: Cannot obfuscate binary operation {inst.OpCode.Code} with operand type {op2}. This is a limitation of the BasicObfuscator."); - return false; - } - IMethod opMethod = GetMethod(ctx.importer, inst.OpCode.Code, op1); + IMethod opMethod = GetBinaryOpMethod(ctx.importer, inst.OpCode.Code, op1, op2); if (opMethod == null) { + Debug.LogWarning($"BasicObfuscator: Cannot obfuscate binary operation {inst.OpCode.Code} with operand type {op2}. This is a limitation of the BasicObfuscator."); return false; } outputInsts.Add(Instruction.Create(OpCodes.Call, opMethod)); diff --git a/Runtime/ExprUtility.cs b/Runtime/ExprUtility.cs index 5192664..ff037e0 100644 --- a/Runtime/ExprUtility.cs +++ b/Runtime/ExprUtility.cs @@ -1,3 +1,5 @@ +using System; + namespace Obfuz { public static class ExprUtility @@ -22,6 +24,16 @@ namespace Obfuz return a + b; } + public static IntPtr Add(IntPtr a, IntPtr b) + { + return (IntPtr)((long)a + (long)b); + } + + public static IntPtr Add(IntPtr a, int b) + { + return a + b; + } + public static int Subtract(int a, int b) { return a - b; @@ -42,6 +54,16 @@ namespace Obfuz return a - b; } + public static IntPtr Subtract(IntPtr a, IntPtr b) + { + return (IntPtr)((long)a - (long)b); + } + + public static IntPtr Subtract(IntPtr a, int b) + { + return a - b; + } + public static int Multiply(int a, int b) { return a * b; @@ -62,6 +84,16 @@ namespace Obfuz return a * b; } + public static IntPtr Multiply(IntPtr a, IntPtr b) + { + return (IntPtr)((long)a * (long)b); + } + + public static IntPtr Multiply(IntPtr a, int b) + { + return (IntPtr)((long)a * b); + } + public static int Divide(int a, int b) { return a / b;