public static INode Read(InspectableAssembly ia, MethodSignature signature, MethodBodyBlock rawBody) { /*Console.WriteLine("=== IL Bytes ==="); foreach (var b in ilBytes) Console.Write("{0:X2} ", b); Console.WriteLine();*/ var parser = new ILMethodParser(ia, signature, rawBody); return parser.Parse(); }
public void Parse(P.Program program, string filename) { var context = new ParseContext(program); var ia = new InspectableAssembly(filename, context); EntryPointQueue(ia, context); while(context.Todo.Count > 0) { context.Todo.Dequeue().Process(); } }
private void EntryPointQueue(InspectableAssembly ia, ParseContext context) { foreach (var typeHandle in ia.Reader.TypeDefinitions) { var parseTarget = ia.CreateParseTarget(typeHandle); parseTarget.MethodName = "Main"; if (IgnoreClassList.Contains(parseTarget.ClassName)) continue; context.AddTodo(parseTarget); } }
public ParseTarget(ParseContext context, string assemblyName, Version assemblyVersion, string fqName) { AssemblyName = assemblyName; ClassName = fqName; AssemblyVersion = assemblyVersion; for(int i = 0; i < Extensions.Length; i++) { try { var path = TryExtenstion(Extensions[i]); Ia = new InspectableAssembly(path, context); } catch { if (i == Extensions.Length - 1) throw; } } }
private static ElementType ReadType(InspectableAssembly ia, byte[] blob, ref int index) { var ret = new ElementType((EElementType)blob[index++]); // class or struct if (ret.Type == EElementType.Class || ret.Type == EElementType.ValueType || ret.Type == EElementType.CMod_Required || ret.Type == EElementType.CMod_Optional) { //next is metadata token? var tokenRaw = UncompressInt(blob, ref index); int token = (tokenRaw & ~0x03) >> 2; switch(tokenRaw & 0x03) { case 0: //typedef token |= 0x02000000; break; case 1: //typeref token |= 0x01000000; break; case 2: //typespec token |= 0x20000000; break; } var handle = MetadataTokens.Handle(token); switch (handle.Kind) { case HandleKind.TypeDefinition: ret.Target = ia.GetClassImmediate(token); break; default: throw new Exception("Go f**k yourself handle"); } } else if(ret.Type == EElementType.SzArray || ret.Type == EElementType.Reference) { ElementType next; do { next = ReadType(ia, blob, ref index); if (next.Type.IsCustomMod()) Console.WriteLine("?? SzArray custom mod ??"); } while (next.Type.IsCustomMod()); ret.Secondary = next; } else if(ret.Type == EElementType.MVar) { ret.Number = UncompressInt(blob, ref index); } return ret; }
/*public static MethodSignature SetGenerics(InspectableAssembly ia, byte[] specBloc, MethodSignature @base) { var ret = @base.Clone(); if (ret.NumGeneric != count) throw new Exception("Mismatched generic signature"); // do parameters for(int i = 0; i < ret.ParameterTypes.Count; i++) { if(ret.ParameterTypes[i].Type == EElementType.MVar) ret.ParameterTypes[i] = types[ret.ParameterTypes[i].Number]; else if(ret.ParameterTypes[i].HasSecondary && ret.ParameterTypes[i].Secondary.Type == EElementType.Mvar) { } } ret.NumGeneric = 0; // do return type if (ret.ReturnType.Type == EElementType.MVar) ret.ReturnType = types[ret.ReturnType.Number]; return ret; }*/ public static IList<ElementType> ParseLocalSignature(InspectableAssembly ia, byte[] blob) { var ret = new List<ElementType>(); int index = 0; if (blob[index++] != 0x07) throw new Exception("Bad locals signature"); int numberOfEntries = blob[index++]; for(; numberOfEntries > 0; numberOfEntries--) { ret.Add(ReadType(ia, blob, ref index)); } return ret; }
public static GenericSignature ParseGenericSignature(InspectableAssembly ia, byte[] specBloc) { int index = 0; if (specBloc[index++] != 10) throw new Exception("Poop generic signature"); int count = specBloc[index++]; var ret = new GenericSignature(); for (int i = 0; i < count; i++) ret.Add(ReadType(ia, specBloc, ref index)); return ret; }
public static MethodSignature ParseMethodSignature(InspectableAssembly ia, byte[] blob) { var ret = new MethodSignature(); int index = 0; ret.Flags = (EMethodFlags)blob[index++]; if (ret.Flags.HasFlag(EMethodFlags.Generic)) ret.NumGeneric = UncompressInt(blob, ref index); ret.NumNormal = UncompressInt(blob, ref index); ret.ReturnType = ReadType(ia, blob, ref index); if (ret.Flags.HasFlag(EMethodFlags.ExplicitThis)) { ret.ThisType = ReadType(ia, blob, ref index); ret.NumNormal--; } for(int i = 0; i < ret.NumNormal; i++) { ret.ParameterTypes.Add(ReadType(ia, blob, ref index)); } return ret; }
public static FieldSignature ParseFieldSignature(InspectableAssembly ia, byte[] blob) { var ret = new FieldSignature(); int index = 0; if (blob[index++] != 0x06) throw new Exception("Invalid field signature"); while(index < blob.Length) { var type = ReadType(ia, blob, ref index); if (type.Type.IsCustomMod()) { if (type.Target == ia.Context.Program.Classes[VolatileClassName]) ret.IsVolatile = true; // other custom mods } else ret.Type = type; } return ret; }
public ParseTarget(InspectableAssembly ia, string fqName) { AssemblyName = Path.GetFileNameWithoutExtension(ia.Stream.Name); ClassName = fqName; AssemblyVersion = new Version(); Ia = ia; }
public ParseTarget(InspectableAssembly ia, Method m) { Ia = ia; Method = m; MethodSignature = m.Signature; MethodName = m.Name; ClassName = ia.GetFullyQualifiedName( ia.Reader.GetTypeDefinition( ((MethodDefinition)m.SourceHandle).GetDeclaringType())); }
public void AddClass(InspectableAssembly ia, TypeDefinitionHandle typeHandle, Class c) { int token = MetadataTokens.GetToken(ia.Reader, typeHandle); m_tokenReference.Add(token, c); Program.Classes.Add(c.Name, c); }