Code Monkey home page Code Monkey logo

dinvoke's Introduction

DInvoke

Dynamic replacement for PInvoke on Windows. DInvoke contains powerful primitives that may be combined intelligently to dynamically invoke unmanaged code from disk or from memory with careful precision. This may be used for many purposes such as PE parsing, intelligent dynamic API resolution, dynamically loading PE plugins at runtime, process injection, and avoiding API hooks.

Features:

  • Dynamically invoke unmanaged APIs without PInvoke
  • Primitives allowing for strategic API hook evasion
  • Manually map unmanaged PE modules from managed code
  • Map PE modules into sections backed by arbitrary modules on disk
  • Modular process injection API
  • Growing library of data structures, delegates, and function wrappers (please share :-)
  • .NET v3.5+ support

Conference talk (Staying # & Bringing Covert Injection Tradecraft to .NET): https://www.youtube.com/watch?v=FuxpMXTgV9s

Blog posts:

  1. Emulating Covert Operations - Dynamic Invocation (Avoiding PInvoke & API Hooks): https://thewover.github.io/Dynamic-Invoke/
  2. Coming soon.

This project was originally created for SharpSploit (https://github.com/cobbr/SharpSploit). With permission from the author(s), it is now hosted here as a standalone library and NuGet.

NuGet: https://www.nuget.org/packages/DInvoke/

Example 1 - Resolving Exported Unmanaged APIs

The example below demonstrates how to use DInvoke to dynamically find and call exports of a DLL.

  1. Get the base address of ntdll.dll. It is loaded into every Windows process when it is initialized, so we know that it will already be loaded. As such, we can safely search the PEB’s list of loaded modules to find a reference to it. Once we’ve found its base address from the PEB, we print the address.
  2. Use GetLibraryAddress to find an export within ntdll.dll by name.
  3. Use GetLibraryAddress to find an export within ntdll.dll by ordinal.
  4. Use GetLibraryAddress to find an export within ntdll.dll by keyed hash.
  5. Given the base address of ntdll.dll that we found earlier, use GetExportAddress to find an export within the module in memory by name.
///Author: b33f (@FuzzySec, Ruben Boonen)
using System;

using DynamicInvoke = DInvoke.DynamicInvoke;

namespace SpTestcase
{
    class Program
    {

        static void Main(string[] args)
        {
            // Details
            String testDetail = @"
            #=================>
            # Hello there!
            # I find things dynamically; base
            # addresses and function pointers.
            #=================>
            ";
            Console.WriteLine(testDetail);

            // Get NTDLL base from the PEB
            Console.WriteLine("[?] Resolve Ntdll base from the PEB..");
            IntPtr hNtdll = DynamicInvoke.Generic.GetPebLdrModuleEntry("ntdll.dll");
            Console.WriteLine("[>] Ntdll base address : " + string.Format("{0:X}", hNtdll.ToInt64()) + "\n");

            // Search function by name
            Console.WriteLine("[?] Specifying the name of a DLL (\"ntdll.dll\"), resolve a function by walking the export table in-memory..");
            Console.WriteLine("[+] Search by name --> NtCommitComplete");
            IntPtr pNtCommitComplete = DynamicInvoke.Generic.GetLibraryAddress("ntdll.dll", "NtCommitComplete", true);
            Console.WriteLine("[>] pNtCommitComplete : " + string.Format("{0:X}", pNtCommitComplete.ToInt64()) + "\n");

            Console.WriteLine("[+] Search by ordinal --> 0x260 (NtSetSystemTime)");
            IntPtr pNtSetSystemTime = DynamicInvoke.Generic.GetLibraryAddress("ntdll.dll", 0x260, true);
            Console.WriteLine("[>] pNtSetSystemTime : " + string.Format("{0:X}", pNtSetSystemTime.ToInt64()) + "\n");

            Console.WriteLine("[+] Search by keyed hash --> 138F2374EC295F225BD918F7D8058316 (RtlAdjustPrivilege)");
            Console.WriteLine("[>] Hash : HMACMD5(Key).ComputeHash(FunctionName)");
            String fHash = DynamicInvoke.Generic.GetAPIHash("RtlAdjustPrivilege", 0xaabb1122);
            IntPtr pRtlAdjustPrivilege = DynamicInvoke.Generic.GetLibraryAddress("ntdll.dll", fHash, 0xaabb1122);
            Console.WriteLine("[>] pRtlAdjustPrivilege : " + string.Format("{0:X}", pRtlAdjustPrivilege.ToInt64()) + "\n");

            // Search for function from base address of DLL
            Console.WriteLine("[?] Specifying the base address of DLL in memory ({0:X}), resolve function by walking its export table...", hNtdll.ToInt64());
            Console.WriteLine("[+] Search by name --> NtCommitComplete");
            IntPtr pNtCommitComplete2 = DynamicInvoke.Generic.GetExportAddress(hNtdll, "NtCommitComplete");
            Console.WriteLine("[>] pNtCommitComplete : " + string.Format("{0:X}", pNtCommitComplete2.ToInt64()) + "\n");

            // Pause execution
            Console.WriteLine("[*] Pausing execution..");
            Console.ReadLine();
        }
    }
}

Example 2 - Invoking Unmanaged Code

In the example below, we first call OpenProcess normally using PInvoke. Then, we will call it in several ways using DInvoke to demonstrate that each mechanism successfully executes the unmanaged code and evades API hooks.

///Author: TheWover
using System;
using System.Runtime.InteropServices;

using Data = DInvoke.Data;
using DynamicInvoke = DInvoke.DynamicInvoke;
using ManualMap = DInvoke.ManualMap;

namespace SpTestcase
{
    class Program
    {

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern IntPtr OpenProcess(
            Data.Win32.Kernel32.ProcessAccessFlags processAccess,
            bool bInheritHandle,
            uint processId
        );

        static void Main(string[] args)
        {
            // Details
            String testDetail = @"
            #=================>
            # Hello there!
            # I demonstrate API Hooking bypasses
            # by calling OpenProcess via
            # PInvoke then DInvoke.
            # All handles are requested with
            # PROCESS_ALL_ACCESS permissions.
            #=================>
            ";
            Console.WriteLine(testDetail);

            //PID of current process.
            uint id = Convert.ToUInt32(System.Diagnostics.Process.GetCurrentProcess().Id);

            //Process handle
            IntPtr hProc;

            // Create the array for the parameters for OpenProcess
            object[] paramaters =
            {
                Data.Win32.Kernel32.ProcessAccessFlags.PROCESS_ALL_ACCESS,
                false,
                id
            };

            // Pause execution
            Console.WriteLine("[*] Pausing execution..");
            Console.ReadLine();

            //////////////////////////////////////////////////////////////////////////////////////////////////////////
            // Call OpenProcess using PInvoke
            Console.WriteLine("[?] Call OpenProcess via PInvoke ...");
            hProc = OpenProcess(Data.Win32.Kernel32.ProcessAccessFlags.PROCESS_ALL_ACCESS, false, id);
            Console.WriteLine("[>] Process handle : " + string.Format("{0:X}", hProc.ToInt64()) + "\n");

            // Pause execution
            Console.WriteLine("[*] Pausing execution..");
            Console.ReadLine();

            //////////////////////////////////////////////////////////////////////////////////////////////////////////
            // Call OpenProcess using GetLibraryAddress (underneath the hood)
            Console.WriteLine("[?] Call OpenProcess from the loaded module list using System.Diagnostics.Process.GetCurrentProcess().Modules ...");
            hProc = DynamicInvoke.Win32.OpenProcess(Data.Win32.Kernel32.ProcessAccessFlags.PROCESS_ALL_ACCESS, false, id);
            Console.WriteLine("[>] Process handle : " + string.Format("{0:X}", hProc.ToInt64()) + "\n");

            // Pause execution
            Console.WriteLine("[*] Pausing execution..");
            Console.ReadLine();

            //////////////////////////////////////////////////////////////////////////////////////////////////////////
            // Search function by name from module in PEB
            Console.WriteLine("[?] Specifying the name of a DLL (\"kernel32.dll\"), search the PEB for the loaded module and resolve a function by walking the export table in-memory...");
            Console.WriteLine("[+] Search by name --> OpenProcess");
            IntPtr pkernel32 = DynamicInvoke.Generic.GetPebLdrModuleEntry("kernel32.dll");
            IntPtr pOpenProcess = DynamicInvoke.Generic.GetExportAddress(pkernel32, "OpenProcess");

            //Call OpenProcess
            hProc = (IntPtr)DynamicInvoke.Generic.DynamicFunctionInvoke(pOpenProcess, typeof(DynamicInvoke.Win32.Delegates.OpenProcess), ref paramaters);
            Console.WriteLine("[>] Process Handle : " + string.Format("{0:X}", hProc.ToInt64()) + "\n");

            // Pause execution
            Console.WriteLine("[*] Pausing execution..");
            Console.ReadLine();

            //////////////////////////////////////////////////////////////////////////////////////////////////////////
            // Manually map kernel32.dll
            // Search function by name from module in PEB
            Console.WriteLine("[?] Manually map a fresh copy of a DLL (\"kernel32.dll\"), and resolve a function by walking the export table in-memory...");
            Console.WriteLine("[+] Search by name --> OpenProcess");
            Data.PE.PE_MANUAL_MAP moduleDetails = ManualMap.Map.MapModuleToMemory("C:\\Windows\\System32\\kernel32.dll");
            Console.WriteLine("[>] Module Base : " + string.Format("{0:X}", moduleDetails.ModuleBase.ToInt64()) + "\n");

            //Call OpenProcess
            hProc = (IntPtr)DynamicInvoke.Generic.CallMappedDLLModuleExport(moduleDetails.PEINFO, moduleDetails.ModuleBase, "OpenProcess", typeof(DynamicInvoke.Win32.Delegates.OpenProcess), paramaters);
            Console.WriteLine("[>] Process Handle : " + string.Format("{0:X}", hProc.ToInt64()) + "\n");

            // Pause execution
            Console.WriteLine("[*] Pausing execution..");
            Console.ReadLine();

            //////////////////////////////////////////////////////////////////////////////////////////////////////////
            // Map kernel32.dll using Module Overloading
            // Search function by name from module in PEB
            Console.WriteLine("[?] Use Module Overloading to map a fresh copy of a DLL (\"kernel32.dll\") into memory backed by another file on disk. Resolve a function by walking the export table in-memory...");
            Console.WriteLine("[+] Search by name --> OpenProcess");
            moduleDetails = ManualMap.Overload.OverloadModule("C:\\Windows\\System32\\kernel32.dll");
            Console.WriteLine("[>] Module Base : " + string.Format("{0:X}", moduleDetails.ModuleBase.ToInt64()) + "\n");

            //Call OpenProcess
            hProc = (IntPtr)DynamicInvoke.Generic.CallMappedDLLModuleExport(moduleDetails.PEINFO, moduleDetails.ModuleBase, "OpenProcess", typeof(DynamicInvoke.Win32.Delegates.OpenProcess), paramaters);
            Console.WriteLine("[>] Process Handle : " + string.Format("{0:X}", hProc.ToInt64()) + "\n");

            // Pause execution
            Console.WriteLine("[*] Pausing execution..");
            Console.ReadLine();

            //////////////////////////////////////////////////////////////////////////////////////////////////////////
            Console.WriteLine("[!] Test complete!");

            // Pause execution
            Console.WriteLine("[*] Pausing execution..");
            Console.ReadLine();

        }
    }
}

To test that this evaded hooks, we will use the tool API Monitor v2 to hook kernel32.dll!OpenProcess. Then we will run the demo through API Monitor. You may observe which of our calls to OpenProcess were caught in hooks by watching for those that are called with the PROCESS_ALL_ACCESS flag. As you will see, API Monitor successfully catches the API call when it is performed with PInvoke. However, it does NOT succeed when we use DInvoke or Manual Mapping. You may watch the video on Vimeo to see this in action.

SharpSploit: Bypassing API Hooks via DInvoke and Manual Mapping

Credit

  • The Wover
  • FuzzySec (b33f)
  • cobbr

dinvoke's People

Contributors

jfmaes avatar s3cur3th1ssh1t avatar thewover avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dinvoke's Issues

Unhoooking and remapping

Add functions to unhook particular API calls and refresh DLLs in their original memory space.

API Set Resolution may loop back to module being loaded

There is a case where a DLL's API Set reference may resolve to the original DLL. An example is Kernel32.dll!InitializeProcThreadAttributeList, which forwards to api-ms-win-core-processthreads-l1-1-0.InitializeProcThreadAttributeList, which resolves back to Kernel32.dll!InitializeProcThreadAttributeList. This causes the API Set to not actually resolve and results in an error when attempting to call the function that was searched for.

Module Overloading is Russian Roulette

Module Overloading without a decoy DLL set might as well be a game of Russian Roulette for how randomly it works and other-randomly it destroys all hope of whatever it was you were trying to not waste your life by doing. Whatever the fuck it's doing, it should not.

I am the one who wrote the code.

Add Deallocate to injection API

Add a Deallocate function to allocation classes that cleans up the artifacts produced by the allocation. This should close relevant handles, clean up memory, and perform any other relevant OPSEC functionality.

A few Memory and handle leaks

Issue 1

Handle leak: CreateSection returns the handle from NtCreateSection as sectionAddress but this handle is never closed and is leaked as a result

        public IntPtr Allocate(PICPayload Payload, Process Process, IntPtr PreferredAddress)
        {
            // Get a convenient handle for the target process.
            IntPtr procHandle = Process.Handle;

            // Create a section to hold our payload
            IntPtr sectionAddress = CreateSection((uint)Payload.Payload.Length, sectionAttributes);
! No call to CloseHandle on sectionAddress 

            // Map a view of the section into our current process with RW permissions

IntPtr sectionAddress = CreateSection((uint)Payload.Payload.Length, sectionAttributes);

Issue 2

Handle leak calling NtCreateSection in MapModuleFromDisk

            // Create section from hFile
            IntPtr hSection = IntPtr.Zero;
            ulong MaxSize = 0;
            Data.Native.NTSTATUS ret = DynamicInvoke.Native.NtCreateSection(
                ref hSection,
! No call to CloseHandle on hSection
                (UInt32)Data.Win32.WinNT.ACCESS_MASK.SECTION_ALL_ACCESS,
                IntPtr.Zero,
                ref MaxSize,
                Data.Win32.WinNT.PAGE_READONLY,
                Data.Win32.WinNT.SEC_IMAGE,
                hFile
            );

Data.Native.NTSTATUS ret = DynamicInvoke.Native.NtCreateSection(

Issue 3

Memory leak with pObjectName due to missing call to FreeHGlobal

        public static Data.PE.PE_MANUAL_MAP MapModuleFromDisk(string DLLPath)
        {
            IntPtr pObjectName = Marshal.AllocHGlobal(Marshal.SizeOf(ObjectName));
! No call to Marshall.FreeHGlobal for this object

IntPtr pObjectName = Marshal.AllocHGlobal(Marshal.SizeOf(ObjectName));

Issue 4

Memory leak due to failure to call Marshal.FreeHGlobal in exception path

        public static Data.PE.PE_MANUAL_MAP MapModuleToMemory(IntPtr pModule, IntPtr pImage, Data.PE.PE_META_DATA PEINFO)
        {
...
            // Write PE header to memory
            UInt32 SizeOfHeaders = PEINFO.Is32Bit ? PEINFO.OptHeader32.SizeOfHeaders : PEINFO.OptHeader64.SizeOfHeaders;
            UInt32 BytesWritten = DynamicInvoke.Native.NtWriteVirtualMemory((IntPtr)(-1), pImage, pModule, SizeOfHeaders);

            // Write sections to memory
            foreach (Data.PE.IMAGE_SECTION_HEADER ish in PEINFO.Sections)
            {
                // Calculate offsets
                IntPtr pVirtualSectionBase = (IntPtr)((UInt64)pImage + ish.VirtualAddress);
                IntPtr pRawSectionBase = (IntPtr)((UInt64)pModule + ish.PointerToRawData);

                // Write data
                BytesWritten = DynamicInvoke.Native.NtWriteVirtualMemory((IntPtr)(-1), pVirtualSectionBase, pRawSectionBase, ish.SizeOfRawData);
                if (BytesWritten != ish.SizeOfRawData)
                {
+                    Marshal.FreeHGlobal(pModule);
                    throw new InvalidOperationException("Failed to write to memory.");
                }
            }

            // Perform relocations
            RelocateModule(PEINFO, pImage);

            // Rewrite IAT
            RewriteModuleIAT(PEINFO, pImage);

            // Set memory protections
            SetModuleSectionPermissions(PEINFO, pImage);

            // Free temp HGlobal
            Marshal.FreeHGlobal(pModule);

throw new InvalidOperationException("Failed to write to memory.");

'Access violation' using OverloadModule with certain modules (e.g., SAMCLI.dll)

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:

shareable_ws_Zero

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);
        }
    }
} 

Code Questions for D/Invoke's GetSyscallStub Code

About the code for GetSyscallStub function, I have some questions for it.
unknown

  • Why the code allocates the NTDLL twice (pModule variable and pImage variable)?
  • For the GetExportFunction for variable pFunc, why doesn't use the pModule variable instead of the pImage variable?
  • What is the difference between the pModule variable and the pImage variable?
    Any answer is appreciated! 😄

OverloadModule / MapModuleFromDisk not working with export forwards

Description

Using MapModuleFromDisk or OverloadModule in functions with export forwards (e.g., netapi32.dll!NetLocalGroupAddMembers) and then calling CallMappedDLLModuleExport will not work in all cases. After resolving the forward, the function tries to find the new module in the process PEB:

IntPtr hModule = GetPebLdrModuleEntry(ForwardModuleName);
but the process will not necessarily have the module loaded which will return System.AccessViolationException.

Potential fix

When hModule returns null, include a second step to load the dll from disk using the same method (Overload / MapModule). This assumes that the .dll is in the same directory but maybe there is a more elegant solution.

Test code

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.Map.MapModuleFromDisk(@"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);
        }
    }
}

