예제 #1
0
        private static T FindOrLoadObject <T>(string pathName) where T : UObject
        {
            if (typeof(T) == typeof(UPackage))
            {
                return(FindOrLoadPackage(pathName) as T);
            }

            // If there is no dot, add a dot and repeat the object name.
            int packageDelimPos = pathName.IndexOf('.');

            if (packageDelimPos == -1)
            {
                int objectNameStart = pathName.LastIndexOf('/');
                if (objectNameStart != -1)
                {
                    pathName += "." + pathName.Substring(objectNameStart + 1);
                }
            }

            UClass unrealClass = UClass.GetClass <T>();

            if (unrealClass != null)
            {
                unrealClass.GetDefaultObject();// force the CDO to be created if it hasn't already
                T obj = UObject.LoadObject <T>(null, pathName);
                if (obj != null)
                {
                    obj.AddToRoot();
                }
                return(obj);
            }
            return(null);
        }
예제 #2
0
        public static unsafe void HackVTable(UObject obj)
        {
            // This will swap out the vtable entry and store the old one in our managed UClass

            if (!Native_UObjectBaseUtility.IsA(obj.Address, Runtime.Classes.UClass))
            {
                UClass unrealClass = obj.GetClass();
                if (unrealClass.VTableOriginalFunctions == null)
                {
                    IntPtr *vtable = *(IntPtr **)obj.Address;

                    unrealClass.VTableOriginalFunctions = new Dictionary <int, UClass.VTableOriginalFunc>();
                    foreach (FunctionRedirect redirect in vtableRedirects)
                    {
                        if (!Native_UObjectBaseUtility.IsA(obj.Address, redirect.Class))
                        {
                            continue;
                        }

                        IntPtr originalFunctionAddress = vtable[redirect.VTableIndex];

                        if (originalFunctionAddress != redirect.NativeCallback)
                        {
                            IntPtr originalOwnerClassAddress = FindOriginalVTableOwner(
                                redirect.Class, unrealClass.Address, originalFunctionAddress, redirect.VTableIndex);

                            if (originalOwnerClassAddress != unrealClass.Address)
                            {
                                UClass originalOwnerClass = GCHelper.Find <UClass>(originalOwnerClassAddress);
                                if (originalOwnerClass.VTableOriginalFunctions == null)
                                {
                                    HackVTable(originalOwnerClass.GetDefaultObject());
                                }
                            }

                            IntPtr pageAlignedPtr = FMemory.PageAlignPointer((IntPtr)(&vtable[redirect.VTableIndex]));
                            FMemory.PageProtect(pageAlignedPtr, (IntPtr)IntPtr.Size, true, true);
                            *(&vtable[redirect.VTableIndex]) = redirect.NativeCallback;
                        }
                        else
                        {
                            // The VTable has already been swapped out. Find the original function address.
                            UClass superClass = unrealClass;
                            while ((superClass = superClass.GetSuperClass()) != null && superClass.VTableOriginalFunctions == null)
                            {
                            }

                            Debug.Assert(superClass != null && superClass.VTableOriginalFunctions != null &&
                                         superClass.VTableOriginalFunctions.ContainsKey(redirect.VTableIndex));

                            originalFunctionAddress = superClass.VTableOriginalFunctions[redirect.VTableIndex].FuncAddress;
                        }

                        unrealClass.VTableOriginalFunctions.Add(redirect.VTableIndex, new UClass.VTableOriginalFunc(originalFunctionAddress));
                    }
                }
            }
        }
예제 #3
0
        /// <summary>
        /// Get default object of a class.
        /// </summary>
        public static T GetDefault <T>() where T : UObject
        {
            UClass unrealClass = UClass.GetClass <T>();

            if (unrealClass != null)
            {
                return(unrealClass.GetDefaultObject() as T);
            }
            return(null);
        }
예제 #4
0
        /// <summary>
        /// Get the CDO if we are referencing a valid class
        /// </summary>
        /// <returns>the CDO, or NULL</returns>
        public T GetDefaultObject()
        {
            UClass unrealClass = Value;

            if (unrealClass != null)
            {
                return(unrealClass.GetDefaultObject() as T);
            }
            return(null);
        }
예제 #5
0
 /// <summary>
 /// Gets the default object of a class.
 /// </summary>
 /// <typeparam name="T">The object type</typeparam>
 /// <param name="unrealClass">The class to get the CDO for.</param>
 /// <returns>Class default object (CDO).</returns>
 public static T GetDefault <T>(UClass unrealClass) where T : UObject
 {
     if (unrealClass != null && unrealClass.IsA <T>())
     {
         UObject defaultObject = unrealClass.GetDefaultObject();
         if (defaultObject.IsA <T>())
         {
             return(defaultObject as T);
         }
     }
     return(null);
 }