Beispiel #1
0
        public static List <string> AssumedStructPattern(Program.RunData runData, ReadingContext readingContext, out HeuristicaStatus heuristicaStatus)
        {
            Int32 assumedEndOfStructOffset = readingContext.declaredSizeStartOffset + readingContext.declaredSize;
            Int32 assumedSize = readingContext.collectionElementCount > 0 ?
                                readingContext.declaredSize / readingContext.collectionElementCount :
                                readingContext.collectionElementCount;

            try
            {
                string assumedLastName = ExportParsingMachine.FullNameString(runData.uexp, assumedEndOfStructOffset - 8);

                if (assumedLastName == ExportParsingMachine.endOfStructConfigName)
                {
                    heuristicaStatus = HeuristicaStatus.Success;
                    return(new List <string>()
                    {
                        "NTPL"
                    });
                }
            }
            catch (Exception)
            {
            }

            heuristicaStatus = HeuristicaStatus.Failure;
            return(new List <string>());
        }
Beispiel #2
0
        private static void FloatPatternElementProcesser(byte[] uasset, byte[] uexp, ReadingContext readingContext)
        {
            readingContext.pattern.TakeArg();

            ExportParsingMachine.ReportExportContents($"Float Value: {BitConverter.ToSingle(uexp, readingContext.currentUexpOffset)}");

            readingContext.currentUexpOffset += 4;
        }
Beispiel #3
0
        private static void NamePatternElementProcesser(byte[] uasset, byte[] uexp, ReadingContext readingContext)
        {
            readingContext.pattern.TakeArg();

            ExportParsingMachine.ReportExportContents($"Name: {ExportParsingMachine.FullNameString(uexp, readingContext.currentUexpOffset)}");

            readingContext.currentUexpOffset += 8;
        }
        private static void SkipContextSearcher(byte[] uasset, byte[] uexp, ReadingContext readingContext)
        {
            readingContext.pattern.TakeArg();

            Int32 skipLength = Int32.Parse(readingContext.pattern.TakeArg());

            readingContext.currentUexpOffset += skipLength;
        }
Beispiel #5
0
        private static void SizePatternElementProcesser(byte[] uasset, byte[] uexp, ReadingContext readingContext)
        {
            readingContext.declaredSize       = BitConverter.ToInt32(uexp, readingContext.currentUexpOffset);
            readingContext.currentUexpOffset += 4;
            readingContext.pattern.TakeArg();

            ExportParsingMachine.ReportExportContents($"Size: {readingContext.declaredSize}");
        }
        private static void ElementCountContextSearcher(byte[] uasset, byte[] uexp, ReadingContext readingContext)
        {
            readingContext.pattern.TakeArg();

            readingContext.collectionElementCount = BitConverter.ToInt32(uexp, readingContext.currentUexpOffset);
            readingContext.contextCollectionElementCountOffset = readingContext.currentUexpOffset;

            readingContext.currentUexpOffset += 4;
        }
        private static void SizeStartContextSearcher(byte[] uasset, byte[] uexp, ReadingContext readingContext)
        {
            readingContext.pattern.TakeArg();

            readingContext.declaredSizeStartOffset = readingContext.currentUexpOffset;
            if (customRunDara.reportSearchSteps)
            {
                ExportParsingMachine.ReportExportContents($"Context Size start at {readingContext.currentUexpOffset}");
            }
        }
        private static void SkipContextContextSearcher(byte[] uasset, byte[] uexp, ReadingContext readingContext)
        {
            if (customRunDara.reportSearchSteps)
            {
                ExportParsingMachine.ReportExportContents("Skipping context");
            }

            readingContext.pattern.Clear();
            readingContext.currentUexpOffset = readingContext.declaredSizeStartOffset + readingContext.declaredSize;
        }
        private static void SkipIfEndContextSearcher(byte[] uasset, byte[] uexp, ReadingContext readingContext)
        {
            readingContext.pattern.TakeArg();

            if (readingContext.pattern.Count == 0)
            {
                readingContext.currentUexpOffset = readingContext.declaredSizeStartOffset + readingContext.declaredSize;

                ExportParsingMachine.ReportExportContents("Skipping structure due to lack of pattern");
            }
        }
        private static void ContextReturnProcesser(ReadingContext upperContext, ReadingContext finishedContext)
        {
            upperContext.sizeChange += finishedContext.sizeChange;
            if (finishedContext.contextDeclaredSizeOffset != 0)
            {
                DOLib.AddToInt32ByOffset(Program.runData.uexp, finishedContext.sizeChange, finishedContext.contextDeclaredSizeOffset);
            }

            if (customRunDara.taskComplete)
            {
                upperContext.targetContext.Clear();
                upperContext.pattern.Clear();
            }
        }
        private static void SizeContextSearcher(byte[] uasset, byte[] uexp, ReadingContext readingContext)
        {
            readingContext.pattern.TakeArg();

            readingContext.declaredSize = BitConverter.ToInt32(uexp, readingContext.currentUexpOffset);
            readingContext.contextDeclaredSizeOffset = readingContext.currentUexpOffset;

            if (customRunDara.reportSearchSteps)
            {
                ExportParsingMachine.ReportExportContents($"Size is {readingContext.declaredSize}, stored at {readingContext.contextDeclaredSizeOffset}");
            }

            readingContext.currentUexpOffset += 4;
        }