32 bit not working

Hello,

I tried the dll with x64 executables and it works fine. However, it does not work with x86 (wow64) executables.
Any idea ?

Here is my code :

            if (IntPtr.Size == 4)
            {
                //C:\Windows\SysWOW64
                DInvoke.ManualMap.Overload.OverloadModule("C:\\Windows\\SysWOW64\\ntdll.dll");
                DInvoke.ManualMap.Overload.OverloadModule("C:\\Windows\\SysWOW64\\kernel32.dll");
            }
            else 
            {
                DInvoke.ManualMap.Overload.OverloadModule("C:\\Windows\\System32\\ntdll.dll");
                DInvoke.ManualMap.Overload.OverloadModule("C:\\Windows\\System32\\kernel32.dll");
            }

Error is : 'Failed to open file, ObjectNameInvalid'


It occurs with : '>DInvoke.DynamicInvoke.Native.NtOpenFile(ref System.IntPtr FileHandle, DInvoke.Data.Win32.Kernel32.FileAccessFlags DesiredAccess, ref DInvoke.Data.Native.OBJECT_ATTRIBUTES ObjAttr, ref DInvoke.Data.Native.IO_STATUS_BLOCK IoStatusBlock, DInvoke.Data.Win32.Kernel32.FileShareFlags ShareAccess, DInvoke.Data.Win32.Kernel32.FileOpenFlags OpenOptions)
'

