66using System . Security . Cryptography ;
77using System . Threading ;
88using MelonLoader ;
9+ using UnhollowerBaseLib ;
910
1011namespace AdvancedSafety
1112{
@@ -27,12 +28,13 @@ public class ReaderPatches
2728
2829 private static readonly string [ ] ourAllowedFields = { "m_BreakForce" , "m_BreakTorque" , "collisionSphereDistance" , "maxDistance" , "inSlope" , "outSlope" } ;
2930
30- private static readonly Dictionary < string , ( int ProduceMixer , int TransferFloat , int CountNodes , int DebugAssert , int ReaderOOB , int ReallocateString ) > ourOffsets = new ( ) {
31- { "aCEmIwSIcjYriBQDFjQlpTNNW1/kA8Wlbkqelmt1USOMB09cnKwK7QWyOulz9d7DEYJh4+vO0Ldv8gdH+dZCrg==" , ( 0x4997C0 , 0xD7320 , 0 , 0 , 0 , 0 ) } , // U2018.4.20 non-dev
32- { "5dkhl/dWeTREXhHCIkZK17mzZkbjhTKlxb+IUSk+YaWzZrrV+G+M0ekTOEGjZ4dJuB4O3nU/oE3dycXWeJq9uA==" , ( 0xA80660 , 0xC7B40 , 0 , 0 , 0 , 0 ) } , // U2019.4.28 non-dev
33- { "MV6xP7theydao4ENbGi6BbiBxdZsgGOBo/WrPSeIqh6A/E00NImjUNZn+gL+ZxzpVbJms7nUb6zluLL3+aIcfg==" , ( 0xA82350 , 0xC7E50 , 0 , 0 , 0 , 0 ) } , // U2019.4.29 non-dev
34- { "ccZ4F7iE7a78kWdXdMekJzP7/ktzS5jOOS8IOITxa1C5Jg2TKxC0/ywY8F0o9I1vZHsxAO4eh7G2sOGzsR/+uQ==" , ( 0xA83410 , 0xC7E80 , 0 , 0 , 0 , 0 ) } , // U2019.4.30 non-dev
35- { "sgZUlX3+LSHKnTiTC+nXNcdtLOTrAB1fNjBLOwDdKzCyndlFLAdL0udR4S1szTC/q5pnFhG3Kdspsj5jvwLY1A==" , ( 0xA86270 , 0xC8230 , 0xDF29F0 , 0xDDBDC0 , 0x7B9EB0 , 0xC69F0 ) } , // U2019.4.31 non-dev
31+ private static readonly Dictionary < string , ( int ProduceMixer , int TransferFloat , int CountNodes , int DebugAssert ,
32+ int ReaderOOB , int ReallocateString , int TransferMonoObject , int TransferUEObjectSBR ) > ourOffsets = new ( )
33+ {
34+ {
35+ "sgZUlX3+LSHKnTiTC+nXNcdtLOTrAB1fNjBLOwDdKzCyndlFLAdL0udR4S1szTC/q5pnFhG3Kdspsj5jvwLY1A==" ,
36+ ( 0xA86270 , 0xC8230 , 0xDF29F0 , 0xDDBDC0 , 0x7B9EB0 , 0xC69F0 , 0x8D1160 , 0x8E5CD0 )
37+ } , // U2019.4.31 non-dev
3638 } ;
3739
3840 internal static void ApplyPatches ( )
@@ -73,6 +75,12 @@ internal static void ApplyPatches()
7375
7476 // core::StringStorageDefault<char>::reallocate, identified to be an issue by Requi&Ben
7577 DoPatch ( module , offsets . ReallocateString , ReallocateStringPatch , out ourOriginalRealloc ) ;
78+
79+ // TransferPPtrToMonoObject
80+ DoPatch ( module , offsets . TransferMonoObject , TransferMonoObjectPatch , out ourOriginalTransferMonoObject ) ;
81+
82+ // TransferField_NonArray<SafeBinaryRead,Converter_UnityEngineObject>
83+ DoPatch ( module , offsets . TransferUEObjectSBR , TransferUeObjectSbrPatch , out ourOriginalTransferUeObjectSbr ) ;
7684 }
7785
7886 break ;
@@ -149,6 +157,63 @@ private static void ReaderOobPatch(IntPtr thisPtr, long a, long b)
149157 }
150158 }
151159
160+ [ UnmanagedFunctionPointer ( CallingConvention . Cdecl ) ]
161+ private delegate void TransferObjectSbrDelegate ( IntPtr staticInfo , IntPtr runtimeInfo , IntPtr converter ) ;
162+
163+ [ ThreadStatic ] private static Stack < IntPtr > ourCurrentSafeTransferStack ;
164+ private static TransferObjectSbrDelegate ourOriginalTransferUeObjectSbr ;
165+
166+ private static void TransferUeObjectSbrPatch ( IntPtr staticInfo , IntPtr runtimeInfo , IntPtr converter )
167+ {
168+ ourCurrentSafeTransferStack ??= new Stack < IntPtr > ( ) ;
169+ ourCurrentSafeTransferStack . Push ( staticInfo ) ;
170+ try
171+ {
172+ ourOriginalTransferUeObjectSbr ( staticInfo , runtimeInfo , converter ) ;
173+ }
174+ finally
175+ {
176+ ourCurrentSafeTransferStack . Pop ( ) ;
177+ }
178+ }
179+
180+ [ UnmanagedFunctionPointer ( CallingConvention . Cdecl ) ]
181+ private delegate IntPtr TransferMonoObjectDelegate ( ref IntPtr hiddenThisReturn , IntPtr instanceId ,
182+ IntPtr il2cppClass , IntPtr dataToCreateNull , IntPtr transferFlags ) ;
183+
184+ private static TransferMonoObjectDelegate ourOriginalTransferMonoObject ;
185+
186+ private static unsafe IntPtr TransferMonoObjectPatch ( ref IntPtr hiddenThisReturn , IntPtr instanceId ,
187+ IntPtr il2cppClass , IntPtr dataToCreateNull , IntPtr transferFlags )
188+ {
189+ var result = ourOriginalTransferMonoObject ( ref hiddenThisReturn , instanceId , il2cppClass , dataToCreateNull , transferFlags ) ;
190+
191+ if ( hiddenThisReturn == IntPtr . Zero || ourCurrentSafeTransferStack == null || ourCurrentSafeTransferStack . Count == 0 ) return result ;
192+
193+ var objectType = * ( IntPtr * ) hiddenThisReturn ;
194+
195+ var topStaticInfo = ( StaticTransferInfoPrefix * ) ourCurrentSafeTransferStack . Peek ( ) ;
196+ var staticFieldInfoPtr = topStaticInfo ->field ;
197+
198+ var fieldType = IL2CPP . il2cpp_class_from_type ( staticFieldInfoPtr ->typePtr ) ;
199+ if ( IL2CPP . il2cpp_class_is_assignable_from ( fieldType , objectType ) ) return result ;
200+
201+ var fieldName = Marshal . PtrToStringAnsi ( staticFieldInfoPtr ->name ) ;
202+
203+ MelonDebug . Msg ( $ "While deserializing field of type { RenderTypeName ( fieldType ) } named { fieldName } we got an object of type { RenderTypeName ( objectType ) } ") ;
204+ hiddenThisReturn = IntPtr . Zero ;
205+
206+ return result ;
207+ }
208+
209+ private static string RenderTypeName ( IntPtr classPtr ) => Il2CppSystem . Type . internal_from_handle ( IL2CPP . il2cpp_class_get_type ( classPtr ) ) . ToString ( ) ;
210+
211+ [ StructLayout ( LayoutKind . Sequential ) ]
212+ private unsafe struct StaticTransferInfoPrefix
213+ {
214+ public Il2CppFieldInfo_24_1 * field ;
215+ }
216+
152217
153218 [ UnmanagedFunctionPointer ( CallingConvention . Cdecl ) ]
154219 private delegate void DebugAssertDelegate ( IntPtr data ) ;
0 commit comments