From 0889f730fdad827141dbaf5224b5fb70a3453f4a Mon Sep 17 00:00:00 2001 From: walon Date: Tue, 12 Aug 2025 12:46:34 +0800 Subject: [PATCH] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8DEvalStackCalculator?= =?UTF-8?q?=E8=AE=A1=E7=AE=97Ref=E7=B1=BB=E5=9E=8B=E6=A0=88=E5=8F=98?= =?UTF-8?q?=E9=87=8F=E5=85=A8=E9=83=A8=E5=BD=92=E7=BB=93=E6=9D=A5IntPtr?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=EF=BC=8C=E5=AF=BC=E8=87=B4il2cpp=E7=94=9F?= =?UTF-8?q?=E6=88=90=E4=BB=A3=E7=A0=81=E5=87=BA=E9=94=99=E7=9A=84bug=20-?= =?UTF-8?q?=20=E4=BF=AE=E5=A4=8DMethodControlFlowCalculator=E5=B0=86box?= =?UTF-8?q?=E5=90=8E=E7=9A=84=E5=80=BC=E7=B1=BB=E5=9E=8B=E5=8F=98=E9=87=8F?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E5=AE=9A=E4=B9=89=E4=B8=BA=E5=80=BC=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E7=9A=84bug=EF=BC=8C=E6=AD=A3=E7=A1=AE=E5=BA=94?= =?UTF-8?q?=E8=AF=A5=E6=98=AFobject?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Editor/Emit/EvalStackCalculator.cs | 41 +++++++++----- .../MethodControlFlowCalculator.cs | 7 ++- Editor/Utils/MetaUtil.cs | 56 +++++++++++++++++++ 3 files changed, 86 insertions(+), 18 deletions(-) diff --git a/Editor/Emit/EvalStackCalculator.cs b/Editor/Emit/EvalStackCalculator.cs index 0be33a8..c2bc6c9 100644 --- a/Editor/Emit/EvalStackCalculator.cs +++ b/Editor/Emit/EvalStackCalculator.cs @@ -124,7 +124,7 @@ namespace Obfuz.Emit case ElementType.Ptr: case ElementType.FnPtr: case ElementType.ByRef: - datas.Add(new EvalDataTypeWithSig(EvalDataType.I, null)); + datas.Add(new EvalDataTypeWithSig(EvalDataType.I, type)); break; case ElementType.String: case ElementType.Class: @@ -205,11 +205,21 @@ namespace Obfuz.Emit datas.Add(type); } - private void PushStackObject(List datas) + private void PushStackObject(List datas, TypeSig type) { - datas.Add(new EvalDataTypeWithSig(EvalDataType.Ref, _method.Module.CorLibTypes.Object)); + PushStack(datas, new EvalDataTypeWithSig(EvalDataType.Ref, type)); } + private void PushStackPointer(List datas, TypeSig type) + { + PushStack(datas, new EvalDataTypeWithSig(EvalDataType.I, type)); + } + + //private void PushStackObject(List datas) + //{ + // datas.Add(new EvalDataTypeWithSig(EvalDataType.Ref, _method.Module.CorLibTypes.Object)); + //} + private EvalDataType CalcBasicBinOpRetType(EvalDataType op1, EvalDataType op2) { switch (op1) @@ -282,7 +292,7 @@ namespace Obfuz.Emit var inputStackDatas = _blockEvalStackStates[bb].inputStackDatas; if (inputStackDatas.Count == 0) { - inputStackDatas.Add(new EvalDataTypeWithSig(EvalDataType.Ref, handler.CatchType.ToTypeSig())); + PushStackObject(inputStackDatas, handler.CatchType.ToTypeSig()); } } if (handler.IsCatch || handler.IsFilter) @@ -291,7 +301,7 @@ namespace Obfuz.Emit var inputStackDatas = _blockEvalStackStates[bb].inputStackDatas; if (inputStackDatas.Count == 0) { - inputStackDatas.Add(new EvalDataTypeWithSig(EvalDataType.Ref, handler.CatchType.ToTypeSig())); + PushStackObject(inputStackDatas, handler.CatchType.ToTypeSig()); } } } @@ -375,7 +385,7 @@ namespace Obfuz.Emit } case Code.Ldnull: { - PushStackObject(newPushedDatas); + PushStackObject(newPushedDatas, corLibTypes.Object); break; } case Code.Ldc_I4_M1: @@ -518,7 +528,7 @@ namespace Obfuz.Emit case Code.Ldind_Ref: { Assert.IsTrue(stackSize > 0); - PushStackObject(newPushedDatas); + PushStackObject(newPushedDatas, stackDatas[stackSize - 1].typeSig?.RemovePinnedAndModifiers().Next ?? corLibTypes.Object); break; } case Code.Ldind_R4: @@ -701,7 +711,7 @@ namespace Obfuz.Emit } case Code.Ldstr: { - PushStack(newPushedDatas, new EvalDataTypeWithSig(EvalDataType.Ref, corLibTypes.String)); + PushStackObject(newPushedDatas, corLibTypes.String); break; } case Code.Newobj: @@ -714,22 +724,22 @@ namespace Obfuz.Emit { Assert.IsTrue(stackSize > 0); var obj = stackDatas[stackSize - 1]; - Assert.IsTrue(obj.type == EvalDataType.Ref); - PushStack(newPushedDatas, new EvalDataTypeWithSig(EvalDataType.Ref, ((ITypeDefOrRef)inst.Operand).ToTypeSig())); + //Assert.IsTrue(obj.type == EvalDataType.Ref); + PushStackObject(newPushedDatas, ((ITypeDefOrRef)inst.Operand).ToTypeSig()); break; } case Code.Isinst: { Assert.IsTrue(stackSize > 0); var obj = stackDatas[stackSize - 1]; - Assert.IsTrue(obj.type == EvalDataType.Ref); - PushStack(newPushedDatas, new EvalDataTypeWithSig(EvalDataType.Ref, ((ITypeDefOrRef)inst.Operand).ToTypeSig())); + //Assert.IsTrue(obj.type == EvalDataType.Ref); + PushStackObject(newPushedDatas, ((ITypeDefOrRef)inst.Operand).ToTypeSig()); break; } case Code.Unbox: { Assert.IsTrue(stackSize > 0); - PushStack(newPushedDatas, EvalDataType.I); + PushStackPointer(newPushedDatas, corLibTypes.IntPtr); break; } case Code.Unbox_Any: @@ -741,7 +751,8 @@ namespace Obfuz.Emit case Code.Box: { Assert.IsTrue(stackSize > 0); - PushStackObject(newPushedDatas); + //PushStack(newPushedDatas, (ITypeDefOrRef)inst.Operand); + PushStackObject(newPushedDatas, ((ITypeDefOrRef)inst.Operand).ToTypeSig()); break; } case Code.Throw: @@ -829,7 +840,7 @@ namespace Obfuz.Emit case Code.Ldelem_Ref: { Assert.IsTrue(stackSize >= 2); - PushStackObject(newPushedDatas); + PushStackObject(newPushedDatas, stackDatas[stackSize - 2].typeSig.RemovePinnedAndModifiers().Next ?? corLibTypes.Object); break; } case Code.Ldelem: diff --git a/Editor/ObfusPasses/ControlFlowObfus/MethodControlFlowCalculator.cs b/Editor/ObfusPasses/ControlFlowObfus/MethodControlFlowCalculator.cs index a77975e..3aa46db 100644 --- a/Editor/ObfusPasses/ControlFlowObfus/MethodControlFlowCalculator.cs +++ b/Editor/ObfusPasses/ControlFlowObfus/MethodControlFlowCalculator.cs @@ -34,15 +34,16 @@ namespace Obfuz.ObfusPasses.ControlFlowObfus private TypeSig GetLocalTypeSig(ICorLibTypes corLibTypes, EvalDataTypeWithSig type) { + TypeSig typeSig = type.typeSig; switch (type.type) { case EvalDataType.Int32: return corLibTypes.Int32; case EvalDataType.Int64: return corLibTypes.Int64; case EvalDataType.Float: return corLibTypes.Single; case EvalDataType.Double: return corLibTypes.Double; - case EvalDataType.I: return corLibTypes.IntPtr; - case EvalDataType.Ref: Assert.IsNotNull(type.typeSig); return type.typeSig; - case EvalDataType.ValueType: Assert.IsNotNull(type.typeSig); return type.typeSig; + case EvalDataType.I: return typeSig ?? corLibTypes.IntPtr; + case EvalDataType.Ref: return typeSig == null || MetaUtil.IsValueType(typeSig) ? corLibTypes.Object : typeSig; + case EvalDataType.ValueType: Assert.IsNotNull(typeSig); return typeSig; case EvalDataType.Token: throw new System.NotSupportedException("Token type is not supported in BasicBlockInputOutputArguments"); default: throw new System.NotSupportedException("not supported EvalDataType"); } diff --git a/Editor/Utils/MetaUtil.cs b/Editor/Utils/MetaUtil.cs index ac48fca..5c016f4 100644 --- a/Editor/Utils/MetaUtil.cs +++ b/Editor/Utils/MetaUtil.cs @@ -254,6 +254,62 @@ namespace Obfuz.Utils } return false; } + public static bool IsValueType(TypeSig typeSig) + { + var a = typeSig.RemovePinnedAndModifiers(); + switch (a.ElementType) + { + case ElementType.Void: return false; + case ElementType.Boolean: + case ElementType.Char: + case ElementType.I1: + case ElementType.U1: + case ElementType.I2: + case ElementType.U2: + case ElementType.I4: + case ElementType.U4: + case ElementType.I8: + case ElementType.U8: + case ElementType.R4: + case ElementType.R8: return true; + case ElementType.String: return true; + case ElementType.TypedByRef: return false; + case ElementType.I: return true; + case ElementType.U: return true; + case ElementType.Object: return false; + case ElementType.Sentinel: return false; + case ElementType.Ptr: return true; + case ElementType.ByRef: return true; + case ElementType.SZArray: return false; + case ElementType.Array: return false; + case ElementType.ValueType: + { + return true; + } + case ElementType.Var: + case ElementType.MVar: return true; + case ElementType.Class: return false; + case ElementType.GenericInst: + { + var gia = (GenericInstSig)a; + TypeDef typeDef = gia.GenericType.ToTypeDefOrRef().ResolveTypeDef(); + if (typeDef == null) + { + throw new Exception($"type:{a} definition could not be found"); + } + if (typeDef.IsEnum) + { + return true; + } + return typeDef.IsValueType; + } + case ElementType.FnPtr: return true; + case ElementType.ValueArray: return true; + case ElementType.Module: return false; + default: + throw new NotSupportedException(typeSig.ToString()); + } + } public static bool MayRenameCustomDataType(ElementType type) {