Skip to content
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

New options added to CallMappedDLLModuleExport #20

Open
wants to merge 2 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 27 additions & 12 deletions DInvoke/DInvoke/DynamicInvoke/Generic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ public static string GetAPIHash(string APIName, long Key)
/// <param name="ExportName">The name of the export to search for (e.g. "NtAlertResumeThread").</param>
/// <param name="ResolveForwards">Whether or not to resolve export forwards. Default is true.</param>
/// <returns>IntPtr for the desired function.</returns>
public static IntPtr GetExportAddress(IntPtr ModuleBase, string ExportName, bool ResolveForwards = true)
public static IntPtr GetExportAddress(IntPtr ModuleBase, string ExportName, bool ResolveForwards = true, bool CanLoadFromDisk = false, bool Overload = false)
{
IntPtr FunctionPtr = IntPtr.Zero;
try
Expand Down Expand Up @@ -303,7 +303,7 @@ public static IntPtr GetExportAddress(IntPtr ModuleBase, string ExportName, bool

if (ResolveForwards == true)
// If the export address points to a forward, get the address
FunctionPtr = GetForwardAddress(FunctionPtr);
FunctionPtr = GetForwardAddress(FunctionPtr, CanLoadFromDisk, Overload);

break;
}
Expand Down Expand Up @@ -331,7 +331,7 @@ public static IntPtr GetExportAddress(IntPtr ModuleBase, string ExportName, bool
/// <param name="Ordinal">The ordinal number to search for (e.g. 0x136 -> ntdll!NtCreateThreadEx).</param>
/// <param name="ResolveForwards">Whether or not to resolve export forwards. Default is true.</param>
/// <returns>IntPtr for the desired function.</returns>
public static IntPtr GetExportAddress(IntPtr ModuleBase, short Ordinal, bool ResolveForwards = true)
public static IntPtr GetExportAddress(IntPtr ModuleBase, short Ordinal, bool ResolveForwards = true, bool CanLoadFromDisk = false, bool Overload = false)
{
IntPtr FunctionPtr = IntPtr.Zero;
try
Expand Down Expand Up @@ -400,7 +400,7 @@ public static IntPtr GetExportAddress(IntPtr ModuleBase, short Ordinal, bool Res
/// <param name="Key">64-bit integer to initialize the keyed hash object (e.g. 0xabc or 0x1122334455667788).</param>
/// <param name="ResolveForwards">Whether or not to resolve export forwards. Default is true.</param>
/// <returns>IntPtr for the desired function.</returns>
public static IntPtr GetExportAddress(IntPtr ModuleBase, string FunctionHash, long Key, bool ResolveForwards = true)
public static IntPtr GetExportAddress(IntPtr ModuleBase, string FunctionHash, long Key, bool ResolveForwards = true, bool CanLoadFromDisk = false, bool Overload = false)
{
IntPtr FunctionPtr = IntPtr.Zero;
try
Expand Down Expand Up @@ -467,8 +467,9 @@ public static IntPtr GetExportAddress(IntPtr ModuleBase, string FunctionHash, lo
/// <author>The Wover (@TheRealWover)</author>
/// <param name="ExportAddress">Function of an exported address, found by parsing a PE file's export table.</param>
/// <param name="CanLoadFromDisk">Optional, indicates if the function can try to load the DLL from disk if it is not found in the loaded module list.</param>
/// <param name="Overload">Optional, indicates if the dll should be loaded using overload</param>
/// <returns>IntPtr for the forward. If the function is not forwarded, return the original pointer.</returns>
public static IntPtr GetForwardAddress(IntPtr ExportAddress, bool CanLoadFromDisk = false)
public static IntPtr GetForwardAddress(IntPtr ExportAddress, bool CanLoadFromDisk = false, bool Overload = false)
{
IntPtr FunctionPtr = ExportAddress;
try
Expand All @@ -492,7 +493,15 @@ public static IntPtr GetForwardAddress(IntPtr ExportAddress, bool CanLoadFromDis

IntPtr hModule = GetPebLdrModuleEntry(ForwardModuleName);
if (hModule == IntPtr.Zero && CanLoadFromDisk == true)
hModule = LoadModuleFromDisk(ForwardModuleName);
if (Overload)
{
StringBuilder ForwardModulePath = new StringBuilder("",256);
IntPtr ForwardModulePathOut;
Data.Native.NTSTATUS res = Win32.SearchPathW(null, ForwardModuleName, null, (UInt32)ForwardModulePath.Capacity, ForwardModulePath, out ForwardModulePathOut);
hModule = ManualMap.Overload.OverloadModule(ForwardModulePath.ToString()).ModuleBase;
}
else
hModule = LoadModuleFromDisk(ForwardModuleName);
if (hModule != IntPtr.Zero)
{
FunctionPtr = GetExportAddress(hModule, ForwardExportName);
Expand Down Expand Up @@ -728,8 +737,10 @@ public static void CallMappedDLLModule(Data.PE.PE_META_DATA PEINFO, IntPtr Modul
/// <param name="FunctionDelegateType">Prototype for the function, represented as a Delegate object.</param>
/// <param name="Parameters">Arbitrary set of parameters to pass to the function. Can be modified if function uses call by reference.</param>
/// <param name="CallEntry">Specify whether to invoke the module's entry point.</param>
/// <param name="CanLoadFromDisk">Optional, indicates if the function can try to load the DLL from disk if it is not found in the loaded module list.</param>
/// <param name="Overload">Optional, indicates if the dll should be loaded using overload</param>
/// <returns>void</returns>
public static object CallMappedDLLModuleExport(Data.PE.PE_META_DATA PEINFO, IntPtr ModuleMemoryBase, string ExportName, Type FunctionDelegateType, object[] Parameters, bool CallEntry = true)
public static object CallMappedDLLModuleExport(Data.PE.PE_META_DATA PEINFO, IntPtr ModuleMemoryBase, string ExportName, Type FunctionDelegateType, object[] Parameters, bool CallEntry = true, bool CanLoadFromDisk = false, bool Overload = false)
{
// Call entry point if user has specified
if (CallEntry)
Expand All @@ -738,7 +749,7 @@ public static object CallMappedDLLModuleExport(Data.PE.PE_META_DATA PEINFO, IntP
}

// Get export pointer
IntPtr pFunc = GetExportAddress(ModuleMemoryBase, ExportName);
IntPtr pFunc = GetExportAddress(ModuleMemoryBase, ExportName, CanLoadFromDisk: CanLoadFromDisk, Overload: Overload);

// Call export
return DynamicFunctionInvoke(pFunc, FunctionDelegateType, ref Parameters);
Expand All @@ -754,8 +765,10 @@ public static object CallMappedDLLModuleExport(Data.PE.PE_META_DATA PEINFO, IntP
/// <param name="FunctionDelegateType">Prototype for the function, represented as a Delegate object.</param>
/// <param name="Parameters">Arbitrary set of parameters to pass to the function. Can be modified if function uses call by reference.</param>
/// <param name="CallEntry">Specify whether to invoke the module's entry point.</param>
/// <param name="CanLoadFromDisk">Optional, indicates if the function can try to load the DLL from disk if it is not found in the loaded module list.</param>
/// <param name="Overload">Optional, indicates if the dll should be loaded using overload</param>
/// <returns>void</returns>
public static object CallMappedDLLModuleExport(Data.PE.PE_META_DATA PEINFO, IntPtr ModuleMemoryBase, short Ordinal, Type FunctionDelegateType, object[] Parameters, bool CallEntry = true)
public static object CallMappedDLLModuleExport(Data.PE.PE_META_DATA PEINFO, IntPtr ModuleMemoryBase, short Ordinal, Type FunctionDelegateType, object[] Parameters, bool CallEntry = true, bool CanLoadFromDisk = false, bool Overload = false)
{
// Call entry point if user has specified
if (CallEntry)
Expand All @@ -764,7 +777,7 @@ public static object CallMappedDLLModuleExport(Data.PE.PE_META_DATA PEINFO, IntP
}

// Get export pointer
IntPtr pFunc = GetExportAddress(ModuleMemoryBase, Ordinal);
IntPtr pFunc = GetExportAddress(ModuleMemoryBase, Ordinal, CanLoadFromDisk: CanLoadFromDisk, Overload: Overload);

// Call export
return DynamicFunctionInvoke(pFunc, FunctionDelegateType, ref Parameters);
Expand All @@ -781,8 +794,10 @@ public static object CallMappedDLLModuleExport(Data.PE.PE_META_DATA PEINFO, IntP
/// <param name="FunctionDelegateType">Prototype for the function, represented as a Delegate object.</param>
/// <param name="Parameters">Arbitrary set of parameters to pass to the function. Can be modified if function uses call by reference.</param>
/// <param name="CallEntry">Specify whether to invoke the module's entry point.</param>
/// <param name="CanLoadFromDisk">Optional, indicates if the function can try to load the DLL from disk if it is not found in the loaded module list.</param>
/// <param name="Overload">Optional, indicates if the dll should be loaded using overload</param>
/// <returns>void</returns>
public static object CallMappedDLLModuleExport(Data.PE.PE_META_DATA PEINFO, IntPtr ModuleMemoryBase, string FunctionHash, long Key, Type FunctionDelegateType, object[] Parameters, bool CallEntry = true)
public static object CallMappedDLLModuleExport(Data.PE.PE_META_DATA PEINFO, IntPtr ModuleMemoryBase, string FunctionHash, long Key, Type FunctionDelegateType, object[] Parameters, bool CallEntry = true, bool CanLoadFromDisk = false, bool Overload = false)
{
// Call entry point if user has specified
if (CallEntry)
Expand All @@ -791,7 +806,7 @@ public static object CallMappedDLLModuleExport(Data.PE.PE_META_DATA PEINFO, IntP
}

// Get export pointer
IntPtr pFunc = GetExportAddress(ModuleMemoryBase, FunctionHash, Key);
IntPtr pFunc = GetExportAddress(ModuleMemoryBase, FunctionHash, Key, CanLoadFromDisk: CanLoadFromDisk, Overload: Overload);

// Call export
return DynamicFunctionInvoke(pFunc, FunctionDelegateType, ref Parameters);
Expand Down
42 changes: 40 additions & 2 deletions DInvoke/DInvoke/DynamicInvoke/Win32.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,29 @@ public static IntPtr CreateRemoteThread(
return retValue;
}

public static Data.Native.NTSTATUS SearchPathW(
string lpPath,
string lpFileName,
string lpExtension,
UInt32 nBufferLength,
StringBuilder lpBuffer,
out IntPtr filePartOut)
{
filePartOut = IntPtr.Zero;
// Craft an array for the arguments
object[] funcargs =
{
lpPath, lpFileName, lpExtension, nBufferLength, lpBuffer, filePartOut
};

Data.Native.NTSTATUS retValue = (Data.Native.NTSTATUS)Generic.DynamicAPIInvoke(@"kernel32.dll", @"SearchPathW", typeof(Delegates.SearchPathW), ref funcargs);

// Update the modified variables
filePartOut = (IntPtr)funcargs[5];

return retValue;
}

/// <summary>
/// Uses DynamicInvocation to call the IsWow64Process Win32 API. https://docs.microsoft.com/en-us/windows/win32/api/wow64apiset/nf-wow64apiset-iswow64process
/// </summary>
Expand All @@ -67,7 +90,7 @@ public static bool IsWow64Process(IntPtr hProcess, ref bool lpSystemInfo)
// Build the set of parameters to pass in to IsWow64Process
object[] funcargs =
{
hProcess, lpSystemInfo
hProcess,lpSystemInfo
};

bool retVal = (bool)Generic.DynamicAPIInvoke(@"kernel32.dll", @"IsWow64Process", typeof(Delegates.IsWow64Process), ref funcargs);
Expand Down Expand Up @@ -100,9 +123,24 @@ public static bool CloseHandle(IntPtr handle)
public static class Delegates
{
// Kernel32.dll

// https://github.com/Tarkiyah/ansible/blob/b0c8e7926f4ed31c37fabfad7803bd378f8aaba4/lib/ansible/module_utils/csharp/Ansible.Process.cs
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate Data.Native.NTSTATUS SearchPathW(
[MarshalAs(UnmanagedType.LPWStr)]
string lpPath,
[MarshalAs(UnmanagedType.LPWStr)]
string lpFileName,
[MarshalAs(UnmanagedType.LPWStr)]
string lpExtension,
UInt32 nBufferLength,
[MarshalAs(UnmanagedType.LPTStr)]
StringBuilder lpBuffer,
ref IntPtr lpFilePart);

[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate IntPtr CreateRemoteThread(IntPtr hProcess,
public delegate IntPtr CreateRemoteThread(
IntPtr hProcess,
IntPtr lpThreadAttributes,
uint dwStackSize,
IntPtr lpStartAddress,
Expand Down