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); }
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. } } }
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); }
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)); }
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); }
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); }
public void TestFallout4Papyrus() { var falloutScript = "D:\\Spel\\Fallout 4 Scripts\\scripts\\Actor.pex"; var assembly = PapyrusAssemblyDefinition.ReadAssembly(falloutScript); Assert.IsNotNull(assembly.Header.SourceHeader.Source); }
public PapyrusParameterDefinition ReadParameter(PapyrusAssemblyDefinition asm) { return(new PapyrusParameterDefinition { Name = pexReader.ReadStringRef(), TypeName = pexReader.ReadStringRef() }); }
public IEnumerable <PapyrusInstruction> ProcessInstructions(PapyrusAssemblyDefinition targetPapyrusAssembly, PapyrusTypeDefinition targetPapyrusType, PapyrusMethodDefinition targetPapyrusMethod, MethodDefinition method, MethodBody body, Collection <Instruction> instructions, PapyrusCompilerOptions options) { throw new NotImplementedException(); }
private PapyrusFieldDefinition ReadDocumentedField(PapyrusAssemblyDefinition asm, PapyrusTypeDefinition declaringType) { var sfd = ReadFieldDefinition(asm, declaringType); sfd.Documentation = pexReader.ReadString(); return(sfd); }
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); }
private void ReadFields(PapyrusAssemblyDefinition asm, PapyrusTypeDefinition typeDef) { var fieldCount = pexReader.ReadInt16(); for (var i = 0; i < fieldCount; i++) { typeDef.Fields.Add(ReadFieldDefinition(asm, typeDef)); } }
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(); }
/// <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); }
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); } }
public PapyrusAssemblyWriter(PapyrusAssemblyDefinition assembly) { if (assembly == null) { throw new ArgumentNullException(nameof(assembly)); } Assembly = assembly; outputStream = new MemoryStream(); pexWriter = new PexWriter(assembly, outputStream); }
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)); }
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); }
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); }
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); }
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++; } }
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); } } }
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)); }
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); }
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); }
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); }
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; } }
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); } }