ExprObfus的BasicObfuscator支持混淆参数类型为IntPtr的表达式

main
walon 2025-07-21 11:37:29 +08:00
parent 905351789e
commit 3bcf204f69
3 changed files with 139 additions and 33 deletions

View File

@ -153,6 +153,11 @@ 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) }));
@ -161,6 +166,11 @@ 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) }));
@ -169,6 +179,11 @@ 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) }));
@ -269,14 +284,20 @@ 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;
@ -350,14 +371,22 @@ 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;

View File

@ -9,7 +9,35 @@ namespace Obfuz.ObfusPasses.ExprObfus.Obfuscators
class BasicObfuscator : ObfuscatorBase 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) switch (code)
{ {
@ -17,10 +45,19 @@ namespace Obfuz.ObfusPasses.ExprObfus.Obfuscators
{ {
switch (op1) switch (op1)
{ {
case EvalDataType.Int32: return importer.AddInt; case EvalDataType.Int32: return op2 == op1 ? importer.AddInt : null;
case EvalDataType.Int64: return importer.AddLong; case EvalDataType.Int64: return op2 == op1 ? importer.AddLong : null;
case EvalDataType.Float: return importer.AddFloat; case EvalDataType.Float: return op2 == op1 ? importer.AddFloat : null;
case EvalDataType.Double: return importer.AddDouble; 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; default: return null;
} }
} }
@ -28,10 +65,19 @@ namespace Obfuz.ObfusPasses.ExprObfus.Obfuscators
{ {
switch (op1) switch (op1)
{ {
case EvalDataType.Int32: return importer.SubtractInt; case EvalDataType.Int32: return op2 == op1 ? importer.SubtractInt : null;
case EvalDataType.Int64: return importer.SubtractLong; case EvalDataType.Int64: return op2 == op1 ? importer.SubtractLong : null;
case EvalDataType.Float: return importer.SubtractFloat; case EvalDataType.Float: return op2 == op1 ? importer.SubtractFloat : null;
case EvalDataType.Double: return importer.SubtractDouble; 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; default: return null;
} }
} }
@ -39,10 +85,19 @@ namespace Obfuz.ObfusPasses.ExprObfus.Obfuscators
{ {
switch (op1) switch (op1)
{ {
case EvalDataType.Int32: return importer.MultiplyInt; case EvalDataType.Int32: return op2 == op1 ? importer.MultiplyInt : null;
case EvalDataType.Int64: return importer.MultiplyLong; case EvalDataType.Int64: return op2 == op1 ? importer.MultiplyLong : null;
case EvalDataType.Float: return importer.MultiplyFloat; case EvalDataType.Float: return op2 == op1 ? importer.MultiplyFloat : null;
case EvalDataType.Double: return importer.MultiplyDouble; 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; default: return null;
} }
} }
@ -166,9 +221,10 @@ 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 = GetMethod(ctx.importer, inst.OpCode.Code, op); IMethod opMethod = GetUnaryOpMethod(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));
@ -177,14 +233,10 @@ 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)
{ {
if (op1 != op2) IMethod opMethod = GetBinaryOpMethod(ctx.importer, inst.OpCode.Code, 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);
if (opMethod == null) 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; return false;
} }
outputInsts.Add(Instruction.Create(OpCodes.Call, opMethod)); 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<Instruction> outputInsts, ObfusMethodContext ctx) public override bool ObfuscateUnaryBitwiseOp(Instruction inst, EvalDataType op, EvalDataType ret, List<Instruction> outputInsts, ObfusMethodContext ctx)
{ {
IMethod opMethod = GetMethod(ctx.importer, inst.OpCode.Code, op); IMethod opMethod = GetUnaryOpMethod(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));
@ -204,14 +257,10 @@ 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)
{ {
if (op1 != op2) IMethod opMethod = GetBinaryOpMethod(ctx.importer, inst.OpCode.Code, 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);
if (opMethod == null) 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; return false;
} }
outputInsts.Add(Instruction.Create(OpCodes.Call, opMethod)); 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<Instruction> outputInsts, ObfusMethodContext ctx) public override bool ObfuscateBitShiftOp(Instruction inst, EvalDataType op1, EvalDataType op2, EvalDataType ret, List<Instruction> outputInsts, ObfusMethodContext ctx)
{ {
if (op2 != EvalDataType.Int32) IMethod opMethod = GetBinaryOpMethod(ctx.importer, inst.OpCode.Code, op1, op2);
{
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);
if (opMethod == null) 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; return false;
} }
outputInsts.Add(Instruction.Create(OpCodes.Call, opMethod)); outputInsts.Add(Instruction.Create(OpCodes.Call, opMethod));

View File

@ -1,3 +1,5 @@
using System;
namespace Obfuz namespace Obfuz
{ {
public static class ExprUtility public static class ExprUtility
@ -22,6 +24,16 @@ namespace Obfuz
return a + b; 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) public static int Subtract(int a, int b)
{ {
return a - b; return a - b;
@ -42,6 +54,16 @@ namespace Obfuz
return a - b; 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) public static int Multiply(int a, int b)
{ {
return a * b; return a * b;
@ -62,6 +84,16 @@ namespace Obfuz
return a * b; 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) public static int Divide(int a, int b)
{ {
return a / b; return a / b;