Dynamic API Calls in .NET

2 minute read Published:

Using Reflection to call APIs dinamically

Today I’m going to share a way to call APIs without DLLImport. I’ve first saw this years ago at OpenSC.ws as far as I remember and got into the idea. The code was lost since then but I found a copy.

Program.cs

using System;
using System.Reflection;

namespace APICaller
{
class Program
{

```
	public static void Main(string[] args)
	{
		Console.Title = "Dynamic API Caller";
		Console.WriteLine("Press any key to call your API!");
		Console.ReadKey(true);
		
		string className = MethodBase.GetCurrentMethod().DeclaringType.Name; //getting our current class name
		string asmName = Assembly.GetExecutingAssembly().FullName; //getting our current assembly name
		string methodName = MethodBase.GetCurrentMethod().Name; //getting our current method name
		
		//Sample with a simple MessageBox. You can adapt this call to whatever you need
		//(note that you should also adapt the class if needed)
		DynamicAPIs CreateDynamicAPI = new DynamicAPIs("user32.dll",
		                                               "MessageBoxA",
		                                               asmName,
		                                               methodName,
		                                               className,
		                                               typeof(int),
		                                               new object[] {
		                                               	IntPtr.Zero,
		                                               	"Test Message",
		                                               	"Test Title",
		                                               	0
		                                               });			
		
		Console.Write("Press any key to exit . . . ");
		Console.ReadKey(true);
	}
}

```

}

And our mighty class.

DynamicAPIs.cs

using System;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.InteropServices;

namespace APICaller
{
public class DynamicAPIs
{
private readonly string WinLib;
private readonly string MethodName;
private readonly string AssemblyName;
private readonly string ModuleName;
private readonly string ClassName;
private readonly Type ReturnType;
private readonly object[] Parameters;
public DynamicAPIs(string wLib, string mName, string asmName, string modName, string cName, Type rType, object[] Params)
{
WinLib = wLib;
MethodName = mName;
AssemblyName = asmName;
ModuleName = modName;
ClassName = cName;
ReturnType = rType;
Parameters = Params;
CreateDynamicAPI();
}
private object CreateDynamicAPI()
{

```
		AssemblyBuilder ASMB = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName(AssemblyName), AssemblyBuilderAccess.RunAndSave);
		ModuleBuilder MODB = ASMB.DefineDynamicModule(ModuleName);
		TypeBuilder TB = MODB.DefineType(ClassName, TypeAttributes.Public);

		Type[] ParameterTypes = new Type[Parameters.Length];

		for (int i = 0; i <= Parameters.Length - 1; i++) {
			ParameterTypes[i] = Parameters[i].GetType();
		}

		MethodBuilder MB = TB.DefinePInvokeMethod(MethodName, 
							  WinLib, 
							  MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.PinvokeImpl,
		                                          CallingConventions.Standard, 
		                                          ReturnType, ParameterTypes,
		                                          CallingConvention.Winapi,
		                                          CharSet.Ansi);

		MB.SetImplementationFlags(MB.GetMethodImplementationFlags() | MethodImplAttributes.PreserveSig);

		return TB.CreateType().GetMethod(MethodName).Invoke(null, Parameters);

	}
	
}

```

}

Yeah I need to work on this code tags hahaha they look awful.

Anyway, it works, if you need help understanding it, let me know :)

Running the program should give you a console window with a message box, like this.

TMZ

comments powered by Disqus