-
Notifications
You must be signed in to change notification settings - Fork 98
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Feature Request] DLL releases? #39
Comments
Hi. MemoryModulePP supports building as a DLL. You only need to select the configuration ending with DLL for MemoryModule in the configuration manager. In addition, MemoryModulePP integrates ReflectiveDllLoader, so it can self-load into a fully functional MemoryModulePP without using a third-party memory loader. |
I need to initialize the loading from managed (.NET) code, where MemoryModulePP itself and other native |
Also, the build configurations do not work from the MSBuild command-line: Method 1 (Build from solution):
Method 2 (Build from project):
|
Since the DebugDll and ReleaseDll configurations are only the project configuration of MemoryModule and not the solution's configuration, you cannot build through the solution. Building directly from the project will cause compilation errors because the solution directory environment variable $(SolutionDir) is referenced in the project. The value of this variable needs to be specified explicitly. Example of successful compilation from the command line: msbuild MemoryModule.vcxproj /p:SolutionDir="MemoryModulePP solution root directory",Configuration=ReleaseDll,Platform=x64 |
You can use this class to call MemoryModulePP from the .NET platform: public static class MemoryModulePP
{
[DllImport("kernel32.dll")]
private static extern IntPtr VirtualAlloc(
IntPtr lpAddress,
UIntPtr dwSize,
int flAllocationType,
int flProtect
);
[DllImport("kernel32.dll")]
private static extern int VirtualFree(
IntPtr lpAddress,
UIntPtr dwSize,
int dwFreeType
);
[DllImport("kernel32.dll")]
public static extern IntPtr GetProcAddress(
IntPtr hModule,
[MarshalAs(UnmanagedType.LPStr)]string lpProcName
);
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
private delegate IntPtr ReflectiveLoader(IntPtr buffer);
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate int LdrLoadDllMemoryExWDelegate(
[Out] out IntPtr BaseAddress,
[Out] out IntPtr LdrEntry,
[In] uint dwFlags,
[In][MarshalAs(UnmanagedType.LPArray)] byte[] BufferAddress,
[In] UIntPtr BufferSize,
[In][MarshalAs(UnmanagedType.LPWStr)] string DllName,
[In][MarshalAs(UnmanagedType.LPWStr)] string DllFullName
);
public static LdrLoadDllMemoryExWDelegate LdrLoadDllMemoryExW;
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate bool LdrUnloadDllMemoryDelegate([In] IntPtr BaseAddress);
public static LdrUnloadDllMemoryDelegate LdrUnloadDllMemory;
public static IntPtr Initialize(byte[] buffer, int offsetOfReflectiveLoader)
{
System.Diagnostics.Debug.Assert(buffer != null && buffer.Length > 0 && offsetOfReflectiveLoader > 0);
IntPtr result = IntPtr.Zero;
var raw = VirtualAlloc(IntPtr.Zero, (UIntPtr)buffer.Length, 0x00001000, 0x40);
if (raw != IntPtr.Zero)
{
Marshal.Copy(buffer, 0, raw, buffer.Length);
var loader = Marshal.GetDelegateForFunctionPointer<ReflectiveLoader>(raw + offsetOfReflectiveLoader);
result = loader(raw);
if (result != IntPtr.Zero)
{
var ptr = GetProcAddress(result, "LdrLoadDllMemoryExW");
if (ptr != IntPtr.Zero)
{
LdrLoadDllMemoryExW = Marshal.GetDelegateForFunctionPointer<LdrLoadDllMemoryExWDelegate>(ptr);
}
ptr = GetProcAddress(result, "LdrUnloadDllMemory");
if (ptr != IntPtr.Zero)
{
LdrUnloadDllMemory = Marshal.GetDelegateForFunctionPointer<LdrUnloadDllMemoryDelegate>(ptr);
}
}
VirtualFree(raw, UIntPtr.Zero, 0x00008000);
}
return result;
}
} |
Here is an example of calling the MemoryModulePP class, 0x1221 is the offset of class Program
{
static T GetProcAddress<T>(IntPtr hModule, string lpName) where T : class
{
var ptr = MemoryModulePP.GetProcAddress(hModule, lpName);
if (ptr != IntPtr.Zero)
{
return Marshal.GetDelegateForFunctionPointer<T>(ptr);
}
return null;
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
delegate int _exception(int code);
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
delegate int FARPROC();
static void test()
{
byte[] buffer = null;
using (var fs = File.OpenRead("a.dll"))
{
using (var sr = new BinaryReader(fs))
{
buffer = sr.ReadBytes((int)fs.Length);
}
}
var status = MemoryModulePP.LdrLoadDllMemoryExW(out var baseAddress, out _, 0, buffer, UIntPtr.Zero, "kernel64", null);
if (status >= 0)
{
var exception = GetProcAddress<_exception>(baseAddress, "exception");
if (exception != null)
{
for (int i = 0; i < 5; ++i) exception(i);
}
var pfn = GetProcAddress<FARPROC>(baseAddress, "thread");
if (pfn != null && pfn() != 0)
{
Console.WriteLine("thread test failed.\n");
}
MemoryModulePP.LdrUnloadDllMemory(baseAddress);
}
}
static void Main(string[] args)
{
byte[] buffer = null;
using (var fs = File.OpenRead("MemoryModule.dll"))
{
using (var sr = new BinaryReader(fs))
{
buffer = sr.ReadBytes((int)fs.Length);
}
}
var hModule = MemoryModulePP.Initialize(buffer, 0x1221); //
if (hModule != IntPtr.Zero)
{
test();
}
}
} |
Ahh thanks. This works on the command line:
Any plans to support ARM and ARM64 though?
Looks cool if you want some compact code but... Allocating virtual memory, copying some bytes, and then parsing the PE to get an exported function's address, like what |
Yes, it does the same job as most loaders, just to do it without an external loader. If you don't want to use self-loading, you can use a third-party loader to load it, and then call the ReflectiveMapDll function to initialize the environment necessary for MemoryModulePP. |
Hello, I added the configuration for the ARM platform to the solution and successfully ran the tests in a Windows 10 ARM64 simulation environment. I'm not very familiar with the ARM platform, but thanks to the strong compatibility of Windows, I don't need to modify it too much. Just check out the |
Currently, I see that MemoryModulePP has no releases.
Also, it is only built as a static library (
.lib
).There are use cases where a
.dll
ofMemoryModulePP
might be preferred, such as bootstrapping MemoryModulePP from a less powerful.dll
loader.The text was updated successfully, but these errors were encountered: