Beispiel #1
0
		public override void DecompileMethod(MethodDef method, ITextOutput output, DecompilationOptions options)
		{
			WriteComment(output, "Method: ");
			output.WriteDefinition(IdentifierEscaper.Escape(method.FullName), method, TextTokenType.Comment, false);
			output.WriteLine();

			if (!method.HasBody) {
				return;
			}
			
			StartKeywordBlock(output, ".body", method);

			ILAstBuilder astBuilder = new ILAstBuilder();
			ILBlock ilMethod = new ILBlock();
			DecompilerContext context = new DecompilerContext(method.Module) { CurrentType = method.DeclaringType, CurrentMethod = method };
			ilMethod.Body = astBuilder.Build(method, inlineVariables, context);
			
			if (abortBeforeStep != null) {
				new ILAstOptimizer().Optimize(context, ilMethod, abortBeforeStep.Value);
			}
			
			if (context.CurrentMethodIsAsync) {
				output.Write("async", TextTokenType.Keyword);
				output.Write('/', TextTokenType.Operator);
				output.WriteLine("await", TextTokenType.Keyword);
			}
			
			var allVariables = ilMethod.GetSelfAndChildrenRecursive<ILExpression>().Select(e => e.Operand as ILVariable)
				.Where(v => v != null && !v.IsParameter).Distinct();
			foreach (ILVariable v in allVariables) {
				output.WriteDefinition(IdentifierEscaper.Escape(v.Name), v, v.IsParameter ? TextTokenType.Parameter : TextTokenType.Local);
				if (v.Type != null) {
					output.WriteSpace();
					output.Write(':', TextTokenType.Operator);
					output.WriteSpace();
					if (v.IsPinned) {
						output.Write("pinned", TextTokenType.Keyword);
						output.WriteSpace();
					}
					v.Type.WriteTo(output, ILNameSyntax.ShortTypeName);
				}
				if (v.IsGenerated) {
					output.WriteSpace();
					output.Write('[', TextTokenType.Operator);
					output.Write("generated", TextTokenType.Keyword);
					output.Write(']', TextTokenType.Operator);
				}
				output.WriteLine();
			}
			
			var memberMapping = new MemberMapping(method);
			foreach (ILNode node in ilMethod.Body) {
				node.WriteTo(output, memberMapping);
				if (!node.WritesNewLine)
					output.WriteLine();
			}
			output.AddDebugSymbols(memberMapping);
			EndKeywordBlock(output);
		}
Beispiel #2
0
		public override void DecompileMethod(MethodDefinition method, ITextOutput output, DecompilationOptions options)
		{
			if (!method.HasBody) {
				return;
			}
			
			ILAstBuilder astBuilder = new ILAstBuilder();
			ILBlock ilMethod = new ILBlock();
			ilMethod.Body = astBuilder.Build(method, inlineVariables);
			
			if (abortBeforeStep != null) {
				DecompilerContext context = new DecompilerContext(method.Module) { CurrentType = method.DeclaringType, CurrentMethod = method };
				new ILAstOptimizer().Optimize(context, ilMethod, abortBeforeStep.Value);
			}
			
			var allVariables = ilMethod.GetSelfAndChildrenRecursive<ILExpression>().Select(e => e.Operand as ILVariable)
				.Where(v => v != null && !v.IsParameter).Distinct();
			foreach (ILVariable v in allVariables) {
				output.WriteDefinition(v.Name, v);
				if (v.Type != null) {
					output.Write(" : ");
					if (v.IsPinned)
						output.Write("pinned ");
					v.Type.WriteTo(output, ILNameSyntax.ShortTypeName);
				}
				output.WriteLine();
			}
			output.WriteLine();
			
			foreach (ILNode node in ilMethod.Body) {
				node.WriteTo(output);
				output.WriteLine();
			}
		}
Beispiel #3
0
		public static void WriteTo(this Instruction instruction, ITextOutput writer, Func<OpCode, string> getOpCodeDocumentation)
		{
			writer.WriteDefinition(DnlibExtensions.OffsetToString(instruction.GetOffset()), instruction, TextTokenType.Label, false);
			writer.Write(':', TextTokenType.Operator);
			writer.WriteSpace();
			writer.WriteReference(instruction.OpCode.Name, instruction.OpCode, TextTokenType.OpCode);
			if (instruction.Operand != null) {
				writer.WriteSpace();
				if (instruction.OpCode == OpCodes.Ldtoken) {
					var member = instruction.Operand as IMemberRef;
					if (member != null && member.IsMethod) {
						writer.Write("method", TextTokenType.Keyword);
						writer.WriteSpace();
					}
					else if (member != null && member.IsField) {
						writer.Write("field", TextTokenType.Keyword);
						writer.WriteSpace();
					}
				}
				WriteOperand(writer, instruction.Operand);
			}
			if (getOpCodeDocumentation != null) {
				var doc = getOpCodeDocumentation(instruction.OpCode);
				if (doc != null) {
					writer.Write("\t", TextTokenType.Text);
					writer.Write("// " + doc, TextTokenType.Comment);
				}
			}
		}
		public static void WriteTo(this Instruction instruction, ITextOutput writer)
		{
			writer.WriteDefinition(CecilExtensions.OffsetToString(instruction.Offset), instruction);
			writer.Write(": ");
			writer.WriteReference(instruction.OpCode.Name, instruction.OpCode);
			if(null != instruction.Operand) {
				writer.Write(' ');
				WriteOperand(writer, instruction.Operand);
			}
		}
		public static void WriteTo(this Instruction instruction, ITextOutput writer)
		{
			writer.WriteDefinition(CecilExtensions.OffsetToString(instruction.Offset), instruction);
			writer.Write(": ");
			writer.WriteReference(instruction.OpCode.Name, instruction.OpCode);
			if (instruction.Operand != null) {
				writer.Write(' ');
				if (instruction.OpCode == OpCodes.Ldtoken) {
					if (instruction.Operand is MethodReference)
						writer.Write("method ");
					else if (instruction.Operand is FieldReference)
						writer.Write("field ");
				}
				WriteOperand(writer, instruction.Operand);
			}
		}
		public static void WriteTo(this Instruction instruction, MethodDef method, CilBody body, ITextOutput writer)
		{
			writer.WriteDefinition(dnlibExtensions.OffsetToString(instruction.Offset), instruction, true);
			writer.Write(": ");
			writer.WriteReference(instruction.OpCode.Name, instruction.OpCode, true);
			if (instruction.Operand != null) {
				writer.Write(' ');
				if (instruction.OpCode == OpCodes.Ldtoken) {
					if (dnlibExtensions.IsMethod(instruction.Operand))
						writer.WriteKeyword("method ");
					else if (dnlibExtensions.IsField(instruction.Operand))
						writer.WriteKeyword("field ");
				}
				WriteOperand(writer, instruction.Operand);
			}
			else if (method != null && body != null) {
				switch (instruction.OpCode.Code) {
					case Code.Ldloc_0:
					case Code.Ldloc_1:
					case Code.Ldloc_2:
					case Code.Ldloc_3:
						writer.WriteComment("  // ");
						var local = instruction.GetLocal(body.Variables);
						if (local != null)
							WriteOperand(writer, local);
						break;

					case Code.Ldarg_0:
					case Code.Ldarg_1:
					case Code.Ldarg_2:
					case Code.Ldarg_3:
						writer.WriteComment("  // ");
						var arg = instruction.GetParameter(method.Parameters);
						if (arg != null)
							WriteOperand(writer, arg);
						break;
				}
			}
		}
