Exemplo n.º 1
0
        public PapyrusHeader ReadHeader(PapyrusAssemblyDefinition asm)
        {
            var header = new PapyrusHeader(asm);

            header.HeaderIdentifier = pexReader.ReadUInt32();
            switch (header.HeaderIdentifier)
            {
            case PapyrusHeader.Fallout4PapyrusHeaderIdentifier:
                asm.VersionTarget = PapyrusVersionTargets.Fallout4;
                pexReader.SetVersionTarget(PapyrusVersionTargets.Fallout4);
                break;

            default:
                asm.VersionTarget = PapyrusVersionTargets.Skyrim;
                pexReader.SetVersionTarget(PapyrusVersionTargets.Skyrim);
                break;
            }
            header.SourceHeader = ReadHeader();

            ReadStringTable(asm);

            var hasDebugInfoByte = pexReader.ReadByte();

            asm.HasDebugInfo = hasDebugInfoByte == 1;

            return(header);
        }
Exemplo n.º 2
0
        public static void Decompile_FollowersScript()
        {
            var asm = PapyrusAssemblyDefinition.ReadAssembly(
                GetSolutionDir() + @"\Source\Test Scripts\Bad\test.pex");

            var decompiler =
                new PapyrusDecompiler(asm);
            var ctx     = decompiler.CreateContext();
            var methods =
                asm.Types.First()
                .States.SelectMany(s => s.Methods)
                .Where(m => m.Body.Instructions.Count > 2)
                .OrderBy(m => m.Body.Instructions.Count);

            foreach (var method in methods)
            {
                var result = decompiler.Decompile(ctx, method);
                if (result.DecompiledSourceCode.Contains("If (") || result.DecompiledSourceCode.Contains("While ("))
                {
                    // 1. Conditionet i IF satserna uppdateras aldrig och stannar som "If (false) ..."
                    //      - Detta gör att värden som skall användas saknas (om de är en direkt referens till en boolean variable)
                    //      - Eller att Expressions används och "mergas", ex: A == B
                    // 2. Indenten på första raden i en If Sats är fel.
                    // 3. Return kan ibland ha en "Undefined = return EXPRESSION", varför den sista "assign" vid "CheckAssign" sker
                    //    är fortfarande ett frågetecken. Den bör inte göras om destinationen (GetResult()) är undefined.
                    //    men eftersom detta inte händer i källan så är det något som kontrolleras fel eller så har inte alla noder rätt värden.
                }
            }
        }
Exemplo n.º 3
0
        private PapyrusVariableReference ReadValueReference(PapyrusAssemblyDefinition asm, string name = null)
        {
            var tr = new PapyrusVariableReference(new PapyrusStringRef(asm, name),
                                                  (PapyrusPrimitiveType)pexReader.ReadByte());

            switch (tr.Type)
            {
            case PapyrusPrimitiveType.Reference:
                tr.Value = pexReader.ReadString();
                break;

            case PapyrusPrimitiveType.String:
                tr.Value = pexReader.ReadString();
                break;

            case PapyrusPrimitiveType.Boolean:
                tr.Value = pexReader.ReadByte();
                break;

            case PapyrusPrimitiveType.Float:
                tr.Value = pexReader.ReadSingle();
                break;

            case PapyrusPrimitiveType.Integer:
                tr.Value = pexReader.ReadInt32();
                break;

            default:
            case PapyrusPrimitiveType.None:
                break;
            }
            return(tr);
        }
Exemplo n.º 4
0
        private void UpdateUserFlags(TypeDefinition type, PapyrusAssemblyDefinition pex)
        {
            var props = attributeReader.ReadPapyrusAttributes(type);

            pex.Header.UserflagReferenceHeader.Add("hidden", (byte)(props.IsHidden ? 1 : 0));
            pex.Header.UserflagReferenceHeader.Add("conditional", (byte)(props.IsConditional ? 1 : 0));
        }
