I'm trying to figure out if it's possible via reflection (or otherwise) to "audit" some code to enforce validation requirements -- such as checking whether or not code creates any threads (System.Threading.Thread) or uses other BCLs. The assumption is that the code is already compiled into a dll. Thanks!
Look at FxCop. It can load a compiled binary (dll or exe) and perform validation and compliance checking against that compiled IL, regardless of the .NET language used to write it.
You can write your own rules - which you would do in this case to catch cases of "= new Thread()" and the like.
You can do this with reflection if you are very well-versed in IL.
MethodBody mb = this.GetType().GetMethod( "Method", BindingFlags.Default ).GetMethodBody();
byte[] bytes = mb.GetILAsByteArray();
Probably way more trouble than it is worth; the resulting IL will need to be parsed.
An IL parser (but somewhat dated): http://www.codeproject.com/KB/cs/sdilreader.aspx which will generate a list of OpCodes for you (look for OpCodes.Newobj for instantiation of a Thread).
As others have said reflection won't help you as it only describes the metadata of tpyes.
However, the Mono.Cecil project is a runtime way of actually looking at the IL (Intermediate Language) of types within an assembly. Although a product of the Mono framework it is compatible with the Microsoft CLR.
Reflection does not allow inspection of the body of members, only their signatures. In other words, it won't tell you anything about what a particular method or property does, just what it looks like.
To do what you're after, you'll have to use something like ildasm.exe to turn the compiled .dll or .exe into IL, then go over the IL and see if it's doing anything to which you object.
Reflection will allow you to inspect the body of methods through MethodBase.GetMethodBody, which gives you a MethodBody to inspect.
However, at this level you are dealing with raw IL in a byte array, which you have to analyze start to end to find out calls to external methods and what they do etc.
So it won't be pretty or easy, but certainly it's possible.
Related
Is it possible to extract a class from an assembly created with Reflection.Emit and save it physically to a directory?
I would like to use this manipulation to generate projects dynamically with specific content (classes, methods ...).
Is there a way to save dynamic classes with code without need for an external tool to decompile them?
Yes, as long as you pass in AssemblyBuilderAccess.RunAndSave or AssemblyBuilderAccess.Save when you call AssemblyBuilder.DefineDynamicAssembly. Then you can use the Save method to write it to disk - very useful for running it through Peverify to see what you've done wrong :)
Note that this saves the IL - not C# source code, so you would still need to decompile them. If you want C# source code without decompiling, then you would need to generate C# source code as your origin - presumably passing it through Roslyn or CSharpCodeProvider to get the IL.
Note: not all operations are valid when used in this way - if you are skipping accessibility checks, for example, to access non-public members of types outside of your control. This is allowed in some runtime-only scenarios, but is not reliable in assemblies loaded from disk. Similarly, a lot of things are possible in IL that have no direct C# equivalent.
I have a reference to the type and class from certain assembly.
var type = typeof(SomeNamespace.SomeClass);
Is there a way to get meta about what programming language were used to write this class? C# or VB or F#?
So in result i want something like this
var programmingLanguage = getLanguage(type); // C#
UPD:
Can I analyze what Assemblies or Namespaces where used for this class? Maybe this can be a clue to finding out a language?
UPD2:
So far I could use this ( it's just an example for VB detection )
var referenced = type.Assembly.GetReferencedAssemblies()
.Where((r) => r.Name.Contains("VisualBasic"));
VB adds Microsoft.VisualBasic. F# also adds it's own assemblies and C++ declares a lot of 'self use' types which I can detect. So this is "a way". I know it's not error prone. And there will be some false cases. So is there anything better?
.NET does not make this distinction, there's not really a good reason for you to either.
The only way would be to analyse the types and code patterns used. For example, VB projects often reference a different set of assemblies to C#.
If you need to do this for your own assemblies, I would suggest creating a custom Attribute class and decorating your assemblies with it.
Take a read of Decompiled assembly, which programming language was used. There is no facility in .NET assemblies to record the source language. In addition, not only are there C#, F# and VB.NET compilers for .NET, but there are many other compilers too (see http://en.wikipedia.org/wiki/List_of_CLI_languages for a taste of the number). Finally, the IL might have been written directly, rather than via a compiler.
You could try to search for patterns in the IL to try and work out the source language, but if would be highly error-prone. I'm not sure what benefit it would offer either.
See Kieren's answer. An alternative is to compare the assembly files, with some id in the name or metadata to define its language.
See How to get the assembly (System.Reflection.Assembly) for a given type in .Net?
This would only be helpful if you're compiling yourself, or the different language'd binaries are named differently or you can manually name them differently.
If you're compiling yourself, you can add metadata to the binary as a post-build event. See Read/Write 'Extended' file properties (C#) for details on how to add. In the build event, you'll be able to access information about the project - such as it's compilation language.
When using Reflection.Emit to build an assembly at runtime, I'd like to verify the assembly MSIL before saving to disc. Like PEVerify but at runtime. Is there such an API?
It seems that peverify.exe is a front-end to c:\Windows\Microsoft.NET\Framework\v4.0.30319\peverify.dll (or c:\Windows\Microsoft.NET\Framework\v2.0.50727\peverify.dll for CLR 2.0), which is a native DLL (actually, peverify.exe is also native)
I don't see this documented anywhere so it's probably not a public API. You may be able to figure out the exported functions from that DLL using something like Dependency Walker, but I think it would be simpler to just call peverify.exe.
EDIT: anecdotal evidence:
In a compiler step, Boo actually calls peverify.exe.
Nemerle calls peverify.exe in its tests.
Castle.DynamicProxy calls peverify.exe in its tests.
Instead of using PEVerify you could use the ILSpy's decompiler for an in-process solution, as described here: http://www.codeproject.com/Tips/659692/Automated-MSIL-PE-verification-using-ILSpy
A summary of the article is:
Collect the relevant DLLs to reference from your test project, or
runtime IL checker in this case
Iterate through the methods to verify using Mono.Cecil
For each method, add it to the AstBuilder defined in ICSharpCode.Decompiler which performs the validation. Eg.
var context = new DecompilerContext(method.Module) { CurrentType = method.DeclaringType };
var astBuilder = new AstBuilder(context);
astBuilder.AddMethod(method);
Performance-wise I have not checked which method is faster. Although this method is in-proc it may be slower since the Abstract Syntax Tree is built as the IL is validated (I'll have to setup a performance test to check this theory).
I found the ILSpy decompiler to be more reliable than PEVerify as pointed out in the above article, in one instance PEVerify declared one assembly to be valid, while ILSpy correctly gave a beautiful stack trace indicating my error in generation.
Debugging LCG allows you to debug the generated code at runtime using Windbg.
Maybe it can help you.
Calling peverify is indeed probably the best approach, but peverify is located in many different directories depending on the running version of .NET. You can try to enumerate all these paths and check for the latest one, but this was at least 6 different paths at last count IIRC, and isn't cross-platform, ie. doesn't include Mono.
I recently found that I could just link to the Microsoft.Build.Tasks assembly, and then create an instance of Microsoft.Build.Tasks.GetFrameworkSdkPath and call the Path property. One weird behaviour I noticed is that accessing the path the first time throws an exception, but if you just swallow that exception you can access the path from then on.
Peverify.exe is then Path.Combine(new GetFrameworkSdkPath().Path, "bin\peverify").
Using System.Reflection, I can get all methods from a specific class
I need know what are the references to these methods. For example: in Visual Studio, if you want the references of specific object
right click on the object and select "Find All References"
Visual Studio show the references of this selected object
I want make the same, but from code with reflection or another way.
Can I do this?
This cannot be done with reflection. Reflection is a tool for inspecting metadata and assemblies. In order to find all references to a given method / type, you'd need to inspect the underlying IL of an assembly. Reflection only has very limited IL capabilities (simply returns it as a byte array). You'll need to custom inspect that byte stream in order to gather any context about what it's referencing.
That's not something that's directly accessible via runtime reflection on a specific class. You will have to introspect the entire source code tree or resulting IL to determine if any references to a particular method with the same name are the right overload and signature for the method you're trying to find references to.
Furthermore, without additional work, you're never going to find references to a specific method that are themselves invoked via reflection. (This is one reason why obfuscating that kind of code is challenging and error-prone.)
If you're just looking to find the references for informational purposes, Reflector has that feature.
http://www.red-gate.com/products/reflector/
Microsoft released the Common Compiler Infrastructure projects under an open source license. These projects aim to support many compiler-related features, including assembly analysis like you're referring to. The documentation is limited, so you'll need to have a thorough understanding of ECMA-335 (Common Language Infrastructure) to effectively use it for your purposes.
There are no magic code samples here. This is a large and quite complicated task where you'll be on your own most of the way.
When I am reading F# stuff, they are talking about inlining methods, but I thought .NET didn't expose this functionality to programmers. If it's exposed then it has to be in the IL? And so can C# make use of it as well?
Just wondering if this thing is the same as C++ inline functionality.
It is actually more complicated when compared to C++ inlining, because F# works on top of .NET, which has IL as an intermediate language, so there are actually two layers where some inlining can be done:
At the F# -> IL level - The inline keyword allows you to specify that an F# function should be inlined when generating .NET IL code. In this case, the IL instructions of the function will be placed in place of a IL instruction representing a method call.
At the IL -> assembly level - This is fully controlled by JITter (.NET just-in-time compiler), which compiles the IL (intermediate language) to actual executable assembly code. This is done fully automatically, so you cannot specify that something should be inlined at this level. However, JITter also inlines some simple calls (such as calls to property getters and setters).
To answer some of your specific questions, inline is an F#-specific construct that interacts with both the type system (e.g. static member constraints) and code generation (inlining code for optimization purposes). The F# compiler deals with these things, and the information regarding inlining is stored in F#-specific metadata in the assembly, which enables functions to be inlined across F# assembly boundaries.
Guess I'll post as an answer... didn't really want to do such because I don't know anything about F# beyond the basics. :p
http://msdn.microsoft.com/en-us/library/dd548047%28VS.100%29.aspx