实现 AdvancedObfuscator

dev
walon 2025-06-20 18:23:38 +08:00
parent 9c445213b5
commit f247719bc1
1 changed files with 155 additions and 91 deletions

View File

@ -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<Instruction> outputInsts, ObfusMethodContext ctx)
//public override bool ObfuscateBasicUnaryOp(Instruction inst, EvalDataType op, EvalDataType ret, List<Instruction> 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<Instruction> outputInsts, ObfusMethodContext ctx)
{
DefaultMetadataImporter importer = ctx.importer;
EncryptionScopeInfo encryptionScope = ctx.encryptionScope;
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;
// = x + y = x + (y * 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;
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);
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:
{
// y = -x = (x * a + b) * (-ra) + b * ra;
// = x + y = x + (y * 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;
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);
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:
{
// y = -x = (x + a) * b; a = 0.0f, b = 1.0f,
// = x + y = x + (y + a) * b; a = 0.0f, b = 1.0f
float a = 0.0f;
float b = -1.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:
{
// y = -x = (x + a) * b; a = 0.0, b = -1.0,
// = x + y = x + (y + a) * b; a = 0.0, b = 1.0
double a = 0.0;
double b = -1.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;
}
}
outputInsts.Add(inst.Clone());
return true;
}
default: return false;
}
}
public override bool ObfuscateBasicBinOp(Instruction inst, EvalDataType op1, EvalDataType op2, EvalDataType ret, List<Instruction> outputInsts, ObfusMethodContext ctx)
public override bool ObfuscateBasicUnaryOp(Instruction inst, EvalDataType op, EvalDataType ret, List<Instruction> 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 GenerateIdentityTransformForArgument(inst, op, outputInsts, ctx) || base.ObfuscateBasicUnaryOp(inst, op, ret, outputInsts, ctx);
}
return base.ObfuscateBasicBinOp(inst, op1, op2, ret, outputInsts, ctx);
public override bool ObfuscateBasicBinOp(Instruction inst, EvalDataType op1, EvalDataType op2, EvalDataType ret, List<Instruction> outputInsts, ObfusMethodContext 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<Instruction> 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<Instruction> 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<Instruction> 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);
}
}
}