Beispiel #12
0
        public static void ExecutePushedReadingContext(byte[] uasset, byte[] uexp, ReadingContext readingContext)
        {
            IncStructLevel();

            StepsTilEndOfStruct(uasset, uexp);

            DecStructLevel();

            ReadingContext finishedContext = machineState.Pop();

            readingContext.currentUexpOffset = finishedContext.currentUexpOffset;

            if (finishedContext.contextReturnProcesser != null)
            {
                finishedContext.contextReturnProcesser(readingContext, finishedContext);
            }
        }
        private static void ValueContextSearcher(byte[] uasset, byte[] uexp, ReadingContext readingContext)
        {
            string            primitiveTypeName = readingContext.pattern.TakeArg();
            PrimitiveTypeData primitiveType     = primitiveTypes[primitiveTypeName];


            if (readingContext.targetContext.Count == 2)
            {
                Int32 skipsLeft = Int32.Parse(readingContext.targetContext[1]);

                if (primitiveTypeName == readingContext.targetContext[0])
                {
                    if (skipsLeft == 0)
                    {
                        if (customRunDara.reportSearchSteps)
                        {
                            ExportParsingMachine.ReportExportContents($"Found replacement target at {readingContext.currentUexpOffset}");
                        }
                        readingContext.pattern.Clear();
                        readingContext.targetContext.Clear();

                        primitiveType.writer(ref readingContext.currentUexpOffset, customRunDara.newValue);

                        customRunDara.taskComplete = true;
                        return;
                    }
                    else
                    {
                        skipsLeft--;
                        readingContext.targetContext[1] = skipsLeft.ToString();
                    }
                }
            }

            primitiveType.skip(ref readingContext.currentUexpOffset);
            if (customRunDara.reportSearchSteps)
            {
                ExportParsingMachine.ReportExportContents($"Skipping {primitiveTypeName} value");
            }
        }
Beispiel #14
0
        private static bool Step(byte[] uasset, byte[] uexp)
        {
            ReadingContext readingContext = machineState.Peek();


            if (readingContext.pattern.Count == 0)
            {
                return(false);
            }

            if (readingContext.patternAlphabet.ContainsKey(readingContext.pattern[0]))
            {
                readingContext.patternAlphabet[readingContext.pattern[0]](uasset, uexp, readingContext);
            }
            else
            {
                readingContext.currentUexpOffset += 4;
                readingContext.pattern.TakeArg();
            }

            return(true);
        }
Beispiel #15
0
        public static string ObjectByIndexFullNameString(byte[] uasset, byte[] uexp, ReadingContext readingContext)
        {
            Int32 index = BitConverter.ToInt32(uexp, readingContext.currentUexpOffset);

            readingContext.currentUexpOffset += 4;

            string valueStr;

            if (index == 0)
            {
                valueStr = "null";
            }
            else if (index < 0)
            {
                valueStr = $"Import:{ImportByIndexFullNameString(uasset, uexp, index)}";
            }
            else
            {
                valueStr = $"Export:{ExportByIndexFullNameString(uasset, uexp, index)}";
            }

            return(valueStr);
        }
