Using DLLImport with dnlib

462 Views Asked by At

I have a C# project that I want to modify with dnlib. Modifying it with dnspy, I can add the code in just fine. However, I was not able to find a way to add the DLLImport in with dnlib, and all searches came up dry. How can I pull this off? Can it even be done?

EDIT: I dug through dnSpy's source and found a way. I am puttin' it here so that everyone can see it:

var _loadedEXE = ModuleDefMD.Load("EXE.exe");
var _dllReference = new ModuleRefUser(_loadedEXE, "DLL_NAME.dll");

var _flagsDLL = MethodAttributes.PinvokeImpl | MethodAttributes.Public | MethodAttributes.Static;
var _flagsPDLL = MethodImplAttributes.PreserveSig;

var _mapDLL = new ImplMapUser(_dllReference, "", PInvokeAttributes.CallConvCdecl);
            
var _method = new MethodDefUser("METHOD_NAME", MethodSig.CreateStatic(_loadedEXE.CorLibTypes.Int32, _loadedEXE.CorLibTypes.Int32), _flagsPDLL, _flagsDLL);
_method.ImplMap = _mapDLL;

This will result in the following decomp from dnSpy:

[DllImport("DLL_NAME.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int METHOD_NAME(int);

I hope this will be helpful to you so you do not suffer as I have.

1

There are 1 best solutions below

4
On

Implementing VirtualProtect with dnlib

[DllImport("kernel32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Winapi)]
internal static extern bool VirtualProtect(IntPtr address, IntPtr size, uint newProtect, out uint oldProtect);
var virtualProtectNativeMethodAttributes = MethodAttributes.PinvokeImpl | MethodAttributes.Assembly | MethodAttributes.Static;
var virtualProtectNativeMethodImplementationAttributes = MethodImplAttributes.PreserveSig;

var dllReference = new ModuleRefUser(moduleDefMD, "kernel32.dll");
var nativeMethodName = "VirtualProtect";
var implementationMap = new ImplMapUser(dllReference, nativeMethodName, PInvokeAttributes.CharSetAuto | PInvokeAttributes.CallConvWinapi);

var virtualProtectNativeMethod = new MethodDefUser(nativeMethodName,
    MethodSig.CreateStatic(moduleDefMD.CorLibTypes.Boolean, moduleDefMD.CorLibTypes.IntPtr, moduleDefMD.CorLibTypes.IntPtr, moduleDefMD.CorLibTypes.UInt32, moduleDefMD.CorLibTypes.UInt32),
    virtualProtectNativeMethodImplementationAttributes, virtualProtectNativeMethodAttributes);

virtualProtectNativeMethod.ImplMap = implementationMap;
virtualProtectNativeMethod.ParamDefs.Add(new ParamDefUser("address", 1));
virtualProtectNativeMethod.ParamDefs.Add(new ParamDefUser("size", 2));
virtualProtectNativeMethod.ParamDefs.Add(new ParamDefUser("newProtect", 3));
virtualProtectNativeMethod.ParamDefs.Add(new ParamDefUser("oldProtect", 4, ParamAttributes.Out));