Exemplo n.º 5
0
        private PapyrusInstruction ReadInstruction(PapyrusAssemblyDefinition asm)
        {
            var instruction = new PapyrusInstruction();

            instruction.OpCode = (PapyrusOpCodes)pexReader.ReadByte();

            var desc = PapyrusInstructionOpCodeDescription.FromOpCode(instruction.OpCode);

            var references           = new List <PapyrusVariableReference>();
            var instructionParamSize = desc.ArgumentCount;

            for (var p = 0; p < instructionParamSize; p++)
            {
                references.Add(ReadValueReference(asm));
            }

            if (desc.HasOperandArguments)
            {
                var typeRef = ReadValueReference(asm);
                if (typeRef.Type == PapyrusPrimitiveType.Integer)
                {
                    var argCount = (int)typeRef.Value;
                    for (var i = 0; i < argCount; i++)
                    {
                        instruction.OperandArguments.Add(ReadValueReference(asm));
                    }
                }
            }

            instruction.Arguments = references;
            return(instruction);
        }
Exemplo n.º 6
0
        private void ReadStates(PapyrusAssemblyDefinition asm, PapyrusTypeDefinition typeDef)
        {
            var stateCount = pexReader.ReadInt16();

            for (var i = 0; i < stateCount; i++)
            {
                var state = new PapyrusStateDefinition(typeDef);
                state.Name = pexReader.ReadStringRef();
                var methodCount = pexReader.ReadInt16();
                for (var k = 0; k < methodCount; k++)
                {
                    var name   = pexReader.ReadString();
                    var method = ReadMethod(asm);

                    method.DeclaringState = state;
                    method.Name           = new PapyrusStringRef(asm, name);
                    if (method.Name.Value.ToLower().StartsWith("on"))
                    {
                        // For now, lets assume that all functions with the name starting with "On" is an event.
                        method.IsEvent = true;
                    }
                    state.Methods.Add(method);
                }
                // typeDef.States.Add(state);
            }

            UpdateOperands(typeDef.States);
        }
Exemplo n.º 7
0
        public void TestFallout4Papyrus()
        {
            var falloutScript = "D:\\Spel\\Fallout 4 Scripts\\scripts\\Actor.pex";
            var assembly      = PapyrusAssemblyDefinition.ReadAssembly(falloutScript);

            Assert.IsNotNull(assembly.Header.SourceHeader.Source);
        }
Exemplo n.º 8
0
 public PapyrusParameterDefinition ReadParameter(PapyrusAssemblyDefinition asm)
 {
     return(new PapyrusParameterDefinition
     {
         Name = pexReader.ReadStringRef(),
         TypeName = pexReader.ReadStringRef()
     });
 }
Exemplo n.º 9
0
 public IEnumerable <PapyrusInstruction> ProcessInstructions(PapyrusAssemblyDefinition targetPapyrusAssembly,
                                                             PapyrusTypeDefinition targetPapyrusType,
                                                             PapyrusMethodDefinition targetPapyrusMethod, MethodDefinition method, MethodBody body,
                                                             Collection <Instruction> instructions,
                                                             PapyrusCompilerOptions options)
 {
     throw new NotImplementedException();
 }
Exemplo n.º 10
0
        private PapyrusFieldDefinition ReadDocumentedField(PapyrusAssemblyDefinition asm,
                                                           PapyrusTypeDefinition declaringType)
        {
            var sfd = ReadFieldDefinition(asm, declaringType);

            sfd.Documentation = pexReader.ReadString();
            return(sfd);
        }
Exemplo n.º 11
0
        public void TestSkyrimPapyrus()
        {
            var str      = @"C:\CreationKit\Data\scripts\activemagiceffect.pex";
            var assembly = PapyrusAssemblyDefinition.ReadAssembly(str);

            Assert.IsNotNull(assembly.Header.SourceHeader.Source);
            Assert.AreNotEqual(0, assembly.Types.Count);
        }
Exemplo n.º 12
0
        private void ReadFields(PapyrusAssemblyDefinition asm, PapyrusTypeDefinition typeDef)
        {
            var fieldCount = pexReader.ReadInt16();

            for (var i = 0; i < fieldCount; i++)
            {
                typeDef.Fields.Add(ReadFieldDefinition(asm, typeDef));
            }
        }
Exemplo n.º 13
0
 private void ReadTypeInfo(PapyrusAssemblyDefinition asm, PapyrusTypeDefinition typeDef)
 {
     typeDef.Name          = pexReader.ReadStringRef();
     typeDef.Size          = pexReader.ReadInt32();
     typeDef.BaseTypeName  = pexReader.ReadStringRef();
     typeDef.Documentation = pexReader.ReadStringRef();
     typeDef.Flags         = pexReader.ReadByte();
     typeDef.UserFlags     = pexReader.ReadInt32();
     typeDef.AutoStateName = pexReader.ReadStringRef();
 }