Beispiel #7
0
        public override void WriteShort(ITextOutput output, ILanguage language, bool showOffset)
        {
            var smartOutput = output as ISmartTextOutput;

            if (smartOutput != null)
            {
                language.WriteCommentBegin(output, true);
                output.WriteOffsetComment(this, showOffset);
                smartOutput.AddUIElement(() => {
                    return(new System.Windows.Controls.Image {
                        Source = imageSource,
                    });
                });
                output.Write(" = ", TextTokenKind.Comment);
                const string LTR = "\u200E";
                output.WriteDefinition(NameUtils.CleanName(Name) + LTR, this, TextTokenKind.Comment);
                language.WriteCommentEnd(output, true);
                output.WriteLine();
                return;
            }

            base.WriteShort(output, language, showOffset);
        }
Beispiel #8
0
        public virtual void Decompile(Language language, ITextOutput output)
        {
            language.WriteComment(output, string.Empty);
            output.WriteOffsetComment(this);
            output.WriteDefinition(UIUtils.CleanUpName(Name), this, TextTokenType.Comment);
            string extra = null;

            if (r.ResourceType == ResourceType.AssemblyLinked)
            {
                extra = ((AssemblyLinkedResource)r).Assembly.FullName;
            }
            else if (r.ResourceType == ResourceType.Linked)
            {
                var file = ((LinkedResource)r).File;
                extra = string.Format("{0}, {1}, {2}", file.Name, file.ContainsNoMetaData ? "ContainsNoMetaData" : "ContainsMetaData", NumberVMUtils.ByteArrayToString(file.HashValue));
            }
            else if (r.ResourceType == ResourceType.Embedded)
            {
                extra = string.Format("{0} bytes", ((EmbeddedResource)r).Data.Length);
            }
            output.Write(string.Format(" ({0}{1}, {2})", extra == null ? string.Empty : string.Format("{0}, ", extra), r.ResourceType, r.Attributes), TextTokenType.Comment);
            output.WriteLine();
        }
Beispiel #9
0
 public virtual void Decompile(Language language, ITextOutput output)
 {
     language.WriteComment(output, string.Empty);
     if (Options.DecompilerSettingsPanel.CurrentDecompilerSettings.ShowTokenAndRvaComments) {
         long fo = FileOffset;
         if (fo != 0)
             output.Write(string.Format("0x{0:X8}: ", fo), TextTokenType.Comment);
     }
     output.WriteDefinition(UIUtils.CleanUpName(Name), this, TextTokenType.Comment);
     string extra = null;
     if (r.ResourceType == ResourceType.AssemblyLinked)
         extra = ((AssemblyLinkedResource)r).Assembly.FullName;
     else if (r.ResourceType == ResourceType.Linked) {
         var file = ((LinkedResource)r).File;
         extra = string.Format("{0}, {1}, {2}", file.Name, file.ContainsNoMetaData ? "ContainsNoMetaData" : "ContainsMetaData", AsmEditor.NumberVMUtils.ByteArrayToString(file.HashValue));
     }
     output.Write(string.Format(" ({0}{1}, {2})", extra == null ? string.Empty : string.Format("{0}, ", extra), r.ResourceType, r.Attributes), TextTokenType.Comment);
     output.WriteLine();
 }
Beispiel #10
0
        public void Disassemble(MethodBody body)
        {
            // start writing IL code
            var method = body.Method;

            _output.WriteLine("// Method begins at RVA 0x{0:x4}", method.RVA);
            _output.WriteLine("// Code size {0} (0x{0:x})", body.CodeSize);
            _output.WriteLine(".maxstack {0}", body.MaxStackSize);
            if (method.DeclaringType.Module.Assembly != null && method.DeclaringType.Module.Assembly.EntryPoint == method)
            {
                _output.WriteLine(".entrypoint");
            }

            if (method.Body.HasVariables)
            {
                _output.Write(".locals ");
                if (method.Body.InitLocals)
                {
                    _output.Write("init ");
                }
                _output.WriteLine("(");
                _output.Indent();
                foreach (var v in method.Body.Variables)
                {
                    _output.WriteDefinition("[" + v.Index + "] ", v);
                    v.VariableType.WriteTo(_output);
                    if (!string.IsNullOrEmpty(v.ToString()))
                    {
                        _output.Write(' ');
                        _output.Write(DisassemblerHelpers.Escape(v.ToString()));
                    }
                    if (v.Index + 1 < method.Body.Variables.Count)
                    {
                        _output.Write(',');
                    }
                    _output.WriteLine();
                }
                _output.Unindent();
                _output.WriteLine(")");
            }
            _output.WriteLine();

            if (_detectControlStructure && body.Instructions.Count > 0)
            {
                var inst          = body.Instructions[0];
                var branchTargets = GetBranchTargets(body.Instructions);
                WriteStructureBody(new ILStructure(body), branchTargets, ref inst);
            }
            else
            {
                foreach (var inst in method.Body.Instructions)
                {
                    inst.WriteTo(_output);
                    _output.WriteLine();
                }

                if (method.Body.HasExceptionHandlers)
                {
                    _output.WriteLine();
                    foreach (var eh in method.Body.ExceptionHandlers)
                    {
                        eh.WriteTo(_output);
                        _output.WriteLine();
                    }
                }
            }
        }