MiniDumpWriteDump raises an AccessViolationException

Hi,

I am trying to use DInvoke to execute MiniDumpWriteDump for dumping notepad process.
I have tried with HIGH and also system integrity, with SeDebugPrivilege enabled.

I always have same error: System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

I tried using traditional PInvoke and works fine, but I am not interested in this way.

Is known any problem with DInvoke and MiniDumpWriteDump?

Here is my code. Thanks

using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using DInvoke.DynamicInvoke;
using System.Security.Principal;

namespace DMiniDumpWrite
{
    class Program
    {
        /*
        [Flags]
        public enum MINIDUMP_TYPE : uint
        {
            MiniDumpNormal = 0x00000000,
            MiniDumpWithDataSegs = 0x00000001,
            MiniDumpWithFullMemory = 0x00000002,
            MiniDumpWithHandleData = 0x00000004,
            MiniDumpFilterMemory = 0x00000008,
            MiniDumpScanMemory = 0x00000010,
            MiniDumpWithUnloadedModules = 0x00000020,
            MiniDumpWithIndirectlyReferencedMemory = 0x00000040,
            MiniDumpFilterModulePaths = 0x00000080,
            MiniDumpWithProcessThreadData = 0x00000100,
            MiniDumpWithPrivateReadWriteMemory = 0x00000200,
            MiniDumpWithoutOptionalData = 0x00000400,
            MiniDumpWithFullMemoryInfo = 0x00000800,
            MiniDumpWithThreadInfo = 0x00001000,
            MiniDumpWithCodeSegs = 0x00002000,
            MiniDumpWithoutAuxiliaryState = 0x00004000,
            MiniDumpWithFullAuxiliaryState = 0x00008000,
            MiniDumpWithPrivateWriteCopyMemory = 0x00010000,
            MiniDumpIgnoreInaccessibleMemory = 0x00020000,
            MiniDumpWithTokenInformation = 0x00040000,
            MiniDumpWithModuleHeaders = 0x00080000,
            MiniDumpFilterTriage = 0x00100000
        }
        */
        
        
        [UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true)]
        private delegate bool MiniDumpWriteDumpDelegate(IntPtr hProcess, uint ProcessId, IntPtr hFile, uint DumpType, IntPtr ExceptionParam, IntPtr UserStreamParam, IntPtr CallbackParam);



