Created
March 5, 2024 19:02
-
-
Save CamelCaseName/07d96897a7547b83a9d0d658437ef746 to your computer and use it in GitHub Desktop.
Example of self embedded assembly extraction
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Reflection; | |
using System.Runtime.Loader; | |
namespace AssemblyTest | |
{ | |
internal class AssemblyTest | |
{ | |
static AssemblyTest() | |
{ | |
SetOurResolveHandlerAtFront(); | |
} | |
private static Assembly AssemblyResolveEventListener(object sender, ResolveEventArgs args) | |
{ | |
if (args is null) return null!; | |
string dllName = args.Name[..args.Name.IndexOf(',')]; | |
foreach (var field in typeof(AssemblyTest.Properties.Resources).GetProperties(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)) | |
{ | |
if (field.Name == dllName.Replace('.', '_')) | |
{ | |
return Assembly.Load((byte[])field.GetValue(null)!); | |
} | |
} | |
return null!; | |
} | |
private static void SetOurResolveHandlerAtFront() | |
{ | |
BindingFlags flags = BindingFlags.Static | BindingFlags.NonPublic; | |
FieldInfo? field = null; | |
Type domainType = typeof(AssemblyLoadContext); | |
while (field is null) | |
{ | |
if (domainType is not null) | |
{ | |
field = domainType.GetField("AssemblyResolve", flags); | |
} | |
else | |
{ | |
return; | |
} | |
if (field is null) | |
domainType = domainType.BaseType!; | |
} | |
MulticastDelegate resolveDelegate = (MulticastDelegate)field.GetValue(null)!; | |
Delegate[] subscribers = resolveDelegate.GetInvocationList(); | |
Delegate currentDelegate = resolveDelegate; | |
for (int i = 0; i < subscribers.Length; i++) | |
currentDelegate = Delegate.RemoveAll(currentDelegate, subscribers[i])!; | |
Delegate[] newSubscriptions = new Delegate[subscribers.Length + 1]; | |
newSubscriptions[0] = (ResolveEventHandler)AssemblyResolveEventListener!; | |
Array.Copy(subscribers, 0, newSubscriptions, 1, subscribers.Length); | |
currentDelegate = Delegate.Combine(newSubscriptions)!; | |
field.SetValue(null, currentDelegate); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Just add all DLLs you want to load internally into your normal Resource.resx file.
this method can also be used to use specific assembly versions dynamically as we run before all other assembly resolvers