Beispiel #11
0
 public virtual void WriteShort(ITextOutput output, ILanguage language, bool showOffset)
 {
     language.WriteCommentBegin(output, true);
     output.WriteOffsetComment(this, showOffset);
     output.WriteDefinition(NameUtils.CleanName(Name), this, TextTokenKind.Comment);
     string extra = null;
     switch (resource.ResourceType) {
     case ResourceType.AssemblyLinked:
         extra = ((AssemblyLinkedResource)resource).Assembly.FullName;
         break;
     case ResourceType.Linked:
         var file = ((LinkedResource)resource).File;
         extra = string.Format("{0}, {1}, {2}", file.Name, file.ContainsNoMetaData ? "ContainsNoMetaData" : "ContainsMetaData", NumberVMUtils.ByteArrayToString(file.HashValue));
         break;
     case ResourceType.Embedded:
         extra = string.Format(dnSpy_Shared_Resources.NumberOfBytes, ((EmbeddedResource)resource).Data.Length);
         break;
     }
     output.Write(string.Format(" ({0}{1}, {2})", extra == null ? string.Empty : string.Format("{0}, ", extra), resource.ResourceType, resource.Attributes), TextTokenKind.Comment);
     language.WriteCommentEnd(output, true);
     output.WriteLine();
 }
Beispiel #12
0
 public virtual void Decompile(Language language, ITextOutput output)
 {
     language.WriteComment(output, string.Empty);
     if (Options.DecompilerSettingsPanel.CurrentDecompilerSettings.ShowTokenAndRvaComments) {
         long fo = FileOffset;
         if (fo != 0)
             output.Write(string.Format("0x{0:X8}: ", fo), TextTokenType.Comment);
     }
     output.WriteDefinition(UIUtils.CleanUpName(Name), this, TextTokenType.Comment);
     output.Write(string.Format(" = {0}", ValueString), TextTokenType.Comment);
     output.WriteLine();
 }
Beispiel #13
0
        public override void Decompile(FieldDef field, ITextOutput output, DecompilationContext ctx)
        {
            output.WriteReference(IdentifierEscaper.Escape(field.FieldType.GetFullName()), field.FieldType.ToTypeDefOrRef(), TextTokenKindUtils.GetTextTokenType(field.FieldType));
            output.WriteSpace();
            output.WriteDefinition(IdentifierEscaper.Escape(field.Name), field, TextTokenKindUtils.GetTextTokenType(field), false);
            var c = field.Constant;

            if (c != null)
            {
                output.WriteSpace();
                output.Write("=", TextTokenKind.Operator);
                output.WriteSpace();
                if (c.Value == null)
                {
                    output.Write("null", TextTokenKind.Keyword);
                }
                else
                {
                    switch (c.Type)
                    {
                    case ElementType.Boolean:
                        if (c.Value is bool)
                        {
                            output.Write((bool)c.Value ? "true" : "false", TextTokenKind.Keyword);
                        }
                        else
                        {
                            goto default;
                        }
                        break;

                    case ElementType.Char:
                        output.Write(string.Format("'{0}'", c.Value), TextTokenKind.Char);
                        break;

                    case ElementType.I1:
                    case ElementType.U1:
                    case ElementType.I2:
                    case ElementType.U2:
                    case ElementType.I4:
                    case ElementType.U4:
                    case ElementType.I8:
                    case ElementType.U8:
                    case ElementType.R4:
                    case ElementType.R8:
                    case ElementType.I:
                    case ElementType.U:
                        output.Write(string.Format("{0}", c.Value), TextTokenKind.Number);
                        break;

                    case ElementType.String:
                        output.Write(string.Format("{0}", c.Value), TextTokenKind.String);
                        break;

                    default:
                        output.Write(string.Format("{0}", c.Value), TextTokenKind.Text);
                        break;
                    }
                }
            }
        }
Beispiel #14
0
        public void Disassemble(MethodDef method, MemberMapping debugSymbols)
        {
            // start writing IL code
            CilBody body     = method.Body;
            uint    codeSize = (uint)body.GetCodeSize();
            uint    rva      = (uint)method.RVA;
            long    offset   = method.Module.ToFileOffset(rva);

            if (options.ShowTokenAndRvaComments)
            {
                output.WriteLine(string.Format("// Header Size: {0} {1}", method.Body.HeaderSize, method.Body.HeaderSize == 1 ? "byte" : "bytes"), TextTokenType.Comment);
                output.WriteLine(string.Format("// Code Size: {0} (0x{0:X}) {1}", codeSize, codeSize == 1 ? "byte" : "bytes"), TextTokenType.Comment);
                if (body.LocalVarSigTok != 0)
                {
                    output.WriteLine(string.Format("// LocalVarSig Token: 0x{0:X8} RID: {1}", body.LocalVarSigTok, body.LocalVarSigTok & 0xFFFFFF), TextTokenType.Comment);
                }
            }
            output.Write(".maxstack", TextTokenType.ILDirective);
            output.WriteSpace();
            output.WriteLine(string.Format("{0}", body.MaxStack), TextTokenType.Number);
            if (method.DeclaringType.Module.EntryPoint == method)
            {
                output.WriteLine(".entrypoint", TextTokenType.ILDirective);
            }

            if (method.Body.HasVariables)
            {
                output.Write(".locals", TextTokenType.ILDirective);
                output.WriteSpace();
                if (method.Body.InitLocals)
                {
                    output.Write("init", TextTokenType.Keyword);
                    output.WriteSpace();
                }
                output.WriteLine("(", TextTokenType.Operator);
                output.Indent();
                foreach (var v in method.Body.Variables)
                {
                    output.Write('[', TextTokenType.Operator);
                    output.WriteDefinition(v.Index.ToString(), v, TextTokenType.Number);
                    output.Write(']', TextTokenType.Operator);
                    output.WriteSpace();
                    v.Type.WriteTo(output);
                    if (!string.IsNullOrEmpty(v.Name))
                    {
                        output.WriteSpace();
                        output.Write(DisassemblerHelpers.Escape(v.Name), TextTokenType.Local);
                    }
                    if (v.Index + 1 < method.Body.Variables.Count)
                    {
                        output.Write(',', TextTokenType.Operator);
                    }
                    output.WriteLine();
                }
                output.Unindent();
                output.WriteLine(")", TextTokenType.Operator);
            }
            output.WriteLine();

            uint baseRva  = rva == 0 ? 0 : rva + method.Body.HeaderSize;
            long baseOffs = baseRva == 0 ? 0 : method.Module.ToFileOffset(baseRva);

            using (var byteReader = !options.ShowILBytes || options.CreateInstructionBytesReader == null ? null : options.CreateInstructionBytesReader(method)) {
                if (detectControlStructure && body.Instructions.Count > 0)
                {
                    int            index         = 0;
                    HashSet <uint> branchTargets = GetBranchTargets(body.Instructions);
                    WriteStructureBody(body, new ILStructure(body), branchTargets, ref index, debugSymbols, method.Body.GetCodeSize(), baseRva, baseOffs, byteReader, method);
                }
                else
                {
                    var instructions = method.Body.Instructions;
                    for (int i = 0; i < instructions.Count; i++)
                    {
                        var inst          = instructions[i];
                        var startLocation = output.Location;
                        inst.WriteTo(output, options, baseRva, baseOffs, byteReader, method);

                        if (debugSymbols != null)
                        {
                            // add IL code mappings - used in debugger
                            var next = i + 1 < instructions.Count ? instructions[i + 1] : null;
                            debugSymbols.MemberCodeMappings.Add(
                                new SourceCodeMapping()
                            {
                                StartLocation       = output.Location,
                                EndLocation         = output.Location,
                                ILInstructionOffset = new ILRange(inst.Offset, next == null ? (uint)method.Body.GetCodeSize() : next.Offset),
                                MemberMapping       = debugSymbols
                            });
                        }

                        output.WriteLine();
                    }
                    if (method.Body.HasExceptionHandlers)
                    {
                        output.WriteLine();
                        foreach (var eh in method.Body.ExceptionHandlers)
                        {
                            eh.WriteTo(output, method);
                            output.WriteLine();
                        }
                    }
                }
            }
        }