Beispiel #16
0
        private static void TextPropertyDirtyHackPatternElementProcesser(byte[] uasset, byte[] uexp, ReadingContext readingContext)
        {
            readingContext.pattern.TakeArg();

            //Epic Games probably like it when you have to f**k your brain with TexProperty having a body prefix which varies in SIZE between types.
            //I don't. I hope the author of that idea got a proper remedy.

            readingContext.currentUexpOffset = readingContext.declaredSizeStartOffset + readingContext.declaredSize;
            ExportParsingMachine.ReportExportContents("Text Property support is postponed. ETA depends on readability of UE shitcode.");
        }
Beispiel #17
0
        private static void MapGeneratorTypesPatternElementProcesser(byte[] uasset, byte[] uexp, ReadingContext readingContext)
        {
            readingContext.pattern.TakeArg();

            string tKey = ExportParsingMachine.FullNameString(uexp, readingContext.currentUexpOffset);

            readingContext.currentUexpOffset += 8;

            string tVal = ExportParsingMachine.FullNameString(uexp, readingContext.currentUexpOffset);

            readingContext.currentUexpOffset += 8;

            ExportParsingMachine.ReportExportContents($"<{tKey}, {tVal}>");

            if (Program.PatternExists($"{Program.PatternFolders.body}/{tKey}") && Program.PatternExists($"{Program.PatternFolders.body}/{tVal}"))
            {
                List <string> keyPattern = Program.GetPattern($"{Program.PatternFolders.body}/{tKey}");
                List <string> valPattern = Program.GetPattern($"{Program.PatternFolders.body}/{tVal}");

                if (keyPattern.TakeArg() == ExportParsingMachine.arrayRepeatPatternElementName &&
                    valPattern.TakeArg() == ExportParsingMachine.arrayRepeatPatternElementName)
                {
                    readingContext.pattern.Add(ExportParsingMachine.elementCountPatternElementName);
                    readingContext.pattern.Add(ExportParsingMachine.arrayRepeatPatternElementName);
                    readingContext.pattern.AddRange(keyPattern);
                    readingContext.pattern.Add(ExportParsingMachine.arrayRepeatEndPatternElementName);

                    readingContext.pattern.Add(ExportParsingMachine.elementCountPatternElementName);
                    readingContext.pattern.Add(ExportParsingMachine.arrayRepeatPatternElementName);
                    readingContext.pattern.AddRange(keyPattern);
                    readingContext.pattern.AddRange(valPattern);
                }
            }
        }
Beispiel #18
0
        private static void StructPropertyArrayTypePatternElementProcesser(byte[] uasset, byte[] uexp, ReadingContext readingContext)
        {
            readingContext.pattern.TakeArg();

            string typeName = ExportParsingMachine.FullNameString(uexp, readingContext.currentUexpOffset);

            readingContext.currentUexpOffset += 8;

            ExportParsingMachine.ReportExportContents($"Element structure type: {typeName}");

            if (Program.PatternExists($"{Program.PatternFolders.structure}/{typeName}"))
            {
                readingContext.pattern.Add(ExportParsingMachine.arrayRepeatPatternElementName);
                readingContext.pattern.AddRange(Program.GetPattern($"{Program.PatternFolders.structure}/{typeName}"));
            }
            else if (Program.config.enablePatternReadingHeuristica && readingContext.collectionElementCount != 0)
            {
                readingContext.pattern.Add(structTypeHeuristicaPatternElementName);
                readingContext.pattern.Add(ExportParsingMachine.skipIfPatternShorterThanPatternElemetnName);
                readingContext.pattern.Add("2");
                readingContext.pattern.Add(ExportParsingMachine.arrayRepeatPatternElementName);
            }
        }
Beispiel #19
0
        private static void ArrayRepeatPatternElementProcesser(byte[] uasset, byte[] uexp, ReadingContext readingContext)
        {
            readingContext.pattern.TakeArg();

            Int32 scaledElementSize;

            // Some element types have no context-free size determination apart from assumed elements total size and count.
            // Also ignore it if we have 0 elements because it is pointless and causes exception.
            if (readingContext.pattern[0] == ExportParsingMachine.scaledArrayElementsPatternElementName &&
                readingContext.collectionElementCount != 0)
            {
                readingContext.pattern.TakeArg();
                scaledElementSize = (readingContext.declaredSizeStartOffset + readingContext.declaredSize -
                                     readingContext.currentUexpOffset) /
                                    (readingContext.collectionElementCount);
            }
            else
            {
                scaledElementSize = -1;
            }

            List <string> repeatedPattern = new List <string>();


            // Passing all the stuff to repeat in cycle which is all past ArrayRepeat and til ArrayRepeatEnd or end of pattern
            while (readingContext.pattern.Count > 0)
            {
                string element = readingContext.pattern.TakeArg();

                if (element == ExportParsingMachine.arrayRepeatEndPatternElementName)
                {
                    break;
                }

                repeatedPattern.Add(element);
            }

            for (int i = 0; i < readingContext.collectionElementCount; i++)
            {
                ExportParsingMachine.ReportExportContents($"Element {i}");

                ExportParsingMachine.machineState.Push(new ReadingContext()
                {
                    currentUexpOffset = readingContext.currentUexpOffset,

                    pattern         = new List <string>(repeatedPattern),
                    patternAlphabet = readingContext.patternAlphabet,

                    structCategory = ReadingContext.StructCategory.nonExport,

                    declaredSize = scaledElementSize
                });

                ExportParsingMachine.ExecutePushedReadingContext(uasset, uexp, readingContext);
            }
        }
