'Access violation' using OverloadModule with certain modules (e.g., SAMCLI.dll)
s0rtega opened this issue · 0 comments
Description
When using OverloadModule with SAMCLI.dll (not previously loaded by the process) the decoy module allocation (NtCreateSection / NtMapViewOfSection) and the payload overload (MapModuleToMemory) seems to work correctly (e.g., returning a valid Ptr to the function in memory, the memory content is correct) but always finish with (0xc0000005) 'Access violation' while executing the function DynamicFunctionInvoke.
Additional information
If the module is loaded with LoadModuleFromDisk (LdrLoadDll) it works correctly. I have been debugging both to identify potential differences (wrong memory address, wrong permissions, wrong content, etc.) but I was not able to see any significant differences. The only thing that I have seen is that, in the method OverloadModule after writing to the allocated section (NtWriteVirtualMemory, RtlZeroMemory) the "shareable WS" becomes "private WS" which does not happen in the other cases:
Test code
Same one with the modifications from #20:
using System;
using System.Runtime.InteropServices;
namespace overload_poc
{
class STRUCTS
{
[StructLayout(LayoutKind.Sequential)]
public struct LOCALGROUP_MEMBERS_INFO_3
{
[MarshalAs(UnmanagedType.LPWStr)]
public string domainandname;
}
}
class DELEGATES
{
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate DInvoke.Data.Native.NTSTATUS NetLocalGroupAddMembers(
string servername,
[MarshalAs(UnmanagedType.LPWStr)]
string groupName,
UInt32 level,
ref STRUCTS.LOCALGROUP_MEMBERS_INFO_3 info,
UInt32 totalentries);
}
class Program
{
static void Main(string[] args)
{
// NetLocalGroupAddMember (forwarded to SAMCLI.NetLocalGroupAddMember)
DInvoke.Data.PE.PE_MANUAL_MAP mappedDLL = DInvoke.ManualMap.Overload.OverloadModule(@"C:\Windows\System32\SAMCLI.dll", @"C:\Windows\System32\SAMCLI.dll");
String group = @"Administrators";
STRUCTS.LOCALGROUP_MEMBERS_INFO_3 username = new STRUCTS.LOCALGROUP_MEMBERS_INFO_3();
username.domainandname = @"myUser";
object[] funcParams =
{
null,
group,
(UInt32)3,
username,
(UInt32)1};
DInvoke.Data.Native.NTSTATUS res = (DInvoke.Data.Native.NTSTATUS)DInvoke.DynamicInvoke.Generic.CallMappedDLLModuleExport(
mappedDLL.PEINFO,
mappedDLL.ModuleBase,
"NetLocalGroupAddMembers",
typeof(DELEGATES.NetLocalGroupAddMembers),
funcParams,
false,
true,
true
);
Console.WriteLine(res);
}
}
}