Beispiel #15
0
        public static void WriteTo(this Instruction instruction, ITextOutput writer, DisassemblerOptions options, uint baseRva, long baseOffs, IInstructionBytesReader byteReader, MethodDef method)
        {
            if (options != null && (options.ShowTokenAndRvaComments || options.ShowILBytes)) {
                writer.Write("/* ", TextTokenType.Comment);

                bool needSpace = false;

                if (options.ShowTokenAndRvaComments) {
                    ulong fileOffset = (ulong)baseOffs + instruction.Offset;
                    writer.WriteReference(string.Format("0x{0:X8}", fileOffset), new AddressReference(options.OwnerModule == null ? null : options.OwnerModule.Location, false, fileOffset, (ulong)instruction.GetSize()), TextTokenType.Comment, false);
                    needSpace = true;
                }

                if (options.ShowILBytes) {
                    if (needSpace)
                        writer.Write(' ', TextTokenType.Comment);
                    if (byteReader == null)
                        writer.Write("??", TextTokenType.Comment);
                    else {
                        int size = instruction.GetSize();
                        for (int i = 0; i < size; i++) {
                            var b = byteReader.ReadByte();
                            if (b < 0)
                                writer.Write("??", TextTokenType.Comment);
                            else
                                writer.Write(string.Format("{0:X2}", b), TextTokenType.Comment);
                        }
                        // Most instructions should be at most 5 bytes in length, but use 6 since
                        // ldftn/ldvirtftn are 6 bytes long. The longest instructions are those with
                        // 8 byte operands, ldc.i8 and ldc.r8: 9 bytes.
                        const int MIN_BYTES = 6;
                        for (int i = size; i < MIN_BYTES; i++)
                            writer.Write("  ", TextTokenType.Comment);
                    }
                }

                writer.Write(" */", TextTokenType.Comment);
                writer.WriteSpace();
            }
            writer.WriteDefinition(DnlibExtensions.OffsetToString(instruction.GetOffset()), new InstructionReference(method, instruction), TextTokenType.Label, false);
            writer.Write(':', TextTokenType.Operator);
            writer.WriteSpace();
            writer.WriteReference(instruction.OpCode.Name, instruction.OpCode, TextTokenType.OpCode);
            if (instruction.Operand != null) {
                int count = OPERAND_ALIGNMENT - instruction.OpCode.Name.Length;
                if (count <= 0)
                    count = 1;
                writer.Write(spaces[count], TextTokenType.Text);
                if (instruction.OpCode == OpCodes.Ldtoken) {
                    var member = instruction.Operand as IMemberRef;
                    if (member != null && member.IsMethod) {
                        writer.Write("method", TextTokenType.Keyword);
                        writer.WriteSpace();
                    }
                    else if (member != null && member.IsField) {
                        writer.Write("field", TextTokenType.Keyword);
                        writer.WriteSpace();
                    }
                }
                WriteOperand(writer, instruction.Operand, method);
            }
            if (options != null && options.GetOpCodeDocumentation != null) {
                var doc = options.GetOpCodeDocumentation(instruction.OpCode);
                if (doc != null) {
                    writer.Write("\t", TextTokenType.Text);
                    writer.Write("// " + doc, TextTokenType.Comment);
                }
            }
        }
Beispiel #16
0
        public override void WriteIdentifier(Identifier identifier)
        {
            if (identifier.IsVerbatim || CSharpOutputVisitor.IsKeyword(identifier.Name, identifier))
            {
                output.Write('@');
            }

            var definition = GetCurrentDefinition();

            if (definition != null)
            {
                output.WriteDefinition(identifier.Name, definition, false);
                return;
            }

            var member = GetCurrentMemberReference();

            if (member != null)
            {
                MemberReference cecil;
                if (member is IType type)
                {
                    cecil = typeSystem.GetCecil(type.GetDefinition());
                }
                else if (member is IMember)
                {
                    cecil = typeSystem.GetCecil((IMember)member);
                }
                else
                {
                    cecil = null;
                }
                if (cecil != null)
                {
                    output.WriteReference(identifier.Name, cecil);
                    return;
                }
            }

            definition = GetCurrentLocalDefinition();
            if (definition != null)
            {
                output.WriteDefinition(identifier.Name, definition);
                return;
            }

            var memberRef = GetCurrentLocalReference();

            if (memberRef != null)
            {
                output.WriteReference(identifier.Name, memberRef, true);
                return;
            }

            if (firstUsingDeclaration)
            {
                output.MarkFoldStart(defaultCollapsed: true);
                firstUsingDeclaration = false;
            }

            output.Write(identifier.Name);
        }
