Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Opposite operation to Assembly Load(byte[] rawAssembly)

Tags:

c#

.net

I notice that there is a method of System.Reflection.Assembly, which is Assembly Load(byte[] rawAssembly).

I wonder if there is an opposite operation like byte[] Store(Assembly assembly). If not, how can I convert an assembly object to byte[] for calling Assembly Load(byte[] rawAssembly) totally in memory without writing the assembly to a file? Thanks!

Comment: The question comes from the situation that I am using a third-party library which returns an Assembly instance to me, and I must use reflection to call its methods. I don't know how the library creates this assembly object. I just wonder if I can store the assembly object to byte[] and reload it with 'Assembly Load(byte[] rawAssembly)'. Thanks!

like image 751
xiagao1982 Avatar asked Jun 02 '13 14:06

xiagao1982


2 Answers

To convert an assembly from AppDomain to byte[] use:

var pi = assembly.GetType().GetMethod("GetRawBytes", BindingFlags.Instance | BindingFlags.NonPublic);
byte[] assemblyBytes = (byte[]) pi.Invoke(assembly, null);
like image 131
PlamenTotev Avatar answered Nov 15 '22 16:11

PlamenTotev


System.Security.Policy.Hash is able to calculate a Hash regardless of the assembly's location. So we have at least 2 ways to obtain an assembly as a byte array:

1) Using reflection:

var hash = new Hash(assembly);
var dllAsArray = (byte[]) hash.GetType()
    .GetMethod("GetRawData", BindingFlags.Instance | BindingFlags.NonPublic)
    .Invoke(hash, new object[0]);

2) Using a fake HashAlgorithm implementation:

public class GetWholeBodyPseudoHash : HashAlgorithm
{
    protected override void Dispose(bool disposing)
    {
        if(disposing) _memoryStream.Dispose();
        base.Dispose(disposing);
    }

    static GetWholeBodyPseudoHash()
    {
        CryptoConfig.AddAlgorithm(typeof(GetWholeBodyPseudoHash), typeof(GetWholeBodyPseudoHash).FullName);
    }

    private MemoryStream _memoryStream=new MemoryStream();
    public override void Initialize()
    {
        _memoryStream.Dispose();
        _memoryStream = new MemoryStream();
    }

    protected override void HashCore(byte[] array, int ibStart, int cbSize)
    {
        _memoryStream.Write(array, ibStart, cbSize);
    }

    protected override byte[] HashFinal()
    {
        return _memoryStream.ToArray();
    }
}

...
var bytes = new Hash(yourAssembly).GenerateHash(new GetWholeBodyPseudoHash());
like image 44
dimzon Avatar answered Nov 15 '22 14:11

dimzon