public void VisualizeMethodBody(MethodBodyBlock body, MethodHandle methodHandle, bool emitHeader = true) { StringBuilder builder = new StringBuilder(); // TODO: Inspect EncLog to find a containing type and display qualified name. var method = GetMethod(methodHandle); if (emitHeader) { builder.AppendFormat("Method {0} (0x{1:X8})", Literal(method.Name), MetadataTokens.GetToken(methodHandle)); builder.AppendLine(); } // TODO: decode signature if (!body.LocalSignature.IsNil) { var localSignature = GetLocalSignature(body.LocalSignature); builder.AppendFormat(" Locals: {0}", Literal(localSignature)); builder.AppendLine(); } ILVisualizerAsTokens.Instance.DumpMethod( builder, body.MaxStack, body.GetILBytes(), ImmutableArray.Create <ILVisualizer.LocalInfo>(), // TODO ImmutableArray.Create <ILVisualizer.HandlerSpan>()); // TOOD: ILVisualizer.GetHandlerSpans(body.ExceptionRegions) builder.AppendLine(); writer.Write(builder.ToString()); }
static private void ProcessMethod(ILGenerator generator, MethodEx methodEx, MethodBase method, MetaDataMapper mapper) { if (method.IsAbstract) { return; } MethodBodyBlock body = null; if (methodEx == null) { throw new ExportException(); } body = CreateBody(methodEx); if (body == null) { throw new ExportException(); } MetaDataResolver.Map(body, mapper); bool verified = CFGVerifier.Check(body); if (!verified) { throw new ExportException(); } Emitter.Emit(generator, body); }
private static unsafe MethodBodyBlock ReadMethodBody(byte[] body) { fixed(byte *bodyPtr = &body[0]) { return(MethodBodyBlock.Create(new BlobReader(bodyPtr, body.Length))); } }
public void PinnedAndUnpinnedLocals() { using (FileStream stream = File.OpenRead(AssemblyPathHelper.GetAssemblyLocation(typeof(PinnedAndUnpinnedLocalsToDecode).GetTypeInfo().Assembly))) using (var peReader = new PEReader(stream)) { MetadataReader reader = peReader.GetMetadataReader(); var provider = new DisassemblingTypeProvider(); TypeDefinitionHandle typeDefHandle = TestMetadataResolver.FindTestType(reader, typeof(PinnedAndUnpinnedLocalsToDecode)); TypeDefinition typeDef = reader.GetTypeDefinition(typeDefHandle); MethodDefinition methodDef = reader.GetMethodDefinition(typeDef.GetMethods().First()); Assert.Equal("DoSomething", reader.GetString(methodDef.Name)); MethodBodyBlock body = peReader.GetMethodBody(methodDef.RelativeVirtualAddress); StandaloneSignature localSignature = reader.GetStandaloneSignature(body.LocalSignature); ImmutableArray <string> localTypes = localSignature.DecodeLocalSignature(provider, genericContext: null); // Compiler can generate temporaries or re-order so just check the ones we expect are there. // (They could get optimized away too. If that happens in practice, change this test to use hard-coded signatures.) Assert.Contains("uint8[] pinned", localTypes); Assert.Contains("uint8[]", localTypes); } }
public static IEnumerable <_ExceptionRegionInfo> GetExceptionRegionInfos(this MethodBodyBlock aThis, Module aModule) { foreach (var x in aThis.ExceptionRegions) { yield return(new _ExceptionRegionInfo(aModule, x)); } }
bool ScanMethodBody(ITypeDefinition analyzedEntity, IMethod method, MethodBodyBlock methodBody) { bool found = false; var blob = methodBody.GetILReader(); var module = (MetadataModule)method.ParentModule; var genericContext = new Decompiler.TypeSystem.GenericContext(); // type parameters don't matter for this analyzer while (!found && blob.RemainingBytes > 0) { var opCode = blob.DecodeOpCode(); if (!CanBeReference(opCode)) { blob.SkipOperand(opCode); continue; } EntityHandle methodHandle = MetadataTokenHelpers.EntityHandleOrNil(blob.ReadInt32()); if (!methodHandle.Kind.IsMemberKind()) { continue; } var ctor = module.ResolveMethod(methodHandle, genericContext); if (ctor == null || !ctor.IsConstructor) { continue; } if (ctor.DeclaringTypeDefinition?.MetadataToken == analyzedEntity.MetadataToken && ctor.ParentModule.PEFile == analyzedEntity.ParentModule.PEFile) { return(true); } } return(false); }
private static unsafe void VisualizeGenerationIL(MetadataVisualizer visualizer, int generationIndex, GenerationData generation, MetadataReader mdReader) { if (generation.PEReaderOpt != null) { foreach (var methodHandle in mdReader.MethodDefinitions) { var method = mdReader.GetMethodDefinition(methodHandle); var rva = method.RelativeVirtualAddress; if (rva != 0) { var body = generation.PEReaderOpt.GetMethodBody(rva); visualizer.VisualizeMethodBody(body, methodHandle); } } } else if (generation.DeltaILOpt != null) { fixed(byte *deltaILPtr = generation.DeltaILOpt) { foreach (var generationHandle in mdReader.MethodDefinitions) { var method = mdReader.GetMethodDefinition(generationHandle); var rva = method.RelativeVirtualAddress; if (rva != 0) { var body = MethodBodyBlock.Create(new BlobReader(deltaILPtr + rva, generation.DeltaILOpt.Length - rva)); visualizer.VisualizeMethodBody(body, generationHandle, generationIndex); } } } } }
public static Value InterpretMethod(MethodBodyHolder holder, MethodBodyBlock body, ParameterValues paramVals, out Exception exc, string indent) { exc = null; GraphProcessor graphProcessor = new GraphProcessor(); IntVisitor visitor = new IntVisitor(graphProcessor, holder, indent); visitor.state = new State(body.Variables.Count); int paramCount = 0; foreach (Variable var in body.Variables.ParameterMapper) { visitor.state.Pool[var] = paramVals[paramCount++]; } visitor.AddTask(body); graphProcessor.Process(); Value result = null; if (visitor.unhandledException != null) { exc = visitor.unhandledException; } else if (body.ReturnType != typeof(void)) { result = visitor.state.Stack.Pop().FromStack(body.ReturnType); } return(result); }
public void Callback(Node node) { if (node is ITypedNode) { ITypedNode theNode = node as ITypedNode; theNode.Type = mapper.Map(theNode.Type); } if (node is ManageField) { ManageField theNode = node as ManageField; theNode.Field = mapper.Map(theNode.Field); } if (node is MethodBodyBlock) { MethodBodyBlock body = node as MethodBodyBlock; foreach (Variable var in body.Variables) { var.Type = mapper.Map(var.Type); } body.ReturnType = mapper.Map(body.ReturnType); } if (node is CallMethod) { CallMethod call = node as CallMethod; ResidualMethod id = Specialization.GetResidualMethod(call); if (id != null) { MethodBodyBlock mbb = mapper.Holder[id]; node.Options["HasPseudoParameter"] = mapper.HasPseudoParameter(mbb); call.MethodWithParams = new MethodInfoExtention(mapper.Map(mbb), call.IsVirtCall, mapper.Map(GetParamTypes(mbb, id.IsConstructor))); } else { call.MethodWithParams = mapper.Map(call.MethodWithParams); } } if (node is NewObject) { NewObject newObj = node as NewObject; ResidualMethod id = Specialization.GetResidualMethod(node); if (id != null) { MethodBodyBlock mbb = mapper.Holder[id]; newObj.CtorWithParams = new MethodInfoExtention(mapper.Map(mbb), false, mapper.Map(GetParamTypes(mbb, id.IsConstructor))); node.Options["HasPseudoParameter"] = mapper.HasPseudoParameter(mbb); } else { newObj.CtorWithParams = mapper.Map(newObj.CtorWithParams); } } if (node is CreateDelegate) { CreateDelegate crDel = node as CreateDelegate; //Andrew TODO: Map this node... } // Graph should be verified AFTER the metadata is resolved }
public static void ForEach(MethodBodyBlock method, ForEachCallback handler) { GraphProcessor graphProcessor = new GraphProcessor(); Visitor visitor = new ForEachVisitor(graphProcessor, handler); visitor.AddTask(method, null); graphProcessor.Process(); }
private EcmaMethodIL(EcmaMethod method, int rva, bool clearInitLocals) { _method = method; _module = method.Module; _methodBody = _module.PEReader.GetMethodBody(rva); _clearInitLocals = clearInitLocals; }
internal BlockBuilder(MethodBodyBlock body, Dictionary <ExceptionRegion, ILVariable> variableByExceptionHandler) { Debug.Assert(body != null); Debug.Assert(variableByExceptionHandler != null); this.body = body; this.variableByExceptionHandler = variableByExceptionHandler; }
public static int GetCodeSize(this MethodBodyBlock body) { if (body == null) { throw new ArgumentNullException(nameof(body)); } return(body.GetILReader().Length); }
internal SpecializingVisitor(GraphProcessor graphProcessor, ResidualAssemblyHolder holder, MethodBodyBlock mbbUp, SpecState state, VariablesHashtable varsHash) : base(graphProcessor) { this.holder = holder; this.mbbUp = mbbUp; this.state = state; this.varsHash = varsHash; this.upDownNodes = new Hashtable(); this.exitData = new ArrayList(); }
public TypeMethodHandle ReadMethod(BaseJIT jit, MethodDefinitionHandle methodHandle) { MethodDefinition methodDefinition = this.metadata.GetMethodDefinition(methodHandle); TypeDefinition typeDefinition = this.metadata.GetTypeDefinition(methodDefinition.GetDeclaringType()); TypeHandle typeHandle = this.typeLoader.LoadType(this.metadata, typeDefinition); MethodBodyBlock methodBody = this.peReader.GetMethodBody(methodDefinition.RelativeVirtualAddress); return(typeHandle.LoadMethod(jit, this, this.metadata, methodHandle, methodBody)); }
bool ScanMethodBody(IField analyzedField, IMethod method, MethodBodyBlock methodBody) { if (methodBody == null) { return(false); } var mainModule = (MetadataModule)method.ParentModule; var blob = methodBody.GetILReader(); var genericContext = new Decompiler.TypeSystem.GenericContext(); // type parameters don't matter for this analyzer while (blob.RemainingBytes > 0) { ILOpCode opCode; try { opCode = blob.DecodeOpCode(); if (!CanBeReference(opCode)) { blob.SkipOperand(opCode); continue; } } catch (BadImageFormatException) { return(false); } EntityHandle fieldHandle = MetadataTokenHelpers.EntityHandleOrNil(blob.ReadInt32()); if (!fieldHandle.Kind.IsMemberKind()) { continue; } IField field; try { field = mainModule.ResolveEntity(fieldHandle, genericContext) as IField; } catch (BadImageFormatException) { continue; } if (field == null) { continue; } if (field.MetadataToken == analyzedField.MetadataToken && field.ParentModule.PEFile == analyzedField.ParentModule.PEFile) { return(true); } } return(false); }
void DisassembleLocalsBlock(MethodDefinitionHandle method, MethodBodyBlock body) { if (body.LocalSignature.IsNil) { return; } output.Write(".locals"); WriteMetadataToken(body.LocalSignature, spaceBefore: true); if (body.LocalVariablesInitialized) { output.Write(" init"); } var blob = metadata.GetStandaloneSignature(body.LocalSignature); var signature = ImmutableArray <Action <ILNameSyntax> > .Empty; try { if (blob.GetKind() == StandaloneSignatureKind.LocalVariables) { signature = blob.DecodeLocalSignature(signatureDecoder, genericContext); } else { output.Write(" /* wrong signature kind */"); } } catch (BadImageFormatException ex) { output.Write($" /* {ex.Message} */"); } output.Write(' '); output.WriteLine("("); output.Indent(); int index = 0; foreach (var v in signature) { output.WriteLocalReference("[" + index + "]", "loc_" + index, isDefinition: true); output.Write(' '); v(ILNameSyntax.TypeName); if (DebugInfo != null && DebugInfo.TryGetName(method, index, out var name)) { output.Write(" " + DisassemblerHelpers.Escape(name)); } if (index + 1 < signature.Length) { output.Write(','); } output.WriteLine(); index++; } output.Unindent(); output.WriteLine(")"); }
protected internal override void VisitMethodBodyBlock(MethodBodyBlock node, object data) { StackTypes stack = data as StackTypes; if (stack.Count != 0) { throw new VerifierException(); } AddTask(node.Next, stack); }
public BasicBlocksGraph(MethodBodyBlock methodBodyBlock) { mbb = methodBodyBlock; mbb.RemoveOption(BasicBlock.BASIC_BLOCK_OPTION); GraphProcessor processor = new GraphProcessor(); BasicBlocksBuilder builder = new BasicBlocksBuilder(processor); entry = builder.createBasicBlock(); builder.AddTask(methodBodyBlock, entry); processor.Process(); blockList = builder.BlockList; }
protected override void VisitMethodBodyBlock(MethodBodyBlock node, object data) { foreach (Variable var in node.Variables) { if (!state.Pool.ContainsVar(var)) { state.Pool[var] = new Location(var.Type); } } AddTask(node.Next); }
internal AnnotatedMethod AnnotateMethod(AnnotatedMethod method) { int count = 0; foreach (AnnotatedMethod key in this.getMethods()) { if (method.SourceMethod == key.SourceMethod) { count++; if (AnnotatedMethod.EqualMethods(method, key)) { return(key); } } } if (count > AnnotatedAssemblyHolder.NUMBER_FOR_MERGE) { AnnotatedMethod keyMethod = null; int keyMethodCreators = 0; foreach (AnnotatedMethod key in this.getMethods()) { if (method.SourceMethod == key.SourceMethod) { int keyCreators = AnnotatedMethod.PseudoMergeMethods(method, key).Count; if (keyMethod == null || keyMethodCreators > keyCreators) { keyMethod = key; keyMethodCreators = keyCreators; } } } if (keyMethod != null && (keyMethodCreators == 0 || count > AnnotatedAssemblyHolder.NUMBER_FOR_LIFT)) { Creators crtrs = AnnotatedMethod.MergeMethods(method, keyMethod); if (!crtrs.IsEmpty) { throw new AnnotatingVisitor.LiftException(crtrs); } return(keyMethod); } } MethodBodyBlock mbbUp = Annotation.AnnotateMethod(this, method); this.addMethodBody(method, mbbUp); return(method); }
public static unsafe string GetMethodIL(this ImmutableArray <byte> ilArray) { var result = new StringBuilder(); fixed(byte *ilPtr = ilArray.ToArray()) { int offset = 0; while (true) { // skip padding: while (offset < ilArray.Length && ilArray[offset] == 0) { offset++; } if (offset == ilArray.Length) { break; } var reader = new BlobReader(ilPtr + offset, ilArray.Length - offset); var methodIL = MethodBodyBlock.Create(reader); if (methodIL == null) { result.AppendFormat( "<invalid byte 0x{0:X2} at offset {1}>", ilArray[offset], offset ); offset++; } else { ILVisualizer.Default.DumpMethod( result, methodIL.MaxStack, methodIL.GetILContent(), ImmutableArray.Create <ILVisualizer.LocalInfo>(), ImmutableArray.Create <ILVisualizer.HandlerSpan>() ); offset += methodIL.Size; } } } return(result.ToString()); }
public static Type[] GetParamTypes(MethodBodyBlock mbb, bool doRemoveThis) { ArrayList paramTypesList = new ArrayList(); int i0 = doRemoveThis ? 1 : 0; int I = mbb.Variables.ParameterMapper.Count; for (int i = i0; i < I; i++) { Variable var = mbb.Variables.ParameterMapper[i]; paramTypesList.Add(var.Type); } Type[] paramTypes = new Type[paramTypesList.Count]; paramTypesList.CopyTo(paramTypes); return(paramTypes); }
internal static CilLocal[] DecodeLocalSignature(MethodBodyBlock methodBody, MetadataReader metadataReader, CilTypeProvider provider) { if (methodBody.LocalSignature.IsNil) { return(new CilLocal[0]); } ImmutableArray <CilType> localTypes = SignatureDecoder.DecodeLocalSignature(methodBody.LocalSignature, provider); CilLocal[] locals = new CilLocal[localTypes.Length]; for (int i = 0; i < localTypes.Length; i++) { string name = "V_" + i; locals[i] = new CilLocal(name, localTypes[i].ToString()); } return(locals); }
public static unsafe MethodBodyBlock GetMethodBodyBlock(this ImmutableArray <byte> ilArray) { fixed(byte *ilPtr = ilArray.AsSpan()) { int offset = 0; // skip padding: while (offset < ilArray.Length && ilArray[offset] == 0) { offset++; } var reader = new BlobReader(ilPtr + offset, ilArray.Length - offset); return(MethodBodyBlock.Create(reader)); } }
public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) { if (relocsOnly) { return(new ObjectData( data: Array.Empty <byte>(), relocs: Array.Empty <Relocation>(), alignment: 1, definedSymbols: new ISymbolDefinitionNode[] { this })); } var rva = _method.MetadataReader.GetMethodDefinition(_method.Handle).RelativeVirtualAddress; var reader = _method.Module.PEReader.GetSectionData(rva).GetReader(); int size = MethodBodyBlock.Create(reader).Size; return(new ObjectData(reader.ReadBytes(size), Array.Empty <Relocation>(), 4, new ISymbolDefinitionNode[] { this })); }
// See: https://github.com/dotnet/corert/blob/635cf21aca11265ded9d78d216424bd609c052f5/src/Common/src/TypeSystem/Ecma/EcmaSignatureParser.cs#L242 public static int GetLocalsCount(this MetadataReader reader, MethodBodyBlock method) { if (method.LocalSignature.IsNil) { return(0); } var entryPointSignature = reader.GetStandaloneSignature(method.LocalSignature); var signatureBlobReader = reader.GetBlobReader(entryPointSignature.Signature); if (signatureBlobReader.ReadSignatureHeader().Kind != SignatureKind.LocalVariables) { throw new BadImageFormatException(); } return(signatureBlobReader.ReadCompressedInteger()); }
public static bool Check(MethodBodyBlock method) { //TODO: Will check parents consistency, if give up to do it automatically RemoveStackTypes(method); GraphProcessor graphProcessor = new GraphProcessor(); VerifierVisitor verifierVisitor = new VerifierVisitor(graphProcessor); verifierVisitor.AddTask(method, new StackTypes()); try { graphProcessor.Process(); } catch (VerifierException) { RemoveStackTypes(method); return(false); } return(true); }
//<SnippetPrintMethods> static void PrintMethods(PEReader reader, MetadataReader mr, TypeDefinition tdef) { MethodDefinitionHandleCollection methods = tdef.GetMethods(); foreach (MethodDefinitionHandle mdefh in methods) { MethodDefinition mdef = mr.GetMethodDefinition(mdefh); string mname = mr.GetString(mdef.Name); Console.WriteLine($"Method: {mname}"); // Get the relative address of the method body in the executable int rva = mdef.RelativeVirtualAddress; if (rva == 0) { Console.WriteLine("Method body not found"); Console.WriteLine(); continue; } // Get method body information MethodBodyBlock mb = reader.GetMethodBody(rva); Console.WriteLine($" Maximum stack size: {mb.MaxStack}"); Console.WriteLine($" Local variables initialized: {mb.LocalVariablesInitialized}"); byte[] il = mb.GetILBytes(); Console.WriteLine($" Method body size: {il.Length}"); Console.WriteLine($" Exception regions: {mb.ExceptionRegions.Length}"); Console.WriteLine(); foreach (var region in mb.ExceptionRegions) { Console.WriteLine(region.Kind.ToString()); Console.WriteLine($" Try block offset: {region.TryOffset}"); Console.WriteLine($" Try block length: {region.TryLength}"); Console.WriteLine($" Handler offset: {region.HandlerOffset}"); Console.WriteLine($" Handler length: {region.HandlerLength}"); Console.WriteLine(); } } }
private static unsafe void VisualizeGenerationIL(MetadataVisualizer visualizer, int generationIndex, GenerationData generation, MetadataReader mdReader) { try { if (generation.PEReaderOpt != null) { foreach (var methodHandle in mdReader.MethodDefinitions) { visualizer.VisualizeMethodBody(methodHandle, rva => generation.PEReaderOpt.GetMethodBody(rva)); } } else if (generation.ILDeltaOpt != null) { fixed(byte *deltaILPtr = generation.ILDeltaOpt) { foreach (var generationHandle in mdReader.MethodDefinitions) { var method = mdReader.GetMethodDefinition(generationHandle); var rva = method.RelativeVirtualAddress; if (rva != 0) { var body = MethodBodyBlock.Create(new BlobReader(deltaILPtr + rva, generation.ILDeltaOpt.Length - rva)); visualizer.VisualizeMethodBody(body, generationHandle, generationIndex); } } } } else { visualizer.WriteLine("<IL not available>"); } } catch (BadImageFormatException) { visualizer.WriteLine("<bad metadata>"); } }
internal static CilLocal[] DecodeLocalSignature(MethodBodyBlock methodBody, MetadataReader metadataReader, CilTypeProvider provider) { if (methodBody.LocalSignature.IsNil) { return new CilLocal[0]; } ImmutableArray<CilType> localTypes = SignatureDecoder.DecodeLocalSignature(methodBody.LocalSignature, provider); CilLocal[] locals = new CilLocal[localTypes.Length]; for (int i = 0; i < localTypes.Length; i++) { string name = "V_" + i; locals[i] = new CilLocal(name, localTypes[i].ToString()); } return locals; }