Beispiel #17
0
		public virtual void Decompile(Language language, ITextOutput output) {
			language.WriteComment(output, string.Empty);
			output.WriteOffsetComment(this);
			output.WriteDefinition(UIUtils.CleanUpName(Name), this, TextTokenType.Comment);
			string extra = null;
			if (r.ResourceType == ResourceType.AssemblyLinked)
				extra = ((AssemblyLinkedResource)r).Assembly.FullName;
			else if (r.ResourceType == ResourceType.Linked) {
				var file = ((LinkedResource)r).File;
				extra = string.Format("{0}, {1}, {2}", file.Name, file.ContainsNoMetaData ? "ContainsNoMetaData" : "ContainsMetaData", NumberVMUtils.ByteArrayToString(file.HashValue));
			}
			else if (r.ResourceType == ResourceType.Embedded)
				extra = string.Format("{0} bytes", ((EmbeddedResource)r).Data.Length);
			output.Write(string.Format(" ({0}{1}, {2})", extra == null ? string.Empty : string.Format("{0}, ", extra), r.ResourceType, r.Attributes), TextTokenType.Comment);
			output.WriteLine();
		}
 public virtual void Decompile(Language language, ITextOutput output)
 {
     language.WriteComment(output, string.Empty);
     output.WriteOffsetComment(this);
     output.WriteDefinition(UIUtils.CleanUpName(Name), this, TextTokenType.Comment);
     output.Write(string.Format(" = {0}", ValueString), TextTokenType.Comment);
     output.WriteLine();
 }
Beispiel #19
0
 public virtual void WriteShort(ITextOutput output, ILanguage language, bool showOffset)
 {
     language.WriteCommentBegin(output, true);
     output.WriteOffsetComment(this, showOffset);
     output.WriteDefinition(NameUtils.CleanName(Name), this, TextTokenKind.Comment);
     output.Write(string.Format(" = {0}", ValueString), TextTokenKind.Comment);
     language.WriteCommentEnd(output, true);
     output.WriteLine();
 }
        public void Disassemble(MethodBody body, MethodDebugSymbols debugSymbols)
        {
            // start writing IL code
            MethodDefinition method = body.Method;

            output.WriteLine("// Method begins at RVA 0x{0:x4}", method.RVA);
            output.WriteLine("// Code size {0} (0x{0:x})", body.CodeSize);
            output.WriteLine(".maxstack {0}", body.MaxStackSize);
            if (method.DeclaringType.Module.Assembly != null && method.DeclaringType.Module.Assembly.EntryPoint == method)
            {
                output.WriteLine(".entrypoint");
            }

            if (method.Body.HasVariables)
            {
                output.Write(".locals ");
                if (method.Body.InitLocals)
                {
                    output.Write("init ");
                }
                output.WriteLine("(");
                output.Indent();
                foreach (var v in method.Body.Variables)
                {
                    output.WriteDefinition("[" + v.Index + "] ", v);
                    v.VariableType.WriteTo(output);
                    string name;
                    if (body.Method.DebugInformation.TryGetName(v, out name))
                    {
                        output.Write(' ');
                        output.Write(DisassemblerHelpers.Escape(name));
                    }
                    if (v.Index + 1 < method.Body.Variables.Count)
                    {
                        output.Write(',');
                    }
                    output.WriteLine();
                }
                output.Unindent();
                output.WriteLine(")");
            }
            output.WriteLine();

            if (detectControlStructure && body.Instructions.Count > 0)
            {
                Instruction   inst          = body.Instructions[0];
                HashSet <int> branchTargets = GetBranchTargets(body.Instructions);
                WriteStructureBody(new ILStructure(body), branchTargets, ref inst, debugSymbols, method.Body.CodeSize);
            }
            else
            {
                foreach (var inst in method.Body.Instructions)
                {
                    var startLocation = output.Location;
                    inst.WriteTo(output);

                    if (debugSymbols != null)
                    {
                        // add IL code mappings - used in debugger
                        debugSymbols.SequencePoints.Add(
                            new SequencePoint()
                        {
                            StartLocation = output.Location,
                            EndLocation   = output.Location,
                            ILRanges      = new ILRange[] { new ILRange(inst.Offset, inst.Next == null ? method.Body.CodeSize : inst.Next.Offset) }
                        });
                    }

                    output.WriteLine();
                }
                if (method.Body.HasExceptionHandlers)
                {
                    output.WriteLine();
                    foreach (var eh in method.Body.ExceptionHandlers)
                    {
                        eh.WriteTo(output);
                        output.WriteLine();
                    }
                }
            }
        }
Beispiel #21
0
        void WriteDefinition(string value, string def = null)
        {
            string str = NumberVMUtils.ToString(value, true);

            output.WriteDefinition(str, BamlToolTipReference.Create(def ?? IdentifierEscaper.Escape(value)), TextTokenKind.String, true);
        }