Exemplo n.º 14
0
 /// <summary>
 ///     Initializes a new instance of the <see cref="DecompilerContext" /> class.
 /// </summary>
 /// <param name="decompiler">The decompiler.</param>
 /// <param name="flowAnalyzer"></param>
 /// <param name="asm">The asm.</param>
 public DecompilerContext(IPapyrusDecompiler decompiler, IFlowAnalyzer flowAnalyzer,
                          PapyrusAssemblyDefinition asm)
 {
     this.decompiler   = decompiler;
     this.flowAnalyzer = flowAnalyzer;
     this.asm          = asm;
     TempStringTable   = new PapyrusStringTable();
     codeBlocks        = new Map <int, PapyrusCodeBlock>();
     flowAnalyzer.SetContext(this);
 }
Exemplo n.º 15
0
        private void ReadHeaderUserflags(PapyrusAssemblyDefinition asm)
        {
            var userflagCount = pexReader.ReadInt16();

            for (var userflagIndex = 0; userflagIndex < userflagCount; userflagIndex++)
            {
                var stringValue = pexReader.ReadString();
                var flagValue   = pexReader.ReadByte();
                asm.Header.UserflagReferenceHeader.Add(stringValue.Ref(asm), flagValue);
            }
        }
Exemplo n.º 16
0
        public PapyrusAssemblyWriter(PapyrusAssemblyDefinition assembly)
        {
            if (assembly == null)
            {
                throw new ArgumentNullException(nameof(assembly));
            }

            Assembly     = assembly;
            outputStream = new MemoryStream();
            pexWriter    = new PexWriter(assembly, outputStream);
        }
Exemplo n.º 17
0
 private PapyrusAssemblyDefinition ReadPapyrusAssembly(string arg, int maxCount)
 {
     assembliesReadTick++;
     assembliesRead++;
     if (assembliesReadTick >= 100 || assembliesRead == maxCount || maxCount < 1000)
     {
         ui.DrawProgressBarWithInfo(assembliesRead, maxCount);
         assembliesReadTick = 0;
     }
     return(PapyrusAssemblyDefinition.ReadAssembly(arg));
 }
Exemplo n.º 18
0
        private PapyrusTypeDefinition CreateType(PapyrusAssemblyDefinition pex, TypeDefinition type,
                                                 PapyrusCompilerOptions options, bool isStruct = false)
        {
            var papyrusType = new PapyrusTypeDefinition(pex, isStruct);


            if (isStruct)
            {
                papyrusType.IsStruct = true;
                papyrusType.IsClass  = false;
            }

            papyrusType.Name          = type.Name.Ref(pex);
            papyrusType.AutoStateName = "".Ref(pex);
            papyrusType.Documentation = "".Ref(pex);
            papyrusType.BaseTypeName  = type.BaseType != null
                ? Utility.GetPapyrusBaseType(type.BaseType).Ref(pex)
                : "".Ref(pex);

            UpdateUserFlags(type, pex);

            // Create Fields
            CreateFields(type, pex).ForEach(papyrusType.Fields.Add);

            // Create Properties
            CreateProperties(papyrusAssemblies, type, papyrusType, pex).ForEach(papyrusType.Properties.Add);

            // Create Structs
            foreach (var nestedType in type.NestedTypes)
            {
                // Make sure we don't add any delegate classes, as those are not supported as is
                if (delegatePairDefinition.DelegateTypeDefinitions.Contains(nestedType))
                {
                    continue;
                }
                // We do not want to include any Enums either :-)
                if (EnumDefinitions.Contains(nestedType))
                {
                    continue;
                }
                papyrusType.NestedTypes.Add(CreateStruct(nestedType, pex, options));
            }

            if (!isStruct)
            {
                var autoState = new PapyrusStateDefinition(papyrusType)
                {
                    Name = "".Ref(pex)
                };
                // -- Do not create the methods until all types has been parsed. excluding getters and setters
                // CreateMethods(type, papyrusType, pex, options).ForEach(autoState.Methods.Add);
            }
            return(papyrusType);
        }
