public static bool RandomizeExport(ExportEntry arg1, RandomizationOption arg2)
 {
     // Write debug code here
     //var hi = arg1.InstancedFullPath;
     if (arg1.ClassName == "Function")
     {
         var         unFunc = UE3FunctionReader.ReadFunction(arg1);
         TextBuilder tb     = new TextBuilder();
         unFunc.Decompile(tb, false, false);
     }
     return(true);
 }
Exemple #2
0
        public override List <(UIndex, string)> GetUIndexes(MEGame game)
        {
            List <(UIndex, string)> uIndices = base.GetUIndexes(game);

            uIndices.Add((Children, "ChildListStart"));

            if (Export.ClassName == "Function")
            {
                if (Export.Game == MEGame.ME3)
                {
                    try
                    {
                        (List <Token> tokens, _) = Bytecode.ParseBytecode(ScriptBytes, Export);
                        foreach (var t in tokens)
                        {
                            {
                                var refs = t.inPackageReferences.Where(x => x.type == Token.INPACKAGEREFTYPE_ENTRY);
                                uIndices.AddRange(refs.Select(x => (new UIndex(x.value), $"Reference inside of function at 0x{x.position:X}")));
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        Debug.WriteLine($"Error decompiling function {Export.FullPath}: {e.Message}");
                    }
                }
                else
                {
                    try
                    {
                        var func = UE3FunctionReader.ReadFunction(Export);
                        func.Decompile(new TextBuilder(), false); //parse bytecode
                        var entryRefs = func.EntryReferences;
                        uIndices.AddRange(entryRefs.Select(x =>
                                                           (new UIndex(x.Value.UIndex), $"Reference inside of function at 0x{x.Key:X}")));
                    }
                    catch (Exception e)
                    {
                        Debug.WriteLine($"Error decompiling function {Export.FullPath}: {e.Message}");
                    }
                }
            }

            return(uIndices);
        }
Exemple #3
0
        private void StartFunctionScan(byte[] data)
        {
            DecompiledScriptBlocks.ClearEx();
            TokenList.ClearEx();
            ScriptHeaderBlocks.ClearEx();
            ScriptFooterBlocks.ClearEx();
            if (CurrentLoadedExport.FileRef.Game == MEGame.ME3)
            {
                var func = new ME3Explorer.Unreal.Classes.Function(data, CurrentLoadedExport, CurrentLoadedExport.ClassName == "State" ? Convert.ToInt32(StartOffset_Changer.Text) : 32);


                func.ParseFunction();
                DecompiledScriptBlocks.Add(func.GetSignature());
                DecompiledScriptBlocks.AddRange(func.ScriptBlocks);
                TokenList.AddRange(func.SingularTokenList);

                int pos = 12;

                var functionSuperclass = BitConverter.ToInt32(CurrentLoadedExport.Data, pos);
                ScriptHeaderBlocks.Add(new ScriptHeaderItem("Function superclass", functionSuperclass, pos, functionSuperclass != 0 ? CurrentLoadedExport.FileRef.getEntry(functionSuperclass) : null));

                pos += 4;
                var nextItemCompilingChain = BitConverter.ToInt32(CurrentLoadedExport.Data, pos);
                ScriptHeaderBlocks.Add(new ScriptHeaderItem("Next item in loading chain", nextItemCompilingChain, pos, nextItemCompilingChain > 0 ? CurrentLoadedExport : null));

                pos += 4;
                nextItemCompilingChain = BitConverter.ToInt32(CurrentLoadedExport.Data, pos);
                ScriptHeaderBlocks.Add(new ScriptHeaderItem("Children Probe Start", nextItemCompilingChain, pos, nextItemCompilingChain > 0 ? CurrentLoadedExport : null));

                pos += 4;
                ScriptHeaderBlocks.Add(new ScriptHeaderItem("Unknown 2 (Memory size?)", BitConverter.ToInt32(CurrentLoadedExport.Data, pos), pos));

                pos += 4;
                ScriptHeaderBlocks.Add(new ScriptHeaderItem("Size", BitConverter.ToInt32(CurrentLoadedExport.Data, pos), pos));

                pos = CurrentLoadedExport.Data.Length - 6;
                string flagStr = func.GetFlags();
                ScriptFooterBlocks.Add(new ScriptHeaderItem("Native Index", BitConverter.ToInt16(CurrentLoadedExport.Data, pos), pos));
                pos += 2;
                ScriptFooterBlocks.Add(new ScriptHeaderItem("Flags", $"0x{BitConverter.ToInt32(CurrentLoadedExport.Data, pos).ToString("X8")} {func.GetFlags().Substring(6)}", pos));
            }
            else if (CurrentLoadedExport.FileRef.Game == MEGame.ME1)
            {
                //Header
                int pos = 16;

                var nextItemCompilingChain = BitConverter.ToInt32(CurrentLoadedExport.Data, pos);
                ScriptHeaderBlocks.Add(new ScriptHeaderItem("Next item in loading chain", nextItemCompilingChain, pos, nextItemCompilingChain > 0 ? CurrentLoadedExport : null));

                pos += 8;
                nextItemCompilingChain = BitConverter.ToInt32(CurrentLoadedExport.Data, pos);
                ScriptHeaderBlocks.Add(new ScriptHeaderItem("Children Probe Start", nextItemCompilingChain, pos, nextItemCompilingChain > 0 ? CurrentLoadedExport : null));

                pos += 4;
                ScriptHeaderBlocks.Add(new ScriptHeaderItem("Unknown 1 (??)", BitConverter.ToInt32(CurrentLoadedExport.Data, pos), pos));

                pos += 4;
                ScriptHeaderBlocks.Add(new ScriptHeaderItem("Unknown 2 (Line??)", BitConverter.ToInt32(CurrentLoadedExport.Data, pos), pos));

                pos += 4;
                ScriptHeaderBlocks.Add(new ScriptHeaderItem("Unknown 3 (TextPos??)", BitConverter.ToInt32(CurrentLoadedExport.Data, pos), pos));

                pos += 4;
                ScriptHeaderBlocks.Add(new ScriptHeaderItem("Script Size", BitConverter.ToInt32(CurrentLoadedExport.Data, pos), pos));
                pos          += 4;
                BytecodeStart = pos;
                var func = UE3FunctionReader.ReadFunction(CurrentLoadedExport);
                func.Decompile(new TextBuilder(), false); //parse bytecode

                bool defined = func.HasFlag("Defined");
                if (defined)
                {
                    DecompiledScriptBlocks.Add(func.FunctionSignature + " {");
                }
                else
                {
                    DecompiledScriptBlocks.Add(func.FunctionSignature);
                }
                for (int i = 0; i < func.Statements.statements.Count; i++)
                {
                    Statement s = func.Statements.statements[i];
                    DecompiledScriptBlocks.Add(s);
                    if (s.Reader != null && i == 0)
                    {
                        //Add tokens read from statement. All of them point to the same reader, so just do only the first one.
                        TokenList.AddRange(s.Reader.ReadTokens.Select(x => x.ToBytecodeSingularToken(pos)).OrderBy(x => x.StartPos));
                    }
                }

                if (defined)
                {
                    DecompiledScriptBlocks.Add("}");
                }

                //Footer
                pos = CurrentLoadedExport.Data.Length - (func.HasFlag("Net") ? 17 : 15);
                string flagStr = func.GetFlags();
                ScriptFooterBlocks.Add(new ScriptHeaderItem("Native Index", BitConverter.ToInt16(CurrentLoadedExport.Data, pos), pos));
                pos += 2;

                ScriptFooterBlocks.Add(new ScriptHeaderItem("Operator Precedence", CurrentLoadedExport.Data[pos], pos));
                pos++;

                int functionFlags = BitConverter.ToInt32(CurrentLoadedExport.Data, pos);
                ScriptFooterBlocks.Add(new ScriptHeaderItem("Flags", $"0x{functionFlags.ToString("X8")} {flagStr}", pos));
                pos += 4;

                //if ((functionFlags & func._flagSet.GetMask("Net")) != 0)
                //{
                //ScriptFooterBlocks.Add(new ScriptHeaderItem("Unknown 1 (RepOffset?)", BitConverter.ToInt16(CurrentLoadedExport.Data, pos), pos));
                //pos += 2;
                //}

                int friendlyNameIndex = BitConverter.ToInt32(CurrentLoadedExport.Data, pos);
                ScriptFooterBlocks.Add(new ScriptHeaderItem("Friendly Name Table Index", $"0x{friendlyNameIndex.ToString("X8")} {CurrentLoadedExport.FileRef.getNameEntry(friendlyNameIndex)}", pos));
                pos += 4;

                ScriptFooterBlocks.Add(new ScriptHeaderItem("Unknown 2", $"0x{BitConverter.ToInt16(CurrentLoadedExport.Data, pos).ToString("X4")}", pos));
                pos += 4;

                //ME1Explorer.Unreal.Classes.Function func = new ME1Explorer.Unreal.Classes.Function(data, CurrentLoadedExport.FileRef as ME1Package);
                //try
                //{
                //    Function_TextBox.Text = func.ToRawText();
                //}
                //catch (Exception e)
                //{
                //    Function_TextBox.Text = "Error parsing function: " + e.Message;
                //}
            }
            else
            {
                //Function_TextBox.Text = "Parsing UnrealScript Functions for this game is not supported.";
            }
        }
Exemple #4
0
        public void TestFunctionParsing()
        {
            // This method is essentially test of the BytecodeEditor parser with the actual ui logic all removed
            GlobalTest.Init();

            // Loads compressed packages, save them uncompressed. Load package, save re-compressed, compare results
            var packagesPath = GlobalTest.GetTestPackagesDirectory();
            //var packages = Directory.GetFiles(packagesPath, "*.*", SearchOption.AllDirectories);
            var packages = Directory.GetFiles(packagesPath, "*.*", SearchOption.AllDirectories);

            foreach (var p in packages)
            {
                if (p.RepresentsPackageFilePath())
                {
                    (var game, var platform) = GlobalTest.GetExpectedTypes(p);

                    // Use to skip
                    //if (platform != MEPackage.GamePlatform.Xenon) continue;
                    //if (game != MEGame.ME1) continue;

                    Console.WriteLine($"Opening package {p}");

                    // Do not use package caching in tests
                    var originalLoadedPackage = MEPackageHandler.OpenMEPackage(p, forceLoadFromDisk: true);
                    foreach (var export in originalLoadedPackage.Exports.Where(x => x.ClassName == "Function" || x.ClassName == "State"))
                    {
                        //Console.WriteLine($" >> Decompiling {export.InstancedFullPath}");
                        var data    = export.Data;
                        var funcBin = ObjectBinary.From <UFunction>(export); //parse it out
                        if (export.FileRef.Game == MEGame.ME3 || export.FileRef.Platform == MEPackage.GamePlatform.PS3)
                        {
                            var func = new Function(data, export);
                            func.ParseFunction();
                            func.GetSignature();
                            if (export.ClassName == "Function")
                            {
                                var    nativeBackOffset = export.FileRef.Game < MEGame.ME3 ? 7 : 6;
                                var    pos         = data.Length - nativeBackOffset;
                                string flagStr     = func.GetFlags();
                                var    nativeIndex = EndianReader.ToInt16(data, pos, export.FileRef.Endian);
                                pos += 2;
                                var flags = EndianReader.ToInt16(data, pos, export.FileRef.Endian);
                            }
                            else
                            {
                                //State
                                //parse remaining
                                var footerstartpos = 0x20 + funcBin.ScriptStorageSize;
                                var footerdata     = data.Slice(footerstartpos, (int)data.Length - (footerstartpos));
                                var fpos           = 0;
                                //ScriptFooterBlocks.Add(new ScriptHeaderItem("Probemask?", "??", fpos + footerstartpos) { length = 8 });
                                fpos += 0x8;

                                //ScriptFooterBlocks.Add(new ScriptHeaderItem("Unknown 8 FF's", "??", fpos + footerstartpos) { length = 8 });
                                fpos += 0x8;

                                //ScriptFooterBlocks.Add(new ScriptHeaderItem("Label Table Offset", "??", fpos + footerstartpos) { length = 2 });
                                fpos += 0x2;

                                var stateFlagsBytes = footerdata.Slice(fpos, 0x4);
                                var stateFlags      = (StateFlags)EndianReader.ToInt32(stateFlagsBytes, 0, export.FileRef.Endian);
                                var names           = stateFlags.ToString().Split(new[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries);
                                fpos += 0x4;

                                var numMappedFunctions = EndianReader.ToInt32(footerdata, fpos, export.FileRef.Endian);
                                fpos += 4;
                                for (int i = 0; i < numMappedFunctions; i++)
                                {
                                    var name        = EndianReader.ToInt32(footerdata, fpos, export.FileRef.Endian);
                                    var uindex      = EndianReader.ToInt32(footerdata, fpos + 8, export.FileRef.Endian);
                                    var funcMapText = $"{export.FileRef.GetNameEntry(name)} => {export.FileRef.GetEntry(uindex)?.FullPath}()";
                                    fpos += 12;
                                }
                            }
                        }
                        else if (export.FileRef.Game == MEGame.ME1 || export.FileRef.Game == MEGame.ME2)
                        {
                            //Header
                            int pos = 16;

                            var nextItemCompilingChain = EndianReader.ToInt32(data, pos, export.FileRef.Endian);
                            //ScriptHeaderBlocks.Add(new ScriptHeaderItem("Next item in loading chain", nextItemCompilingChain, pos, nextItemCompilingChain > 0 ? export : null));

                            pos += 8;
                            nextItemCompilingChain = EndianReader.ToInt32(data, pos, export.FileRef.Endian);
                            //ScriptHeaderBlocks.Add(new ScriptHeaderItem("Children Probe Start", nextItemCompilingChain, pos, nextItemCompilingChain > 0 ? export : null));

                            pos += 8;
                            var line = EndianReader.ToInt32(data, pos, export.FileRef.Endian);
                            //ScriptHeaderBlocks.Add(new ScriptHeaderItem("Line", EndianReader.ToInt32(data, pos, export.FileRef.Endian), pos));

                            pos += 4;
                            //EndianReader.ToInt32(data, pos, export.FileRef.Endian)
                            //ScriptHeaderBlocks.Add(new ScriptHeaderItem("TextPos", EndianReader.ToInt32(data, pos, export.FileRef.Endian), pos));

                            pos += 4;
                            int scriptSize = EndianReader.ToInt32(data, pos, export.FileRef.Endian);
                            //ScriptHeaderBlocks.Add(new ScriptHeaderItem("Script Size", scriptSize, pos));
                            pos += 4;
                            var BytecodeStart = pos;
                            var func          = export.ClassName == "State" ? UE3FunctionReader.ReadState(export, data) : UE3FunctionReader.ReadFunction(export, data);
                            func.Decompile(new TextBuilder(), false); //parse bytecode

                            bool defined = func.HasFlag("Defined");
                            //if (defined)
                            //{
                            //    DecompiledScriptBlocks.Add(func.FunctionSignature + " {");
                            //}
                            //else
                            //{
                            //    //DecompiledScriptBlocks.Add(func.FunctionSignature);
                            //}
                            for (int i = 0; i < func.Statements.statements.Count; i++)
                            {
                                Statement s = func.Statements.statements[i];
                                s.SetPaddingForScriptSize(scriptSize);
                                if (s.Reader != null && i == 0)
                                {
                                    //Add tokens read from statement. All of them point to the same reader, so just do only the first one.
                                    s.Reader.ReadTokens.Select(x => x.ToBytecodeSingularToken(pos)).OrderBy(x => x.StartPos);
                                }
                            }

                            //if (defined)
                            //{
                            //    DecompiledScriptBlocks.Add("}");
                            //}

                            //Footer
                            pos = data.Length - (func.HasFlag("Net") ? 17 : 15);
                            string flagStr = func.GetFlags();
                            //ScriptFooterBlocks.Add(new ScriptHeaderItem("Native Index", EndianReader.ToInt16(data, pos, export.FileRef.Endian), pos));
                            pos += 2;

                            //ScriptFooterBlocks.Add(new ScriptHeaderItem("Operator Precedence", data[pos], pos));
                            pos++;

                            int functionFlags = EndianReader.ToInt32(data, pos, export.FileRef.Endian);
                            //ScriptFooterBlocks.Add(new ScriptHeaderItem("Flags", $"0x{functionFlags:X8} {flagStr}", pos));
                            pos += 4;

                            //if ((functionFlags & func._flagSet.GetMask("Net")) != 0)
                            //{
                            //ScriptFooterBlocks.Add(new ScriptHeaderItem("Unknown 1 (RepOffset?)", EndianReader.ToInt16(data, pos, export.FileRef.Endian), pos));
                            //pos += 2;
                            //}

                            int friendlyNameIndex = EndianReader.ToInt32(data, pos, export.FileRef.Endian);
                            var friendlyName      = export.FileRef.GetNameEntry(friendlyNameIndex);
                            //ScriptFooterBlocks.Add(new ScriptHeaderItem("Friendly Name", Pcc.GetNameEntry(friendlyNameIndex), pos) { length = 8 });
                            pos += 8;

                            //ME1Explorer.Unreal.Classes.Function func = new ME1Explorer.Unreal.Classes.Function(data, export.FileRef as ME1Package);
                            //try
                            //{
                            //    Function_TextBox.Text = func.ToRawText();
                            //}
                            //catch (Exception e)
                            //{
                            //    Function_TextBox.Text = "Error parsing function: " + e.Message;
                            //}
                        }
                        else
                        {
                            //Function_TextBox.Text = "Parsing UnrealScript Functions for this game is not supported.";
                        }
                    }
                    //}
                }
            }
        }
        public static int ReplaceAllReferencesToThisOne(this IEntry baseEntry, IEntry replacementEntry)
        {
            int rcount = 0;
            int selectedEntryUIndex = baseEntry.UIndex;
            int replacementUIndex   = replacementEntry.UIndex;
            var references          = baseEntry.GetEntriesThatReferenceThisOne();

            foreach ((IEntry entry, List <string> propsList) in references)
            {
                if (entry is ExportEntry exp)
                {
                    if (propsList.Any(l => l.StartsWith("Property:")))
                    {
                        var newprops = replacePropertyReferences(exp.GetProperties(), selectedEntryUIndex, replacementUIndex, ref rcount);
                        exp.WriteProperties(newprops);
                    }
                    else
                    {
                        if (propsList.Any(l => l.StartsWith("(Binary prop:")) && !exp.IsDefaultObject && ObjectBinary.From(exp) is ObjectBinary objBin)
                        {
                            List <(UIndex, string)> indices = objBin.GetUIndexes(exp.FileRef.Game);
                            foreach ((UIndex uIndex, _) in indices)
                            {
                                if (uIndex.value == selectedEntryUIndex)
                                {
                                    uIndex.value = replacementUIndex;
                                    rcount++;
                                }
                            }

                            //script relinking is not covered by standard binary relinking
                            if (objBin is UStruct uStruct && uStruct.ScriptBytes.Length > 0)
                            {
                                if (exp.Game == MEGame.ME3)
                                {
                                    (List <Token> tokens, _) = Bytecode.ParseBytecode(uStruct.ScriptBytes, exp);
                                    foreach (Token token in tokens)
                                    {
                                        foreach ((int pos, int type, int value) in token.inPackageReferences)
                                        {
                                            switch (type)
                                            {
                                            case Token.INPACKAGEREFTYPE_ENTRY when value == selectedEntryUIndex:
                                                uStruct.ScriptBytes.OverwriteRange(pos, BitConverter.GetBytes(replacementUIndex));
                                                rcount++;
                                                break;
                                            }
                                        }
                                    }
                                }
                                else
                                {
                                    var func = entry.ClassName == "State" ? UE3FunctionReader.ReadState(exp) : UE3FunctionReader.ReadFunction(exp);
                                    func.Decompile(new TextBuilder(), false);

                                    foreach ((long position, IEntry ent) in func.EntryReferences)
                                    {
                                        if (ent.UIndex == selectedEntryUIndex && position < uStruct.ScriptBytes.Length)
                                        {
                                            uStruct.ScriptBytes.OverwriteRange((int)position, BitConverter.GetBytes(replacementUIndex));
                                            rcount++;
                                        }
                                    }
                                }
                            }

                            exp.WriteBinary(objBin);
                        }
                    }
                }
            }

            return(rcount);
Exemple #6
0
        public static List <EntryStringPair> Relink(ExportEntry sourceExport, ExportEntry relinkingExport, OrderedMultiValueDictionary <IEntry, IEntry> crossPCCObjectMappingList,
                                                    bool importExportDependencies = false, RelinkerCache relinkerCache = null)
        {
            var        relinkFailedReport = new List <EntryStringPair>();
            IMEPackage sourcePcc          = sourceExport.FileRef;

            byte[] prePropBinary = relinkingExport.GetPrePropBinary();

            //Relink stack
            if (relinkingExport.HasStack)
            {
                int uIndex       = BitConverter.ToInt32(prePropBinary, 0);
                var relinkResult = relinkUIndex(sourceExport.FileRef, relinkingExport, ref uIndex, "Stack: Node",
                                                crossPCCObjectMappingList, "", importExportDependencies, relinkerCache);
                if (relinkResult is null)
                {
                    prePropBinary.OverwriteRange(0, BitConverter.GetBytes(uIndex));
                }
                else
                {
                    relinkFailedReport.Add(relinkResult);
                }

                uIndex       = BitConverter.ToInt32(prePropBinary, 4);
                relinkResult = relinkUIndex(sourceExport.FileRef, relinkingExport, ref uIndex, "Stack: StateNode",
                                            crossPCCObjectMappingList, "", importExportDependencies, relinkerCache);
                if (relinkResult is null)
                {
                    prePropBinary.OverwriteRange(4, BitConverter.GetBytes(uIndex));
                }
                else
                {
                    relinkFailedReport.Add(relinkResult);
                }
            }
            //Relink Component's TemplateOwnerClass
            else if (relinkingExport.TemplateOwnerClassIdx is var toci && toci >= 0)
            {
                int uIndex       = BitConverter.ToInt32(prePropBinary, toci);
                var relinkResult = relinkUIndex(sourceExport.FileRef, relinkingExport, ref uIndex, "TemplateOwnerClass",
                                                crossPCCObjectMappingList, "", importExportDependencies, relinkerCache);
                if (relinkResult is null)
                {
                    prePropBinary.OverwriteRange(toci, BitConverter.GetBytes(uIndex));
                }
                else
                {
                    relinkFailedReport.Add(relinkResult);
                }
            }

            //Relink Properties
            PropertyCollection props = relinkingExport.GetProperties();

            relinkFailedReport.AddRange(relinkPropertiesRecursive(sourcePcc, relinkingExport, props, crossPCCObjectMappingList, "", importExportDependencies, relinkerCache));

            //Relink Binary
            try
            {
                if (relinkingExport.Game != sourcePcc.Game && (relinkingExport.IsClass || relinkingExport.ClassName == "State" || relinkingExport.ClassName == "Function"))
                {
                    relinkFailedReport.Add(new EntryStringPair(relinkingExport, $"{relinkingExport.UIndex} {relinkingExport.FullPath} binary relinking failed. Cannot port {relinkingExport.ClassName} between games!"));
                }
                else if (ObjectBinary.From(relinkingExport) is ObjectBinary objBin)
                {
                    List <(UIndex, string)> indices = objBin.GetUIndexes(relinkingExport.FileRef.Game);

                    foreach ((UIndex uIndex, string propName) in indices)
                    {
                        var result = relinkUIndex(sourcePcc, relinkingExport, ref uIndex.value, $"(Binary Property: {propName})",
                                                  crossPCCObjectMappingList, "", importExportDependencies, relinkerCache);
                        if (result != null)
                        {
                            relinkFailedReport.Add(result);
                        }
                    }

                    //UStruct is abstract baseclass for Class, State, and Function, and can have script in it
                    if (objBin is UStruct uStructBinary && uStructBinary.ScriptBytes.Length > 0)
                    {
                        if (relinkingExport.Game == MEGame.ME3)
                        {
                            (List <Token> tokens, _) = Bytecode.ParseBytecode(uStructBinary.ScriptBytes, sourceExport);
                            foreach (Token token in tokens)
                            {
                                relinkFailedReport.AddRange(RelinkToken(token, uStructBinary.ScriptBytes, sourceExport, relinkingExport,
                                                                        crossPCCObjectMappingList, importExportDependencies, relinkerCache));
                            }
                        }
                        else
                        {
                            var func = sourceExport.ClassName == "State" ? UE3FunctionReader.ReadState(sourceExport) : UE3FunctionReader.ReadFunction(sourceExport);
                            func.Decompile(new TextBuilder(), false); //parse bytecode
                            var nameRefs  = func.NameReferences;
                            var entryRefs = func.EntryReferences;
                            foreach ((long position, NameReference nameRef) in nameRefs)
                            {
                                if (position < uStructBinary.ScriptBytes.Length)
                                {
                                    RelinkNameReference(nameRef.Name, position, uStructBinary.ScriptBytes, relinkingExport);
                                }
                            }

                            foreach ((long position, IEntry entry) in entryRefs)
                            {
                                if (position < uStructBinary.ScriptBytes.Length)
                                {
                                    relinkFailedReport.AddRange(RelinkUnhoodEntryReference(entry, position, uStructBinary.ScriptBytes, sourceExport, relinkingExport,
                                                                                           crossPCCObjectMappingList, importExportDependencies, relinkerCache));
                                }
                            }
                        }
                    }
                    relinkingExport.WritePrePropsAndPropertiesAndBinary(prePropBinary, props, objBin);
                    return(relinkFailedReport);
                }
            }
            catch (Exception e) when(!CoreLib.IsDebug)
            {
                relinkFailedReport.Add(new EntryStringPair(relinkingExport, $"{relinkingExport.UIndex} {relinkingExport.FullPath} binary relinking failed due to exception: {e.Message}"));
            }

            relinkingExport.WritePrePropsAndProperties(prePropBinary, props);
            return(relinkFailedReport);
        }