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