Beispiel #22
0
        public static void WriteTo(this Instruction instruction, ITextOutput writer, DisassemblerOptions options, uint baseRva, long baseOffs, IInstructionBytesReader byteReader, MethodDef method)
        {
            if (options != null && (options.ShowTokenAndRvaComments || options.ShowILBytes))
            {
                writer.Write("/* ", TextTokenType.Comment);

                bool needSpace = false;

                if (options.ShowTokenAndRvaComments)
                {
                    ulong fileOffset = (ulong)baseOffs + instruction.Offset;
                    writer.WriteReference(string.Format("0x{0:X8}", fileOffset), new AddressReference(options.OwnerModule == null ? null : options.OwnerModule.Location, false, fileOffset, (ulong)instruction.GetSize()), TextTokenType.Comment, false);
                    needSpace = true;
                }

                if (options.ShowILBytes)
                {
                    if (needSpace)
                    {
                        writer.Write(' ', TextTokenType.Comment);
                    }
                    if (byteReader == null)
                    {
                        writer.Write("??", TextTokenType.Comment);
                    }
                    else
                    {
                        int size = instruction.GetSize();
                        for (int i = 0; i < size; i++)
                        {
                            var b = byteReader.ReadByte();
                            if (b < 0)
                            {
                                writer.Write("??", TextTokenType.Comment);
                            }
                            else
                            {
                                writer.Write(string.Format("{0:X2}", b), TextTokenType.Comment);
                            }
                        }
                        // Most instructions should be at most 5 bytes in length, but use 6 since
                        // ldftn/ldvirtftn are 6 bytes long. The longest instructions are those with
                        // 8 byte operands, ldc.i8 and ldc.r8: 9 bytes.
                        const int MIN_BYTES = 6;
                        for (int i = size; i < MIN_BYTES; i++)
                        {
                            writer.Write("  ", TextTokenType.Comment);
                        }
                    }
                }

                writer.Write(" */", TextTokenType.Comment);
                writer.WriteSpace();
            }
            writer.WriteDefinition(DnlibExtensions.OffsetToString(instruction.GetOffset()), new InstructionReference(method, instruction), TextTokenType.Label, false);
            writer.Write(':', TextTokenType.Operator);
            writer.WriteSpace();
            writer.WriteReference(instruction.OpCode.Name, instruction.OpCode, TextTokenType.OpCode);
            if (instruction.Operand != null)
            {
                int count = OPERAND_ALIGNMENT - instruction.OpCode.Name.Length;
                if (count <= 0)
                {
                    count = 1;
                }
                writer.Write(spaces[count], TextTokenType.Text);
                if (instruction.OpCode == OpCodes.Ldtoken)
                {
                    var member = instruction.Operand as IMemberRef;
                    if (member != null && member.IsMethod)
                    {
                        writer.Write("method", TextTokenType.Keyword);
                        writer.WriteSpace();
                    }
                    else if (member != null && member.IsField)
                    {
                        writer.Write("field", TextTokenType.Keyword);
                        writer.WriteSpace();
                    }
                }
                WriteOperand(writer, instruction.Operand, method);
            }
            if (options != null && options.GetOpCodeDocumentation != null)
            {
                var doc = options.GetOpCodeDocumentation(instruction.OpCode);
                if (doc != null)
                {
                    writer.Write("\t", TextTokenType.Text);
                    writer.Write("// " + doc, TextTokenType.Comment);
                }
            }
        }
Beispiel #23
0
        public void Disassemble(MethodBody body, MemberMapping methodMapping)
        {
            // start writing IL code
            MethodDefinition method = body.Method;

            output.WriteLine("// Method begins at RVA 0x{0:x4}", method.RVA);
            output.WriteLine("// Code size {0} (0x{0:x})", body.CodeSize);
            output.WriteLine(".maxstack {0}", body.MaxStackSize);
            if (method.DeclaringType.Module.Assembly.EntryPoint == method)
            {
                output.WriteLine(".entrypoint");
            }

            if (method.Body.HasVariables)
            {
                output.Write(".locals ");
                if (method.Body.InitLocals)
                {
                    output.Write("init ");
                }
                output.WriteLine("(");
                output.Indent();
                foreach (var v in method.Body.Variables)
                {
                    output.WriteDefinition("[" + v.Index + "] ", v);
                    v.VariableType.WriteTo(output);
                    if (!string.IsNullOrEmpty(v.Name))
                    {
                        output.Write(' ');
                        output.Write(DisassemblerHelpers.Escape(v.Name));
                    }
                    if (v.Index + 1 < method.Body.Variables.Count)
                    {
                        output.Write(',');
                    }
                    output.WriteLine();
                }
                output.Unindent();
                output.WriteLine(")");
            }
            output.WriteLine();

            if (detectControlStructure && body.Instructions.Count > 0)
            {
                Instruction   inst          = body.Instructions[0];
                HashSet <int> branchTargets = GetBranchTargets(body.Instructions);
                WriteStructureBody(new ILStructure(body), branchTargets, ref inst, methodMapping, method.Body.CodeSize);
            }
            else
            {
                foreach (var inst in method.Body.Instructions)
                {
                    inst.WriteTo(output);

                    if (methodMapping != null)
                    {
                        // add IL code mappings - used in debugger
                        methodMapping.MemberCodeMappings.Add(
                            new SourceCodeMapping()
                        {
                            SourceCodeLine      = output.CurrentLine,
                            ILInstructionOffset = new ILRange {
                                From = inst.Offset, To = inst.Next == null ? method.Body.CodeSize : inst.Next.Offset
                            },
                            MemberMapping = methodMapping
                        });
                    }

                    output.WriteLine();
                }
                if (method.Body.HasExceptionHandlers)
                {
                    output.WriteLine();
                    foreach (var eh in method.Body.ExceptionHandlers)
                    {
                        eh.WriteTo(output);
                        output.WriteLine();
                    }
                }
            }
        }
Beispiel #24
0
        public override void Decompile(MethodDef method, ITextOutput output, DecompilationContext ctx)
        {
            WriteCommentBegin(output, true);
            output.Write("Method: ", TextTokenKind.Comment);
            output.WriteDefinition(IdentifierEscaper.Escape(method.FullName), method, TextTokenKind.Comment, false);
            WriteCommentEnd(output, true);
            output.WriteLine();

            if (!method.HasBody)
            {
                return;
            }

            StartKeywordBlock(output, ".body", method);

            ILAstBuilder      astBuilder = new ILAstBuilder();
            ILBlock           ilMethod   = new ILBlock();
            DecompilerContext context    = new DecompilerContext(method.Module)
            {
                CurrentType = method.DeclaringType, CurrentMethod = method
            };

            ilMethod.Body = astBuilder.Build(method, inlineVariables, context);

            if (abortBeforeStep != null)
            {
                new ILAstOptimizer().Optimize(context, ilMethod, abortBeforeStep.Value);
            }

            if (context.CurrentMethodIsAsync)
            {
                output.Write("async", TextTokenKind.Keyword);
                output.Write("/", TextTokenKind.Operator);
                output.WriteLine("await", TextTokenKind.Keyword);
            }

            var allVariables = ilMethod.GetSelfAndChildrenRecursive <ILExpression>().Select(e => e.Operand as ILVariable)
                               .Where(v => v != null && !v.IsParameter).Distinct();

            foreach (ILVariable v in allVariables)
            {
                output.WriteDefinition(IdentifierEscaper.Escape(v.Name), v, v.IsParameter ? TextTokenKind.Parameter : TextTokenKind.Local);
                if (v.Type != null)
                {
                    output.WriteSpace();
                    output.Write(":", TextTokenKind.Operator);
                    output.WriteSpace();
                    if (v.IsPinned)
                    {
                        output.Write("pinned", TextTokenKind.Keyword);
                        output.WriteSpace();
                    }
                    v.Type.WriteTo(output, ILNameSyntax.ShortTypeName);
                }
                if (v.GeneratedByDecompiler)
                {
                    output.WriteSpace();
                    output.Write("[", TextTokenKind.Operator);
                    output.Write("generated", TextTokenKind.Keyword);
                    output.Write("]", TextTokenKind.Operator);
                }
                output.WriteLine();
            }

            var memberMapping = new MemberMapping(method);

            foreach (ILNode node in ilMethod.Body)
            {
                node.WriteTo(output, memberMapping);
                if (!node.WritesNewLine)
                {
                    output.WriteLine();
                }
            }
            output.AddDebugSymbols(memberMapping);
            EndKeywordBlock(output);
        }