Beispiel #20
0
        private static void ElementCountPatternElementProcesser(byte[] uasset, byte[] uexp, ReadingContext readingContext)
        {
            readingContext.pattern.TakeArg();

            Int32 elementCount = BitConverter.ToInt32(uexp, readingContext.currentUexpOffset);

            readingContext.currentUexpOffset += 4;

            readingContext.collectionElementCount = elementCount;

            ExportParsingMachine.ReportExportContents($"Elements Count: {elementCount}");
        }
Beispiel #21
0
        private static void NoneTerminatedPropListPatternElementProcesser(byte[] uasset, byte[] uexp, ReadingContext readingContext)
        {
            string substructName = ExportParsingMachine.FullNameString(uexp, readingContext.currentUexpOffset);

            readingContext.currentUexpOffset += 8;

            if (substructName == ExportParsingMachine.endOfStructConfigName)
            {
                readingContext.pattern.TakeArg();
                return;
            }

            string typeName = ExportParsingMachine.FullNameString(uexp, readingContext.currentUexpOffset);

            readingContext.currentUexpOffset += 8;

            ExportParsingMachine.ReportExportContents("------------------------------");
            ExportParsingMachine.ReportExportContents($"{substructName} is {typeName}");

            List <string> propertyPattern;

            try
            {
                propertyPattern = Program.GetPattern($"{Program.PatternFolders.property}/{typeName}");
            }
            catch
            {
                ExportParsingMachine.ReportExportContents($"Failed to find a pattern for property type {typeName}");

                Int32 assumedSize = BitConverter.ToInt32(uexp, readingContext.currentUexpOffset);
                readingContext.currentUexpOffset += 8;

                ExportParsingMachine.ReportExportContents($"Assumed property size {assumedSize}");

                ExportParsingMachine.ReportExportContents($"Assumed property body {BitConverter.ToString(uexp, readingContext.currentUexpOffset + 1, assumedSize)}");

                throw;
            }

            ExportParsingMachine.machineState.Push(new ReadingContext()
            {
                currentUexpOffset       = readingContext.currentUexpOffset,
                declaredSize            = -1,
                declaredSizeStartOffset = -1,
                collectionElementCount  = -1,

                pattern         = propertyPattern,
                patternAlphabet = readingContext.patternAlphabet,

                structCategory = ReadingContext.StructCategory.nonExport
            });

            ExportParsingMachine.ExecutePushedReadingContext(uasset, uexp, readingContext);
        }
Beispiel #22
0
        private static void StructTypeNameIndexPatternElementProcesser(byte[] uasset, byte[] uexp, ReadingContext readingContext)
        {
            readingContext.pattern.TakeArg();
            string typeName = ExportParsingMachine.FullNameString(uexp, readingContext.currentUexpOffset);

            ExportParsingMachine.ReportExportContents($"Structure Type: {typeName}");

            readingContext.currentUexpOffset += 8;

            if (Program.PatternExists($"{Program.PatternFolders.structure}/{typeName}"))
            {
                readingContext.pattern.AddRange(Program.GetPattern($"{Program.PatternFolders.structure}/{typeName}"));
            }
            else if (Program.config.enablePatternReadingHeuristica)
            {
                readingContext.pattern.Add(structTypeHeuristicaPatternElementName);
                readingContext.pattern.Add(ExportParsingMachine.skipIfPatternEndsPatternElementName);
            }
        }
