简体   繁体   中英

Is code executable on loading an assembly into the AppDomain

Is it possible to write code, which will be automatically executed when loading an assembly into an AppDomain with Assembly.Load ? I need this information because our PlugIn system loads PlugIns and then check if they are valid, because they contain a signature in an attribute .

EDIT

I want to know whether the creator of the plugin is able to execute code when i am loading the assembly. If this is possible, we got some security issues.

From a security perspective I made the following findings when investigating this issue in depth:

from another question on Stack overflow, Jon Skeet says: "I don't believe there's any way of forcing a method to be run on assembly load"

If this was said by anyone else I would have ignored it, but if Jon Skeet says its impossible, its probably impossible.

Secondly, I tested Module Initializers in depth. This will only fire code right before a class in the assembly is instantiated. If no class from the assembly is explicitly instantiated, the Module Initializer will also not fire.

What is possible is if somewhere in your code, or a 3rd parties code that is running in your domain, the code loads and instantiates all classes with a certain Interface or base class or Attribute through out your app domain, and you might not be aware of this code. In such a case, code in the constructors of these classes will fire as soon as they are instantiated.

but other than that, through testing all scenarios and ideas that I could think of, and doing searches across the web, I came to the conclusion that it is not possible to execute code in a assembly, by simply loading the assembly.

The AppDomain.AssemblyLoad Event allows you to handle an event when an assembly is loaded into the AppDomain. You can find an example on the page linked.

Although this not directly answering the question, it does provide a good workaround for the question asked.

If you need to reflect the types in the assembly, while wanting to be 100% sure that no code in the assembly is executed. you can do this without actually loading the assembly in to your AppDomain by using the Assembly.ReflectionOnlyLoadFrom method. this will allow you to look at they types in the assembly but will NOT allow you to instantiate any of them, and will also not load the assembly in to the AppDomain.

Look at this example as exlanation

public void AssemblyLoadTest(string assemblyToLoad)
{
    var initialAppDomainAssemblyCount = AppDomain.CurrentDomain.GetAssemblies().Count(); //4

    Assembly.ReflectionOnlyLoad(assemblyToLoad);
    var reflectionOnlyAppDomainAssemblyCount = AppDomain.CurrentDomain.GetAssemblies().Count(); //4

    //Shows that assembly is NOT loaded in to AppDomain with Assembly.ReflectionOnlyLoad
    Assert.AreEqual(initialAppDomainAssemblyCount, reflectionOnlyAppDomainAssemblyCount); // 4 == 4

    Assembly.Load(assemblyToLoad);
    var loadAppDomainAssemblyCount = AppDomain.CurrentDomain.GetAssemblies().Count(); //5

    //Shows that assembly is loaded in to AppDomain with Assembly.Load
    Assert.AreNotEqual(initialAppDomainAssemblyCount, loadAppDomainAssemblyCount); // 4 != 5
}

If you just need to check information of the assembly like the publicKey, instead of loading the Assembly, load the AssemblyName directly:

AssemblyName an = AssemblyName.GetAssemblyName("myfile.exe");
byte[] publicKey = an.GetPublicKey();
CultureInfo culture = an.CultureInfo;
Version version = an.Version;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM