diff --git a/Editor/ObfusPasses/ExprObfus/Obfuscators/AdvancedObfuscator.cs b/Editor/ObfusPasses/ExprObfus/Obfuscators/AdvancedObfuscator.cs index 1499132..5bf2814 100644 --- a/Editor/ObfusPasses/ExprObfus/Obfuscators/AdvancedObfuscator.cs +++ b/Editor/ObfusPasses/ExprObfus/Obfuscators/AdvancedObfuscator.cs @@ -6,6 +6,8 @@ using Obfuz.Utils; using Obfuz.Data; using UnityEngine; using UnityEngine.Assertions; +using JetBrains.Annotations; +using System; namespace Obfuz.ObfusPasses.ExprObfus.Obfuscators { @@ -72,122 +74,184 @@ namespace Obfuz.ObfusPasses.ExprObfus.Obfuscators outputInsts.Add(inst); } - public override bool ObfuscateBasicUnaryOp(Instruction inst, EvalDataType op, EvalDataType ret, List outputInsts, ObfusMethodContext ctx) + //public override bool ObfuscateBasicUnaryOp(Instruction inst, EvalDataType op, EvalDataType ret, List outputInsts, ObfusMethodContext ctx) + //{ + // IRandom random = ctx.localRandom; + // ModuleConstFieldAllocator constFieldAllocator = ctx.constFieldAllocator; + + // switch (inst.OpCode.Code) + // { + // case Code.Neg: + // { + // switch (op) + // { + // case EvalDataType.Int32: + // { + // // y = -x = (x * a + b) * (-ra) + b * ra; + // int a = random.NextInt() | 0x1; + // int ra = MathUtil.ModInverse32(a); + // Assert.AreEqual(1, a * ra); + // int b = random.NextInt(); + // int b_ra = b * ra; + // float constProbability = 0.5f; + // LoadConstInt(a, random, constProbability, constFieldAllocator, outputInsts); + // outputInsts.Add(Instruction.Create(OpCodes.Mul)); + // LoadConstInt(b, random, constProbability, constFieldAllocator, outputInsts); + // outputInsts.Add(Instruction.Create(OpCodes.Add)); + // LoadConstInt(-ra, random, constProbability, constFieldAllocator, outputInsts); + // outputInsts.Add(Instruction.Create(OpCodes.Mul)); + // LoadConstInt(b_ra, random, constProbability, constFieldAllocator, outputInsts); + // outputInsts.Add(Instruction.Create(OpCodes.Add)); + // return true; + // } + // case EvalDataType.Int64: + // { + // // y = -x = (x * a + b) * (-ra) + b * ra; + // long a = random.NextLong() | 0x1L; + // long ra = MathUtil.ModInverse64(a); + // Assert.AreEqual(1L, a * ra); + // long b = random.NextLong(); + // long b_ra = b * ra; + // float constProbability = 0.5f; + // LoadConstLong(a, random, constProbability, constFieldAllocator, outputInsts); + // outputInsts.Add(Instruction.Create(OpCodes.Mul)); + // LoadConstLong(b, random, constProbability, constFieldAllocator, outputInsts); + // outputInsts.Add(Instruction.Create(OpCodes.Add)); + // LoadConstLong(-ra, random, constProbability, constFieldAllocator, outputInsts); + // outputInsts.Add(Instruction.Create(OpCodes.Mul)); + // LoadConstLong(b_ra, random, constProbability, constFieldAllocator, outputInsts); + // outputInsts.Add(Instruction.Create(OpCodes.Add)); + // return true; + // } + // case EvalDataType.Float: + // { + // // y = -x = (x + a) * b; a = 0.0f, b = 1.0f, + // float a = 0.0f; + // float b = -1.0f; + // float constProbability = 0f; + // LoadConstFloat(a, random, constProbability, constFieldAllocator, outputInsts); + // outputInsts.Add(Instruction.Create(OpCodes.Add)); + // LoadConstFloat(b, random, constProbability, constFieldAllocator, outputInsts); + // outputInsts.Add(Instruction.Create(OpCodes.Mul)); + // return true; + // } + // case EvalDataType.Double: + // { + // // y = -x = (x + a) * b; a = 0.0, b = -1.0, + // double a = 0.0; + // double b = -1.0; + // float constProbability = 0f; + // LoadConstDouble(a, random, constProbability, constFieldAllocator, outputInsts); + // outputInsts.Add(Instruction.Create(OpCodes.Add)); + // LoadConstDouble(b, random, constProbability, constFieldAllocator, outputInsts); + // outputInsts.Add(Instruction.Create(OpCodes.Mul)); + // return true; + // } + // } + // break; + // } + // } + // return base.ObfuscateBasicUnaryOp(inst, op, ret, outputInsts, ctx); + //} + + + private bool GenerateIdentityTransformForArgument(Instruction inst, EvalDataType op, List outputInsts, ObfusMethodContext ctx) { - DefaultMetadataImporter importer = ctx.importer; - EncryptionScopeInfo encryptionScope = ctx.encryptionScope; IRandom random = ctx.localRandom; ModuleConstFieldAllocator constFieldAllocator = ctx.constFieldAllocator; - - switch (inst.OpCode.Code) + switch (op) { - case Code.Neg: + case EvalDataType.Int32: { - switch (op) - { - case EvalDataType.Int32: - { - // y = -x = (x * a + b) * (-ra) + b * ra; - int a = random.NextInt() | 0x1; - int ra = MathUtil.ModInverse32(a); - Assert.AreEqual(1, a * ra); - int b = random.NextInt(); - int b_ra = b * ra; - float constProbability = 0.5f; - LoadConstInt(a, random, constProbability, constFieldAllocator, outputInsts); - outputInsts.Add(Instruction.Create(OpCodes.Mul)); - LoadConstInt(b, random, constProbability, constFieldAllocator, outputInsts); - outputInsts.Add(Instruction.Create(OpCodes.Add)); - LoadConstInt(-ra, random, constProbability, constFieldAllocator, outputInsts); - outputInsts.Add(Instruction.Create(OpCodes.Mul)); - LoadConstInt(b_ra, random, constProbability, constFieldAllocator, outputInsts); - outputInsts.Add(Instruction.Create(OpCodes.Add)); - return true; - } - case EvalDataType.Int64: - { - // y = -x = (x * a + b) * (-ra) + b * ra; - long a = random.NextLong() | 0x1L; - long ra = MathUtil.ModInverse64(a); - Assert.AreEqual(1L, a * ra); - long b = random.NextLong(); - long b_ra = b * ra; - float constProbability = 0.5f; - LoadConstLong(a, random, constProbability, constFieldAllocator, outputInsts); - outputInsts.Add(Instruction.Create(OpCodes.Mul)); - LoadConstLong(b, random, constProbability, constFieldAllocator, outputInsts); - outputInsts.Add(Instruction.Create(OpCodes.Add)); - LoadConstLong(-ra, random, constProbability, constFieldAllocator, outputInsts); - outputInsts.Add(Instruction.Create(OpCodes.Mul)); - LoadConstLong(b_ra, random, constProbability, constFieldAllocator, outputInsts); - outputInsts.Add(Instruction.Create(OpCodes.Add)); - return true; - } - case EvalDataType.Float: - { - // y = -x = (x + a) * b; a = 0.0f, b = 1.0f, - float a = 0.0f; - float b = -1.0f; - float constProbability = 0f; - LoadConstFloat(a, random, constProbability, constFieldAllocator, outputInsts); - outputInsts.Add(Instruction.Create(OpCodes.Add)); - LoadConstFloat(b, random, constProbability, constFieldAllocator, outputInsts); - outputInsts.Add(Instruction.Create(OpCodes.Mul)); - return true; - } - case EvalDataType.Double: - { - // y = -x = (x + a) * b; a = 0.0, b = -1.0, - double a = 0.0; - double b = -1.0; - float constProbability = 0f; - LoadConstDouble(a, random, constProbability, constFieldAllocator, outputInsts); - outputInsts.Add(Instruction.Create(OpCodes.Add)); - LoadConstDouble(b, random, constProbability, constFieldAllocator, outputInsts); - outputInsts.Add(Instruction.Create(OpCodes.Mul)); - return true; - } - } + // = x + y = x + (y * a + b) * ra + (-b * ra) + int a = random.NextInt() | 0x1; + int ra = MathUtil.ModInverse32(a); + int b = random.NextInt(); + int b_ra = -b * ra; + float constProbability = 0.5f; + LoadConstInt(a, random, constProbability, constFieldAllocator, outputInsts); + outputInsts.Add(Instruction.Create(OpCodes.Mul)); + LoadConstInt(b, random, constProbability, constFieldAllocator, outputInsts); + outputInsts.Add(Instruction.Create(OpCodes.Add)); + LoadConstInt(ra, random, constProbability, constFieldAllocator, outputInsts); + outputInsts.Add(Instruction.Create(OpCodes.Mul)); + LoadConstInt(b_ra, random, constProbability, constFieldAllocator, outputInsts); + outputInsts.Add(Instruction.Create(OpCodes.Add)); + outputInsts.Add(inst.Clone()); + return true; + } + case EvalDataType.Int64: + { + // = x + y = x + (y * a + b) * ra + (-b * ra) + long a = random.NextLong() | 0x1L; + long ra = MathUtil.ModInverse64(a); + long b = random.NextLong(); + long b_ra = -b * ra; + float constProbability = 0.5f; + LoadConstLong(a, random, constProbability, constFieldAllocator, outputInsts); + outputInsts.Add(Instruction.Create(OpCodes.Mul)); + LoadConstLong(b, random, constProbability, constFieldAllocator, outputInsts); + outputInsts.Add(Instruction.Create(OpCodes.Add)); + LoadConstLong(ra, random, constProbability, constFieldAllocator, outputInsts); + outputInsts.Add(Instruction.Create(OpCodes.Mul)); + LoadConstLong(b_ra, random, constProbability, constFieldAllocator, outputInsts); + outputInsts.Add(Instruction.Create(OpCodes.Add)); + outputInsts.Add(inst.Clone()); + return true; + } + case EvalDataType.Float: + { + // = x + y = x + (y + a) * b; a = 0.0f, b = 1.0f + float a = 0.0f; + float b = 1.0f; + float constProbability = 0f; + LoadConstFloat(a, random, constProbability, constFieldAllocator, outputInsts); + outputInsts.Add(Instruction.Create(OpCodes.Add)); + LoadConstFloat(b, random, constProbability, constFieldAllocator, outputInsts); + outputInsts.Add(Instruction.Create(OpCodes.Mul)); + outputInsts.Add(inst.Clone()); + return true; + } + case EvalDataType.Double: + { + // = x + y = x + (y + a) * b; a = 0.0, b = 1.0 + double a = 0.0; + double b = 1.0; + float constProbability = 0f; + LoadConstDouble(a, random, constProbability, constFieldAllocator, outputInsts); + outputInsts.Add(Instruction.Create(OpCodes.Add)); + LoadConstDouble(b, random, constProbability, constFieldAllocator, outputInsts); + outputInsts.Add(Instruction.Create(OpCodes.Mul)); + outputInsts.Add(inst.Clone()); return true; } default: return false; } } + public override bool ObfuscateBasicUnaryOp(Instruction inst, EvalDataType op, EvalDataType ret, List outputInsts, ObfusMethodContext ctx) + { + return GenerateIdentityTransformForArgument(inst, op, outputInsts, ctx) || base.ObfuscateBasicUnaryOp(inst, op, ret, outputInsts, ctx); + } + 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; - } - - return base.ObfuscateBasicBinOp(inst, op1, op2, ret, outputInsts, ctx); + return GenerateIdentityTransformForArgument(inst, op2, outputInsts, ctx) || base.ObfuscateBasicBinOp(inst, op1, op2, ret, outputInsts, ctx); } public override bool ObfuscateUnaryBitwiseOp(Instruction inst, EvalDataType op, EvalDataType ret, List outputInsts, ObfusMethodContext ctx) { - return base.ObfuscateUnaryBitwiseOp(inst, op, ret, outputInsts, ctx); + return GenerateIdentityTransformForArgument(inst, op, outputInsts, ctx) || base.ObfuscateUnaryBitwiseOp(inst, op, ret, outputInsts, ctx); } 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; - } - return base.ObfuscateBinBitwiseOp(inst, op1 , op2, ret, outputInsts, ctx); + return GenerateIdentityTransformForArgument(inst, op2, outputInsts, ctx) || base.ObfuscateBinBitwiseOp(inst, op1 , op2, ret, outputInsts, ctx); } 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; - } - return base.ObfuscateBitShiftOp(inst, op1, op2 , ret, outputInsts, ctx); + return GenerateIdentityTransformForArgument(inst, op2, outputInsts, ctx) || base.ObfuscateBitShiftOp(inst, op1, op2 , ret, outputInsts, ctx); } } }