Beispiel #23
0
        private static void UnknownBytesPatternElementProcesser(byte[] uasset, byte[] uexp, ReadingContext readingContext)
        {
            readingContext.pattern.TakeArg();

            Int32 count = Int32.Parse(readingContext.pattern.TakeArg());

            ExportParsingMachine.ReportExportContents($"Unknown Bytes: {BitConverter.ToString(uexp, readingContext.currentUexpOffset, count)}");

            readingContext.currentUexpOffset += count;
        }
Beispiel #24
0
        private static void SizePrefixedNullTermStringPatternElementProcesser(byte[] uasset, byte[] uexp, ReadingContext readingContext)
        {
            readingContext.pattern.TakeArg();

            string value = Program.SizePrefixedStringFromOffsetOffsetAdvance(uexp, ref readingContext.currentUexpOffset);

            ExportParsingMachine.ReportExportContents($"String: {value}");
        }
Beispiel #25
0
 private static void GUIDPatternElementProcesser(byte[] uasset, byte[] uexp, ReadingContext readingContext)
 {
     readingContext.pattern.TakeArg();
     ExportParsingMachine.ReportExportContents(ExportParsingMachine.GUIDFromUexpOffsetToString(ref readingContext.currentUexpOffset));
 }
Beispiel #26
0
        private static void SkipIfPatternShorterThanPatternElementProcesser(byte[] uasset, byte[] uexp, ReadingContext readingContext)
        {
            readingContext.pattern.TakeArg();

            Int32 minimalCountToProceed = Int32.Parse(readingContext.pattern.TakeArg());

            if (readingContext.pattern.Count < minimalCountToProceed)
            {
                readingContext.currentUexpOffset = readingContext.declaredSizeStartOffset + readingContext.declaredSize;
                readingContext.pattern.Clear();

                ExportParsingMachine.ReportExportContents("Skipping structure due to lack of pattern");
            }
        }
Beispiel #27
0
        private static void ObjectIndexPatternElementProcesser(byte[] uasset, byte[] uexp, ReadingContext readingContext)
        {
            readingContext.pattern.TakeArg();
            string valueStr = ExportParsingMachine.ObjectByIndexFullNameString(uasset, uexp, readingContext);

            ExportParsingMachine.ReportExportContents($"Object: {valueStr}");
        }
Beispiel #28
0
        private static void StructTypeHeurisitcaPatternElementProcesser(byte[] uasset, byte[] uexp, ReadingContext readingContext)
        {
            readingContext.pattern.TakeArg();

            readingContext.pattern.AddRange(PatternHeuristica.AssumedStructPattern(Program.runData, readingContext,
                                                                                   out PatternHeuristica.HeuristicaStatus heuristicaStatus));

            switch (heuristicaStatus)
            {
            case PatternHeuristica.HeuristicaStatus.Failure:
                ExportParsingMachine.ReportExportContents("Heuristica failed to give assumed structure pattern");
                break;

            case PatternHeuristica.HeuristicaStatus.NonCriticalFailure:
                ExportParsingMachine.ReportExportContents("Heuristica failed to find a meaningful pattern, boilerplate is provided");
                break;

            case PatternHeuristica.HeuristicaStatus.Success:
                ExportParsingMachine.ReportExportContents("Heuristica proposed a structure pattern, applying it");
                break;
            }
        }
Beispiel #29
0
        private static void BytePropPatternElementProcesser(byte[] uasset, byte[] uexp, ReadingContext readingContext)
        {
            readingContext.pattern.TakeArg();

            ExportParsingMachine.ReportExportContents($"Bytes Value: {BitConverter.ToString(uexp, readingContext.currentUexpOffset, readingContext.declaredSize)}");

            readingContext.currentUexpOffset += readingContext.declaredSize;
        }
Beispiel #30
0
        private static void ArrayElementTypeNameIndexPatternElementProcesser(byte[] uasset, byte[] uexp, ReadingContext readingContext)
        {
            readingContext.pattern.TakeArg();

            string typeName = ExportParsingMachine.FullNameString(uexp, readingContext.currentUexpOffset);

            readingContext.currentUexpOffset += 8;

            ExportParsingMachine.ReportExportContents($"Array Element Type: {typeName}");

            if (Program.PatternExists($"{Program.PatternFolders.body}/{typeName}"))
            {
                readingContext.pattern.AddRange(Program.GetPattern($"{Program.PatternFolders.body}/{typeName}"));
            }
        }