-2

For example...

using System;
using System.IO;

namespace Whatever
{
  public class SomeClass
  {
  }
}

If this is compiled into class library mylibrary.dll, I want to be able to use reflection to load mylibrary.dll and find out if it is referencing the System.IO namespace.

I've tried using Assembly.GetReferencedAssemblies and then identifying namespaces in those assemblies, but this will always give me all of the namespaces defined in those assemblies whether or not they're actually referenced in mylibrary.dll. Since System.IO shares an assembly with System and many other important namespaces, this won't work.

Another thing I've thought of is to find out if a class from that namespace is referenced, but I can't find a way to do that using reflection.

This is for a plugin system, and the idea is to prevent the plugin from using certain namespaces, such as System.IO, by refusing to load the library if those namespaces are referenced.

Dave Carlile
  • 7,347
  • 1
  • 20
  • 23
  • 1
    have you started at least with a simple google search [C# reflection find namespace](https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=c%23%20reflection%20find%20namespace) – MethodMan Oct 08 '14 at 17:54
  • Your example code is **not** referencing the `System.IO` namespace because it doesn't use any class from that namespace. – Lucas Trzesniewski Oct 08 '14 at 17:56
  • Yes, I have done that. Those all return classes DEFINED by the name space. I need to know what namespaces are being referenced. Completely different things, and I have not been able to find out how to do this using Google. So thanks for the down votes without fully reading and understanding my questions.] – Dave Carlile Oct 08 '14 at 18:01
  • 1
    @CrappyCodingGuy We understand your question perfectly well. Did you try Jon Skeet's solution [here](http://stackoverflow.com/questions/1549198/finding-all-namespaces-in-an-assembly-using-reflection-dotnet) (first result of DJ KRAZE's seach)? – tnw Oct 08 '14 at 18:03
  • No, you aren't understanding my question. If you look at Jon Skeet's solution, it's using `Assembly.GetTypes`. If you look at the documentation for that, it states: Resturns "An array that contains all the types that are defined in this assembly.". It works wonderfully for that, and it will happily return the `Whatever.SomeClass` in my example. It returns types/namespaces that are **defined** in the assembly. That is **not** what I'm looking for. – Dave Carlile Oct 08 '14 at 18:17
  • 2
    Namespaces specified on a `using` statement are _not references_. Only _assemblies_ are referenced. Furthermore, `using` statements are only a design time feature. There is nothing in the compiled MSIL for a using statement – Chris Dunaway Oct 08 '14 at 18:30
  • @ChrisDunaway Thank you for understanding my question and actually having a discussion instead of assuming. After trying a hundred combinations of keywords for searching I finally ran across this which is looking promising: http://stackoverflow.com/questions/5821507/is-there-a-way-to-get-all-namespaces-youre-using-within-a-class-through-c-sha ... Basically it involves using reflection to drill into the code and find every type that is being used. – Dave Carlile Oct 08 '14 at 18:44
  • I was going to suggest something like that but there's no way to know if the person who wrote the code put a `using` statement at the top or just used the full name of the class in the code. I guess you could get the full type name and then everything to the left of the last dot would be the namespace. – Chris Dunaway Oct 08 '14 at 18:55

1 Answers1

1

You can load the assembly in Mono.Cecil. It will allow you to read the actual MSIL opcodes in each function.

Some of these opcodes will reference classes: call/callvirt/newobj and the like. Read all arguments to each of these classes and you'll be able to make a list of the referenced types, which will in turn lead you to a list of namespaces.

BUT...

Since you're trying o use this for security I must say it's not a good idea: this is easy to bypass. For instance you could use reflection. You could block the reflection APIs too, but then you could bypass it with compiled lambda expressions, or P/Invoke, or a mixed mode assembly... You could block them too but I don't think you'll be able to prevent every possible workaround.

What you should do, is load your assembly into a sandboxed AppDomain and let the CLR reject the insecure API calls for you. This is a feature that was actually designed for that purpose. It's implemented in the CLR and it'll be much safer to rely on it instead of your own solution.

Community
  • 1
  • 1
Lucas Trzesniewski
  • 50,214
  • 11
  • 107
  • 158
  • Yeah, I was working through the code I linked to above, and I can see how there would be a lot of holes. The AppDomain concept is perfect, but this is running in Unity, and at least initial research indicates that Mono doesn't fully support AppDomain security. – Dave Carlile Oct 08 '14 at 19:21