Beispiel #25
0
		void StartKeywordBlock(ITextOutput output, string keyword, IMemberDef member)
		{
			output.Write(keyword, TextTokenType.Keyword);
			output.WriteSpace();
			output.WriteDefinition(IdentifierEscaper.Escape(member.Name), member, TextTokenHelper.GetTextTokenType(member), false);
			output.WriteSpace();
			output.WriteLeftBrace();
			output.WriteLine();
			output.Indent();
		}
Beispiel #26
0
        internal void WriteDefinitionTo(ITextOutput output)
        {
            switch (Kind)
            {
            case VariableKind.Local:
                output.Write("local ");
                break;

            case VariableKind.PinnedLocal:
                output.Write("pinned local ");
                break;

            case VariableKind.Parameter:
                output.Write("param ");
                break;

            case VariableKind.Exception:
                output.Write("exception ");
                break;

            case VariableKind.StackSlot:
                output.Write("stack ");
                break;

            case VariableKind.InitializerTarget:
                output.Write("initializer ");
                break;

            case VariableKind.ForeachLocal:
                output.Write("foreach ");
                break;

            case VariableKind.UsingLocal:
                output.Write("using ");
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
            output.WriteDefinition(this.Name, this, isLocal: true);
            output.Write(" : ");
            Type.WriteTo(output);
            output.Write('(');
            if (Kind == VariableKind.Parameter || Kind == VariableKind.Local || Kind == VariableKind.PinnedLocal)
            {
                output.Write("Index={0}, ", Index);
            }
            output.Write("LoadCount={0}, AddressCount={1}, StoreCount={2})", LoadCount, AddressCount, StoreCount);
            if (hasInitialValue && Kind != VariableKind.Parameter)
            {
                output.Write(" init");
            }
            if (CaptureScope != null)
            {
                output.Write(" captured in " + CaptureScope.EntryPoint.Label);
            }
            if (StateMachineField != null)
            {
                output.Write(" from state-machine");
            }
        }
        public void Disassemble(MethodDef method, CilBody body, MemberMapping methodMapping)
        {
            // start writing IL code
            output.WriteLineComment("// Method Token is 0x{0:x8}", method.MDToken.Raw);
            output.WriteLineComment("// Method begins at RVA 0x{0:x}", method.RVA);
            output.WriteLineComment("// Code size {0} (0x{0:x})", body.GetCodeSize());
            output.WriteKeyword(".maxstack ");
            output.WriteLiteral(body.MaxStack.ToString());
            output.WriteLine();
            if (method.DeclaringType.Module.Assembly != null && method.DeclaringType.Module.EntryPoint == method)
            {
                output.WriteKeyword(".entrypoint");
                output.WriteLine();
            }

            if (method.Body.HasVariables)
            {
                output.WriteKeyword(".locals ");
                if (method.Body.InitLocals)
                {
                    output.WriteKeyword("init ");
                }
                output.WriteLine("(");
                output.Indent();
                foreach (var v in method.Body.Variables)
                {
                    output.WriteDefinition("[" + v.Index + "]", v, true);
                    output.Write(" ");
                    v.Type.WriteTo(output);
                    if (!string.IsNullOrEmpty(v.Name))
                    {
                        output.Write(' ');
                        output.Write(DisassemblerHelpers.Escape(v.Name));
                    }
                    if (v.Index + 1 < method.Body.Variables.Count)
                    {
                        output.Write(',');
                    }
                    output.WriteLine();
                }
                output.Unindent();
                output.WriteLine(")");
            }
            output.WriteLine();

            if (detectControlStructure && body.Instructions.Count > 0)
            {
                Instruction inst          = body.Instructions[0];
                var         branchTargets = GetBranchTargets(body.Instructions);
                WriteStructureBody(method, body, new ILStructure(body), branchTargets, ref inst, methodMapping, method.Body.GetCodeSize());
            }
            else
            {
                foreach (var inst in method.Body.Instructions)
                {
                    var startLocation = output.Location;
                    inst.WriteTo(method, body, output);

                    if (methodMapping != null)
                    {
                        var next = inst.GetNext(body);
                        // add IL code mappings - used in debugger
                        methodMapping.MemberCodeMappings.Add(
                            new SourceCodeMapping()
                        {
                            StartLocation       = output.Location,
                            EndLocation         = output.Location,
                            ILInstructionOffset = new ILRange {
                                From = inst.Offset, To = next == null ? method.Body.GetCodeSize() : next.Offset
                            },
                            MemberMapping = methodMapping
                        });
                    }

                    output.WriteLine();
                }
                if (method.Body.HasExceptionHandlers)
                {
                    output.WriteLine();
                    foreach (var eh in method.Body.ExceptionHandlers)
                    {
                        eh.WriteTo(output);
                        output.WriteLine();
                    }
                }
            }
        }
Beispiel #28
0
        public void Disassemble(MethodDef method, MemberMapping debugSymbols)
        {
            // start writing IL code
            CilBody body     = method.Body;
            uint    codeSize = (uint)body.GetCodeSize();

            output.WriteLine(string.Format("// RVA 0x{0:x8} - 0x{1:x8} ({2} (0x{2:x}) bytes)", (uint)method.RVA, (uint)method.RVA + codeSize, codeSize), TextTokenType.Comment);
            output.WriteLine(string.Format("// Metadata token 0x{0:x8} (RID {1})", method.MDToken.ToInt32(), method.Rid), TextTokenType.Comment);
            if (body.LocalVarSigTok != 0)
            {
                output.WriteLine(string.Format("// LocalVarSig token 0x{0:x8} (RID {1})", body.LocalVarSigTok, body.LocalVarSigTok & 0xFFFFFF), TextTokenType.Comment);
            }
            output.Write(".maxstack", TextTokenType.ILDirective);
            output.WriteSpace();
            output.WriteLine(string.Format("{0}", body.MaxStack), TextTokenType.Number);
            if (method.DeclaringType.Module.EntryPoint == method)
            {
                output.WriteLine(".entrypoint", TextTokenType.ILDirective);
            }

            if (method.Body.HasVariables)
            {
                output.Write(".locals", TextTokenType.ILDirective);
                output.WriteSpace();
                if (method.Body.InitLocals)
                {
                    output.Write("init", TextTokenType.Keyword);
                    output.WriteSpace();
                }
                output.WriteLine("(", TextTokenType.Operator);
                output.Indent();
                foreach (var v in method.Body.Variables)
                {
                    output.Write('[', TextTokenType.Operator);
                    output.WriteDefinition(v.Index.ToString(), v, TextTokenType.Number);
                    output.Write(']', TextTokenType.Operator);
                    output.WriteSpace();
                    v.Type.WriteTo(output);
                    if (!string.IsNullOrEmpty(v.Name))
                    {
                        output.WriteSpace();
                        output.Write(DisassemblerHelpers.Escape(v.Name), TextTokenType.Local);
                    }
                    if (v.Index + 1 < method.Body.Variables.Count)
                    {
                        output.Write(',', TextTokenType.Operator);
                    }
                    output.WriteLine();
                }
                output.Unindent();
                output.WriteLine(")", TextTokenType.Operator);
            }
            output.WriteLine();

            if (detectControlStructure && body.Instructions.Count > 0)
            {
                int            index         = 0;
                HashSet <uint> branchTargets = GetBranchTargets(body.Instructions);
                WriteStructureBody(body, new ILStructure(body), branchTargets, ref index, debugSymbols, method.Body.GetCodeSize());
            }
            else
            {
                var instructions = method.Body.Instructions;
                for (int i = 0; i < instructions.Count; i++)
                {
                    var inst          = instructions[i];
                    var startLocation = output.Location;
                    inst.WriteTo(output, options.GetOpCodeDocumentation);

                    if (debugSymbols != null)
                    {
                        // add IL code mappings - used in debugger
                        var next = i + 1 < instructions.Count ? instructions[i + 1] : null;
                        debugSymbols.MemberCodeMappings.Add(
                            new SourceCodeMapping()
                        {
                            StartLocation       = output.Location,
                            EndLocation         = output.Location,
                            ILInstructionOffset = new ILRange(inst.Offset, next == null ? (uint)method.Body.GetCodeSize() : next.Offset),
                            MemberMapping       = debugSymbols
                        });
                    }

                    output.WriteLine();
                }
                if (method.Body.HasExceptionHandlers)
                {
                    output.WriteLine();
                    foreach (var eh in method.Body.ExceptionHandlers)
                    {
                        eh.WriteTo(output);
                        output.WriteLine();
                    }
                }
            }
        }
 public void DisassembleMethod(MethodDefinition method)
 {
     // write method header
     output.WriteDefinition(".method ", method);
     DisassembleMethodInternal(method);
 }
Beispiel #30
0
 public override void WriteTo(ITextOutput output)
 {
     output.WriteDefinition(Name + ":", this);
 }
 public void WriteDefinition(string text, object definition, bool isLocal = true)
 {
     _inner.WriteDefinition(text, definition, isLocal);
     _currentLineLength += text.Length;
 }
Beispiel #32
0
		public override void DecompileField(FieldDef field, ITextOutput output, DecompilationOptions options)
		{
			output.WriteReference(IdentifierEscaper.Escape(field.FieldType.GetFullName()), field.FieldType.ToTypeDefOrRef(), TextTokenHelper.GetTextTokenType(field.FieldType));
			output.WriteSpace();
			output.WriteDefinition(IdentifierEscaper.Escape(field.Name), field, TextTokenHelper.GetTextTokenType(field), false);
			var c = field.Constant;
			if (c != null) {
				output.WriteSpace();
				output.Write('=', TextTokenType.Operator);
				output.WriteSpace();
				if (c.Value == null)
					output.Write("null", TextTokenType.Keyword);
				else {
					switch (c.Type) {
					case ElementType.Boolean:
						if (c.Value is bool)
							output.Write((bool)c.Value ? "true" : "false", TextTokenType.Keyword);
						else
							goto default;
						break;

					case ElementType.Char:
						output.Write(string.Format("'{0}'", c.Value), TextTokenType.Char);
						break;

					case ElementType.I1:
					case ElementType.U1:
					case ElementType.I2:
					case ElementType.U2:
					case ElementType.I4:
					case ElementType.U4:
					case ElementType.I8:
					case ElementType.U8:
					case ElementType.R4:
					case ElementType.R8:
					case ElementType.I:
					case ElementType.U:
						output.Write(string.Format("{0}", c.Value), TextTokenType.Number);
						break;

					case ElementType.String:
						output.Write(string.Format("{0}", c.Value), TextTokenType.String);
						break;

					default:
						output.Write(string.Format("{0}", c.Value), TextTokenType.Text);
						break;
					}
				}
			}
		}
Beispiel #33
0
        public override void WriteShort(ITextOutput output, ILanguage language, bool showOffset)
        {
            var smartOutput = output as ISmartTextOutput;
            if (smartOutput != null) {
                language.WriteCommentBegin(output, true);
                output.WriteOffsetComment(this, showOffset);
                smartOutput.AddUIElement(() => {
                    return new System.Windows.Controls.Image {
                        Source = imageSource,
                    };
                });
                output.Write(" = ", TextTokenKind.Comment);
                output.WriteDefinition(NameUtils.CleanName(Name), this, TextTokenKind.Comment);
                language.WriteCommentEnd(output, true);
                output.WriteLine();
                return;
            }

            base.WriteShort(output, language, showOffset);
        }
Beispiel #34
0
 /// <summary>
 /// Write human readable output.
 /// </summary>
 public override void WriteTo(ITextOutput output, FormattingOptions format)
 {
     output.WriteDefinition(Name + ":", this);
 }
Beispiel #35
0
        void WriteDefinition(string value, string def = null)
        {
            string str = string.Format("\"{0}\"", TextWriterTokenWriter.ConvertString(value));

            output.WriteDefinition(str, def ?? IdentifierEscaper.Escape(value), TextTokenType.String, true);
        }