        [DllImport("kernel32.dll", SetLastError = true)]
        static extern IntPtr OpenProcess(uint processAccess, bool bInheritHandle, int processId);

        [DllImport("kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool CloseHandle(IntPtr hObject);

        static void Main(string[] args)
        {
            try
            {

                Process[] lsass = Process.GetProcessesByName("notepad");
                

                IntPtr hProcess = OpenProcess(0x001F0FFF, false, lsass[0].Id); 
                
                using (FileStream fs = new FileStream("dump.dmp", FileMode.Create, FileAccess.ReadWrite, FileShare.Write))
                 {
                                                  
                    IntPtr pFunction = Generic.GetLibraryAddress(@"C:\Windows\System32\dbghelp.dll", "MiniDumpWriteDump", true);
                    
                    MiniDumpWriteDumpDelegate miniDumpWriteDump = (MiniDumpWriteDumpDelegate)Marshal.GetDelegateForFunctionPointer(pFunction, typeof(MiniDumpWriteDumpDelegate));
                    
                    bool success = miniDumpWriteDump(hProcess,(uint)lsass[0].Id,fs.SafeFileHandle.DangerousGetHandle(),(uint)2, IntPtr.Zero,IntPtr.Zero,IntPtr.Zero);
                    
                    
                    if (success)
                    {
                        Console.WriteLine("Dumped");
                    }
                    else
                    {
                        Console.WriteLine("Error dumping");
                    }
                }

                CloseHandle(hProcess);
            }
            //catch (Exception ex)
            //{
            //    Console.WriteLine("Errorx: " + ex.Message);
            //}
            catch (AccessViolationException ex)
            {
                Console.WriteLine("AccessViolationException: " + ex.Message);
            }
        }
    }
}

Could not install package 'DInvoke 1.0.4'.

I think you have to add explicit versions supported...

Could not install package 'DInvoke 1.0.4'. You are trying to install this package into a project that targets '.NETFramework,Version=v4.5', but the package does not contain any assembly references or content files that are compatible with that framework. For more information, contact the package author.

syscallstubs seem to malfunction

There's something going wrong with the syscall stubs or the invocation explanation on the blogpost.
when tested using regopenkey,regwritevalue,regclose, it seems the syscalls work, but the object attributes get misinterpreted for some reason.

when testing using manualmap or overload, the functionality seems fine.

Passing null as argument

Hello.
Please help me to pass null as parameter to winapi.

var arg = new object[2] {IntPtr.Zero, 3};
and
var arg = new object[2] {null, 3};

leads to memory corruption, seems like pointer to zeroed memory passed instead of nullptr.

FileNotFoundException in RewriteModuleIAT

I think this is meant to work?

using DInvoke.DynamicInvoke;
using DInvoke.ManualMap;
using Data = DInvoke.Data;

using System;

namespace DInvokeTest
{
    class Program
    {
        static void Main(string[] args)
        {
            var pid = int.Parse(args[0]);

            var map = Overload.OverloadModule(@"C:\Windows\System32\kernel32.dll");

            var paramaters = new object[]
            {
                Data.Win32.Kernel32.ProcessAccessFlags.PROCESS_ALL_ACCESS,
                false,
                pid
            };

            var hProcess = (IntPtr)Generic.CallMappedDLLModuleExport(map.PEINFO, map.ModuleBase, "OpenProcess",
                typeof(Win32.Delegates.OpenProcess), paramaters);

            Console.WriteLine("Handle => 0x" + string.Format("{0:X}", hProcess.ToInt64()));
        }
    }
}
Unhandled Exception: System.IO.FileNotFoundException: api-ms-win-core-processthreads-l1-1-0.dll, unable to find the specified file.
   at DInvoke.ManualMap.Map.RewriteModuleIAT(PE_META_DATA PEINFO, IntPtr ModuleMemoryBase)
   at DInvoke.ManualMap.Map.MapModuleToMemory(IntPtr pModule, IntPtr pImage, PE_META_DATA PEINFO)
   at DInvoke.ManualMap.Overload.OverloadModule(Byte[] Payload, String DecoyModulePath, Boolean LegitSigned)
   at DInvokeTest.Program.Main(String[] args)

Probably a duplicate of cobbr/SharpSploit#58

Does not resolve export forwards

The current version of DInvoke does not resolve export forwards. It assumes that all exports are not forwarded. This may be demonstrated by attempting to resolve kernel32.dll!InitializeSRWLock.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.