コード例 #1
0
ファイル: VTableHacks.cs プロジェクト: zwywilliam/USharp
        private static unsafe IntPtr FindOriginalVTableOwner(IntPtr baseMostClass, IntPtr ownerClass, IntPtr functionAddress, int vtableIndex)
        {
            // Don't search lower than the target base
            if (ownerClass == baseMostClass)
            {
                return(ownerClass);
            }

            IntPtr originalOwner = ownerClass;

            while ((ownerClass = Native_UClass.GetSuperClass(ownerClass)) != IntPtr.Zero)
            {
                IntPtr  obj    = Native_UClass.GetDefaultObject(ownerClass, true);
                IntPtr *vtable = *(IntPtr **)obj;
                if (vtable[vtableIndex] == functionAddress)
                {
                    originalOwner = ownerClass;
                }

                // Don't search lower than the target base
                if (ownerClass == baseMostClass)
                {
                    return(ownerClass);
                }
            }
            return(originalOwner);
        }
コード例 #2
0
        private void MoveToTransientPackage(IntPtr obj)
        {
            // Copy of UObjectBase.cpp UClassCompiledInDefer

            // Check if rooted?
            Native_UObjectBaseUtility.RemoveFromRoot(obj);
            Native_UObjectBaseUtility.ClearFlags(obj, EObjectFlags.Standalone | EObjectFlags.Public);

            IntPtr defaultObject = Native_UClass.GetDefaultObject(obj, false);

            if (defaultObject != IntPtr.Zero)
            {
                // Check if rooted?
                Native_UObjectBaseUtility.RemoveFromRoot(defaultObject);
                Native_UObjectBaseUtility.ClearFlags(defaultObject, EObjectFlags.Standalone | EObjectFlags.Public);
            }

            FName oldClassRename = NativeReflection.MakeUniqueObjectName(NativeReflection.GetTransientPackage(),
                                                                         Native_UObjectBase.GetClass(obj), new FName("USharpHotReload_" + Native_UObjectBase.GetFName(obj)));

            using (FStringUnsafe oldClassRenameUnsafe = new FStringUnsafe(oldClassRename.ToString()))
            {
                Native_UObject.Rename(obj, ref oldClassRenameUnsafe.Array, NativeReflection.GetTransientPackage(), ERenameFlags.None);
            }

            Native_UObjectBaseUtility.SetFlags(obj, EObjectFlags.Transient);
            Native_UObjectBaseUtility.AddToRoot(obj);
        }
コード例 #3
0
ファイル: VTableHacks.cs プロジェクト: zwywilliam/USharp
        public static unsafe void Load()
        {
            vtableRedirects = new List <FunctionRedirect>();
            AddVTableRedirects();

            // We have three classes UDummyObject3 : UDummyObject2 : UDummyObject1 : UObject
            //
            // UDummyObject1 overrides function "X"
            // UDummyObject2 doesn't function "X"
            // UDummyObject3 overrides function "X"
            //
            // Scan the vtable for each dummy object, search for an entry where vtable entry 1==2 && 1!=3
            // - We can assume this entry is our desired vtable index
            // - This may break down in situations where there is multiple inheritance
            // - If this fails to complete properly this will result in a crash (or worse)

            foreach (FunctionRedirect redirect in vtableRedirects)
            {
                IntPtr dummyClass1 = NativeReflection.GetClass("/Script/USharp." + redirect.DummyName + "1");
                IntPtr dummyClass2 = NativeReflection.GetClass("/Script/USharp." + redirect.DummyName + "2");
                IntPtr dummyClass3 = NativeReflection.GetClass("/Script/USharp." + redirect.DummyName + "3");

                IntPtr dummyObject1 = Native_UClass.GetDefaultObject(dummyClass1, true);
                IntPtr dummyObject2 = Native_UClass.GetDefaultObject(dummyClass2, true);
                IntPtr dummyObject3 = Native_UClass.GetDefaultObject(dummyClass3, true);

                IntPtr *dummyVTable1 = *(IntPtr **)dummyObject1;
                IntPtr *dummyVTable2 = *(IntPtr **)dummyObject2;
                IntPtr *dummyVTable3 = *(IntPtr **)dummyObject3;

                for (int i = 0; i < int.MaxValue; i++)
                {
                    IntPtr dummyFunc1 = dummyVTable1[i];
                    IntPtr dummyFunc2 = dummyVTable2[i];
                    IntPtr dummyFunc3 = dummyVTable3[i];

                    if (dummyFunc1 == dummyFunc2 && dummyFunc1 != dummyFunc3)
                    {
                        redirect.NativeCallback = dummyFunc1;
                        redirect.VTableIndex    = i;
                        break;
                    }
                }
            }
        }
コード例 #4
0
 /// <summary>
 /// Get the default object from the class
 /// </summary>
 /// <param name="createIfNeeded">if true (default) then the CDO is created if it is NULL.</param>
 /// <returns>the CDO for this class</returns>
 public UObject GetDefaultObject(bool createIfNeeded = true)
 {
     return(GCHelper.Find(Native_UClass.GetDefaultObject(Address, createIfNeeded)));
 }