Exemplo n.º 19
0
        public void Decompile_FollowersScript()
        {
            var asm = PapyrusAssemblyDefinition.ReadAssembly(
                @"D:\Git\PapyrusDotNet\Source\Test Scripts\Fallout 4\followersscript.pex");

            var decompiler =
                new PapyrusDecompiler(asm);
            var ctx    = decompiler.CreateContext();
            var method =
                asm.Types.First().States.First().Methods.OrderBy(m => m.Body.Instructions.Count).First(m => m.HasBody);
            var result = decompiler.Decompile(ctx, method);
        }
Exemplo n.º 20
0
        public void TestManySkyrimPapyrus()
        {
            var scripts = Directory.GetFiles(@"C:\CreationKit\Data\scripts\", "*.pex", SearchOption.AllDirectories);
            var success = 0;

            foreach (var script in scripts)
            {
                var assembly = PapyrusAssemblyDefinition.ReadAssembly(script);
                Assert.IsNotNull(assembly.Header.SourceHeader.Source);
                Assert.AreNotEqual(0, assembly.Types.Count);
                success++;
            }
            Assert.AreNotEqual(0, success);
        }
Exemplo n.º 21
0
        public static void TestManySkyrimPapyrus()
        {
            var scripts = Directory.GetFiles(@"C:\CreationKit\Data\scripts\", "*.pex", SearchOption.AllDirectories);
            var success = 0;

            foreach (var script in scripts)
            {
                var assembly = PapyrusAssemblyDefinition.ReadAssembly(script);
                if (assembly == null || assembly.IsCorrupted)
                {
                    throw new Exception($"TEST FAILED AT {success}!");
                }
                success++;
            }
        }
Exemplo n.º 22
0
        private void ReadStringTable(PapyrusAssemblyDefinition asm)
        {
            var stringTableLength = pexReader.ReadInt16();

            var stringTable = new PapyrusStringTable();

            for (var i = 0; i < stringTableLength; i++)
            {
                stringTable.Add(pexReader.ReadString(), true);
            }

            asm.StringTable = stringTable;

            pexReader.SetStringTable(stringTable);
        }
        private void PrepareTypes(PapyrusAssemblyDefinition inputAssembly)
        {
            foreach (var type in inputAssembly.Types)
            {
                if (DefinedTypes.All(t => t.Name != type.Name.Value))
                {
                    // NamespaceResolver.Resolve(type.Name.Value) + "." +
                    var defType = mainModule.DefineType(type.Name.Value,
                                                        TypeAttributes.Public);


                    DefinedTypes.Add(defType);
                    ReferenceTypes.Add(defType);
                }
            }
        }
Exemplo n.º 24
0
        private CSharpOutput CreateCSharpDump(PapyrusAssemblyDefinition asm)
        {
            var type = asm.Types.First();

            var outputFileName = type.Name.Value + ".cs";

            var sourceBuilder     = new SourceBuilder();
            var outputFileContent =
                WriteType(sourceBuilder, asm, type)
                .Replace(" ::", " ")
                .Replace("(::", "(")
                .Replace(",::", ",")
                .Replace("!::", "!");

            return(new CSharpOutput(outputFileName, outputFileContent));
        }
Exemplo n.º 25
0
        private PapyrusFieldDefinition ReadFieldDefinition(PapyrusAssemblyDefinition asm,
                                                           PapyrusTypeDefinition declaringType)
        {
            var fd = new PapyrusFieldDefinition(asm, declaringType);

            // Field Definition

            fd.Name      = pexReader.ReadStringRef();
            fd.TypeName  = pexReader.ReadString();
            fd.UserFlags = pexReader.ReadInt32();
            {
                // Type Reference
                fd.DefaultValue = ReadValueReference(asm, fd.TypeName);
            }
            fd.Flags = pexReader.ReadByte(); //== 1;
            return(fd);
        }
Exemplo n.º 26
0
        private void SetHeaderInfo(ClrAssemblyInput input, PapyrusAssemblyDefinition pex, TypeDefinition type)
        {
            pex.Header.HeaderIdentifier = input.TargetPapyrusVersion == PapyrusVersionTargets.Fallout4
                ? PapyrusHeader.Fallout4PapyrusHeaderIdentifier
                : PapyrusHeader.SkyrimPapyrusHeaderIdentifier;

            pex.Header.SourceHeader.Version = input.TargetPapyrusVersion == PapyrusVersionTargets.Fallout4
                ? PapyrusHeader.Fallout4PapyrusVersion
                : PapyrusHeader.SkyrimPapyrusVersion;
            pex.Header.SourceHeader.Source = "PapyrusDotNet" + type.Name + ".psc";

            pex.Header.SourceHeader.User        = Environment.UserName;
            pex.Header.SourceHeader.Computer    = Environment.MachineName;
            pex.Header.SourceHeader.GameId      = (short)input.TargetPapyrusVersion;
            pex.Header.SourceHeader.CompileTime = UnixTimeConverterUtility.Convert(DateTime.Now);
            pex.Header.SourceHeader.ModifyTime  = UnixTimeConverterUtility.Convert(DateTime.Now);
        }
Exemplo n.º 27
0
        public void TestPapyrusMethodFlags()
        {
            var m = new PapyrusMethodDefinition(PapyrusAssemblyDefinition.CreateAssembly(PapyrusVersionTargets.Fallout4));

            m.SetFlags(PapyrusMethodFlags.Global);
            Assert.IsTrue(m.IsGlobal);
            Assert.IsFalse(m.IsNative);

            m.IsNative = true;
            Assert.IsTrue(m.IsGlobal);
            Assert.IsTrue(m.IsNative);


            m.IsGlobal = false;
            Assert.IsFalse(m.IsGlobal);
            Assert.IsTrue(m.IsNative);
        }
Exemplo n.º 28
0
        public void LoadPex(string fileName)
        {
            var name          = Path.GetFileName(fileName);
            var directoryName = Path.GetDirectoryName(fileName);

            if (name != null && loadedAssemblyNames.ContainsKey(name.ToLower()))
            {
                if (MessageBox.Show("This file has already been loaded.\r\nDo you want to reload it?", "Reload?",
                                    MessageBoxButton.YesNo) != MessageBoxResult.Yes)
                {
                    return;
                }
            }

            var loadedAssembly = PapyrusAssemblyDefinition.ReadAssembly(fileName);
            var loadIndex      = -1;

            if (name != null && loadedAssemblyNames.ContainsKey(name.ToLower()))
            {
                loadIndex = Array.IndexOf(loadedAssemblyNames.Values.ToArray(), name.ToLower());
            }

            if (loadIndex == -1)
            {
                loadedAssemblies.Add(loadedAssembly);

                if (name != null)
                {
                    loadedAssemblyNames.Add(name.ToLower(), name.ToLower());
                }
            }
            else
            {
                loadedAssemblies[loadIndex] = loadedAssembly;
            }

            if (!loadedAssemblyFolders.Contains(directoryName))
            {
                loadedAssemblyFolders.Add(directoryName);
            }

            //BuildPexTree(ref PexTree);

            //RaiseCommandsCanExecute();
        }
        /// <summary>
        ///     Builds the type index, mapping a table reference to its type.
        /// </summary>
        public void BuildVarTypeMap(PapyrusAssemblyDefinition asm, PapyrusMethodDefinition method)
        {
            varTypes.Clear();
            var obj = asm.Types.First();

            foreach (var t in obj.Fields)
            {
                varTypes[t.Name.Value.ToLower()] = t.TypeName;
            }
            foreach (var t in method.Parameters)
            {
                varTypes[t.Name.Value.ToLower()] = t.TypeName.Value;
            }
            foreach (var t in method.GetVariables())
            {
                varTypes[t.Name.Value.ToLower()] = t.TypeName.Value;
            }
        }
Exemplo n.º 30
0
        private void ReadStructs(PapyrusAssemblyDefinition asm, PapyrusTypeDefinition typeDef)
        {
            var structCount = pexReader.ReadInt16();

            for (var i = 0; i < structCount; i++)
            {
                var structDef = new PapyrusTypeDefinition(asm, true);
                structDef.IsStruct = true;
                structDef.Name     = pexReader.ReadStringRef();

                var variableCount = pexReader.ReadInt16();
                for (var l = 0; l < variableCount; l++)
                {
                    structDef.Fields.Add(ReadDocumentedField(asm, typeDef));
                }
                typeDef.NestedTypes.Add(structDef);
            }
        }