diff --git a/README.md b/README.md
index 8e2e218..f43758c 100644
--- a/README.md
+++ b/README.md
@@ -529,6 +529,12 @@ last_visit_time : 22/09/2020 12:04:07
[...Snipped...]
```
+### Reprobate
+
+Reprobate consists of two `cs` files which contain all of the [DynamicInvoke](https://thewover.github.io/Dynamic-Invoke/) functionality and are meant to be plug-and-play for your C# projects. This can be preferable to using a nuget package or whole-sale including [SharpSploit](https://github.com/cobbr/SharpSploit). Eventually I will integrate bubble-sort Syscall ID identification as well to avoid manual ntdll mapping/enumeration.
+
+For further details check out => [BlueHatIL 2020: Staying # and Bringing Covert Injection Tradecraft to .NET](https://github.com/FuzzySecurity/BlueHatIL-2020)
+
## Windows API
### GetAPISetMapping
diff --git a/Reprobate/h_reprobate.cs b/Reprobate/h_reprobate.cs
new file mode 100644
index 0000000..37e9a20
--- /dev/null
+++ b/Reprobate/h_reprobate.cs
@@ -0,0 +1,2726 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+
+namespace YourProjectHere
+{
+ class h_reprobate
+ {
+ [StructLayout(LayoutKind.Sequential)]
+ public struct UNICODE_STRING
+ {
+ public UInt16 Length;
+ public UInt16 MaximumLength;
+ public IntPtr Buffer;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct ANSI_STRING
+ {
+ public UInt16 Length;
+ public UInt16 MaximumLength;
+ public IntPtr Buffer;
+ }
+
+ public struct PROCESS_BASIC_INFORMATION
+ {
+ public IntPtr ExitStatus;
+ public IntPtr PebBaseAddress;
+ public IntPtr AffinityMask;
+ public IntPtr BasePriority;
+ public UIntPtr UniqueProcessId;
+ public int InheritedFromUniqueProcessId;
+
+ public int Size
+ {
+ get { return (int)Marshal.SizeOf(typeof(PROCESS_BASIC_INFORMATION)); }
+ }
+ }
+
+ [StructLayout(LayoutKind.Sequential, Pack = 0)]
+ public struct OBJECT_ATTRIBUTES
+ {
+ public Int32 Length;
+ public IntPtr RootDirectory;
+ public IntPtr ObjectName; // -> UNICODE_STRING
+ public uint Attributes;
+ public IntPtr SecurityDescriptor;
+ public IntPtr SecurityQualityOfService;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct IO_STATUS_BLOCK
+ {
+ public IntPtr Status;
+ public IntPtr Information;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct CLIENT_ID
+ {
+ public IntPtr UniqueProcess;
+ public IntPtr UniqueThread;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct OSVERSIONINFOEX
+ {
+ public uint OSVersionInfoSize;
+ public uint MajorVersion;
+ public uint MinorVersion;
+ public uint BuildNumber;
+ public uint PlatformId;
+ [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
+ public string CSDVersion;
+ public ushort ServicePackMajor;
+ public ushort ServicePackMinor;
+ public ushort SuiteMask;
+ public byte ProductType;
+ public byte Reserved;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct LIST_ENTRY
+ {
+ public IntPtr Flink;
+ public IntPtr Blink;
+ }
+
+ public enum MEMORYINFOCLASS : int
+ {
+ MemoryBasicInformation = 0,
+ MemoryWorkingSetList,
+ MemorySectionName,
+ MemoryBasicVlmInformation
+ }
+
+ public enum PROCESSINFOCLASS : int
+ {
+ ProcessBasicInformation = 0, // 0, q: PROCESS_BASIC_INFORMATION, PROCESS_EXTENDED_BASIC_INFORMATION
+ ProcessQuotaLimits, // qs: QUOTA_LIMITS, QUOTA_LIMITS_EX
+ ProcessIoCounters, // q: IO_COUNTERS
+ ProcessVmCounters, // q: VM_COUNTERS, VM_COUNTERS_EX
+ ProcessTimes, // q: KERNEL_USER_TIMES
+ ProcessBasePriority, // s: KPRIORITY
+ ProcessRaisePriority, // s: ULONG
+ ProcessDebugPort, // q: HANDLE
+ ProcessExceptionPort, // s: HANDLE
+ ProcessAccessToken, // s: PROCESS_ACCESS_TOKEN
+ ProcessLdtInformation, // 10
+ ProcessLdtSize,
+ ProcessDefaultHardErrorMode, // qs: ULONG
+ ProcessIoPortHandlers, // (kernel-mode only)
+ ProcessPooledUsageAndLimits, // q: POOLED_USAGE_AND_LIMITS
+ ProcessWorkingSetWatch, // q: PROCESS_WS_WATCH_INFORMATION[]; s: void
+ ProcessUserModeIOPL,
+ ProcessEnableAlignmentFaultFixup, // s: BOOLEAN
+ ProcessPriorityClass, // qs: PROCESS_PRIORITY_CLASS
+ ProcessWx86Information,
+ ProcessHandleCount, // 20, q: ULONG, PROCESS_HANDLE_INFORMATION
+ ProcessAffinityMask, // s: KAFFINITY
+ ProcessPriorityBoost, // qs: ULONG
+ ProcessDeviceMap, // qs: PROCESS_DEVICEMAP_INFORMATION, PROCESS_DEVICEMAP_INFORMATION_EX
+ ProcessSessionInformation, // q: PROCESS_SESSION_INFORMATION
+ ProcessForegroundInformation, // s: PROCESS_FOREGROUND_BACKGROUND
+ ProcessWow64Information, // q: ULONG_PTR
+ ProcessImageFileName, // q: UNICODE_STRING
+ ProcessLUIDDeviceMapsEnabled, // q: ULONG
+ ProcessBreakOnTermination, // qs: ULONG
+ ProcessDebugObjectHandle, // 30, q: HANDLE
+ ProcessDebugFlags, // qs: ULONG
+ ProcessHandleTracing, // q: PROCESS_HANDLE_TRACING_QUERY; s: size 0 disables, otherwise enables
+ ProcessIoPriority, // qs: ULONG
+ ProcessExecuteFlags, // qs: ULONG
+ ProcessResourceManagement,
+ ProcessCookie, // q: ULONG
+ ProcessImageInformation, // q: SECTION_IMAGE_INFORMATION
+ ProcessCycleTime, // q: PROCESS_CYCLE_TIME_INFORMATION
+ ProcessPagePriority, // q: ULONG
+ ProcessInstrumentationCallback, // 40
+ ProcessThreadStackAllocation, // s: PROCESS_STACK_ALLOCATION_INFORMATION, PROCESS_STACK_ALLOCATION_INFORMATION_EX
+ ProcessWorkingSetWatchEx, // q: PROCESS_WS_WATCH_INFORMATION_EX[]
+ ProcessImageFileNameWin32, // q: UNICODE_STRING
+ ProcessImageFileMapping, // q: HANDLE (input)
+ ProcessAffinityUpdateMode, // qs: PROCESS_AFFINITY_UPDATE_MODE
+ ProcessMemoryAllocationMode, // qs: PROCESS_MEMORY_ALLOCATION_MODE
+ ProcessGroupInformation, // q: USHORT[]
+ ProcessTokenVirtualizationEnabled, // s: ULONG
+ ProcessConsoleHostProcess, // q: ULONG_PTR
+ ProcessWindowInformation, // 50, q: PROCESS_WINDOW_INFORMATION
+ ProcessHandleInformation, // q: PROCESS_HANDLE_SNAPSHOT_INFORMATION // since WIN8
+ ProcessMitigationPolicy, // s: PROCESS_MITIGATION_POLICY_INFORMATION
+ ProcessDynamicFunctionTableInformation,
+ ProcessHandleCheckingMode,
+ ProcessKeepAliveCount, // q: PROCESS_KEEPALIVE_COUNT_INFORMATION
+ ProcessRevokeFileHandles, // s: PROCESS_REVOKE_FILE_HANDLES_INFORMATION
+ MaxProcessInfoClass
+ };
+
+ ///
+ /// NT_CREATION_FLAGS is an undocumented enum. https://processhacker.sourceforge.io/doc/ntpsapi_8h_source.html
+ ///
+ public enum NT_CREATION_FLAGS : ulong
+ {
+ CREATE_SUSPENDED = 0x00000001,
+ SKIP_THREAD_ATTACH = 0x00000002,
+ HIDE_FROM_DEBUGGER = 0x00000004,
+ HAS_SECURITY_DESCRIPTOR = 0x00000010,
+ ACCESS_CHECK_IN_TARGET = 0x00000020,
+ INITIAL_THREAD = 0x00000080
+ }
+
+ ///
+ /// NTSTATUS is an undocument enum. https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/596a1078-e883-4972-9bbc-49e60bebca55
+ /// https://www.pinvoke.net/default.aspx/Enums/NtStatus.html
+ ///
+ public enum NTSTATUS : uint
+ {
+ // Success
+ Success = 0x00000000,
+ Wait0 = 0x00000000,
+ Wait1 = 0x00000001,
+ Wait2 = 0x00000002,
+ Wait3 = 0x00000003,
+ Wait63 = 0x0000003f,
+ Abandoned = 0x00000080,
+ AbandonedWait0 = 0x00000080,
+ AbandonedWait1 = 0x00000081,
+ AbandonedWait2 = 0x00000082,
+ AbandonedWait3 = 0x00000083,
+ AbandonedWait63 = 0x000000bf,
+ UserApc = 0x000000c0,
+ KernelApc = 0x00000100,
+ Alerted = 0x00000101,
+ Timeout = 0x00000102,
+ Pending = 0x00000103,
+ Reparse = 0x00000104,
+ MoreEntries = 0x00000105,
+ NotAllAssigned = 0x00000106,
+ SomeNotMapped = 0x00000107,
+ OpLockBreakInProgress = 0x00000108,
+ VolumeMounted = 0x00000109,
+ RxActCommitted = 0x0000010a,
+ NotifyCleanup = 0x0000010b,
+ NotifyEnumDir = 0x0000010c,
+ NoQuotasForAccount = 0x0000010d,
+ PrimaryTransportConnectFailed = 0x0000010e,
+ PageFaultTransition = 0x00000110,
+ PageFaultDemandZero = 0x00000111,
+ PageFaultCopyOnWrite = 0x00000112,
+ PageFaultGuardPage = 0x00000113,
+ PageFaultPagingFile = 0x00000114,
+ CrashDump = 0x00000116,
+ ReparseObject = 0x00000118,
+ NothingToTerminate = 0x00000122,
+ ProcessNotInJob = 0x00000123,
+ ProcessInJob = 0x00000124,
+ ProcessCloned = 0x00000129,
+ FileLockedWithOnlyReaders = 0x0000012a,
+ FileLockedWithWriters = 0x0000012b,
+
+ // Informational
+ Informational = 0x40000000,
+ ObjectNameExists = 0x40000000,
+ ThreadWasSuspended = 0x40000001,
+ WorkingSetLimitRange = 0x40000002,
+ ImageNotAtBase = 0x40000003,
+ RegistryRecovered = 0x40000009,
+
+ // Warning
+ Warning = 0x80000000,
+ GuardPageViolation = 0x80000001,
+ DatatypeMisalignment = 0x80000002,
+ Breakpoint = 0x80000003,
+ SingleStep = 0x80000004,
+ BufferOverflow = 0x80000005,
+ NoMoreFiles = 0x80000006,
+ HandlesClosed = 0x8000000a,
+ PartialCopy = 0x8000000d,
+ DeviceBusy = 0x80000011,
+ InvalidEaName = 0x80000013,
+ EaListInconsistent = 0x80000014,
+ NoMoreEntries = 0x8000001a,
+ LongJump = 0x80000026,
+ DllMightBeInsecure = 0x8000002b,
+
+ // Error
+ Error = 0xc0000000,
+ Unsuccessful = 0xc0000001,
+ NotImplemented = 0xc0000002,
+ InvalidInfoClass = 0xc0000003,
+ InfoLengthMismatch = 0xc0000004,
+ AccessViolation = 0xc0000005,
+ InPageError = 0xc0000006,
+ PagefileQuota = 0xc0000007,
+ InvalidHandle = 0xc0000008,
+ BadInitialStack = 0xc0000009,
+ BadInitialPc = 0xc000000a,
+ InvalidCid = 0xc000000b,
+ TimerNotCanceled = 0xc000000c,
+ InvalidParameter = 0xc000000d,
+ NoSuchDevice = 0xc000000e,
+ NoSuchFile = 0xc000000f,
+ InvalidDeviceRequest = 0xc0000010,
+ EndOfFile = 0xc0000011,
+ WrongVolume = 0xc0000012,
+ NoMediaInDevice = 0xc0000013,
+ NoMemory = 0xc0000017,
+ ConflictingAddresses = 0xc0000018,
+ NotMappedView = 0xc0000019,
+ UnableToFreeVm = 0xc000001a,
+ UnableToDeleteSection = 0xc000001b,
+ IllegalInstruction = 0xc000001d,
+ AlreadyCommitted = 0xc0000021,
+ AccessDenied = 0xc0000022,
+ BufferTooSmall = 0xc0000023,
+ ObjectTypeMismatch = 0xc0000024,
+ NonContinuableException = 0xc0000025,
+ BadStack = 0xc0000028,
+ NotLocked = 0xc000002a,
+ NotCommitted = 0xc000002d,
+ InvalidParameterMix = 0xc0000030,
+ ObjectNameInvalid = 0xc0000033,
+ ObjectNameNotFound = 0xc0000034,
+ ObjectNameCollision = 0xc0000035,
+ ObjectPathInvalid = 0xc0000039,
+ ObjectPathNotFound = 0xc000003a,
+ ObjectPathSyntaxBad = 0xc000003b,
+ DataOverrun = 0xc000003c,
+ DataLate = 0xc000003d,
+ DataError = 0xc000003e,
+ CrcError = 0xc000003f,
+ SectionTooBig = 0xc0000040,
+ PortConnectionRefused = 0xc0000041,
+ InvalidPortHandle = 0xc0000042,
+ SharingViolation = 0xc0000043,
+ QuotaExceeded = 0xc0000044,
+ InvalidPageProtection = 0xc0000045,
+ MutantNotOwned = 0xc0000046,
+ SemaphoreLimitExceeded = 0xc0000047,
+ PortAlreadySet = 0xc0000048,
+ SectionNotImage = 0xc0000049,
+ SuspendCountExceeded = 0xc000004a,
+ ThreadIsTerminating = 0xc000004b,
+ BadWorkingSetLimit = 0xc000004c,
+ IncompatibleFileMap = 0xc000004d,
+ SectionProtection = 0xc000004e,
+ EasNotSupported = 0xc000004f,
+ EaTooLarge = 0xc0000050,
+ NonExistentEaEntry = 0xc0000051,
+ NoEasOnFile = 0xc0000052,
+ EaCorruptError = 0xc0000053,
+ FileLockConflict = 0xc0000054,
+ LockNotGranted = 0xc0000055,
+ DeletePending = 0xc0000056,
+ CtlFileNotSupported = 0xc0000057,
+ UnknownRevision = 0xc0000058,
+ RevisionMismatch = 0xc0000059,
+ InvalidOwner = 0xc000005a,
+ InvalidPrimaryGroup = 0xc000005b,
+ NoImpersonationToken = 0xc000005c,
+ CantDisableMandatory = 0xc000005d,
+ NoLogonServers = 0xc000005e,
+ NoSuchLogonSession = 0xc000005f,
+ NoSuchPrivilege = 0xc0000060,
+ PrivilegeNotHeld = 0xc0000061,
+ InvalidAccountName = 0xc0000062,
+ UserExists = 0xc0000063,
+ NoSuchUser = 0xc0000064,
+ GroupExists = 0xc0000065,
+ NoSuchGroup = 0xc0000066,
+ MemberInGroup = 0xc0000067,
+ MemberNotInGroup = 0xc0000068,
+ LastAdmin = 0xc0000069,
+ WrongPassword = 0xc000006a,
+ IllFormedPassword = 0xc000006b,
+ PasswordRestriction = 0xc000006c,
+ LogonFailure = 0xc000006d,
+ AccountRestriction = 0xc000006e,
+ InvalidLogonHours = 0xc000006f,
+ InvalidWorkstation = 0xc0000070,
+ PasswordExpired = 0xc0000071,
+ AccountDisabled = 0xc0000072,
+ NoneMapped = 0xc0000073,
+ TooManyLuidsRequested = 0xc0000074,
+ LuidsExhausted = 0xc0000075,
+ InvalidSubAuthority = 0xc0000076,
+ InvalidAcl = 0xc0000077,
+ InvalidSid = 0xc0000078,
+ InvalidSecurityDescr = 0xc0000079,
+ ProcedureNotFound = 0xc000007a,
+ InvalidImageFormat = 0xc000007b,
+ NoToken = 0xc000007c,
+ BadInheritanceAcl = 0xc000007d,
+ RangeNotLocked = 0xc000007e,
+ DiskFull = 0xc000007f,
+ ServerDisabled = 0xc0000080,
+ ServerNotDisabled = 0xc0000081,
+ TooManyGuidsRequested = 0xc0000082,
+ GuidsExhausted = 0xc0000083,
+ InvalidIdAuthority = 0xc0000084,
+ AgentsExhausted = 0xc0000085,
+ InvalidVolumeLabel = 0xc0000086,
+ SectionNotExtended = 0xc0000087,
+ NotMappedData = 0xc0000088,
+ ResourceDataNotFound = 0xc0000089,
+ ResourceTypeNotFound = 0xc000008a,
+ ResourceNameNotFound = 0xc000008b,
+ ArrayBoundsExceeded = 0xc000008c,
+ FloatDenormalOperand = 0xc000008d,
+ FloatDivideByZero = 0xc000008e,
+ FloatInexactResult = 0xc000008f,
+ FloatInvalidOperation = 0xc0000090,
+ FloatOverflow = 0xc0000091,
+ FloatStackCheck = 0xc0000092,
+ FloatUnderflow = 0xc0000093,
+ IntegerDivideByZero = 0xc0000094,
+ IntegerOverflow = 0xc0000095,
+ PrivilegedInstruction = 0xc0000096,
+ TooManyPagingFiles = 0xc0000097,
+ FileInvalid = 0xc0000098,
+ InsufficientResources = 0xc000009a,
+ InstanceNotAvailable = 0xc00000ab,
+ PipeNotAvailable = 0xc00000ac,
+ InvalidPipeState = 0xc00000ad,
+ PipeBusy = 0xc00000ae,
+ IllegalFunction = 0xc00000af,
+ PipeDisconnected = 0xc00000b0,
+ PipeClosing = 0xc00000b1,
+ PipeConnected = 0xc00000b2,
+ PipeListening = 0xc00000b3,
+ InvalidReadMode = 0xc00000b4,
+ IoTimeout = 0xc00000b5,
+ FileForcedClosed = 0xc00000b6,
+ ProfilingNotStarted = 0xc00000b7,
+ ProfilingNotStopped = 0xc00000b8,
+ NotSameDevice = 0xc00000d4,
+ FileRenamed = 0xc00000d5,
+ CantWait = 0xc00000d8,
+ PipeEmpty = 0xc00000d9,
+ CantTerminateSelf = 0xc00000db,
+ InternalError = 0xc00000e5,
+ InvalidParameter1 = 0xc00000ef,
+ InvalidParameter2 = 0xc00000f0,
+ InvalidParameter3 = 0xc00000f1,
+ InvalidParameter4 = 0xc00000f2,
+ InvalidParameter5 = 0xc00000f3,
+ InvalidParameter6 = 0xc00000f4,
+ InvalidParameter7 = 0xc00000f5,
+ InvalidParameter8 = 0xc00000f6,
+ InvalidParameter9 = 0xc00000f7,
+ InvalidParameter10 = 0xc00000f8,
+ InvalidParameter11 = 0xc00000f9,
+ InvalidParameter12 = 0xc00000fa,
+ ProcessIsTerminating = 0xc000010a,
+ MappedFileSizeZero = 0xc000011e,
+ TooManyOpenedFiles = 0xc000011f,
+ Cancelled = 0xc0000120,
+ CannotDelete = 0xc0000121,
+ InvalidComputerName = 0xc0000122,
+ FileDeleted = 0xc0000123,
+ SpecialAccount = 0xc0000124,
+ SpecialGroup = 0xc0000125,
+ SpecialUser = 0xc0000126,
+ MembersPrimaryGroup = 0xc0000127,
+ FileClosed = 0xc0000128,
+ TooManyThreads = 0xc0000129,
+ ThreadNotInProcess = 0xc000012a,
+ TokenAlreadyInUse = 0xc000012b,
+ PagefileQuotaExceeded = 0xc000012c,
+ CommitmentLimit = 0xc000012d,
+ InvalidImageLeFormat = 0xc000012e,
+ InvalidImageNotMz = 0xc000012f,
+ InvalidImageProtect = 0xc0000130,
+ InvalidImageWin16 = 0xc0000131,
+ LogonServer = 0xc0000132,
+ DifferenceAtDc = 0xc0000133,
+ SynchronizationRequired = 0xc0000134,
+ DllNotFound = 0xc0000135,
+ IoPrivilegeFailed = 0xc0000137,
+ OrdinalNotFound = 0xc0000138,
+ EntryPointNotFound = 0xc0000139,
+ ControlCExit = 0xc000013a,
+ InvalidAddress = 0xc0000141,
+ PortNotSet = 0xc0000353,
+ DebuggerInactive = 0xc0000354,
+ CallbackBypass = 0xc0000503,
+ PortClosed = 0xc0000700,
+ MessageLost = 0xc0000701,
+ InvalidMessage = 0xc0000702,
+ RequestCanceled = 0xc0000703,
+ RecursiveDispatch = 0xc0000704,
+ LpcReceiveBufferExpected = 0xc0000705,
+ LpcInvalidConnectionUsage = 0xc0000706,
+ LpcRequestsNotAllowed = 0xc0000707,
+ ResourceInUse = 0xc0000708,
+ ProcessIsProtected = 0xc0000712,
+ VolumeDirty = 0xc0000806,
+ FileCheckedOut = 0xc0000901,
+ CheckOutRequired = 0xc0000902,
+ BadFileType = 0xc0000903,
+ FileTooLarge = 0xc0000904,
+ FormsAuthRequired = 0xc0000905,
+ VirusInfected = 0xc0000906,
+ VirusDeleted = 0xc0000907,
+ TransactionalConflict = 0xc0190001,
+ InvalidTransaction = 0xc0190002,
+ TransactionNotActive = 0xc0190003,
+ TmInitializationFailed = 0xc0190004,
+ RmNotActive = 0xc0190005,
+ RmMetadataCorrupt = 0xc0190006,
+ TransactionNotJoined = 0xc0190007,
+ DirectoryNotRm = 0xc0190008,
+ CouldNotResizeLog = 0xc0190009,
+ TransactionsUnsupportedRemote = 0xc019000a,
+ LogResizeInvalidSize = 0xc019000b,
+ RemoteFileVersionMismatch = 0xc019000c,
+ CrmProtocolAlreadyExists = 0xc019000f,
+ TransactionPropagationFailed = 0xc0190010,
+ CrmProtocolNotFound = 0xc0190011,
+ TransactionSuperiorExists = 0xc0190012,
+ TransactionRequestNotValid = 0xc0190013,
+ TransactionNotRequested = 0xc0190014,
+ TransactionAlreadyAborted = 0xc0190015,
+ TransactionAlreadyCommitted = 0xc0190016,
+ TransactionInvalidMarshallBuffer = 0xc0190017,
+ CurrentTransactionNotValid = 0xc0190018,
+ LogGrowthFailed = 0xc0190019,
+ ObjectNoLongerExists = 0xc0190021,
+ StreamMiniversionNotFound = 0xc0190022,
+ StreamMiniversionNotValid = 0xc0190023,
+ MiniversionInaccessibleFromSpecifiedTransaction = 0xc0190024,
+ CantOpenMiniversionWithModifyIntent = 0xc0190025,
+ CantCreateMoreStreamMiniversions = 0xc0190026,
+ HandleNoLongerValid = 0xc0190028,
+ NoTxfMetadata = 0xc0190029,
+ LogCorruptionDetected = 0xc0190030,
+ CantRecoverWithHandleOpen = 0xc0190031,
+ RmDisconnected = 0xc0190032,
+ EnlistmentNotSuperior = 0xc0190033,
+ RecoveryNotNeeded = 0xc0190034,
+ RmAlreadyStarted = 0xc0190035,
+ FileIdentityNotPersistent = 0xc0190036,
+ CantBreakTransactionalDependency = 0xc0190037,
+ CantCrossRmBoundary = 0xc0190038,
+ TxfDirNotEmpty = 0xc0190039,
+ IndoubtTransactionsExist = 0xc019003a,
+ TmVolatile = 0xc019003b,
+ RollbackTimerExpired = 0xc019003c,
+ TxfAttributeCorrupt = 0xc019003d,
+ EfsNotAllowedInTransaction = 0xc019003e,
+ TransactionalOpenNotAllowed = 0xc019003f,
+ TransactedMappingUnsupportedRemote = 0xc0190040,
+ TxfMetadataAlreadyPresent = 0xc0190041,
+ TransactionScopeCallbacksNotSet = 0xc0190042,
+ TransactionRequiredPromotion = 0xc0190043,
+ CannotExecuteFileInTransaction = 0xc0190044,
+ TransactionsNotFrozen = 0xc0190045,
+
+ MaximumNtStatus = 0xffffffff
+ }
+
+ /////////////////win32
+ ///
+ public static class Win32
+ {
+ public static class Kernel32
+ {
+ [StructLayout(LayoutKind.Sequential)]
+ public struct IMAGE_BASE_RELOCATION
+ {
+ public uint VirtualAdress;
+ public uint SizeOfBlock;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct IMAGE_IMPORT_DESCRIPTOR
+ {
+ public uint OriginalFirstThunk;
+ public uint TimeDateStamp;
+ public uint ForwarderChain;
+ public uint Name;
+ public uint FirstThunk;
+ }
+
+ public struct SYSTEM_INFO
+ {
+ public ushort wProcessorArchitecture;
+ public ushort wReserved;
+ public uint dwPageSize;
+ public IntPtr lpMinimumApplicationAddress;
+ public IntPtr lpMaximumApplicationAddress;
+ public UIntPtr dwActiveProcessorMask;
+ public uint dwNumberOfProcessors;
+ public uint dwProcessorType;
+ public uint dwAllocationGranularity;
+ public ushort wProcessorLevel;
+ public ushort wProcessorRevision;
+ };
+
+ public enum Platform
+ {
+ x86,
+ x64,
+ IA64,
+ Unknown
+ }
+
+ [Flags]
+ public enum ProcessAccessFlags : UInt32
+ {
+ // https://msdn.microsoft.com/en-us/library/windows/desktop/ms684880%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396
+ PROCESS_ALL_ACCESS = 0x001F0FFF,
+ PROCESS_CREATE_PROCESS = 0x0080,
+ PROCESS_CREATE_THREAD = 0x0002,
+ PROCESS_DUP_HANDLE = 0x0040,
+ PROCESS_QUERY_INFORMATION = 0x0400,
+ PROCESS_QUERY_LIMITED_INFORMATION = 0x1000,
+ PROCESS_SET_INFORMATION = 0x0200,
+ PROCESS_SET_QUOTA = 0x0100,
+ PROCESS_SUSPEND_RESUME = 0x0800,
+ PROCESS_TERMINATE = 0x0001,
+ PROCESS_VM_OPERATION = 0x0008,
+ PROCESS_VM_READ = 0x0010,
+ PROCESS_VM_WRITE = 0x0020,
+ SYNCHRONIZE = 0x00100000
+ }
+
+ [Flags]
+ public enum FileAccessFlags : UInt32
+ {
+ DELETE = 0x10000,
+ FILE_READ_DATA = 0x1,
+ FILE_READ_ATTRIBUTES = 0x80,
+ FILE_READ_EA = 0x8,
+ READ_CONTROL = 0x20000,
+ FILE_WRITE_DATA = 0x2,
+ FILE_WRITE_ATTRIBUTES = 0x100,
+ FILE_WRITE_EA = 0x10,
+ FILE_APPEND_DATA = 0x4,
+ WRITE_DAC = 0x40000,
+ WRITE_OWNER = 0x80000,
+ SYNCHRONIZE = 0x100000,
+ FILE_EXECUTE = 0x20
+ }
+
+ [Flags]
+ public enum FileShareFlags : UInt32
+ {
+ FILE_SHARE_NONE = 0x0,
+ FILE_SHARE_READ = 0x1,
+ FILE_SHARE_WRITE = 0x2,
+ FILE_SHARE_DELETE = 0x4
+ }
+
+ [Flags]
+ public enum FileOpenFlags : UInt32
+ {
+ FILE_DIRECTORY_FILE = 0x1,
+ FILE_WRITE_THROUGH = 0x2,
+ FILE_SEQUENTIAL_ONLY = 0x4,
+ FILE_NO_INTERMEDIATE_BUFFERING = 0x8,
+ FILE_SYNCHRONOUS_IO_ALERT = 0x10,
+ FILE_SYNCHRONOUS_IO_NONALERT = 0x20,
+ FILE_NON_DIRECTORY_FILE = 0x40,
+ FILE_CREATE_TREE_CONNECTION = 0x80,
+ FILE_COMPLETE_IF_OPLOCKED = 0x100,
+ FILE_NO_EA_KNOWLEDGE = 0x200,
+ FILE_OPEN_FOR_RECOVERY = 0x400,
+ FILE_RANDOM_ACCESS = 0x800,
+ FILE_DELETE_ON_CLOSE = 0x1000,
+ FILE_OPEN_BY_FILE_ID = 0x2000,
+ FILE_OPEN_FOR_BACKUP_INTENT = 0x4000,
+ FILE_NO_COMPRESSION = 0x8000
+ }
+
+ [Flags]
+ public enum StandardRights : uint
+ {
+ Delete = 0x00010000,
+ ReadControl = 0x00020000,
+ WriteDac = 0x00040000,
+ WriteOwner = 0x00080000,
+ Synchronize = 0x00100000,
+ Required = 0x000f0000,
+ Read = ReadControl,
+ Write = ReadControl,
+ Execute = ReadControl,
+ All = 0x001f0000,
+
+ SpecificRightsAll = 0x0000ffff,
+ AccessSystemSecurity = 0x01000000,
+ MaximumAllowed = 0x02000000,
+ GenericRead = 0x80000000,
+ GenericWrite = 0x40000000,
+ GenericExecute = 0x20000000,
+ GenericAll = 0x10000000
+ }
+
+ [Flags]
+ public enum ThreadAccess : uint
+ {
+ Terminate = 0x0001,
+ SuspendResume = 0x0002,
+ Alert = 0x0004,
+ GetContext = 0x0008,
+ SetContext = 0x0010,
+ SetInformation = 0x0020,
+ QueryInformation = 0x0040,
+ SetThreadToken = 0x0080,
+ Impersonate = 0x0100,
+ DirectImpersonation = 0x0200,
+ SetLimitedInformation = 0x0400,
+ QueryLimitedInformation = 0x0800,
+ All = StandardRights.Required | StandardRights.Synchronize | 0x3ff
+ }
+
+ [Flags]
+ public enum AllocationType : uint
+ {
+ Commit = 0x1000,
+ Reserve = 0x2000,
+ Decommit = 0x4000,
+ Release = 0x8000,
+ Reset = 0x80000,
+ Physical = 0x400000,
+ TopDown = 0x100000,
+ WriteWatch = 0x200000,
+ ResetUndo = 0x1000000,
+ LargePages = 0x20000000
+ }
+
+ [Flags]
+ public enum MemoryProtection : uint
+ {
+ Execute = 0x10,
+ ExecuteRead = 0x20,
+ ExecuteReadWrite = 0x40,
+ ExecuteWriteCopy = 0x80,
+ NoAccess = 0x01,
+ ReadOnly = 0x02,
+ ReadWrite = 0x04,
+ WriteCopy = 0x08,
+ GuardModifierflag = 0x100,
+ NoCacheModifierflag = 0x200,
+ WriteCombineModifierflag = 0x400
+ }
+
+ public enum PSS_CAPTURE_FLAGS : uint
+ {
+ PSS_CAPTURE_NONE = 0x00000000,
+ PSS_CAPTURE_VA_CLONE = 0x00000001,
+ PSS_CAPTURE_RESERVED_00000002 = 0x00000002,
+ PSS_CAPTURE_HANDLES = 0x00000004,
+ PSS_CAPTURE_HANDLE_NAME_INFORMATION = 0x00000008,
+ PSS_CAPTURE_HANDLE_BASIC_INFORMATION = 0x00000010,
+ PSS_CAPTURE_HANDLE_TYPE_SPECIFIC_INFORMATION = 0x00000020,
+ PSS_CAPTURE_HANDLE_TRACE = 0x00000040,
+ PSS_CAPTURE_THREADS = 0x00000080,
+ PSS_CAPTURE_THREAD_CONTEXT = 0x00000100,
+ PSS_CAPTURE_THREAD_CONTEXT_EXTENDED = 0x00000200,
+ PSS_CAPTURE_RESERVED_00000400 = 0x00000400,
+ PSS_CAPTURE_VA_SPACE = 0x00000800,
+ PSS_CAPTURE_VA_SPACE_SECTION_INFORMATION = 0x00001000,
+ PSS_CREATE_BREAKAWAY_OPTIONAL = 0x04000000,
+ PSS_CREATE_BREAKAWAY = 0x08000000,
+ PSS_CREATE_FORCE_BREAKAWAY = 0x10000000,
+ PSS_CREATE_USE_VM_ALLOCATIONS = 0x20000000,
+ PSS_CREATE_MEASURE_PERFORMANCE = 0x40000000,
+ PSS_CREATE_RELEASE_SECTION = 0x80000000
+ }
+
+ public enum PSS_QUERY_INFORMATION_CLASS
+ {
+ PSS_QUERY_PROCESS_INFORMATION = 0,
+ PSS_QUERY_VA_CLONE_INFORMATION = 1,
+ PSS_QUERY_AUXILIARY_PAGES_INFORMATION = 2,
+ PSS_QUERY_VA_SPACE_INFORMATION = 3,
+ PSS_QUERY_HANDLE_INFORMATION = 4,
+ PSS_QUERY_THREAD_INFORMATION = 5,
+ PSS_QUERY_HANDLE_TRACE_INFORMATION = 6,
+ PSS_QUERY_PERFORMANCE_COUNTERS = 7
+ }
+ }
+
+ public static class User32
+ {
+ public static int WH_KEYBOARD_LL { get; } = 13;
+ public static int WM_KEYDOWN { get; } = 0x0100;
+
+ public delegate IntPtr HookProc(int nCode, IntPtr wParam, IntPtr lParam);
+ }
+
+ public static class Netapi32
+ {
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
+ public struct LOCALGROUP_USERS_INFO_0
+ {
+ [MarshalAs(UnmanagedType.LPWStr)] internal string name;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct LOCALGROUP_USERS_INFO_1
+ {
+ [MarshalAs(UnmanagedType.LPWStr)] public string name;
+ [MarshalAs(UnmanagedType.LPWStr)] public string comment;
+ }
+
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
+ public struct LOCALGROUP_MEMBERS_INFO_2
+ {
+ public IntPtr lgrmi2_sid;
+ public int lgrmi2_sidusage;
+ [MarshalAs(UnmanagedType.LPWStr)] public string lgrmi2_domainandname;
+ }
+
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
+ public struct WKSTA_USER_INFO_1
+ {
+ public string wkui1_username;
+ public string wkui1_logon_domain;
+ public string wkui1_oth_domains;
+ public string wkui1_logon_server;
+ }
+
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
+ public struct SESSION_INFO_10
+ {
+ public string sesi10_cname;
+ public string sesi10_username;
+ public int sesi10_time;
+ public int sesi10_idle_time;
+ }
+
+ public enum SID_NAME_USE : UInt16
+ {
+ SidTypeUser = 1,
+ SidTypeGroup = 2,
+ SidTypeDomain = 3,
+ SidTypeAlias = 4,
+ SidTypeWellKnownGroup = 5,
+ SidTypeDeletedAccount = 6,
+ SidTypeInvalid = 7,
+ SidTypeUnknown = 8,
+ SidTypeComputer = 9
+ }
+
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
+ public struct SHARE_INFO_1
+ {
+ public string shi1_netname;
+ public uint shi1_type;
+ public string shi1_remark;
+
+ public SHARE_INFO_1(string netname, uint type, string remark)
+ {
+ this.shi1_netname = netname;
+ this.shi1_type = type;
+ this.shi1_remark = remark;
+ }
+ }
+ }
+
+ public static class Advapi32
+ {
+
+ // http://www.pinvoke.net/default.aspx/advapi32.openprocesstoken
+ public const UInt32 STANDARD_RIGHTS_REQUIRED = 0x000F0000;
+ public const UInt32 STANDARD_RIGHTS_READ = 0x00020000;
+ public const UInt32 TOKEN_ASSIGN_PRIMARY = 0x0001;
+ public const UInt32 TOKEN_DUPLICATE = 0x0002;
+ public const UInt32 TOKEN_IMPERSONATE = 0x0004;
+ public const UInt32 TOKEN_QUERY = 0x0008;
+ public const UInt32 TOKEN_QUERY_SOURCE = 0x0010;
+ public const UInt32 TOKEN_ADJUST_PRIVILEGES = 0x0020;
+ public const UInt32 TOKEN_ADJUST_GROUPS = 0x0040;
+ public const UInt32 TOKEN_ADJUST_DEFAULT = 0x0080;
+ public const UInt32 TOKEN_ADJUST_SESSIONID = 0x0100;
+ public const UInt32 TOKEN_READ = (STANDARD_RIGHTS_READ | TOKEN_QUERY);
+ public const UInt32 TOKEN_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | TOKEN_ASSIGN_PRIMARY |
+ TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_QUERY_SOURCE |
+ TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS | TOKEN_ADJUST_DEFAULT |
+ TOKEN_ADJUST_SESSIONID);
+ public const UInt32 TOKEN_ALT = (TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY);
+
+ // https://msdn.microsoft.com/en-us/library/windows/desktop/ms682434(v=vs.85).aspx
+ [Flags]
+ public enum CREATION_FLAGS : uint
+ {
+ NONE = 0x00000000,
+ DEBUG_PROCESS = 0x00000001,
+ DEBUG_ONLY_THIS_PROCESS = 0x00000002,
+ CREATE_SUSPENDED = 0x00000004,
+ DETACHED_PROCESS = 0x00000008,
+ CREATE_NEW_CONSOLE = 0x00000010,
+ NORMAL_PRIORITY_CLASS = 0x00000020,
+ IDLE_PRIORITY_CLASS = 0x00000040,
+ HIGH_PRIORITY_CLASS = 0x00000080,
+ REALTIME_PRIORITY_CLASS = 0x00000100,
+ CREATE_NEW_PROCESS_GROUP = 0x00000200,
+ CREATE_UNICODE_ENVIRONMENT = 0x00000400,
+ CREATE_SEPARATE_WOW_VDM = 0x00000800,
+ CREATE_SHARED_WOW_VDM = 0x00001000,
+ CREATE_FORCEDOS = 0x00002000,
+ BELOW_NORMAL_PRIORITY_CLASS = 0x00004000,
+ ABOVE_NORMAL_PRIORITY_CLASS = 0x00008000,
+ INHERIT_PARENT_AFFINITY = 0x00010000,
+ INHERIT_CALLER_PRIORITY = 0x00020000,
+ CREATE_PROTECTED_PROCESS = 0x00040000,
+ EXTENDED_STARTUPINFO_PRESENT = 0x00080000,
+ PROCESS_MODE_BACKGROUND_BEGIN = 0x00100000,
+ PROCESS_MODE_BACKGROUND_END = 0x00200000,
+ CREATE_BREAKAWAY_FROM_JOB = 0x01000000,
+ CREATE_PRESERVE_CODE_AUTHZ_LEVEL = 0x02000000,
+ CREATE_DEFAULT_ERROR_MODE = 0x04000000,
+ CREATE_NO_WINDOW = 0x08000000,
+ PROFILE_USER = 0x10000000,
+ PROFILE_KERNEL = 0x20000000,
+ PROFILE_SERVER = 0x40000000,
+ CREATE_IGNORE_SYSTEM_DEFAULT = 0x80000000
+ }
+
+ [Flags]
+ public enum LOGON_FLAGS
+ {
+ NONE = 0x00000000,
+ LOGON_WITH_PROFILE = 0x00000001,
+ LOGON_NETCREDENTIALS_ONLY = 0x00000002
+ }
+
+ public enum LOGON_TYPE
+ {
+ LOGON32_LOGON_INTERACTIVE = 2,
+ LOGON32_LOGON_NETWORK,
+ LOGON32_LOGON_BATCH,
+ LOGON32_LOGON_SERVICE,
+ LOGON32_LOGON_UNLOCK = 7,
+ LOGON32_LOGON_NETWORK_CLEARTEXT,
+ LOGON32_LOGON_NEW_CREDENTIALS
+ }
+
+ public enum LOGON_PROVIDER
+ {
+ LOGON32_PROVIDER_DEFAULT,
+ LOGON32_PROVIDER_WINNT35,
+ LOGON32_PROVIDER_WINNT40,
+ LOGON32_PROVIDER_WINNT50
+ }
+
+ [Flags]
+ public enum SCM_ACCESS : uint
+ {
+ SC_MANAGER_CONNECT = 0x00001,
+ SC_MANAGER_CREATE_SERVICE = 0x00002,
+ SC_MANAGER_ENUMERATE_SERVICE = 0x00004,
+ SC_MANAGER_LOCK = 0x00008,
+ SC_MANAGER_QUERY_LOCK_STATUS = 0x00010,
+ SC_MANAGER_MODIFY_BOOT_CONFIG = 0x00020,
+
+ SC_MANAGER_ALL_ACCESS = ACCESS_MASK.STANDARD_RIGHTS_REQUIRED |
+ SC_MANAGER_CONNECT |
+ SC_MANAGER_CREATE_SERVICE |
+ SC_MANAGER_ENUMERATE_SERVICE |
+ SC_MANAGER_LOCK |
+ SC_MANAGER_QUERY_LOCK_STATUS |
+ SC_MANAGER_MODIFY_BOOT_CONFIG,
+
+ GENERIC_READ = ACCESS_MASK.STANDARD_RIGHTS_READ |
+ SC_MANAGER_ENUMERATE_SERVICE |
+ SC_MANAGER_QUERY_LOCK_STATUS,
+
+ GENERIC_WRITE = ACCESS_MASK.STANDARD_RIGHTS_WRITE |
+ SC_MANAGER_CREATE_SERVICE |
+ SC_MANAGER_MODIFY_BOOT_CONFIG,
+
+ GENERIC_EXECUTE = ACCESS_MASK.STANDARD_RIGHTS_EXECUTE |
+ SC_MANAGER_CONNECT | SC_MANAGER_LOCK,
+
+ GENERIC_ALL = SC_MANAGER_ALL_ACCESS,
+ }
+
+ [Flags]
+ public enum ACCESS_MASK : uint
+ {
+ DELETE = 0x00010000,
+ READ_CONTROL = 0x00020000,
+ WRITE_DAC = 0x00040000,
+ WRITE_OWNER = 0x00080000,
+ SYNCHRONIZE = 0x00100000,
+ STANDARD_RIGHTS_REQUIRED = 0x000F0000,
+ STANDARD_RIGHTS_READ = 0x00020000,
+ STANDARD_RIGHTS_WRITE = 0x00020000,
+ STANDARD_RIGHTS_EXECUTE = 0x00020000,
+ STANDARD_RIGHTS_ALL = 0x001F0000,
+ SPECIFIC_RIGHTS_ALL = 0x0000FFFF,
+ ACCESS_SYSTEM_SECURITY = 0x01000000,
+ MAXIMUM_ALLOWED = 0x02000000,
+ GENERIC_READ = 0x80000000,
+ GENERIC_WRITE = 0x40000000,
+ GENERIC_EXECUTE = 0x20000000,
+ GENERIC_ALL = 0x10000000,
+ DESKTOP_READOBJECTS = 0x00000001,
+ DESKTOP_CREATEWINDOW = 0x00000002,
+ DESKTOP_CREATEMENU = 0x00000004,
+ DESKTOP_HOOKCONTROL = 0x00000008,
+ DESKTOP_JOURNALRECORD = 0x00000010,
+ DESKTOP_JOURNALPLAYBACK = 0x00000020,
+ DESKTOP_ENUMERATE = 0x00000040,
+ DESKTOP_WRITEOBJECTS = 0x00000080,
+ DESKTOP_SWITCHDESKTOP = 0x00000100,
+ WINSTA_ENUMDESKTOPS = 0x00000001,
+ WINSTA_READATTRIBUTES = 0x00000002,
+ WINSTA_ACCESSCLIPBOARD = 0x00000004,
+ WINSTA_CREATEDESKTOP = 0x00000008,
+ WINSTA_WRITEATTRIBUTES = 0x00000010,
+ WINSTA_ACCESSGLOBALATOMS = 0x00000020,
+ WINSTA_EXITWINDOWS = 0x00000040,
+ WINSTA_ENUMERATE = 0x00000100,
+ WINSTA_READSCREEN = 0x00000200,
+ WINSTA_ALL_ACCESS = 0x0000037F
+ }
+
+ [Flags]
+ public enum SERVICE_ACCESS : uint
+ {
+ SERVICE_QUERY_CONFIG = 0x00001,
+ SERVICE_CHANGE_CONFIG = 0x00002,
+ SERVICE_QUERY_STATUS = 0x00004,
+ SERVICE_ENUMERATE_DEPENDENTS = 0x00008,
+ SERVICE_START = 0x00010,
+ SERVICE_STOP = 0x00020,
+ SERVICE_PAUSE_CONTINUE = 0x00040,
+ SERVICE_INTERROGATE = 0x00080,
+ SERVICE_USER_DEFINED_CONTROL = 0x00100,
+
+ SERVICE_ALL_ACCESS = (ACCESS_MASK.STANDARD_RIGHTS_REQUIRED |
+ SERVICE_QUERY_CONFIG |
+ SERVICE_CHANGE_CONFIG |
+ SERVICE_QUERY_STATUS |
+ SERVICE_ENUMERATE_DEPENDENTS |
+ SERVICE_START |
+ SERVICE_STOP |
+ SERVICE_PAUSE_CONTINUE |
+ SERVICE_INTERROGATE |
+ SERVICE_USER_DEFINED_CONTROL),
+
+ GENERIC_READ = ACCESS_MASK.STANDARD_RIGHTS_READ |
+ SERVICE_QUERY_CONFIG |
+ SERVICE_QUERY_STATUS |
+ SERVICE_INTERROGATE |
+ SERVICE_ENUMERATE_DEPENDENTS,
+
+ GENERIC_WRITE = ACCESS_MASK.STANDARD_RIGHTS_WRITE |
+ SERVICE_CHANGE_CONFIG,
+
+ GENERIC_EXECUTE = ACCESS_MASK.STANDARD_RIGHTS_EXECUTE |
+ SERVICE_START |
+ SERVICE_STOP |
+ SERVICE_PAUSE_CONTINUE |
+ SERVICE_USER_DEFINED_CONTROL,
+
+ ACCESS_SYSTEM_SECURITY = ACCESS_MASK.ACCESS_SYSTEM_SECURITY,
+ DELETE = ACCESS_MASK.DELETE,
+ READ_CONTROL = ACCESS_MASK.READ_CONTROL,
+ WRITE_DAC = ACCESS_MASK.WRITE_DAC,
+ WRITE_OWNER = ACCESS_MASK.WRITE_OWNER,
+ }
+
+ [Flags]
+ public enum SERVICE_TYPE : uint
+ {
+ SERVICE_KERNEL_DRIVER = 0x00000001,
+ SERVICE_FILE_SYSTEM_DRIVER = 0x00000002,
+ SERVICE_WIN32_OWN_PROCESS = 0x00000010,
+ SERVICE_WIN32_SHARE_PROCESS = 0x00000020,
+ SERVICE_INTERACTIVE_PROCESS = 0x00000100,
+ }
+
+ public enum SERVICE_START : uint
+ {
+ SERVICE_BOOT_START = 0x00000000,
+ SERVICE_SYSTEM_START = 0x00000001,
+ SERVICE_AUTO_START = 0x00000002,
+ SERVICE_DEMAND_START = 0x00000003,
+ SERVICE_DISABLED = 0x00000004,
+ }
+
+ public enum SERVICE_ERROR
+ {
+ SERVICE_ERROR_IGNORE = 0x00000000,
+ SERVICE_ERROR_NORMAL = 0x00000001,
+ SERVICE_ERROR_SEVERE = 0x00000002,
+ SERVICE_ERROR_CRITICAL = 0x00000003,
+ }
+ }
+
+ public static class Dbghelp
+ {
+ public enum MINIDUMP_TYPE
+ {
+ MiniDumpNormal = 0x00000000,
+ MiniDumpWithDataSegs = 0x00000001,
+ MiniDumpWithFullMemory = 0x00000002,
+ MiniDumpWithHandleData = 0x00000004,
+ MiniDumpFilterMemory = 0x00000008,
+ MiniDumpScanMemory = 0x00000010,
+ MiniDumpWithUnloadedModules = 0x00000020,
+ MiniDumpWithIndirectlyReferencedMemory = 0x00000040,
+ MiniDumpFilterModulePaths = 0x00000080,
+ MiniDumpWithProcessThreadData = 0x00000100,
+ MiniDumpWithPrivateReadWriteMemory = 0x00000200,
+ MiniDumpWithoutOptionalData = 0x00000400,
+ MiniDumpWithFullMemoryInfo = 0x00000800,
+ MiniDumpWithThreadInfo = 0x00001000,
+ MiniDumpWithCodeSegs = 0x00002000,
+ MiniDumpWithoutAuxiliaryState = 0x00004000,
+ MiniDumpWithFullAuxiliaryState = 0x00008000,
+ MiniDumpWithPrivateWriteCopyMemory = 0x00010000,
+ MiniDumpIgnoreInaccessibleMemory = 0x00020000,
+ MiniDumpWithTokenInformation = 0x00040000,
+ MiniDumpWithModuleHeaders = 0x00080000,
+ MiniDumpFilterTriage = 0x00100000,
+ MiniDumpValidTypeFlags = 0x001fffff
+ }
+
+ public enum MINIDUMP_CALLBACK_TYPE : uint
+ {
+ ModuleCallback,
+ ThreadCallback,
+ ThreadExCallback,
+ IncludeThreadCallback,
+ IncludeModuleCallback,
+ MemoryCallback,
+ CancelCallback,
+ WriteKernelMinidumpCallback,
+ KernelMinidumpStatusCallback,
+ RemoveMemoryCallback,
+ IncludeVmRegionCallback,
+ IoStartCallback,
+ IoWriteAllCallback,
+ IoFinishCallback,
+ ReadMemoryFailureCallback,
+ SecondaryFlagsCallback,
+ IsProcessSnapshotCallback,
+ VmStartCallback,
+ VmQueryCallback,
+ VmPreReadCallback,
+ }
+
+ public struct MINIDUMP_CALLBACK_INFORMATION
+ {
+ public MINIDUMP_CALLBACK_ROUTINE CallbackRoutine;
+ public IntPtr CallbackParam;
+ }
+
+ [StructLayout(LayoutKind.Explicit, Pack = 4)]
+ public struct MINIDUMP_CALLBACK_OUTPUT
+ {
+ [FieldOffset(0)]
+ public int Status;
+ }
+
+ [StructLayout(LayoutKind.Explicit)]
+ public struct MINIDUMP_CALLBACK_INPUT
+ {
+ [FieldOffset(0)]
+ public uint ProcessId;
+ [FieldOffset(4)]
+ public IntPtr ProcessHandle;
+ [FieldOffset(12)]
+ public MINIDUMP_CALLBACK_TYPE CallbackType;
+ [FieldOffset(16)]
+ public int Status;
+ }
+
+ [UnmanagedFunctionPointer(CallingConvention.StdCall)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public delegate bool MINIDUMP_CALLBACK_ROUTINE(
+ [In] IntPtr CallbackParam,
+ [In] ref MINIDUMP_CALLBACK_INPUT CallbackInput,
+ [In, Out] ref MINIDUMP_CALLBACK_OUTPUT CallbackOutput
+ );
+ }
+
+ public class WinBase
+ {
+ [StructLayout(LayoutKind.Sequential)]
+ public struct _SYSTEM_INFO
+ {
+ public UInt16 wProcessorArchitecture;
+ public UInt16 wReserved;
+ public UInt32 dwPageSize;
+ public IntPtr lpMinimumApplicationAddress;
+ public IntPtr lpMaximumApplicationAddress;
+ public IntPtr dwActiveProcessorMask;
+ public UInt32 dwNumberOfProcessors;
+ public UInt32 dwProcessorType;
+ public UInt32 dwAllocationGranularity;
+ public UInt16 wProcessorLevel;
+ public UInt16 wProcessorRevision;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct _SECURITY_ATTRIBUTES
+ {
+ UInt32 nLength;
+ IntPtr lpSecurityDescriptor;
+ Boolean bInheritHandle;
+ };
+ }
+
+ public class WinNT
+ {
+ public const UInt32 PAGE_NOACCESS = 0x01;
+ public const UInt32 PAGE_READONLY = 0x02;
+ public const UInt32 PAGE_READWRITE = 0x04;
+ public const UInt32 PAGE_WRITECOPY = 0x08;
+ public const UInt32 PAGE_EXECUTE = 0x10;
+ public const UInt32 PAGE_EXECUTE_READ = 0x20;
+ public const UInt32 PAGE_EXECUTE_READWRITE = 0x40;
+ public const UInt32 PAGE_EXECUTE_WRITECOPY = 0x80;
+ public const UInt32 PAGE_GUARD = 0x100;
+ public const UInt32 PAGE_NOCACHE = 0x200;
+ public const UInt32 PAGE_WRITECOMBINE = 0x400;
+ public const UInt32 PAGE_TARGETS_INVALID = 0x40000000;
+ public const UInt32 PAGE_TARGETS_NO_UPDATE = 0x40000000;
+
+ public const UInt32 SEC_COMMIT = 0x08000000;
+ public const UInt32 SEC_IMAGE = 0x1000000;
+ public const UInt32 SEC_IMAGE_NO_EXECUTE = 0x11000000;
+ public const UInt32 SEC_LARGE_PAGES = 0x80000000;
+ public const UInt32 SEC_NOCACHE = 0x10000000;
+ public const UInt32 SEC_RESERVE = 0x4000000;
+ public const UInt32 SEC_WRITECOMBINE = 0x40000000;
+
+ public const UInt32 SE_PRIVILEGE_ENABLED = 0x2;
+ public const UInt32 SE_PRIVILEGE_ENABLED_BY_DEFAULT = 0x1;
+ public const UInt32 SE_PRIVILEGE_REMOVED = 0x4;
+ public const UInt32 SE_PRIVILEGE_USED_FOR_ACCESS = 0x3;
+
+ public const UInt64 SE_GROUP_ENABLED = 0x00000004L;
+ public const UInt64 SE_GROUP_ENABLED_BY_DEFAULT = 0x00000002L;
+ public const UInt64 SE_GROUP_INTEGRITY = 0x00000020L;
+ public const UInt32 SE_GROUP_INTEGRITY_32 = 0x00000020;
+ public const UInt64 SE_GROUP_INTEGRITY_ENABLED = 0x00000040L;
+ public const UInt64 SE_GROUP_LOGON_ID = 0xC0000000L;
+ public const UInt64 SE_GROUP_MANDATORY = 0x00000001L;
+ public const UInt64 SE_GROUP_OWNER = 0x00000008L;
+ public const UInt64 SE_GROUP_RESOURCE = 0x20000000L;
+ public const UInt64 SE_GROUP_USE_FOR_DENY_ONLY = 0x00000010L;
+
+ public enum _SECURITY_IMPERSONATION_LEVEL
+ {
+ SecurityAnonymous,
+ SecurityIdentification,
+ SecurityImpersonation,
+ SecurityDelegation
+ }
+
+ public enum TOKEN_TYPE
+ {
+ TokenPrimary = 1,
+ TokenImpersonation
+ }
+
+ public enum _TOKEN_ELEVATION_TYPE
+ {
+ TokenElevationTypeDefault = 1,
+ TokenElevationTypeFull,
+ TokenElevationTypeLimited
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct _MEMORY_BASIC_INFORMATION32
+ {
+ public UInt32 BaseAddress;
+ public UInt32 AllocationBase;
+ public UInt32 AllocationProtect;
+ public UInt32 RegionSize;
+ public UInt32 State;
+ public UInt32 Protect;
+ public UInt32 Type;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct _MEMORY_BASIC_INFORMATION64
+ {
+ public UInt64 BaseAddress;
+ public UInt64 AllocationBase;
+ public UInt32 AllocationProtect;
+ public UInt32 __alignment1;
+ public UInt64 RegionSize;
+ public UInt32 State;
+ public UInt32 Protect;
+ public UInt32 Type;
+ public UInt32 __alignment2;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct _LUID_AND_ATTRIBUTES
+ {
+ public _LUID Luid;
+ public UInt32 Attributes;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct _LUID
+ {
+ public UInt32 LowPart;
+ public UInt32 HighPart;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct _TOKEN_STATISTICS
+ {
+ public _LUID TokenId;
+ public _LUID AuthenticationId;
+ public UInt64 ExpirationTime;
+ public TOKEN_TYPE TokenType;
+ public _SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
+ public UInt32 DynamicCharged;
+ public UInt32 DynamicAvailable;
+ public UInt32 GroupCount;
+ public UInt32 PrivilegeCount;
+ public _LUID ModifiedId;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct _TOKEN_PRIVILEGES
+ {
+ public UInt32 PrivilegeCount;
+ public _LUID_AND_ATTRIBUTES Privileges;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct _TOKEN_MANDATORY_LABEL
+ {
+ public _SID_AND_ATTRIBUTES Label;
+ }
+
+ public struct _SID
+ {
+ public byte Revision;
+ public byte SubAuthorityCount;
+ public WinNT._SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
+ public ulong[] SubAuthority;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct _SID_IDENTIFIER_AUTHORITY
+ {
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6, ArraySubType = UnmanagedType.I1)]
+ public byte[] Value;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct _SID_AND_ATTRIBUTES
+ {
+ public IntPtr Sid;
+ public UInt32 Attributes;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct _PRIVILEGE_SET
+ {
+ public UInt32 PrivilegeCount;
+ public UInt32 Control;
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
+ public _LUID_AND_ATTRIBUTES[] Privilege;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct _TOKEN_USER
+ {
+ public _SID_AND_ATTRIBUTES User;
+ }
+
+ public enum _SID_NAME_USE
+ {
+ SidTypeUser = 1,
+ SidTypeGroup,
+ SidTypeDomain,
+ SidTypeAlias,
+ SidTypeWellKnownGroup,
+ SidTypeDeletedAccount,
+ SidTypeInvalid,
+ SidTypeUnknown,
+ SidTypeComputer,
+ SidTypeLabel
+ }
+
+ public enum _TOKEN_INFORMATION_CLASS
+ {
+ TokenUser = 1,
+ TokenGroups,
+ TokenPrivileges,
+ TokenOwner,
+ TokenPrimaryGroup,
+ TokenDefaultDacl,
+ TokenSource,
+ TokenType,
+ TokenImpersonationLevel,
+ TokenStatistics,
+ TokenRestrictedSids,
+ TokenSessionId,
+ TokenGroupsAndPrivileges,
+ TokenSessionReference,
+ TokenSandBoxInert,
+ TokenAuditPolicy,
+ TokenOrigin,
+ TokenElevationType,
+ TokenLinkedToken,
+ TokenElevation,
+ TokenHasRestrictions,
+ TokenAccessInformation,
+ TokenVirtualizationAllowed,
+ TokenVirtualizationEnabled,
+ TokenIntegrityLevel,
+ TokenUIAccess,
+ TokenMandatoryPolicy,
+ TokenLogonSid,
+ TokenIsAppContainer,
+ TokenCapabilities,
+ TokenAppContainerSid,
+ TokenAppContainerNumber,
+ TokenUserClaimAttributes,
+ TokenDeviceClaimAttributes,
+ TokenRestrictedUserClaimAttributes,
+ TokenRestrictedDeviceClaimAttributes,
+ TokenDeviceGroups,
+ TokenRestrictedDeviceGroups,
+ TokenSecurityAttributes,
+ TokenIsRestricted,
+ MaxTokenInfoClass
+ }
+
+ // http://www.pinvoke.net/default.aspx/Enums.ACCESS_MASK
+ [Flags]
+ public enum ACCESS_MASK : uint
+ {
+ DELETE = 0x00010000,
+ READ_CONTROL = 0x00020000,
+ WRITE_DAC = 0x00040000,
+ WRITE_OWNER = 0x00080000,
+ SYNCHRONIZE = 0x00100000,
+ STANDARD_RIGHTS_REQUIRED = 0x000F0000,
+ STANDARD_RIGHTS_READ = 0x00020000,
+ STANDARD_RIGHTS_WRITE = 0x00020000,
+ STANDARD_RIGHTS_EXECUTE = 0x00020000,
+ STANDARD_RIGHTS_ALL = 0x001F0000,
+ SPECIFIC_RIGHTS_ALL = 0x0000FFF,
+ ACCESS_SYSTEM_SECURITY = 0x01000000,
+ MAXIMUM_ALLOWED = 0x02000000,
+ GENERIC_READ = 0x80000000,
+ GENERIC_WRITE = 0x40000000,
+ GENERIC_EXECUTE = 0x20000000,
+ GENERIC_ALL = 0x10000000,
+ DESKTOP_READOBJECTS = 0x00000001,
+ DESKTOP_CREATEWINDOW = 0x00000002,
+ DESKTOP_CREATEMENU = 0x00000004,
+ DESKTOP_HOOKCONTROL = 0x00000008,
+ DESKTOP_JOURNALRECORD = 0x00000010,
+ DESKTOP_JOURNALPLAYBACK = 0x00000020,
+ DESKTOP_ENUMERATE = 0x00000040,
+ DESKTOP_WRITEOBJECTS = 0x00000080,
+ DESKTOP_SWITCHDESKTOP = 0x00000100,
+ WINSTA_ENUMDESKTOPS = 0x00000001,
+ WINSTA_READATTRIBUTES = 0x00000002,
+ WINSTA_ACCESSCLIPBOARD = 0x00000004,
+ WINSTA_CREATEDESKTOP = 0x00000008,
+ WINSTA_WRITEATTRIBUTES = 0x00000010,
+ WINSTA_ACCESSGLOBALATOMS = 0x00000020,
+ WINSTA_EXITWINDOWS = 0x00000040,
+ WINSTA_ENUMERATE = 0x00000100,
+ WINSTA_READSCREEN = 0x00000200,
+ WINSTA_ALL_ACCESS = 0x0000037F,
+
+ SECTION_ALL_ACCESS = 0x10000000,
+ SECTION_QUERY = 0x0001,
+ SECTION_MAP_WRITE = 0x0002,
+ SECTION_MAP_READ = 0x0004,
+ SECTION_MAP_EXECUTE = 0x0008,
+ SECTION_EXTEND_SIZE = 0x0010
+ };
+ }
+
+ public class ProcessThreadsAPI
+ {
+ [Flags]
+ internal enum STARTF : uint
+ {
+ STARTF_USESHOWWINDOW = 0x00000001,
+ STARTF_USESIZE = 0x00000002,
+ STARTF_USEPOSITION = 0x00000004,
+ STARTF_USECOUNTCHARS = 0x00000008,
+ STARTF_USEFILLATTRIBUTE = 0x00000010,
+ STARTF_RUNFULLSCREEN = 0x00000020,
+ STARTF_FORCEONFEEDBACK = 0x00000040,
+ STARTF_FORCEOFFFEEDBACK = 0x00000080,
+ STARTF_USESTDHANDLES = 0x00000100,
+ }
+
+ // https://msdn.microsoft.com/en-us/library/windows/desktop/ms686331(v=vs.85).aspx
+ [StructLayout(LayoutKind.Sequential)]
+ public struct _STARTUPINFO
+ {
+ public UInt32 cb;
+ public String lpReserved;
+ public String lpDesktop;
+ public String lpTitle;
+ public UInt32 dwX;
+ public UInt32 dwY;
+ public UInt32 dwXSize;
+ public UInt32 dwYSize;
+ public UInt32 dwXCountChars;
+ public UInt32 dwYCountChars;
+ public UInt32 dwFillAttribute;
+ public UInt32 dwFlags;
+ public UInt16 wShowWindow;
+ public UInt16 cbReserved2;
+ public IntPtr lpReserved2;
+ public IntPtr hStdInput;
+ public IntPtr hStdOutput;
+ public IntPtr hStdError;
+ };
+
+ //https://msdn.microsoft.com/en-us/library/windows/desktop/ms686331(v=vs.85).aspx
+ [StructLayout(LayoutKind.Sequential)]
+ public struct _STARTUPINFOEX
+ {
+ _STARTUPINFO StartupInfo;
+ // PPROC_THREAD_ATTRIBUTE_LIST lpAttributeList;
+ };
+
+ //https://msdn.microsoft.com/en-us/library/windows/desktop/ms684873(v=vs.85).aspx
+ [StructLayout(LayoutKind.Sequential)]
+ public struct _PROCESS_INFORMATION
+ {
+ public IntPtr hProcess;
+ public IntPtr hThread;
+ public UInt32 dwProcessId;
+ public UInt32 dwThreadId;
+ };
+ }
+
+ public class WinCred
+ {
+#pragma warning disable 0618
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
+ public struct _CREDENTIAL
+ {
+ public CRED_FLAGS Flags;
+ public UInt32 Type;
+ public IntPtr TargetName;
+ public IntPtr Comment;
+ public FILETIME LastWritten;
+ public UInt32 CredentialBlobSize;
+ public UInt32 Persist;
+ public UInt32 AttributeCount;
+ public IntPtr Attributes;
+ public IntPtr TargetAlias;
+ public IntPtr UserName;
+ }
+#pragma warning restore 0618
+
+ public enum CRED_FLAGS : uint
+ {
+ NONE = 0x0,
+ PROMPT_NOW = 0x2,
+ USERNAME_TARGET = 0x4
+ }
+
+ public enum CRED_PERSIST : uint
+ {
+ Session = 1,
+ LocalMachine,
+ Enterprise
+ }
+
+ public enum CRED_TYPE : uint
+ {
+ Generic = 1,
+ DomainPassword,
+ DomainCertificate,
+ DomainVisiblePassword,
+ GenericCertificate,
+ DomainExtended,
+ Maximum,
+ MaximumEx = Maximum + 1000,
+ }
+ }
+
+ public class Secur32
+ {
+ public struct _SECURITY_LOGON_SESSION_DATA
+ {
+ public UInt32 Size;
+ public WinNT._LUID LoginID;
+ public _LSA_UNICODE_STRING Username;
+ public _LSA_UNICODE_STRING LoginDomain;
+ public _LSA_UNICODE_STRING AuthenticationPackage;
+ public UInt32 LogonType;
+ public UInt32 Session;
+ public IntPtr pSid;
+ public UInt64 LoginTime;
+ public _LSA_UNICODE_STRING LogonServer;
+ public _LSA_UNICODE_STRING DnsDomainName;
+ public _LSA_UNICODE_STRING Upn;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct _LSA_UNICODE_STRING
+ {
+ public UInt16 Length;
+ public UInt16 MaximumLength;
+ public IntPtr Buffer;
+ }
+ }
+ }
+
+ /////////////////PE
+ ///
+ public class PE
+ {
+ // DllMain constants
+ public const UInt32 DLL_PROCESS_DETACH = 0;
+ public const UInt32 DLL_PROCESS_ATTACH = 1;
+ public const UInt32 DLL_THREAD_ATTACH = 2;
+ public const UInt32 DLL_THREAD_DETACH = 3;
+
+ // Primary class for loading PE
+ [UnmanagedFunctionPointer(CallingConvention.StdCall)]
+ public delegate bool DllMain(IntPtr hinstDLL, uint fdwReason, IntPtr lpvReserved);
+
+ [Flags]
+ public enum DataSectionFlags : uint
+ {
+ TYPE_NO_PAD = 0x00000008,
+ CNT_CODE = 0x00000020,
+ CNT_INITIALIZED_DATA = 0x00000040,
+ CNT_UNINITIALIZED_DATA = 0x00000080,
+ LNK_INFO = 0x00000200,
+ LNK_REMOVE = 0x00000800,
+ LNK_COMDAT = 0x00001000,
+ NO_DEFER_SPEC_EXC = 0x00004000,
+ GPREL = 0x00008000,
+ MEM_FARDATA = 0x00008000,
+ MEM_PURGEABLE = 0x00020000,
+ MEM_16BIT = 0x00020000,
+ MEM_LOCKED = 0x00040000,
+ MEM_PRELOAD = 0x00080000,
+ ALIGN_1BYTES = 0x00100000,
+ ALIGN_2BYTES = 0x00200000,
+ ALIGN_4BYTES = 0x00300000,
+ ALIGN_8BYTES = 0x00400000,
+ ALIGN_16BYTES = 0x00500000,
+ ALIGN_32BYTES = 0x00600000,
+ ALIGN_64BYTES = 0x00700000,
+ ALIGN_128BYTES = 0x00800000,
+ ALIGN_256BYTES = 0x00900000,
+ ALIGN_512BYTES = 0x00A00000,
+ ALIGN_1024BYTES = 0x00B00000,
+ ALIGN_2048BYTES = 0x00C00000,
+ ALIGN_4096BYTES = 0x00D00000,
+ ALIGN_8192BYTES = 0x00E00000,
+ ALIGN_MASK = 0x00F00000,
+ LNK_NRELOC_OVFL = 0x01000000,
+ MEM_DISCARDABLE = 0x02000000,
+ MEM_NOT_CACHED = 0x04000000,
+ MEM_NOT_PAGED = 0x08000000,
+ MEM_SHARED = 0x10000000,
+ MEM_EXECUTE = 0x20000000,
+ MEM_READ = 0x40000000,
+ MEM_WRITE = 0x80000000
+ }
+
+ public struct IMAGE_DOS_HEADER
+ { // DOS .EXE header
+ public UInt16 e_magic; // Magic number
+ public UInt16 e_cblp; // Bytes on last page of file
+ public UInt16 e_cp; // Pages in file
+ public UInt16 e_crlc; // Relocations
+ public UInt16 e_cparhdr; // Size of header in paragraphs
+ public UInt16 e_minalloc; // Minimum extra paragraphs needed
+ public UInt16 e_maxalloc; // Maximum extra paragraphs needed
+ public UInt16 e_ss; // Initial (relative) SS value
+ public UInt16 e_sp; // Initial SP value
+ public UInt16 e_csum; // Checksum
+ public UInt16 e_ip; // Initial IP value
+ public UInt16 e_cs; // Initial (relative) CS value
+ public UInt16 e_lfarlc; // File address of relocation table
+ public UInt16 e_ovno; // Overlay number
+ public UInt16 e_res_0; // Reserved words
+ public UInt16 e_res_1; // Reserved words
+ public UInt16 e_res_2; // Reserved words
+ public UInt16 e_res_3; // Reserved words
+ public UInt16 e_oemid; // OEM identifier (for e_oeminfo)
+ public UInt16 e_oeminfo; // OEM information; e_oemid specific
+ public UInt16 e_res2_0; // Reserved words
+ public UInt16 e_res2_1; // Reserved words
+ public UInt16 e_res2_2; // Reserved words
+ public UInt16 e_res2_3; // Reserved words
+ public UInt16 e_res2_4; // Reserved words
+ public UInt16 e_res2_5; // Reserved words
+ public UInt16 e_res2_6; // Reserved words
+ public UInt16 e_res2_7; // Reserved words
+ public UInt16 e_res2_8; // Reserved words
+ public UInt16 e_res2_9; // Reserved words
+ public UInt32 e_lfanew; // File address of new exe header
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct IMAGE_DATA_DIRECTORY
+ {
+ public UInt32 VirtualAddress;
+ public UInt32 Size;
+ }
+
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ public struct IMAGE_OPTIONAL_HEADER32
+ {
+ public UInt16 Magic;
+ public Byte MajorLinkerVersion;
+ public Byte MinorLinkerVersion;
+ public UInt32 SizeOfCode;
+ public UInt32 SizeOfInitializedData;
+ public UInt32 SizeOfUninitializedData;
+ public UInt32 AddressOfEntryPoint;
+ public UInt32 BaseOfCode;
+ public UInt32 BaseOfData;
+ public UInt32 ImageBase;
+ public UInt32 SectionAlignment;
+ public UInt32 FileAlignment;
+ public UInt16 MajorOperatingSystemVersion;
+ public UInt16 MinorOperatingSystemVersion;
+ public UInt16 MajorImageVersion;
+ public UInt16 MinorImageVersion;
+ public UInt16 MajorSubsystemVersion;
+ public UInt16 MinorSubsystemVersion;
+ public UInt32 Win32VersionValue;
+ public UInt32 SizeOfImage;
+ public UInt32 SizeOfHeaders;
+ public UInt32 CheckSum;
+ public UInt16 Subsystem;
+ public UInt16 DllCharacteristics;
+ public UInt32 SizeOfStackReserve;
+ public UInt32 SizeOfStackCommit;
+ public UInt32 SizeOfHeapReserve;
+ public UInt32 SizeOfHeapCommit;
+ public UInt32 LoaderFlags;
+ public UInt32 NumberOfRvaAndSizes;
+
+ public IMAGE_DATA_DIRECTORY ExportTable;
+ public IMAGE_DATA_DIRECTORY ImportTable;
+ public IMAGE_DATA_DIRECTORY ResourceTable;
+ public IMAGE_DATA_DIRECTORY ExceptionTable;
+ public IMAGE_DATA_DIRECTORY CertificateTable;
+ public IMAGE_DATA_DIRECTORY BaseRelocationTable;
+ public IMAGE_DATA_DIRECTORY Debug;
+ public IMAGE_DATA_DIRECTORY Architecture;
+ public IMAGE_DATA_DIRECTORY GlobalPtr;
+ public IMAGE_DATA_DIRECTORY TLSTable;
+ public IMAGE_DATA_DIRECTORY LoadConfigTable;
+ public IMAGE_DATA_DIRECTORY BoundImport;
+ public IMAGE_DATA_DIRECTORY IAT;
+ public IMAGE_DATA_DIRECTORY DelayImportDescriptor;
+ public IMAGE_DATA_DIRECTORY CLRRuntimeHeader;
+ public IMAGE_DATA_DIRECTORY Reserved;
+ }
+
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ public struct IMAGE_OPTIONAL_HEADER64
+ {
+ public UInt16 Magic;
+ public Byte MajorLinkerVersion;
+ public Byte MinorLinkerVersion;
+ public UInt32 SizeOfCode;
+ public UInt32 SizeOfInitializedData;
+ public UInt32 SizeOfUninitializedData;
+ public UInt32 AddressOfEntryPoint;
+ public UInt32 BaseOfCode;
+ public UInt64 ImageBase;
+ public UInt32 SectionAlignment;
+ public UInt32 FileAlignment;
+ public UInt16 MajorOperatingSystemVersion;
+ public UInt16 MinorOperatingSystemVersion;
+ public UInt16 MajorImageVersion;
+ public UInt16 MinorImageVersion;
+ public UInt16 MajorSubsystemVersion;
+ public UInt16 MinorSubsystemVersion;
+ public UInt32 Win32VersionValue;
+ public UInt32 SizeOfImage;
+ public UInt32 SizeOfHeaders;
+ public UInt32 CheckSum;
+ public UInt16 Subsystem;
+ public UInt16 DllCharacteristics;
+ public UInt64 SizeOfStackReserve;
+ public UInt64 SizeOfStackCommit;
+ public UInt64 SizeOfHeapReserve;
+ public UInt64 SizeOfHeapCommit;
+ public UInt32 LoaderFlags;
+ public UInt32 NumberOfRvaAndSizes;
+
+ public IMAGE_DATA_DIRECTORY ExportTable;
+ public IMAGE_DATA_DIRECTORY ImportTable;
+ public IMAGE_DATA_DIRECTORY ResourceTable;
+ public IMAGE_DATA_DIRECTORY ExceptionTable;
+ public IMAGE_DATA_DIRECTORY CertificateTable;
+ public IMAGE_DATA_DIRECTORY BaseRelocationTable;
+ public IMAGE_DATA_DIRECTORY Debug;
+ public IMAGE_DATA_DIRECTORY Architecture;
+ public IMAGE_DATA_DIRECTORY GlobalPtr;
+ public IMAGE_DATA_DIRECTORY TLSTable;
+ public IMAGE_DATA_DIRECTORY LoadConfigTable;
+ public IMAGE_DATA_DIRECTORY BoundImport;
+ public IMAGE_DATA_DIRECTORY IAT;
+ public IMAGE_DATA_DIRECTORY DelayImportDescriptor;
+ public IMAGE_DATA_DIRECTORY CLRRuntimeHeader;
+ public IMAGE_DATA_DIRECTORY Reserved;
+ }
+
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ public struct IMAGE_FILE_HEADER
+ {
+ public UInt16 Machine;
+ public UInt16 NumberOfSections;
+ public UInt32 TimeDateStamp;
+ public UInt32 PointerToSymbolTable;
+ public UInt32 NumberOfSymbols;
+ public UInt16 SizeOfOptionalHeader;
+ public UInt16 Characteristics;
+ }
+
+ [StructLayout(LayoutKind.Explicit)]
+ public struct IMAGE_SECTION_HEADER
+ {
+ [FieldOffset(0)]
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
+ public char[] Name;
+ [FieldOffset(8)]
+ public UInt32 VirtualSize;
+ [FieldOffset(12)]
+ public UInt32 VirtualAddress;
+ [FieldOffset(16)]
+ public UInt32 SizeOfRawData;
+ [FieldOffset(20)]
+ public UInt32 PointerToRawData;
+ [FieldOffset(24)]
+ public UInt32 PointerToRelocations;
+ [FieldOffset(28)]
+ public UInt32 PointerToLinenumbers;
+ [FieldOffset(32)]
+ public UInt16 NumberOfRelocations;
+ [FieldOffset(34)]
+ public UInt16 NumberOfLinenumbers;
+ [FieldOffset(36)]
+ public DataSectionFlags Characteristics;
+
+ public string Section
+ {
+ get { return new string(Name); }
+ }
+ }
+
+ [StructLayout(LayoutKind.Explicit)]
+ public struct IMAGE_EXPORT_DIRECTORY
+ {
+ [FieldOffset(0)]
+ public UInt32 Characteristics;
+ [FieldOffset(4)]
+ public UInt32 TimeDateStamp;
+ [FieldOffset(8)]
+ public UInt16 MajorVersion;
+ [FieldOffset(10)]
+ public UInt16 MinorVersion;
+ [FieldOffset(12)]
+ public UInt32 Name;
+ [FieldOffset(16)]
+ public UInt32 Base;
+ [FieldOffset(20)]
+ public UInt32 NumberOfFunctions;
+ [FieldOffset(24)]
+ public UInt32 NumberOfNames;
+ [FieldOffset(28)]
+ public UInt32 AddressOfFunctions;
+ [FieldOffset(32)]
+ public UInt32 AddressOfNames;
+ [FieldOffset(36)]
+ public UInt32 AddressOfOrdinals;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct IMAGE_BASE_RELOCATION
+ {
+ public uint VirtualAdress;
+ public uint SizeOfBlock;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct PE_META_DATA
+ {
+ public UInt32 Pe;
+ public Boolean Is32Bit;
+ public IMAGE_FILE_HEADER ImageFileHeader;
+ public IMAGE_OPTIONAL_HEADER32 OptHeader32;
+ public IMAGE_OPTIONAL_HEADER64 OptHeader64;
+ public IMAGE_SECTION_HEADER[] Sections;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct PE_MANUAL_MAP
+ {
+ public String DecoyModule;
+ public IntPtr ModuleBase;
+ public PE_META_DATA PEINFO;
+ }
+
+ [StructLayout(LayoutKind.Explicit)]
+ public struct IMAGE_THUNK_DATA32
+ {
+ [FieldOffset(0)]
+ public UInt32 ForwarderString;
+ [FieldOffset(0)]
+ public UInt32 Function;
+ [FieldOffset(0)]
+ public UInt32 Ordinal;
+ [FieldOffset(0)]
+ public UInt32 AddressOfData;
+ }
+
+ [StructLayout(LayoutKind.Explicit)]
+ public struct IMAGE_THUNK_DATA64
+ {
+ [FieldOffset(0)]
+ public UInt64 ForwarderString;
+ [FieldOffset(0)]
+ public UInt64 Function;
+ [FieldOffset(0)]
+ public UInt64 Ordinal;
+ [FieldOffset(0)]
+ public UInt64 AddressOfData;
+ }
+
+ [StructLayout(LayoutKind.Explicit)]
+ public struct ApiSetNamespace
+ {
+ [FieldOffset(0x0C)]
+ public int Count;
+
+ [FieldOffset(0x10)]
+ public int EntryOffset;
+ }
+
+ [StructLayout(LayoutKind.Explicit, Size = 24)]
+ public struct ApiSetNamespaceEntry
+ {
+ [FieldOffset(0x04)]
+ public int NameOffset;
+
+ [FieldOffset(0x08)]
+ public int NameLength;
+
+ [FieldOffset(0x10)]
+ public int ValueOffset;
+ }
+
+ [StructLayout(LayoutKind.Explicit)]
+ public struct ApiSetValueEntry
+ {
+ [FieldOffset(0x0C)]
+ public int ValueOffset;
+
+ [FieldOffset(0x10)]
+ public int ValueCount;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct LDR_DATA_TABLE_ENTRY
+ {
+ public LIST_ENTRY InLoadOrderLinks;
+ public LIST_ENTRY InMemoryOrderLinks;
+ public LIST_ENTRY InInitializationOrderLinks;
+ public IntPtr DllBase;
+ public IntPtr EntryPoint;
+ public UInt32 SizeOfImage;
+ public UNICODE_STRING FullDllName;
+ public UNICODE_STRING BaseDllName;
+ }
+ }
+
+ /////////////////Native
+ ///
+
+ public static NTSTATUS NtCreateThreadEx(
+ ref IntPtr threadHandle,
+ h_reprobate.Win32.WinNT.ACCESS_MASK desiredAccess,
+ IntPtr objectAttributes,
+ IntPtr processHandle,
+ IntPtr startAddress,
+ IntPtr parameter,
+ bool createSuspended,
+ int stackZeroBits,
+ int sizeOfStack,
+ int maximumStackSize,
+ IntPtr attributeList)
+ {
+ // Craft an array for the arguments
+ object[] funcargs =
+ {
+ threadHandle, desiredAccess, objectAttributes, processHandle, startAddress, parameter, createSuspended, stackZeroBits,
+ sizeOfStack, maximumStackSize, attributeList
+ };
+
+ NTSTATUS retValue = (NTSTATUS)reprobate.DynamicAPIInvoke(@"ntdll.dll", @"NtCreateThreadEx",
+ typeof(DELEGATES.NtCreateThreadEx), ref funcargs);
+
+ // Update the modified variables
+ threadHandle = (IntPtr)funcargs[0];
+
+ return retValue;
+ }
+
+ public static NTSTATUS RtlCreateUserThread(
+ IntPtr Process,
+ IntPtr ThreadSecurityDescriptor,
+ bool CreateSuspended,
+ IntPtr ZeroBits,
+ IntPtr MaximumStackSize,
+ IntPtr CommittedStackSize,
+ IntPtr StartAddress,
+ IntPtr Parameter,
+ ref IntPtr Thread,
+ IntPtr ClientId)
+ {
+ // Craft an array for the arguments
+ object[] funcargs =
+ {
+ Process, ThreadSecurityDescriptor, CreateSuspended, ZeroBits,
+ MaximumStackSize, CommittedStackSize, StartAddress, Parameter,
+ Thread, ClientId
+ };
+
+ NTSTATUS retValue = (NTSTATUS)reprobate.DynamicAPIInvoke(@"ntdll.dll", @"RtlCreateUserThread",
+ typeof(DELEGATES.RtlCreateUserThread), ref funcargs);
+
+ // Update the modified variables
+ Thread = (IntPtr)funcargs[8];
+
+ return retValue;
+ }
+
+ public static NTSTATUS NtCreateSection(
+ ref IntPtr SectionHandle,
+ uint DesiredAccess,
+ IntPtr ObjectAttributes,
+ ref ulong MaximumSize,
+ uint SectionPageProtection,
+ uint AllocationAttributes,
+ IntPtr FileHandle)
+ {
+
+ // Craft an array for the arguments
+ object[] funcargs =
+ {
+ SectionHandle, DesiredAccess, ObjectAttributes, MaximumSize, SectionPageProtection, AllocationAttributes, FileHandle
+ };
+
+ NTSTATUS retValue = (NTSTATUS)reprobate.DynamicAPIInvoke(@"ntdll.dll", @"NtCreateSection", typeof(DELEGATES.NtCreateSection), ref funcargs);
+ if (retValue != NTSTATUS.Success)
+ {
+ throw new InvalidOperationException("Unable to create section, " + retValue);
+ }
+
+ // Update the modified variables
+ SectionHandle = (IntPtr)funcargs[0];
+ MaximumSize = (ulong)funcargs[3];
+
+ return retValue;
+ }
+
+ public static NTSTATUS NtUnmapViewOfSection(IntPtr hProc, IntPtr baseAddr)
+ {
+ // Craft an array for the arguments
+ object[] funcargs =
+ {
+ hProc, baseAddr
+ };
+
+ NTSTATUS result = (NTSTATUS)reprobate.DynamicAPIInvoke(@"ntdll.dll", @"NtUnmapViewOfSection",
+ typeof(DELEGATES.NtUnmapViewOfSection), ref funcargs);
+
+ return result;
+ }
+
+ public static NTSTATUS NtMapViewOfSection(
+ IntPtr SectionHandle,
+ IntPtr ProcessHandle,
+ ref IntPtr BaseAddress,
+ IntPtr ZeroBits,
+ IntPtr CommitSize,
+ IntPtr SectionOffset,
+ ref ulong ViewSize,
+ uint InheritDisposition,
+ uint AllocationType,
+ uint Win32Protect)
+ {
+
+ // Craft an array for the arguments
+ object[] funcargs =
+ {
+ SectionHandle, ProcessHandle, BaseAddress, ZeroBits, CommitSize, SectionOffset, ViewSize, InheritDisposition, AllocationType,
+ Win32Protect
+ };
+
+ NTSTATUS retValue = (NTSTATUS)reprobate.DynamicAPIInvoke(@"ntdll.dll", @"NtMapViewOfSection", typeof(DELEGATES.NtMapViewOfSection), ref funcargs);
+ if (retValue != NTSTATUS.Success && retValue != NTSTATUS.ImageNotAtBase)
+ {
+ throw new InvalidOperationException("Unable to map view of section, " + retValue);
+ }
+
+ // Update the modified variables.
+ BaseAddress = (IntPtr)funcargs[2];
+ ViewSize = (ulong)funcargs[6];
+
+ return retValue;
+ }
+
+ public static void RtlInitUnicodeString(ref UNICODE_STRING DestinationString, [MarshalAs(UnmanagedType.LPWStr)] string SourceString)
+ {
+ // Craft an array for the arguments
+ object[] funcargs =
+ {
+ DestinationString, SourceString
+ };
+
+ reprobate.DynamicAPIInvoke(@"ntdll.dll", @"RtlInitUnicodeString", typeof(DELEGATES.RtlInitUnicodeString), ref funcargs);
+
+ // Update the modified variables
+ DestinationString = (UNICODE_STRING)funcargs[0];
+ }
+
+ public static NTSTATUS LdrLoadDll(IntPtr PathToFile, UInt32 dwFlags, ref UNICODE_STRING ModuleFileName, ref IntPtr ModuleHandle)
+ {
+ // Craft an array for the arguments
+ object[] funcargs =
+ {
+ PathToFile, dwFlags, ModuleFileName, ModuleHandle
+ };
+
+ NTSTATUS retValue = (NTSTATUS)reprobate.DynamicAPIInvoke(@"ntdll.dll", @"LdrLoadDll", typeof(DELEGATES.LdrLoadDll), ref funcargs);
+
+ // Update the modified variables
+ ModuleHandle = (IntPtr)funcargs[3];
+
+ return retValue;
+ }
+
+ public static void RtlZeroMemory(IntPtr Destination, int Length)
+ {
+ // Craft an array for the arguments
+ object[] funcargs =
+ {
+ Destination, Length
+ };
+
+ reprobate.DynamicAPIInvoke(@"ntdll.dll", @"RtlZeroMemory", typeof(DELEGATES.RtlZeroMemory), ref funcargs);
+ }
+
+ public static NTSTATUS NtQueryInformationProcess(IntPtr hProcess, PROCESSINFOCLASS processInfoClass, out IntPtr pProcInfo)
+ {
+ int processInformationLength;
+ UInt32 RetLen = 0;
+
+ switch (processInfoClass)
+ {
+ case PROCESSINFOCLASS.ProcessWow64Information:
+ pProcInfo = Marshal.AllocHGlobal(IntPtr.Size);
+ RtlZeroMemory(pProcInfo, IntPtr.Size);
+ processInformationLength = IntPtr.Size;
+ break;
+ case PROCESSINFOCLASS.ProcessBasicInformation:
+ PROCESS_BASIC_INFORMATION PBI = new PROCESS_BASIC_INFORMATION();
+ pProcInfo = Marshal.AllocHGlobal(Marshal.SizeOf(PBI));
+ RtlZeroMemory(pProcInfo, Marshal.SizeOf(PBI));
+ Marshal.StructureToPtr(PBI, pProcInfo, true);
+ processInformationLength = Marshal.SizeOf(PBI);
+ break;
+ default:
+ throw new InvalidOperationException($"Invalid ProcessInfoClass: {processInfoClass}");
+ }
+
+ object[] funcargs =
+ {
+ hProcess, processInfoClass, pProcInfo, processInformationLength, RetLen
+ };
+
+ NTSTATUS retValue = (NTSTATUS)reprobate.DynamicAPIInvoke(@"ntdll.dll", @"NtQueryInformationProcess", typeof(DELEGATES.NtQueryInformationProcess), ref funcargs);
+ if (retValue != NTSTATUS.Success)
+ {
+ throw new UnauthorizedAccessException("Access is denied.");
+ }
+
+ // Update the modified variables
+ pProcInfo = (IntPtr)funcargs[2];
+
+ return retValue;
+ }
+
+ public static bool NtQueryInformationProcessWow64Information(IntPtr hProcess)
+ {
+ NTSTATUS retValue = NtQueryInformationProcess(hProcess, PROCESSINFOCLASS.ProcessWow64Information, out IntPtr pProcInfo);
+ if (retValue != NTSTATUS.Success)
+ {
+ throw new UnauthorizedAccessException("Access is denied.");
+ }
+
+ if (Marshal.ReadIntPtr(pProcInfo) == IntPtr.Zero)
+ {
+ return false;
+ }
+ return true;
+ }
+
+ public static PROCESS_BASIC_INFORMATION NtQueryInformationProcessBasicInformation(IntPtr hProcess)
+ {
+ NTSTATUS retValue = NtQueryInformationProcess(hProcess, PROCESSINFOCLASS.ProcessBasicInformation, out IntPtr pProcInfo);
+ if (retValue != NTSTATUS.Success)
+ {
+ throw new UnauthorizedAccessException("Access is denied.");
+ }
+
+ return (PROCESS_BASIC_INFORMATION)Marshal.PtrToStructure(pProcInfo, typeof(PROCESS_BASIC_INFORMATION));
+ }
+
+ public static IntPtr NtOpenProcess(UInt32 ProcessId, h_reprobate.Win32.Kernel32.ProcessAccessFlags DesiredAccess)
+ {
+ // Create OBJECT_ATTRIBUTES & CLIENT_ID ref's
+ IntPtr ProcessHandle = IntPtr.Zero;
+ OBJECT_ATTRIBUTES oa = new OBJECT_ATTRIBUTES();
+ CLIENT_ID ci = new CLIENT_ID();
+ ci.UniqueProcess = (IntPtr)ProcessId;
+
+ // Craft an array for the arguments
+ object[] funcargs =
+ {
+ ProcessHandle, DesiredAccess, oa, ci
+ };
+
+ NTSTATUS retValue = (NTSTATUS)reprobate.DynamicAPIInvoke(@"ntdll.dll", @"NtOpenProcess", typeof(DELEGATES.NtOpenProcess), ref funcargs);
+ if (retValue != NTSTATUS.Success && retValue == NTSTATUS.InvalidCid)
+ {
+ throw new InvalidOperationException("An invalid client ID was specified.");
+ }
+ if (retValue != NTSTATUS.Success)
+ {
+ throw new UnauthorizedAccessException("Access is denied.");
+ }
+
+ // Update the modified variables
+ ProcessHandle = (IntPtr)funcargs[0];
+
+ return ProcessHandle;
+ }
+
+ public static void NtQueueApcThread(IntPtr ThreadHandle, IntPtr ApcRoutine, IntPtr ApcArgument1, IntPtr ApcArgument2, IntPtr ApcArgument3)
+ {
+ // Craft an array for the arguments
+ object[] funcargs =
+ {
+ ThreadHandle, ApcRoutine, ApcArgument1, ApcArgument2, ApcArgument3
+ };
+
+ NTSTATUS retValue = (NTSTATUS)reprobate.DynamicAPIInvoke(@"ntdll.dll", @"NtQueueApcThread", typeof(DELEGATES.NtQueueApcThread), ref funcargs);
+ if (retValue != NTSTATUS.Success)
+ {
+ throw new InvalidOperationException("Unable to queue APC, " + retValue);
+ }
+ }
+
+ public static IntPtr NtOpenThread(int TID, h_reprobate.Win32.Kernel32.ThreadAccess DesiredAccess)
+ {
+ // Create OBJECT_ATTRIBUTES & CLIENT_ID ref's
+ IntPtr ThreadHandle = IntPtr.Zero;
+ OBJECT_ATTRIBUTES oa = new OBJECT_ATTRIBUTES();
+ CLIENT_ID ci = new CLIENT_ID();
+ ci.UniqueThread = (IntPtr)TID;
+
+ // Craft an array for the arguments
+ object[] funcargs =
+ {
+ ThreadHandle, DesiredAccess, oa, ci
+ };
+
+ NTSTATUS retValue = (NTSTATUS)reprobate.DynamicAPIInvoke(@"ntdll.dll", @"NtOpenThread", typeof(DELEGATES.NtOpenProcess), ref funcargs);
+ if (retValue != NTSTATUS.Success && retValue == NTSTATUS.InvalidCid)
+ {
+ throw new InvalidOperationException("An invalid client ID was specified.");
+ }
+ if (retValue != NTSTATUS.Success)
+ {
+ throw new UnauthorizedAccessException("Access is denied.");
+ }
+
+ // Update the modified variables
+ ThreadHandle = (IntPtr)funcargs[0];
+
+ return ThreadHandle;
+ }
+
+ public static IntPtr NtAllocateVirtualMemory(IntPtr ProcessHandle, ref IntPtr BaseAddress, IntPtr ZeroBits, ref IntPtr RegionSize, h_reprobate.Win32.Kernel32.AllocationType AllocationType, UInt32 Protect)
+ {
+ // Craft an array for the arguments
+ object[] funcargs =
+ {
+ ProcessHandle, BaseAddress, ZeroBits, RegionSize, AllocationType, Protect
+ };
+
+ NTSTATUS retValue = (NTSTATUS)reprobate.DynamicAPIInvoke(@"ntdll.dll", @"NtAllocateVirtualMemory", typeof(DELEGATES.NtAllocateVirtualMemory), ref funcargs);
+ if (retValue == NTSTATUS.AccessDenied)
+ {
+ // STATUS_ACCESS_DENIED
+ throw new UnauthorizedAccessException("Access is denied.");
+ }
+ if (retValue == NTSTATUS.AlreadyCommitted)
+ {
+ // STATUS_ALREADY_COMMITTED
+ throw new InvalidOperationException("The specified address range is already committed.");
+ }
+ if (retValue == NTSTATUS.CommitmentLimit)
+ {
+ // STATUS_COMMITMENT_LIMIT
+ throw new InvalidOperationException("Your system is low on virtual memory.");
+ }
+ if (retValue == NTSTATUS.ConflictingAddresses)
+ {
+ // STATUS_CONFLICTING_ADDRESSES
+ throw new InvalidOperationException("The specified address range conflicts with the address space.");
+ }
+ if (retValue == NTSTATUS.InsufficientResources)
+ {
+ // STATUS_INSUFFICIENT_RESOURCES
+ throw new InvalidOperationException("Insufficient system resources exist to complete the API call.");
+ }
+ if (retValue == NTSTATUS.InvalidHandle)
+ {
+ // STATUS_INVALID_HANDLE
+ throw new InvalidOperationException("An invalid HANDLE was specified.");
+ }
+ if (retValue == NTSTATUS.InvalidPageProtection)
+ {
+ // STATUS_INVALID_PAGE_PROTECTION
+ throw new InvalidOperationException("The specified page protection was not valid.");
+ }
+ if (retValue == NTSTATUS.NoMemory)
+ {
+ // STATUS_NO_MEMORY
+ throw new InvalidOperationException("Not enough virtual memory or paging file quota is available to complete the specified operation.");
+ }
+ if (retValue == NTSTATUS.ObjectTypeMismatch)
+ {
+ // STATUS_OBJECT_TYPE_MISMATCH
+ throw new InvalidOperationException("There is a mismatch between the type of object that is required by the requested operation and the type of object that is specified in the request.");
+ }
+ if (retValue != NTSTATUS.Success)
+ {
+ // STATUS_PROCESS_IS_TERMINATING == 0xC000010A
+ throw new InvalidOperationException("An attempt was made to duplicate an object handle into or out of an exiting process.");
+ }
+
+ BaseAddress = (IntPtr)funcargs[1];
+ return BaseAddress;
+ }
+
+ public static void NtFreeVirtualMemory(IntPtr ProcessHandle, ref IntPtr BaseAddress, ref IntPtr RegionSize, h_reprobate.Win32.Kernel32.AllocationType FreeType)
+ {
+ // Craft an array for the arguments
+ object[] funcargs =
+ {
+ ProcessHandle, BaseAddress, RegionSize, FreeType
+ };
+
+ NTSTATUS retValue = (NTSTATUS)reprobate.DynamicAPIInvoke(@"ntdll.dll", @"NtFreeVirtualMemory", typeof(DELEGATES.NtFreeVirtualMemory), ref funcargs);
+ if (retValue == NTSTATUS.AccessDenied)
+ {
+ // STATUS_ACCESS_DENIED
+ throw new UnauthorizedAccessException("Access is denied.");
+ }
+ if (retValue == NTSTATUS.InvalidHandle)
+ {
+ // STATUS_INVALID_HANDLE
+ throw new InvalidOperationException("An invalid HANDLE was specified.");
+ }
+ if (retValue != NTSTATUS.Success)
+ {
+ // STATUS_OBJECT_TYPE_MISMATCH == 0xC0000024
+ throw new InvalidOperationException("There is a mismatch between the type of object that is required by the requested operation and the type of object that is specified in the request.");
+ }
+ }
+
+ public static string GetFilenameFromMemoryPointer(IntPtr hProc, IntPtr pMem)
+ {
+ // Alloc buffer for result struct
+ IntPtr pBase = IntPtr.Zero;
+ IntPtr RegionSize = (IntPtr)0x500;
+ IntPtr pAlloc = NtAllocateVirtualMemory(hProc, ref pBase, IntPtr.Zero, ref RegionSize, h_reprobate.Win32.Kernel32.AllocationType.Commit | h_reprobate.Win32.Kernel32.AllocationType.Reserve, h_reprobate.Win32.WinNT.PAGE_READWRITE);
+
+ // Prepare NtQueryVirtualMemory parameters
+ MEMORYINFOCLASS memoryInfoClass = MEMORYINFOCLASS.MemorySectionName;
+ UInt32 MemoryInformationLength = 0x500;
+ UInt32 Retlen = 0;
+
+ // Craft an array for the arguments
+ object[] funcargs =
+ {
+ hProc, pMem, memoryInfoClass, pAlloc, MemoryInformationLength, Retlen
+ };
+
+ NTSTATUS retValue = (NTSTATUS)reprobate.DynamicAPIInvoke(@"ntdll.dll", @"NtQueryVirtualMemory", typeof(DELEGATES.NtQueryVirtualMemory), ref funcargs);
+
+ string FilePath = string.Empty;
+ if (retValue == NTSTATUS.Success)
+ {
+ UNICODE_STRING sn = (UNICODE_STRING)Marshal.PtrToStructure(pAlloc, typeof(UNICODE_STRING));
+ FilePath = Marshal.PtrToStringUni(sn.Buffer);
+ }
+
+ // Free allocation
+ NtFreeVirtualMemory(hProc, ref pAlloc, ref RegionSize, h_reprobate.Win32.Kernel32.AllocationType.Reserve);
+ if (retValue == NTSTATUS.AccessDenied)
+ {
+ // STATUS_ACCESS_DENIED
+ throw new UnauthorizedAccessException("Access is denied.");
+ }
+ if (retValue == NTSTATUS.AccessViolation)
+ {
+ // STATUS_ACCESS_VIOLATION
+ throw new InvalidOperationException("The specified base address is an invalid virtual address.");
+ }
+ if (retValue == NTSTATUS.InfoLengthMismatch)
+ {
+ // STATUS_INFO_LENGTH_MISMATCH
+ throw new InvalidOperationException("The MemoryInformation buffer is larger than MemoryInformationLength.");
+ }
+ if (retValue == NTSTATUS.InvalidParameter)
+ {
+ // STATUS_INVALID_PARAMETER
+ throw new InvalidOperationException("The specified base address is outside the range of accessible addresses.");
+ }
+ return FilePath;
+ }
+
+ public static UInt32 NtProtectVirtualMemory(IntPtr ProcessHandle, ref IntPtr BaseAddress, ref IntPtr RegionSize, UInt32 NewProtect)
+ {
+ // Craft an array for the arguments
+ UInt32 OldProtect = 0;
+ object[] funcargs =
+ {
+ ProcessHandle, BaseAddress, RegionSize, NewProtect, OldProtect
+ };
+
+ NTSTATUS retValue = (NTSTATUS)reprobate.DynamicAPIInvoke(@"ntdll.dll", @"NtProtectVirtualMemory", typeof(DELEGATES.NtProtectVirtualMemory), ref funcargs);
+ if (retValue != NTSTATUS.Success)
+ {
+ throw new InvalidOperationException("Failed to change memory protection, " + retValue);
+ }
+
+ OldProtect = (UInt32)funcargs[4];
+ return OldProtect;
+ }
+
+ public static UInt32 NtWriteVirtualMemory(IntPtr ProcessHandle, IntPtr BaseAddress, IntPtr Buffer, UInt32 BufferLength)
+ {
+ // Craft an array for the arguments
+ UInt32 BytesWritten = 0;
+ object[] funcargs =
+ {
+ ProcessHandle, BaseAddress, Buffer, BufferLength, BytesWritten
+ };
+
+ NTSTATUS retValue = (NTSTATUS)reprobate.DynamicAPIInvoke(@"ntdll.dll", @"NtWriteVirtualMemory", typeof(DELEGATES.NtWriteVirtualMemory), ref funcargs);
+ if (retValue != NTSTATUS.Success)
+ {
+ throw new InvalidOperationException("Failed to write memory, " + retValue);
+ }
+
+ BytesWritten = (UInt32)funcargs[4];
+ return BytesWritten;
+ }
+
+ public static IntPtr LdrGetProcedureAddress(IntPtr hModule, IntPtr FunctionName, IntPtr Ordinal, ref IntPtr FunctionAddress)
+ {
+ // Craft an array for the arguments
+ object[] funcargs =
+ {
+ hModule, FunctionName, Ordinal, FunctionAddress
+ };
+
+ NTSTATUS retValue = (NTSTATUS)reprobate.DynamicAPIInvoke(@"ntdll.dll", @"LdrGetProcedureAddress", typeof(DELEGATES.LdrGetProcedureAddress), ref funcargs);
+ if (retValue != NTSTATUS.Success)
+ {
+ throw new InvalidOperationException("Failed get procedure address, " + retValue);
+ }
+
+ FunctionAddress = (IntPtr)funcargs[3];
+ return FunctionAddress;
+ }
+
+ public static void RtlGetVersion(ref OSVERSIONINFOEX VersionInformation)
+ {
+ // Craft an array for the arguments
+ object[] funcargs =
+ {
+ VersionInformation
+ };
+
+ NTSTATUS retValue = (NTSTATUS)reprobate.DynamicAPIInvoke(@"ntdll.dll", @"RtlGetVersion", typeof(DELEGATES.RtlGetVersion), ref funcargs);
+ if (retValue != NTSTATUS.Success)
+ {
+ throw new InvalidOperationException("Failed get procedure address, " + retValue);
+ }
+
+ VersionInformation = (OSVERSIONINFOEX)funcargs[0];
+ }
+
+ public static UInt32 NtReadVirtualMemory(IntPtr ProcessHandle, IntPtr BaseAddress, IntPtr Buffer, ref UInt32 NumberOfBytesToRead)
+ {
+ // Craft an array for the arguments
+ UInt32 NumberOfBytesRead = 0;
+ object[] funcargs =
+ {
+ ProcessHandle, BaseAddress, Buffer, NumberOfBytesToRead, NumberOfBytesRead
+ };
+
+ NTSTATUS retValue = (NTSTATUS)reprobate.DynamicAPIInvoke(@"ntdll.dll", @"NtReadVirtualMemory", typeof(DELEGATES.NtReadVirtualMemory), ref funcargs);
+ if (retValue != NTSTATUS.Success)
+ {
+ throw new InvalidOperationException("Failed to read memory, " + retValue);
+ }
+
+ NumberOfBytesRead = (UInt32)funcargs[4];
+ return NumberOfBytesRead;
+ }
+
+ public static IntPtr NtOpenFile(ref IntPtr FileHandle, h_reprobate.Win32.Kernel32.FileAccessFlags DesiredAccess, ref OBJECT_ATTRIBUTES ObjAttr, ref IO_STATUS_BLOCK IoStatusBlock, h_reprobate.Win32.Kernel32.FileShareFlags ShareAccess, h_reprobate.Win32.Kernel32.FileOpenFlags OpenOptions)
+ {
+ // Craft an array for the arguments
+ object[] funcargs =
+ {
+ FileHandle, DesiredAccess, ObjAttr, IoStatusBlock, ShareAccess, OpenOptions
+ };
+
+ NTSTATUS retValue = (NTSTATUS)reprobate.DynamicAPIInvoke(@"ntdll.dll", @"NtOpenFile", typeof(DELEGATES.NtOpenFile), ref funcargs);
+ if (retValue != NTSTATUS.Success)
+ {
+ throw new InvalidOperationException("Failed to open file, " + retValue);
+ }
+
+
+ FileHandle = (IntPtr)funcargs[0];
+ return FileHandle;
+ }
+
+ ///
+ /// Holds delegates for API calls in the NT Layer.
+ /// Must be public so that they may be used with SharpSploit.Execution.DynamicInvoke.Generic.DynamicFunctionInvoke
+ ///
+ ///
+ ///
+ /// // These delegates may also be used directly.
+ ///
+ /// // Get a pointer to the NtCreateThreadEx function.
+ /// IntPtr pFunction = Execution.DynamicInvoke.Generic.GetLibraryAddress(@"ntdll.dll", "NtCreateThreadEx");
+ ///
+ /// // Create an instance of a NtCreateThreadEx delegate from our function pointer.
+ /// DELEGATES.NtCreateThreadEx createThread = (NATIVE_DELEGATES.NtCreateThreadEx)Marshal.GetDelegateForFunctionPointer(
+ /// pFunction, typeof(NATIVE_DELEGATES.NtCreateThreadEx));
+ ///
+ /// // Invoke NtCreateThreadEx using the delegate
+ /// createThread(ref threadHandle, h_reprobate.Win32.WinNT.ACCESS_MASK.SPECIFIC_RIGHTS_ALL | h_reprobate.Win32.WinNT.ACCESS_MASK.STANDARD_RIGHTS_ALL, IntPtr.Zero,
+ /// procHandle, startAddress, IntPtr.Zero, NT_CREATION_FLAGS.HIDE_FROM_DEBUGGER, 0, 0, 0, IntPtr.Zero);
+ ///
+ ///
+ public struct DELEGATES
+ {
+ [UnmanagedFunctionPointer(CallingConvention.StdCall)]
+ public delegate NTSTATUS NtCreateThreadEx(
+ out IntPtr threadHandle,
+ h_reprobate.Win32.WinNT.ACCESS_MASK desiredAccess,
+ IntPtr objectAttributes,
+ IntPtr processHandle,
+ IntPtr startAddress,
+ IntPtr parameter,
+ bool createSuspended,
+ int stackZeroBits,
+ int sizeOfStack,
+ int maximumStackSize,
+ IntPtr attributeList);
+
+ [UnmanagedFunctionPointer(CallingConvention.StdCall)]
+ public delegate NTSTATUS RtlCreateUserThread(
+ IntPtr Process,
+ IntPtr ThreadSecurityDescriptor,
+ bool CreateSuspended,
+ IntPtr ZeroBits,
+ IntPtr MaximumStackSize,
+ IntPtr CommittedStackSize,
+ IntPtr StartAddress,
+ IntPtr Parameter,
+ ref IntPtr Thread,
+ IntPtr ClientId);
+
+ [UnmanagedFunctionPointer(CallingConvention.StdCall)]
+ public delegate NTSTATUS NtCreateSection(
+ ref IntPtr SectionHandle,
+ uint DesiredAccess,
+ IntPtr ObjectAttributes,
+ ref ulong MaximumSize,
+ uint SectionPageProtection,
+ uint AllocationAttributes,
+ IntPtr FileHandle);
+
+ [UnmanagedFunctionPointer(CallingConvention.StdCall)]
+ public delegate NTSTATUS NtUnmapViewOfSection(
+ IntPtr hProc,
+ IntPtr baseAddr);
+
+ [UnmanagedFunctionPointer(CallingConvention.StdCall)]
+ public delegate NTSTATUS NtMapViewOfSection(
+ IntPtr SectionHandle,
+ IntPtr ProcessHandle,
+ out IntPtr BaseAddress,
+ IntPtr ZeroBits,
+ IntPtr CommitSize,
+ IntPtr SectionOffset,
+ out ulong ViewSize,
+ uint InheritDisposition,
+ uint AllocationType,
+ uint Win32Protect);
+
+ [UnmanagedFunctionPointer(CallingConvention.StdCall)]
+ public delegate UInt32 LdrLoadDll(
+ IntPtr PathToFile,
+ UInt32 dwFlags,
+ ref UNICODE_STRING ModuleFileName,
+ ref IntPtr ModuleHandle);
+
+ [UnmanagedFunctionPointer(CallingConvention.StdCall)]
+ public delegate void RtlInitUnicodeString(
+ ref UNICODE_STRING DestinationString,
+ [MarshalAs(UnmanagedType.LPWStr)]
+ string SourceString);
+
+ [UnmanagedFunctionPointer(CallingConvention.StdCall)]
+ public delegate void RtlZeroMemory(
+ IntPtr Destination,
+ int length);
+
+ [UnmanagedFunctionPointer(CallingConvention.StdCall)]
+ public delegate UInt32 NtQueryInformationProcess(
+ IntPtr processHandle,
+ PROCESSINFOCLASS processInformationClass,
+ IntPtr processInformation,
+ int processInformationLength,
+ ref UInt32 returnLength);
+
+ [UnmanagedFunctionPointer(CallingConvention.StdCall)]
+ public delegate UInt32 NtOpenProcess(
+ ref IntPtr ProcessHandle,
+ h_reprobate.Win32.Kernel32.ProcessAccessFlags DesiredAccess,
+ ref OBJECT_ATTRIBUTES ObjectAttributes,
+ ref CLIENT_ID ClientId);
+
+ [UnmanagedFunctionPointer(CallingConvention.StdCall)]
+ public delegate UInt32 NtQueueApcThread(
+ IntPtr ThreadHandle,
+ IntPtr ApcRoutine,
+ IntPtr ApcArgument1,
+ IntPtr ApcArgument2,
+ IntPtr ApcArgument3);
+
+ [UnmanagedFunctionPointer(CallingConvention.StdCall)]
+ public delegate UInt32 NtOpenThread(
+ ref IntPtr ThreadHandle,
+ h_reprobate.Win32.Kernel32.ThreadAccess DesiredAccess,
+ ref OBJECT_ATTRIBUTES ObjectAttributes,
+ ref CLIENT_ID ClientId);
+
+ [UnmanagedFunctionPointer(CallingConvention.StdCall)]
+ public delegate UInt32 NtAllocateVirtualMemory(
+ IntPtr ProcessHandle,
+ ref IntPtr BaseAddress,
+ IntPtr ZeroBits,
+ ref IntPtr RegionSize,
+ h_reprobate.Win32.Kernel32.AllocationType AllocationType,
+ UInt32 Protect);
+
+ [UnmanagedFunctionPointer(CallingConvention.StdCall)]
+ public delegate UInt32 NtFreeVirtualMemory(
+ IntPtr ProcessHandle,
+ ref IntPtr BaseAddress,
+ ref IntPtr RegionSize,
+ h_reprobate.Win32.Kernel32.AllocationType FreeType);
+
+ [UnmanagedFunctionPointer(CallingConvention.StdCall)]
+ public delegate UInt32 NtQueryVirtualMemory(
+ IntPtr ProcessHandle,
+ IntPtr BaseAddress,
+ MEMORYINFOCLASS MemoryInformationClass,
+ IntPtr MemoryInformation,
+ UInt32 MemoryInformationLength,
+ ref UInt32 ReturnLength);
+
+ [UnmanagedFunctionPointer(CallingConvention.StdCall)]
+ public delegate UInt32 NtProtectVirtualMemory(
+ IntPtr ProcessHandle,
+ ref IntPtr BaseAddress,
+ ref IntPtr RegionSize,
+ UInt32 NewProtect,
+ ref UInt32 OldProtect);
+
+ [UnmanagedFunctionPointer(CallingConvention.StdCall)]
+ public delegate UInt32 NtWriteVirtualMemory(
+ IntPtr ProcessHandle,
+ IntPtr BaseAddress,
+ IntPtr Buffer,
+ UInt32 BufferLength,
+ ref UInt32 BytesWritten);
+
+ [UnmanagedFunctionPointer(CallingConvention.StdCall)]
+ public delegate UInt32 RtlUnicodeStringToAnsiString(
+ ref ANSI_STRING DestinationString,
+ ref UNICODE_STRING SourceString,
+ bool AllocateDestinationString);
+
+ [UnmanagedFunctionPointer(CallingConvention.StdCall)]
+ public delegate UInt32 LdrGetProcedureAddress(
+ IntPtr hModule,
+ IntPtr FunctionName,
+ IntPtr Ordinal,
+ ref IntPtr FunctionAddress);
+
+ [UnmanagedFunctionPointer(CallingConvention.StdCall)]
+ public delegate UInt32 RtlGetVersion(
+ ref OSVERSIONINFOEX VersionInformation);
+
+ [UnmanagedFunctionPointer(CallingConvention.StdCall)]
+ public delegate UInt32 NtReadVirtualMemory(
+ IntPtr ProcessHandle,
+ IntPtr BaseAddress,
+ IntPtr Buffer,
+ UInt32 NumberOfBytesToRead,
+ ref UInt32 NumberOfBytesRead);
+
+ [UnmanagedFunctionPointer(CallingConvention.StdCall)]
+ public delegate UInt32 NtOpenFile(
+ ref IntPtr FileHandle,
+ h_reprobate.Win32.Kernel32.FileAccessFlags DesiredAccess,
+ ref OBJECT_ATTRIBUTES ObjAttr,
+ ref IO_STATUS_BLOCK IoStatusBlock,
+ h_reprobate.Win32.Kernel32.FileShareFlags ShareAccess,
+ h_reprobate.Win32.Kernel32.FileOpenFlags OpenOptions);
+ }
+ }
+}
diff --git a/Reprobate/reprobate.cs b/Reprobate/reprobate.cs
new file mode 100644
index 0000000..de15dda
--- /dev/null
+++ b/Reprobate/reprobate.cs
@@ -0,0 +1,1445 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Security.Cryptography;
+using System.Security.Cryptography.X509Certificates;
+using System.Text;
+
+namespace YourProjectHere
+{
+ class reprobate
+ {
+ ///
+ /// Dynamically invoke an arbitrary function from a DLL, providing its name, function prototype, and arguments.
+ ///
+ /// The Wover (@TheRealWover)
+ /// Name of the DLL.
+ /// Name of the function.
+ /// Prototype for the function, represented as a Delegate object.
+ /// Parameters to pass to the function. Can be modified if function uses call by reference.
+ /// Object returned by the function. Must be unmarshalled by the caller.
+ public static object DynamicAPIInvoke(string DLLName, string FunctionName, Type FunctionDelegateType, ref object[] Parameters)
+ {
+ IntPtr pFunction = GetLibraryAddress(DLLName, FunctionName);
+ return DynamicFunctionInvoke(pFunction, FunctionDelegateType, ref Parameters);
+ }
+
+ ///
+ /// Dynamically invokes an arbitrary function from a pointer. Useful for manually mapped modules or loading/invoking unmanaged code from memory.
+ ///
+ /// The Wover (@TheRealWover)
+ /// A pointer to the unmanaged function.
+ /// Prototype for the function, represented as a Delegate object.
+ /// Arbitrary set of parameters to pass to the function. Can be modified if function uses call by reference.
+ /// Object returned by the function. Must be unmarshalled by the caller.
+ public static object DynamicFunctionInvoke(IntPtr FunctionPointer, Type FunctionDelegateType, ref object[] Parameters)
+ {
+ Delegate funcDelegate = Marshal.GetDelegateForFunctionPointer(FunctionPointer, FunctionDelegateType);
+ return funcDelegate.DynamicInvoke(Parameters);
+ }
+
+ ///
+ /// Resolves LdrLoadDll and uses that function to load a DLL from disk.
+ ///
+ /// Ruben Boonen (@FuzzySec)
+ /// The path to the DLL on disk. Uses the LoadLibrary convention.
+ /// IntPtr base address of the loaded module or IntPtr.Zero if the module was not loaded successfully.
+ public static IntPtr LoadModuleFromDisk(string DLLPath)
+ {
+ h_reprobate.UNICODE_STRING uModuleName = new h_reprobate.UNICODE_STRING();
+ h_reprobate.RtlInitUnicodeString(ref uModuleName, DLLPath);
+
+ IntPtr hModule = IntPtr.Zero;
+ h_reprobate.NTSTATUS CallResult = h_reprobate.LdrLoadDll(IntPtr.Zero, 0, ref uModuleName, ref hModule);
+ if (CallResult != h_reprobate.NTSTATUS.Success || hModule == IntPtr.Zero)
+ {
+ return IntPtr.Zero;
+ }
+
+ return hModule;
+ }
+
+ ///
+ /// Helper for getting the pointer to a function from a DLL loaded by the process.
+ ///
+ /// Ruben Boonen (@FuzzySec)
+ /// The name of the DLL (e.g. "ntdll.dll" or "C:\Windows\System32\ntdll.dll").
+ /// Name of the exported procedure.
+ /// Optional, indicates if the function can try to load the DLL from disk if it is not found in the loaded module list.
+ /// IntPtr for the desired function.
+ public static IntPtr GetLibraryAddress(string DLLName, string FunctionName, bool CanLoadFromDisk = false)
+ {
+ IntPtr hModule = GetLoadedModuleAddress(DLLName);
+ if (hModule == IntPtr.Zero && CanLoadFromDisk)
+ {
+ hModule = LoadModuleFromDisk(DLLName);
+ if (hModule == IntPtr.Zero)
+ {
+ throw new FileNotFoundException(DLLName + ", unable to find the specified file.");
+ }
+ }
+ else if (hModule == IntPtr.Zero)
+ {
+ throw new DllNotFoundException(DLLName + ", Dll was not found.");
+ }
+
+ return GetExportAddress(hModule, FunctionName);
+ }
+
+ ///
+ /// Helper for getting the pointer to a function from a DLL loaded by the process.
+ ///
+ /// Ruben Boonen (@FuzzySec)
+ /// The name of the DLL (e.g. "ntdll.dll" or "C:\Windows\System32\ntdll.dll").
+ /// Ordinal of the exported procedure.
+ /// Optional, indicates if the function can try to load the DLL from disk if it is not found in the loaded module list.
+ /// IntPtr for the desired function.
+ public static IntPtr GetLibraryAddress(string DLLName, short Ordinal, bool CanLoadFromDisk = false)
+ {
+ IntPtr hModule = GetLoadedModuleAddress(DLLName);
+ if (hModule == IntPtr.Zero && CanLoadFromDisk)
+ {
+ hModule = LoadModuleFromDisk(DLLName);
+ if (hModule == IntPtr.Zero)
+ {
+ throw new FileNotFoundException(DLLName + ", unable to find the specified file.");
+ }
+ }
+ else if (hModule == IntPtr.Zero)
+ {
+ throw new DllNotFoundException(DLLName + ", Dll was not found.");
+ }
+
+ return GetExportAddress(hModule, Ordinal);
+ }
+
+ ///
+ /// Helper for getting the pointer to a function from a DLL loaded by the process.
+ ///
+ /// Ruben Boonen (@FuzzySec)
+ /// The name of the DLL (e.g. "ntdll.dll" or "C:\Windows\System32\ntdll.dll").
+ /// Hash of the exported procedure.
+ /// 64-bit integer to initialize the keyed hash object (e.g. 0xabc or 0x1122334455667788).
+ /// Optional, indicates if the function can try to load the DLL from disk if it is not found in the loaded module list.
+ /// IntPtr for the desired function.
+ public static IntPtr GetLibraryAddress(string DLLName, string FunctionHash, long Key, bool CanLoadFromDisk = false)
+ {
+ IntPtr hModule = GetLoadedModuleAddress(DLLName);
+ if (hModule == IntPtr.Zero && CanLoadFromDisk)
+ {
+ hModule = LoadModuleFromDisk(DLLName);
+ if (hModule == IntPtr.Zero)
+ {
+ throw new FileNotFoundException(DLLName + ", unable to find the specified file.");
+ }
+ }
+ else if (hModule == IntPtr.Zero)
+ {
+ throw new DllNotFoundException(DLLName + ", Dll was not found.");
+ }
+
+ return GetExportAddress(hModule, FunctionHash, Key);
+ }
+
+ ///
+ /// Helper for getting the base address of a module loaded by the current process. This base
+ /// address could be passed to GetProcAddress/LdrGetProcedureAddress or it could be used for
+ /// manual export parsing. This function uses the .NET System.Diagnostics.Process class.
+ ///
+ /// Ruben Boonen (@FuzzySec)
+ /// The name of the DLL (e.g. "ntdll.dll").
+ /// IntPtr base address of the loaded module or IntPtr.Zero if the module is not found.
+ public static IntPtr GetLoadedModuleAddress(string DLLName)
+ {
+ ProcessModuleCollection ProcModules = Process.GetCurrentProcess().Modules;
+ foreach (ProcessModule Mod in ProcModules)
+ {
+ if (Mod.FileName.ToLower().EndsWith(DLLName.ToLower()))
+ {
+ return Mod.BaseAddress;
+ }
+ }
+ return IntPtr.Zero;
+ }
+
+ ///
+ /// Helper for getting the base address of a module loaded by the current process. This base
+ /// address could be passed to GetProcAddress/LdrGetProcedureAddress or it could be used for
+ /// manual export parsing. This function parses the _PEB_LDR_DATA structure.
+ ///
+ /// Ruben Boonen (@FuzzySec)
+ /// The name of the DLL (e.g. "ntdll.dll").
+ /// IntPtr base address of the loaded module or IntPtr.Zero if the module is not found.
+ public static IntPtr GetPebLdrModuleEntry(string DLLName)
+ {
+ // Get _PEB pointer
+ h_reprobate.PROCESS_BASIC_INFORMATION pbi = h_reprobate.NtQueryInformationProcessBasicInformation((IntPtr)(-1));
+
+ // Set function variables
+ bool Is32Bit = false;
+ UInt32 LdrDataOffset = 0;
+ UInt32 InLoadOrderModuleListOffset = 0;
+ if (IntPtr.Size == 4)
+ {
+ Is32Bit = true;
+ LdrDataOffset = 0xc;
+ InLoadOrderModuleListOffset = 0xC;
+ }
+ else
+ {
+ LdrDataOffset = 0x18;
+ InLoadOrderModuleListOffset = 0x10;
+ }
+
+ // Get module InLoadOrderModuleList -> _LIST_ENTRY
+ IntPtr PEB_LDR_DATA = Marshal.ReadIntPtr((IntPtr)((UInt64)pbi.PebBaseAddress + LdrDataOffset));
+ IntPtr pInLoadOrderModuleList = (IntPtr)((UInt64)PEB_LDR_DATA + InLoadOrderModuleListOffset);
+ h_reprobate.LIST_ENTRY le = (h_reprobate.LIST_ENTRY)Marshal.PtrToStructure(pInLoadOrderModuleList, typeof(h_reprobate.LIST_ENTRY));
+
+ // Loop entries
+ IntPtr flink = le.Flink;
+ IntPtr hModule = IntPtr.Zero;
+ h_reprobate.PE.LDR_DATA_TABLE_ENTRY dte = (h_reprobate.PE.LDR_DATA_TABLE_ENTRY)Marshal.PtrToStructure(flink, typeof(h_reprobate.PE.LDR_DATA_TABLE_ENTRY));
+ while (dte.InLoadOrderLinks.Flink != le.Blink)
+ {
+ // Match module name
+ if (Marshal.PtrToStringUni(dte.FullDllName.Buffer).EndsWith(DLLName, StringComparison.OrdinalIgnoreCase))
+ {
+ hModule = dte.DllBase;
+ }
+
+ // Move Ptr
+ flink = dte.InLoadOrderLinks.Flink;
+ dte = (h_reprobate.PE.LDR_DATA_TABLE_ENTRY)Marshal.PtrToStructure(flink, typeof(h_reprobate.PE.LDR_DATA_TABLE_ENTRY));
+ }
+
+ return hModule;
+ }
+
+ ///
+ /// Generate an HMAC-MD5 hash of the supplied string using an Int64 as the key. This is useful for unique hash based API lookups.
+ ///
+ /// Ruben Boonen (@FuzzySec)
+ /// API name to hash.
+ /// 64-bit integer to initialize the keyed hash object (e.g. 0xabc or 0x1122334455667788).
+ /// string, the computed MD5 hash value.
+ public static string GetAPIHash(string APIName, long Key)
+ {
+ byte[] data = Encoding.UTF8.GetBytes(APIName.ToLower());
+ byte[] kbytes = BitConverter.GetBytes(Key);
+
+ using (HMACMD5 hmac = new HMACMD5(kbytes))
+ {
+ byte[] bHash = hmac.ComputeHash(data);
+ return BitConverter.ToString(bHash).Replace("-", "");
+ }
+ }
+
+ ///
+ /// Given a module base address, resolve the address of a function by manually walking the module export table.
+ ///
+ /// Ruben Boonen (@FuzzySec)
+ /// A pointer to the base address where the module is loaded in the current process.
+ /// The name of the export to search for (e.g. "NtAlertResumeThread").
+ /// IntPtr for the desired function.
+ public static IntPtr GetExportAddress(IntPtr ModuleBase, string ExportName)
+ {
+ IntPtr FunctionPtr = IntPtr.Zero;
+ try
+ {
+ // Traverse the PE header in memory
+ Int32 PeHeader = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + 0x3C));
+ Int16 OptHeaderSize = Marshal.ReadInt16((IntPtr)(ModuleBase.ToInt64() + PeHeader + 0x14));
+ Int64 OptHeader = ModuleBase.ToInt64() + PeHeader + 0x18;
+ Int16 Magic = Marshal.ReadInt16((IntPtr)OptHeader);
+ Int64 pExport = 0;
+ if (Magic == 0x010b)
+ {
+ pExport = OptHeader + 0x60;
+ }
+ else
+ {
+ pExport = OptHeader + 0x70;
+ }
+
+ // Read -> IMAGE_EXPORT_DIRECTORY
+ Int32 ExportRVA = Marshal.ReadInt32((IntPtr)pExport);
+ Int32 OrdinalBase = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x10));
+ Int32 NumberOfFunctions = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x14));
+ Int32 NumberOfNames = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x18));
+ Int32 FunctionsRVA = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x1C));
+ Int32 NamesRVA = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x20));
+ Int32 OrdinalsRVA = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x24));
+
+ // Loop the array of export name RVA's
+ for (int i = 0; i < NumberOfNames; i++)
+ {
+ string FunctionName = Marshal.PtrToStringAnsi((IntPtr)(ModuleBase.ToInt64() + Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + NamesRVA + i * 4))));
+ if (FunctionName.Equals(ExportName, StringComparison.OrdinalIgnoreCase))
+ {
+ Int32 FunctionOrdinal = Marshal.ReadInt16((IntPtr)(ModuleBase.ToInt64() + OrdinalsRVA + i * 2)) + OrdinalBase;
+ Int32 FunctionRVA = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + FunctionsRVA + (4 * (FunctionOrdinal - OrdinalBase))));
+ FunctionPtr = (IntPtr)((Int64)ModuleBase + FunctionRVA);
+ break;
+ }
+ }
+ }
+ catch
+ {
+ // Catch parser failure
+ throw new InvalidOperationException("Failed to parse module exports.");
+ }
+
+ if (FunctionPtr == IntPtr.Zero)
+ {
+ // Export not found
+ throw new MissingMethodException(ExportName + ", export not found.");
+ }
+ return FunctionPtr;
+ }
+
+ ///
+ /// Given a module base address, resolve the address of a function by manually walking the module export table.
+ ///
+ /// Ruben Boonen (@FuzzySec)
+ /// A pointer to the base address where the module is loaded in the current process.
+ /// The ordinal number to search for (e.g. 0x136 -> ntdll!NtCreateThreadEx).
+ /// IntPtr for the desired function.
+ public static IntPtr GetExportAddress(IntPtr ModuleBase, short Ordinal)
+ {
+ IntPtr FunctionPtr = IntPtr.Zero;
+ try
+ {
+ // Traverse the PE header in memory
+ Int32 PeHeader = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + 0x3C));
+ Int16 OptHeaderSize = Marshal.ReadInt16((IntPtr)(ModuleBase.ToInt64() + PeHeader + 0x14));
+ Int64 OptHeader = ModuleBase.ToInt64() + PeHeader + 0x18;
+ Int16 Magic = Marshal.ReadInt16((IntPtr)OptHeader);
+ Int64 pExport = 0;
+ if (Magic == 0x010b)
+ {
+ pExport = OptHeader + 0x60;
+ }
+ else
+ {
+ pExport = OptHeader + 0x70;
+ }
+
+ // Read -> IMAGE_EXPORT_DIRECTORY
+ Int32 ExportRVA = Marshal.ReadInt32((IntPtr)pExport);
+ Int32 OrdinalBase = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x10));
+ Int32 NumberOfFunctions = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x14));
+ Int32 NumberOfNames = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x18));
+ Int32 FunctionsRVA = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x1C));
+ Int32 NamesRVA = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x20));
+ Int32 OrdinalsRVA = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x24));
+
+ // Loop the array of export name RVA's
+ for (int i = 0; i < NumberOfNames; i++)
+ {
+ Int32 FunctionOrdinal = Marshal.ReadInt16((IntPtr)(ModuleBase.ToInt64() + OrdinalsRVA + i * 2)) + OrdinalBase;
+ if (FunctionOrdinal == Ordinal)
+ {
+ Int32 FunctionRVA = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + FunctionsRVA + (4 * (FunctionOrdinal - OrdinalBase))));
+ FunctionPtr = (IntPtr)((Int64)ModuleBase + FunctionRVA);
+ break;
+ }
+ }
+ }
+ catch
+ {
+ // Catch parser failure
+ throw new InvalidOperationException("Failed to parse module exports.");
+ }
+
+ if (FunctionPtr == IntPtr.Zero)
+ {
+ // Export not found
+ throw new MissingMethodException(Ordinal + ", ordinal not found.");
+ }
+ return FunctionPtr;
+ }
+
+ ///
+ /// Given a module base address, resolve the address of a function by manually walking the module export table.
+ ///
+ /// Ruben Boonen (@FuzzySec)
+ /// A pointer to the base address where the module is loaded in the current process.
+ /// Hash of the exported procedure.
+ /// 64-bit integer to initialize the keyed hash object (e.g. 0xabc or 0x1122334455667788).
+ /// IntPtr for the desired function.
+ public static IntPtr GetExportAddress(IntPtr ModuleBase, string FunctionHash, long Key)
+ {
+ IntPtr FunctionPtr = IntPtr.Zero;
+ try
+ {
+ // Traverse the PE header in memory
+ Int32 PeHeader = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + 0x3C));
+ Int16 OptHeaderSize = Marshal.ReadInt16((IntPtr)(ModuleBase.ToInt64() + PeHeader + 0x14));
+ Int64 OptHeader = ModuleBase.ToInt64() + PeHeader + 0x18;
+ Int16 Magic = Marshal.ReadInt16((IntPtr)OptHeader);
+ Int64 pExport = 0;
+ if (Magic == 0x010b)
+ {
+ pExport = OptHeader + 0x60;
+ }
+ else
+ {
+ pExport = OptHeader + 0x70;
+ }
+
+ // Read -> IMAGE_EXPORT_DIRECTORY
+ Int32 ExportRVA = Marshal.ReadInt32((IntPtr)pExport);
+ Int32 OrdinalBase = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x10));
+ Int32 NumberOfFunctions = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x14));
+ Int32 NumberOfNames = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x18));
+ Int32 FunctionsRVA = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x1C));
+ Int32 NamesRVA = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x20));
+ Int32 OrdinalsRVA = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + ExportRVA + 0x24));
+
+ // Loop the array of export name RVA's
+ for (int i = 0; i < NumberOfNames; i++)
+ {
+ string FunctionName = Marshal.PtrToStringAnsi((IntPtr)(ModuleBase.ToInt64() + Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + NamesRVA + i * 4))));
+ if (GetAPIHash(FunctionName, Key).Equals(FunctionHash, StringComparison.OrdinalIgnoreCase))
+ {
+ Int32 FunctionOrdinal = Marshal.ReadInt16((IntPtr)(ModuleBase.ToInt64() + OrdinalsRVA + i * 2)) + OrdinalBase;
+ Int32 FunctionRVA = Marshal.ReadInt32((IntPtr)(ModuleBase.ToInt64() + FunctionsRVA + (4 * (FunctionOrdinal - OrdinalBase))));
+ FunctionPtr = (IntPtr)((Int64)ModuleBase + FunctionRVA);
+ break;
+ }
+ }
+ }
+ catch
+ {
+ // Catch parser failure
+ throw new InvalidOperationException("Failed to parse module exports.");
+ }
+
+ if (FunctionPtr == IntPtr.Zero)
+ {
+ // Export not found
+ throw new MissingMethodException(FunctionHash + ", export hash not found.");
+ }
+ return FunctionPtr;
+ }
+
+ ///
+ /// Given a module base address, resolve the address of a function by calling LdrGetProcedureAddress.
+ ///
+ /// Ruben Boonen (@FuzzySec)
+ /// A pointer to the base address where the module is loaded in the current process.
+ /// The name of the export to search for (e.g. "NtAlertResumeThread").
+ /// IntPtr for the desired function.
+ public static IntPtr GetNativeExportAddress(IntPtr ModuleBase, string ExportName)
+ {
+ h_reprobate.ANSI_STRING aFunc = new h_reprobate.ANSI_STRING
+ {
+ Length = (ushort)ExportName.Length,
+ MaximumLength = (ushort)(ExportName.Length + 2),
+ Buffer = Marshal.StringToCoTaskMemAnsi(ExportName)
+ };
+
+ IntPtr pAFunc = Marshal.AllocHGlobal(Marshal.SizeOf(aFunc));
+ Marshal.StructureToPtr(aFunc, pAFunc, true);
+
+ IntPtr pFuncAddr = IntPtr.Zero;
+ h_reprobate.LdrGetProcedureAddress(ModuleBase, pAFunc, IntPtr.Zero, ref pFuncAddr);
+
+ Marshal.FreeHGlobal(pAFunc);
+
+ return pFuncAddr;
+ }
+
+ ///
+ /// Given a module base address, resolve the address of a function by calling LdrGetProcedureAddress.
+ ///
+ /// Ruben Boonen (@FuzzySec)
+ /// A pointer to the base address where the module is loaded in the current process.
+ /// The ordinal number to search for (e.g. 0x136 -> ntdll!NtCreateThreadEx).
+ /// IntPtr for the desired function.
+ public static IntPtr GetNativeExportAddress(IntPtr ModuleBase, short Ordinal)
+ {
+ IntPtr pFuncAddr = IntPtr.Zero;
+ IntPtr pOrd = (IntPtr)Ordinal;
+
+ h_reprobate.LdrGetProcedureAddress(ModuleBase, IntPtr.Zero, pOrd, ref pFuncAddr);
+
+ return pFuncAddr;
+ }
+
+ ///
+ /// Retrieve PE header information from the module base pointer.
+ ///
+ /// Ruben Boonen (@FuzzySec)
+ /// Pointer to the module base.
+ /// h_reprobate.PE.PE_META_DATA
+ public static h_reprobate.PE.PE_META_DATA GetPeMetaData(IntPtr pModule)
+ {
+ h_reprobate.PE.PE_META_DATA PeMetaData = new h_reprobate.PE.PE_META_DATA();
+ try
+ {
+ UInt32 e_lfanew = (UInt32)Marshal.ReadInt32((IntPtr)((UInt64)pModule + 0x3c));
+ PeMetaData.Pe = (UInt32)Marshal.ReadInt32((IntPtr)((UInt64)pModule + e_lfanew));
+ // Validate PE signature
+ if (PeMetaData.Pe != 0x4550)
+ {
+ throw new InvalidOperationException("Invalid PE signature.");
+ }
+ PeMetaData.ImageFileHeader = (h_reprobate.PE.IMAGE_FILE_HEADER)Marshal.PtrToStructure((IntPtr)((UInt64)pModule + e_lfanew + 0x4), typeof(h_reprobate.PE.IMAGE_FILE_HEADER));
+ IntPtr OptHeader = (IntPtr)((UInt64)pModule + e_lfanew + 0x18);
+ UInt16 PEArch = (UInt16)Marshal.ReadInt16(OptHeader);
+ // Validate PE arch
+ if (PEArch == 0x010b) // Image is x32
+ {
+ PeMetaData.Is32Bit = true;
+ PeMetaData.OptHeader32 = (h_reprobate.PE.IMAGE_OPTIONAL_HEADER32)Marshal.PtrToStructure(OptHeader, typeof(h_reprobate.PE.IMAGE_OPTIONAL_HEADER32));
+ }
+ else if (PEArch == 0x020b) // Image is x64
+ {
+ PeMetaData.Is32Bit = false;
+ PeMetaData.OptHeader64 = (h_reprobate.PE.IMAGE_OPTIONAL_HEADER64)Marshal.PtrToStructure(OptHeader, typeof(h_reprobate.PE.IMAGE_OPTIONAL_HEADER64));
+ }
+ else
+ {
+ throw new InvalidOperationException("Invalid magic value (PE32/PE32+).");
+ }
+ // Read sections
+ h_reprobate.PE.IMAGE_SECTION_HEADER[] SectionArray = new h_reprobate.PE.IMAGE_SECTION_HEADER[PeMetaData.ImageFileHeader.NumberOfSections];
+ for (int i = 0; i < PeMetaData.ImageFileHeader.NumberOfSections; i++)
+ {
+ IntPtr SectionPtr = (IntPtr)((UInt64)OptHeader + PeMetaData.ImageFileHeader.SizeOfOptionalHeader + (UInt32)(i * 0x28));
+ SectionArray[i] = (h_reprobate.PE.IMAGE_SECTION_HEADER)Marshal.PtrToStructure(SectionPtr, typeof(h_reprobate.PE.IMAGE_SECTION_HEADER));
+ }
+ PeMetaData.Sections = SectionArray;
+ }
+ catch
+ {
+ throw new InvalidOperationException("Invalid module base specified.");
+ }
+ return PeMetaData;
+ }
+
+ ///
+ /// Resolve host DLL for API Set DLL.
+ ///
+ /// Ruben Boonen (@FuzzySec)
+ /// Dictionary, a combination of Key:APISetDLL and Val:HostDLL.
+ public static Dictionary GetApiSetMapping()
+ {
+ h_reprobate.PROCESS_BASIC_INFORMATION pbi = h_reprobate.NtQueryInformationProcessBasicInformation((IntPtr)(-1));
+ UInt32 ApiSetMapOffset = IntPtr.Size == 4 ? (UInt32)0x38 : 0x68;
+
+ // Create mapping dictionary
+ Dictionary ApiSetDict = new Dictionary();
+
+ IntPtr pApiSetNamespace = Marshal.ReadIntPtr((IntPtr)((UInt64)pbi.PebBaseAddress + ApiSetMapOffset));
+ h_reprobate.PE.ApiSetNamespace Namespace = (h_reprobate.PE.ApiSetNamespace)Marshal.PtrToStructure(pApiSetNamespace, typeof(h_reprobate.PE.ApiSetNamespace));
+ for (var i = 0; i < Namespace.Count; i++)
+ {
+ h_reprobate.PE.ApiSetNamespaceEntry SetEntry = new h_reprobate.PE.ApiSetNamespaceEntry();
+ SetEntry = (h_reprobate.PE.ApiSetNamespaceEntry)Marshal.PtrToStructure((IntPtr)((UInt64)pApiSetNamespace + (UInt64)Namespace.EntryOffset + (UInt64)(i * Marshal.SizeOf(SetEntry))), typeof(h_reprobate.PE.ApiSetNamespaceEntry));
+ string ApiSetEntryName = Marshal.PtrToStringUni((IntPtr)((UInt64)pApiSetNamespace + (UInt64)SetEntry.NameOffset), SetEntry.NameLength / 2) + ".dll";
+
+ h_reprobate.PE.ApiSetValueEntry SetValue = new h_reprobate.PE.ApiSetValueEntry();
+ SetValue = (h_reprobate.PE.ApiSetValueEntry)Marshal.PtrToStructure((IntPtr)((UInt64)pApiSetNamespace + (UInt64)SetEntry.ValueOffset), typeof(h_reprobate.PE.ApiSetValueEntry));
+ string ApiSetValue = string.Empty;
+ if (SetValue.ValueCount != 0)
+ {
+ ApiSetValue = Marshal.PtrToStringUni((IntPtr)((UInt64)pApiSetNamespace + (UInt64)SetValue.ValueOffset), SetValue.ValueCount / 2);
+ }
+
+ // Add pair to dict
+ ApiSetDict.Add(ApiSetEntryName, ApiSetValue);
+ }
+
+ // Return dict
+ return ApiSetDict;
+ }
+
+ ///
+ /// Call a manually mapped PE by its EntryPoint.
+ ///
+ /// Ruben Boonen (@FuzzySec)
+ /// Module meta data struct (h_reprobate.PE.PE_META_DATA).
+ /// Base address of the module in memory.
+ /// void
+ public static void CallMappedPEModule(h_reprobate.PE.PE_META_DATA PEINFO, IntPtr ModuleMemoryBase)
+ {
+ // Call module by EntryPoint (eg Mimikatz.exe)
+ IntPtr hRemoteThread = IntPtr.Zero;
+ IntPtr lpStartAddress = PEINFO.Is32Bit ? (IntPtr)((UInt64)ModuleMemoryBase + PEINFO.OptHeader32.AddressOfEntryPoint) :
+ (IntPtr)((UInt64)ModuleMemoryBase + PEINFO.OptHeader64.AddressOfEntryPoint);
+
+ h_reprobate.NtCreateThreadEx(
+ ref hRemoteThread,
+ h_reprobate.Win32.WinNT.ACCESS_MASK.STANDARD_RIGHTS_ALL,
+ IntPtr.Zero, (IntPtr)(-1),
+ lpStartAddress, IntPtr.Zero,
+ false, 0, 0, 0, IntPtr.Zero
+ );
+ }
+
+ ///
+ /// Call a manually mapped DLL by DllMain -> DLL_PROCESS_ATTACH.
+ ///
+ /// Ruben Boonen (@FuzzySec)
+ /// Module meta data struct (h_reprobate.PE.PE_META_DATA).
+ /// Base address of the module in memory.
+ /// void
+ public static void CallMappedDLLModule(h_reprobate.PE.PE_META_DATA PEINFO, IntPtr ModuleMemoryBase)
+ {
+ IntPtr lpEntryPoint = PEINFO.Is32Bit ? (IntPtr)((UInt64)ModuleMemoryBase + PEINFO.OptHeader32.AddressOfEntryPoint) :
+ (IntPtr)((UInt64)ModuleMemoryBase + PEINFO.OptHeader64.AddressOfEntryPoint);
+
+ h_reprobate.PE.DllMain fDllMain = (h_reprobate.PE.DllMain)Marshal.GetDelegateForFunctionPointer(lpEntryPoint, typeof(h_reprobate.PE.DllMain));
+ bool CallRes = fDllMain(ModuleMemoryBase, h_reprobate.PE.DLL_PROCESS_ATTACH, IntPtr.Zero);
+ if (!CallRes)
+ {
+ throw new InvalidOperationException("Failed to call DllMain -> DLL_PROCESS_ATTACH");
+ }
+ }
+
+ ///
+ /// Call a manually mapped DLL by Export.
+ ///
+ /// Ruben Boonen (@FuzzySec)
+ /// Module meta data struct (h_reprobate.PE.PE_META_DATA).
+ /// Base address of the module in memory.
+ /// The name of the export to search for (e.g. "NtAlertResumeThread").
+ /// Prototype for the function, represented as a Delegate object.
+ /// Arbitrary set of parameters to pass to the function. Can be modified if function uses call by reference.
+ /// Specify whether to invoke the module's entry point.
+ /// void
+ public static object CallMappedDLLModuleExport(h_reprobate.PE.PE_META_DATA PEINFO, IntPtr ModuleMemoryBase, string ExportName, Type FunctionDelegateType, object[] Parameters, bool CallEntry = true)
+ {
+ // Call entry point if user has specified
+ if (CallEntry)
+ {
+ CallMappedDLLModule(PEINFO, ModuleMemoryBase);
+ }
+
+ // Get export pointer
+ IntPtr pFunc = GetExportAddress(ModuleMemoryBase, ExportName);
+
+ // Call export
+ return DynamicFunctionInvoke(pFunc, FunctionDelegateType, ref Parameters);
+ }
+
+ ///
+ /// Read ntdll from disk, find/copy the appropriate syscall stub and free ntdll.
+ ///
+ /// Ruben Boonen (@FuzzySec)
+ /// The name of the function to search for (e.g. "NtAlertResumeThread").
+ /// IntPtr, Syscall stub
+ public static IntPtr GetSyscallStub(string FunctionName)
+ {
+ // Verify process & architecture
+ bool isWOW64 = h_reprobate.NtQueryInformationProcessWow64Information((IntPtr)(-1));
+ if (IntPtr.Size == 4 && isWOW64)
+ {
+ throw new InvalidOperationException("Generating Syscall stubs is not supported for WOW64.");
+ }
+
+ // Find the path for ntdll by looking at the currently loaded module
+ string NtdllPath = string.Empty;
+ ProcessModuleCollection ProcModules = Process.GetCurrentProcess().Modules;
+ foreach (ProcessModule Mod in ProcModules)
+ {
+ if (Mod.FileName.EndsWith("ntdll.dll", StringComparison.OrdinalIgnoreCase))
+ {
+ NtdllPath = Mod.FileName;
+ }
+ }
+
+ // Alloc module into memory for parsing
+ IntPtr pModule = AllocateFileToMemory(NtdllPath);
+
+ // Fetch PE meta data
+ h_reprobate.PE.PE_META_DATA PEINFO = GetPeMetaData(pModule);
+
+ // Alloc PE image memory -> RW
+ IntPtr BaseAddress = IntPtr.Zero;
+ IntPtr RegionSize = PEINFO.Is32Bit ? (IntPtr)PEINFO.OptHeader32.SizeOfImage : (IntPtr)PEINFO.OptHeader64.SizeOfImage;
+ UInt32 SizeOfHeaders = PEINFO.Is32Bit ? PEINFO.OptHeader32.SizeOfHeaders : PEINFO.OptHeader64.SizeOfHeaders;
+
+ IntPtr pImage = h_reprobate.NtAllocateVirtualMemory(
+ (IntPtr)(-1), ref BaseAddress, IntPtr.Zero, ref RegionSize,
+ h_reprobate.Win32.Kernel32.AllocationType.Commit | h_reprobate.Win32.Kernel32.AllocationType.Reserve,
+ h_reprobate.Win32.WinNT.PAGE_READWRITE
+ );
+
+ // Write PE header to memory
+ UInt32 BytesWritten = h_reprobate.NtWriteVirtualMemory((IntPtr)(-1), pImage, pModule, SizeOfHeaders);
+
+ // Write sections to memory
+ foreach (h_reprobate.PE.IMAGE_SECTION_HEADER ish in PEINFO.Sections)
+ {
+ // Calculate offsets
+ IntPtr pVirtualSectionBase = (IntPtr)((UInt64)pImage + ish.VirtualAddress);
+ IntPtr pRawSectionBase = (IntPtr)((UInt64)pModule + ish.PointerToRawData);
+
+ // Write data
+ BytesWritten = h_reprobate.NtWriteVirtualMemory((IntPtr)(-1), pVirtualSectionBase, pRawSectionBase, ish.SizeOfRawData);
+ if (BytesWritten != ish.SizeOfRawData)
+ {
+ throw new InvalidOperationException("Failed to write to memory.");
+ }
+ }
+
+ // Get Ptr to function
+ IntPtr pFunc = GetExportAddress(pImage, FunctionName);
+ if (pFunc == IntPtr.Zero)
+ {
+ throw new InvalidOperationException("Failed to resolve ntdll export.");
+ }
+
+ // Alloc memory for call stub
+ BaseAddress = IntPtr.Zero;
+ RegionSize = (IntPtr)0x50;
+ IntPtr pCallStub = h_reprobate.NtAllocateVirtualMemory(
+ (IntPtr)(-1), ref BaseAddress, IntPtr.Zero, ref RegionSize,
+ h_reprobate.Win32.Kernel32.AllocationType.Commit | h_reprobate.Win32.Kernel32.AllocationType.Reserve,
+ h_reprobate.Win32.WinNT.PAGE_READWRITE
+ );
+
+ // Write call stub
+ BytesWritten = h_reprobate.NtWriteVirtualMemory((IntPtr)(-1), pCallStub, pFunc, 0x50);
+ if (BytesWritten != 0x50)
+ {
+ throw new InvalidOperationException("Failed to write to memory.");
+ }
+
+ // Change call stub permissions
+ h_reprobate.NtProtectVirtualMemory((IntPtr)(-1), ref pCallStub, ref RegionSize, h_reprobate.Win32.WinNT.PAGE_EXECUTE_READ);
+
+ // Free temporary allocations
+ Marshal.FreeHGlobal(pModule);
+ RegionSize = PEINFO.Is32Bit ? (IntPtr)PEINFO.OptHeader32.SizeOfImage : (IntPtr)PEINFO.OptHeader64.SizeOfImage;
+
+ h_reprobate.NtFreeVirtualMemory((IntPtr)(-1), ref pImage, ref RegionSize, h_reprobate.Win32.Kernel32.AllocationType.Reserve);
+
+ return pCallStub;
+ }
+
+ ///
+ /// Maps a DLL from disk into a Section using NtCreateSection.
+ ///
+ /// The Wover (@TheRealWover), Ruben Boonen (@FuzzySec)
+ /// Full path fo the DLL on disk.
+ /// h_reprobate.PE.PE_MANUAL_MAP
+ public static h_reprobate.PE.PE_MANUAL_MAP MapModuleFromDisk(string DLLPath)
+ {
+ // Check file exists
+ if (!File.Exists(DLLPath))
+ {
+ throw new InvalidOperationException("Filepath not found.");
+ }
+
+ // Open file handle
+ h_reprobate.UNICODE_STRING ObjectName = new h_reprobate.UNICODE_STRING();
+ h_reprobate.RtlInitUnicodeString(ref ObjectName, (@"\??\" + DLLPath));
+ IntPtr pObjectName = Marshal.AllocHGlobal(Marshal.SizeOf(ObjectName));
+ Marshal.StructureToPtr(ObjectName, pObjectName, true);
+
+ h_reprobate.OBJECT_ATTRIBUTES objectAttributes = new h_reprobate.OBJECT_ATTRIBUTES();
+ objectAttributes.Length = Marshal.SizeOf(objectAttributes);
+ objectAttributes.ObjectName = pObjectName;
+ objectAttributes.Attributes = 0x40; // OBJ_CASE_INSENSITIVE
+
+ h_reprobate.IO_STATUS_BLOCK ioStatusBlock = new h_reprobate.IO_STATUS_BLOCK();
+
+ IntPtr hFile = IntPtr.Zero;
+ h_reprobate.NtOpenFile(
+ ref hFile,
+ h_reprobate.Win32.Kernel32.FileAccessFlags.FILE_READ_DATA |
+ h_reprobate.Win32.Kernel32.FileAccessFlags.FILE_EXECUTE |
+ h_reprobate.Win32.Kernel32.FileAccessFlags.FILE_READ_ATTRIBUTES |
+ h_reprobate.Win32.Kernel32.FileAccessFlags.SYNCHRONIZE,
+ ref objectAttributes, ref ioStatusBlock,
+ h_reprobate.Win32.Kernel32.FileShareFlags.FILE_SHARE_READ |
+ h_reprobate.Win32.Kernel32.FileShareFlags.FILE_SHARE_DELETE,
+ h_reprobate.Win32.Kernel32.FileOpenFlags.FILE_SYNCHRONOUS_IO_NONALERT |
+ h_reprobate.Win32.Kernel32.FileOpenFlags.FILE_NON_DIRECTORY_FILE
+ );
+
+ // Create section from hFile
+ IntPtr hSection = IntPtr.Zero;
+ ulong MaxSize = 0;
+ h_reprobate.NTSTATUS ret = h_reprobate.NtCreateSection(
+ ref hSection,
+ (UInt32)h_reprobate.Win32.WinNT.ACCESS_MASK.SECTION_ALL_ACCESS,
+ IntPtr.Zero,
+ ref MaxSize,
+ h_reprobate.Win32.WinNT.PAGE_READONLY,
+ h_reprobate.Win32.WinNT.SEC_IMAGE,
+ hFile
+ );
+
+ // Map view of file
+ IntPtr pBaseAddress = IntPtr.Zero;
+ h_reprobate.NtMapViewOfSection(
+ hSection, (IntPtr)(-1), ref pBaseAddress,
+ IntPtr.Zero, IntPtr.Zero, IntPtr.Zero,
+ ref MaxSize, 0x2, 0x0,
+ h_reprobate.Win32.WinNT.PAGE_READWRITE
+ );
+
+ // Prepare return object
+ h_reprobate.PE.PE_MANUAL_MAP SecMapObject = new h_reprobate.PE.PE_MANUAL_MAP
+ {
+ PEINFO = GetPeMetaData(pBaseAddress),
+ ModuleBase = pBaseAddress
+ };
+
+ return SecMapObject;
+ }
+
+ ///
+ /// Allocate file to memory from disk
+ ///
+ /// Ruben Boonen (@FuzzySec)
+ /// Full path to the file to be alloacted.
+ /// IntPtr base address of the allocated file.
+ public static IntPtr AllocateFileToMemory(string FilePath)
+ {
+ if (!File.Exists(FilePath))
+ {
+ throw new InvalidOperationException("Filepath not found.");
+ }
+
+ byte[] bFile = File.ReadAllBytes(FilePath);
+ return AllocateBytesToMemory(bFile);
+ }
+
+ ///
+ /// Allocate a byte array to memory
+ ///
+ /// Ruben Boonen (@FuzzySec)
+ /// Byte array to be allocated.
+ /// IntPtr base address of the allocated file.
+ public static IntPtr AllocateBytesToMemory(byte[] FileByteArray)
+ {
+ IntPtr pFile = Marshal.AllocHGlobal(FileByteArray.Length);
+ Marshal.Copy(FileByteArray, 0, pFile, FileByteArray.Length);
+ return pFile;
+ }
+
+ ///
+ /// Relocates a module in memory.
+ ///
+ /// Ruben Boonen (@FuzzySec)
+ /// Module meta data struct (h_reprobate.PE.PE_META_DATA).
+ /// Base address of the module in memory.
+ /// void
+ public static void RelocateModule(h_reprobate.PE.PE_META_DATA PEINFO, IntPtr ModuleMemoryBase)
+ {
+ h_reprobate.PE.IMAGE_DATA_DIRECTORY idd = PEINFO.Is32Bit ? PEINFO.OptHeader32.BaseRelocationTable : PEINFO.OptHeader64.BaseRelocationTable;
+ Int64 ImageDelta = PEINFO.Is32Bit ? (Int64)((UInt64)ModuleMemoryBase - PEINFO.OptHeader32.ImageBase) :
+ (Int64)((UInt64)ModuleMemoryBase - PEINFO.OptHeader64.ImageBase);
+
+ // Ptr for the base reloc table
+ IntPtr pRelocTable = (IntPtr)((UInt64)ModuleMemoryBase + idd.VirtualAddress);
+ Int32 nextRelocTableBlock = -1;
+ // Loop reloc blocks
+ while (nextRelocTableBlock != 0)
+ {
+ h_reprobate.PE.IMAGE_BASE_RELOCATION ibr = new h_reprobate.PE.IMAGE_BASE_RELOCATION();
+ ibr = (h_reprobate.PE.IMAGE_BASE_RELOCATION)Marshal.PtrToStructure(pRelocTable, typeof(h_reprobate.PE.IMAGE_BASE_RELOCATION));
+
+ Int64 RelocCount = ((ibr.SizeOfBlock - Marshal.SizeOf(ibr)) / 2);
+ for (int i = 0; i < RelocCount; i++)
+ {
+ // Calculate reloc entry ptr
+ IntPtr pRelocEntry = (IntPtr)((UInt64)pRelocTable + (UInt64)Marshal.SizeOf(ibr) + (UInt64)(i * 2));
+ UInt16 RelocValue = (UInt16)Marshal.ReadInt16(pRelocEntry);
+
+ // Parse reloc value
+ // The type should only ever be 0x0, 0x3, 0xA
+ // https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#base-relocation-types
+ UInt16 RelocType = (UInt16)(RelocValue >> 12);
+ UInt16 RelocPatch = (UInt16)(RelocValue & 0xfff);
+
+ // Perform relocation
+ if (RelocType != 0) // IMAGE_REL_BASED_ABSOLUTE (0 -> skip reloc)
+ {
+ try
+ {
+ IntPtr pPatch = (IntPtr)((UInt64)ModuleMemoryBase + ibr.VirtualAdress + RelocPatch);
+ if (RelocType == 0x3) // IMAGE_REL_BASED_HIGHLOW (x86)
+ {
+ Int32 OriginalPtr = Marshal.ReadInt32(pPatch);
+ Marshal.WriteInt32(pPatch, (OriginalPtr + (Int32)ImageDelta));
+ }
+ else // IMAGE_REL_BASED_DIR64 (x64)
+ {
+ Int64 OriginalPtr = Marshal.ReadInt64(pPatch);
+ Marshal.WriteInt64(pPatch, (OriginalPtr + ImageDelta));
+ }
+ }
+ catch
+ {
+ throw new InvalidOperationException("Memory access violation.");
+ }
+ }
+ }
+
+ // Check for next block
+ pRelocTable = (IntPtr)((UInt64)pRelocTable + ibr.SizeOfBlock);
+ nextRelocTableBlock = Marshal.ReadInt32(pRelocTable);
+ }
+ }
+
+ ///
+ /// Rewrite IAT for manually mapped module.
+ ///
+ /// Ruben Boonen (@FuzzySec)
+ /// Module meta data struct (h_reprobate.PE.PE_META_DATA).
+ /// Base address of the module in memory.
+ /// void
+ public static void RewriteModuleIAT(h_reprobate.PE.PE_META_DATA PEINFO, IntPtr ModuleMemoryBase)
+ {
+ h_reprobate.PE.IMAGE_DATA_DIRECTORY idd = PEINFO.Is32Bit ? PEINFO.OptHeader32.ImportTable : PEINFO.OptHeader64.ImportTable;
+
+ // Check if there is no import table
+ if (idd.VirtualAddress == 0)
+ {
+ // Return so that the rest of the module mapping process may continue.
+ return;
+ }
+
+ // Ptr for the base import directory
+ IntPtr pImportTable = (IntPtr)((UInt64)ModuleMemoryBase + idd.VirtualAddress);
+
+ // Get API Set mapping dictionary if on Win10+
+ h_reprobate.OSVERSIONINFOEX OSVersion = new h_reprobate.OSVERSIONINFOEX();
+ h_reprobate.RtlGetVersion(ref OSVersion);
+ Dictionary ApiSetDict = new Dictionary();
+ if (OSVersion.MajorVersion >= 10)
+ {
+ ApiSetDict = GetApiSetMapping();
+ }
+
+ // Loop IID's
+ int counter = 0;
+ h_reprobate.Win32.Kernel32.IMAGE_IMPORT_DESCRIPTOR iid = new h_reprobate.Win32.Kernel32.IMAGE_IMPORT_DESCRIPTOR();
+ iid = (h_reprobate.Win32.Kernel32.IMAGE_IMPORT_DESCRIPTOR)Marshal.PtrToStructure(
+ (IntPtr)((UInt64)pImportTable + (uint)(Marshal.SizeOf(iid) * counter)),
+ typeof(h_reprobate.Win32.Kernel32.IMAGE_IMPORT_DESCRIPTOR)
+ );
+ while (iid.Name != 0)
+ {
+ // Get DLL
+ string DllName = string.Empty;
+ try
+ {
+ DllName = Marshal.PtrToStringAnsi((IntPtr)((UInt64)ModuleMemoryBase + iid.Name));
+ }
+ catch { }
+
+ // Loop imports
+ if (DllName == string.Empty)
+ {
+ throw new InvalidOperationException("Failed to read DLL name.");
+ }
+ else
+ {
+ // API Set DLL?
+ if (OSVersion.MajorVersion >= 10 && (DllName.StartsWith("api-") || DllName.StartsWith("ext-")) &&
+ ApiSetDict.ContainsKey(DllName) && ApiSetDict[DllName].Length > 0)
+ {
+ // Not all API set DLL's have a registered host mapping
+ DllName = ApiSetDict[DllName];
+ }
+
+ // Check and / or load DLL
+ IntPtr hModule = GetLoadedModuleAddress(DllName);
+ if (hModule == IntPtr.Zero)
+ {
+ hModule = LoadModuleFromDisk(DllName);
+ if (hModule == IntPtr.Zero)
+ {
+ throw new FileNotFoundException(DllName + ", unable to find the specified file.");
+ }
+ }
+
+ // Loop thunks
+ if (PEINFO.Is32Bit)
+ {
+ h_reprobate.PE.IMAGE_THUNK_DATA32 oft_itd = new h_reprobate.PE.IMAGE_THUNK_DATA32();
+ for (int i = 0; true; i++)
+ {
+ oft_itd = (h_reprobate.PE.IMAGE_THUNK_DATA32)Marshal.PtrToStructure((IntPtr)((UInt64)ModuleMemoryBase + iid.OriginalFirstThunk + (UInt32)(i * (sizeof(UInt32)))), typeof(h_reprobate.PE.IMAGE_THUNK_DATA32));
+ IntPtr ft_itd = (IntPtr)((UInt64)ModuleMemoryBase + iid.FirstThunk + (UInt64)(i * (sizeof(UInt32))));
+ if (oft_itd.AddressOfData == 0)
+ {
+ break;
+ }
+
+ if (oft_itd.AddressOfData < 0x80000000) // !IMAGE_ORDINAL_FLAG32
+ {
+ IntPtr pImpByName = (IntPtr)((UInt64)ModuleMemoryBase + oft_itd.AddressOfData + sizeof(UInt16));
+ IntPtr pFunc = IntPtr.Zero;
+ pFunc = GetNativeExportAddress(hModule, Marshal.PtrToStringAnsi(pImpByName));
+
+ // Write ProcAddress
+ Marshal.WriteInt32(ft_itd, pFunc.ToInt32());
+ }
+ else
+ {
+ ulong fOrdinal = oft_itd.AddressOfData & 0xFFFF;
+ IntPtr pFunc = IntPtr.Zero;
+ pFunc = GetNativeExportAddress(hModule, (short)fOrdinal);
+
+ // Write ProcAddress
+ Marshal.WriteInt32(ft_itd, pFunc.ToInt32());
+ }
+ }
+ }
+ else
+ {
+ h_reprobate.PE.IMAGE_THUNK_DATA64 oft_itd = new h_reprobate.PE.IMAGE_THUNK_DATA64();
+ for (int i = 0; true; i++)
+ {
+ oft_itd = (h_reprobate.PE.IMAGE_THUNK_DATA64)Marshal.PtrToStructure((IntPtr)((UInt64)ModuleMemoryBase + iid.OriginalFirstThunk + (UInt64)(i * (sizeof(UInt64)))), typeof(h_reprobate.PE.IMAGE_THUNK_DATA64));
+ IntPtr ft_itd = (IntPtr)((UInt64)ModuleMemoryBase + iid.FirstThunk + (UInt64)(i * (sizeof(UInt64))));
+ if (oft_itd.AddressOfData == 0)
+ {
+ break;
+ }
+
+ if (oft_itd.AddressOfData < 0x8000000000000000) // !IMAGE_ORDINAL_FLAG64
+ {
+ IntPtr pImpByName = (IntPtr)((UInt64)ModuleMemoryBase + oft_itd.AddressOfData + sizeof(UInt16));
+ IntPtr pFunc = IntPtr.Zero;
+ pFunc = GetNativeExportAddress(hModule, Marshal.PtrToStringAnsi(pImpByName));
+
+ // Write pointer
+ Marshal.WriteInt64(ft_itd, pFunc.ToInt64());
+ }
+ else
+ {
+ ulong fOrdinal = oft_itd.AddressOfData & 0xFFFF;
+ IntPtr pFunc = IntPtr.Zero;
+ pFunc = GetNativeExportAddress(hModule, (short)fOrdinal);
+
+ // Write pointer
+ Marshal.WriteInt64(ft_itd, pFunc.ToInt64());
+ }
+ }
+ }
+ counter++;
+ iid = (h_reprobate.Win32.Kernel32.IMAGE_IMPORT_DESCRIPTOR)Marshal.PtrToStructure(
+ (IntPtr)((UInt64)pImportTable + (uint)(Marshal.SizeOf(iid) * counter)),
+ typeof(h_reprobate.Win32.Kernel32.IMAGE_IMPORT_DESCRIPTOR)
+ );
+ }
+ }
+ }
+
+ ///
+ /// Set correct module section permissions.
+ ///
+ /// Ruben Boonen (@FuzzySec)
+ /// Module meta data struct (h_reprobate.PE.PE_META_DATA).
+ /// Base address of the module in memory.
+ /// void
+ public static void SetModuleSectionPermissions(h_reprobate.PE.PE_META_DATA PEINFO, IntPtr ModuleMemoryBase)
+ {
+ // Apply RO to the module header
+ IntPtr BaseOfCode = PEINFO.Is32Bit ? (IntPtr)PEINFO.OptHeader32.BaseOfCode : (IntPtr)PEINFO.OptHeader64.BaseOfCode;
+ h_reprobate.NtProtectVirtualMemory((IntPtr)(-1), ref ModuleMemoryBase, ref BaseOfCode, h_reprobate.Win32.WinNT.PAGE_READONLY);
+
+ // Apply section permissions
+ foreach (h_reprobate.PE.IMAGE_SECTION_HEADER ish in PEINFO.Sections)
+ {
+ bool isRead = (ish.Characteristics & h_reprobate.PE.DataSectionFlags.MEM_READ) != 0;
+ bool isWrite = (ish.Characteristics & h_reprobate.PE.DataSectionFlags.MEM_WRITE) != 0;
+ bool isExecute = (ish.Characteristics & h_reprobate.PE.DataSectionFlags.MEM_EXECUTE) != 0;
+ uint flNewProtect = 0;
+ if (isRead & !isWrite & !isExecute)
+ {
+ flNewProtect = h_reprobate.Win32.WinNT.PAGE_READONLY;
+ }
+ else if (isRead & isWrite & !isExecute)
+ {
+ flNewProtect = h_reprobate.Win32.WinNT.PAGE_READWRITE;
+ }
+ else if (isRead & isWrite & isExecute)
+ {
+ flNewProtect = h_reprobate.Win32.WinNT.PAGE_EXECUTE_READWRITE;
+ }
+ else if (isRead & !isWrite & isExecute)
+ {
+ flNewProtect = h_reprobate.Win32.WinNT.PAGE_EXECUTE_READ;
+ }
+ else if (!isRead & !isWrite & isExecute)
+ {
+ flNewProtect = h_reprobate.Win32.WinNT.PAGE_EXECUTE;
+ }
+ else
+ {
+ throw new InvalidOperationException("Unknown section flag, " + ish.Characteristics);
+ }
+
+ // Calculate base
+ IntPtr pVirtualSectionBase = (IntPtr)((UInt64)ModuleMemoryBase + ish.VirtualAddress);
+ IntPtr ProtectSize = (IntPtr)ish.VirtualSize;
+
+ // Set protection
+ h_reprobate.NtProtectVirtualMemory((IntPtr)(-1), ref pVirtualSectionBase, ref ProtectSize, flNewProtect);
+ }
+ }
+
+ ///
+ /// Manually map module into current process.
+ ///
+ /// Ruben Boonen (@FuzzySec)
+ /// Full path to the module on disk.
+ /// PE_MANUAL_MAP object
+ public static h_reprobate.PE.PE_MANUAL_MAP MapModuleToMemory(string ModulePath)
+ {
+ // Verify process & architecture
+ bool isWOW64 = h_reprobate.NtQueryInformationProcessWow64Information((IntPtr)(-1));
+ if (IntPtr.Size == 4 && isWOW64)
+ {
+ throw new InvalidOperationException("Manual mapping in WOW64 is not supported.");
+ }
+
+ // Alloc module into memory for parsing
+ IntPtr pModule = AllocateFileToMemory(ModulePath);
+ return MapModuleToMemory(pModule);
+ }
+
+ ///
+ /// Manually map module into current process.
+ ///
+ /// Ruben Boonen (@FuzzySec)
+ /// Full byte array of the module.
+ /// PE_MANUAL_MAP object
+ public static h_reprobate.PE.PE_MANUAL_MAP MapModuleToMemory(byte[] Module)
+ {
+ // Verify process & architecture
+ bool isWOW64 = h_reprobate.NtQueryInformationProcessWow64Information((IntPtr)(-1));
+ if (IntPtr.Size == 4 && isWOW64)
+ {
+ throw new InvalidOperationException("Manual mapping in WOW64 is not supported.");
+ }
+
+ // Alloc module into memory for parsing
+ IntPtr pModule = AllocateBytesToMemory(Module);
+ return MapModuleToMemory(pModule);
+ }
+
+ ///
+ /// Manually map module into current process starting at the specified base address.
+ ///
+ /// The Wover (@TheRealWover), Ruben Boonen (@FuzzySec)
+ /// Full byte array of the module.
+ /// Address in memory to map module to.
+ /// PE_MANUAL_MAP object
+ public static h_reprobate.PE.PE_MANUAL_MAP MapModuleToMemory(byte[] Module, IntPtr pImage)
+ {
+ // Verify process & architecture
+ Boolean isWOW64 = h_reprobate.NtQueryInformationProcessWow64Information((IntPtr)(-1));
+ if (IntPtr.Size == 4 && isWOW64)
+ {
+ throw new InvalidOperationException("Manual mapping in WOW64 is not supported.");
+ }
+
+ // Alloc module into memory for parsing
+ IntPtr pModule = AllocateBytesToMemory(Module);
+
+ return MapModuleToMemory(pModule, pImage);
+ }
+
+ ///
+ /// Manually map module into current process.
+ ///
+ /// Ruben Boonen (@FuzzySec)
+ /// Pointer to the module base.
+ /// PE_MANUAL_MAP object
+ public static h_reprobate.PE.PE_MANUAL_MAP MapModuleToMemory(IntPtr pModule)
+ {
+ // Fetch PE meta data
+ h_reprobate.PE.PE_META_DATA PEINFO = GetPeMetaData(pModule);
+
+ // Check module matches the process architecture
+ if ((PEINFO.Is32Bit && IntPtr.Size == 8) || (!PEINFO.Is32Bit && IntPtr.Size == 4))
+ {
+ Marshal.FreeHGlobal(pModule);
+ throw new InvalidOperationException("The module architecture does not match the process architecture.");
+ }
+
+ // Alloc PE image memory -> RW
+ IntPtr BaseAddress = IntPtr.Zero;
+ IntPtr RegionSize = PEINFO.Is32Bit ? (IntPtr)PEINFO.OptHeader32.SizeOfImage : (IntPtr)PEINFO.OptHeader64.SizeOfImage;
+ IntPtr pImage = h_reprobate.NtAllocateVirtualMemory(
+ (IntPtr)(-1), ref BaseAddress, IntPtr.Zero, ref RegionSize,
+ h_reprobate.Win32.Kernel32.AllocationType.Commit | h_reprobate.Win32.Kernel32.AllocationType.Reserve,
+ h_reprobate.Win32.WinNT.PAGE_READWRITE
+ );
+ return MapModuleToMemory(pModule, pImage, PEINFO);
+ }
+
+ ///
+ /// Manually map module into current process.
+ ///
+ /// Ruben Boonen (@FuzzySec)
+ /// Pointer to the module base.
+ /// Pointer to the PEINFO image.
+ /// PE_MANUAL_MAP object
+ public static h_reprobate.PE.PE_MANUAL_MAP MapModuleToMemory(IntPtr pModule, IntPtr pImage)
+ {
+ h_reprobate.PE.PE_META_DATA PEINFO = GetPeMetaData(pModule);
+ return MapModuleToMemory(pModule, pImage, PEINFO);
+ }
+
+ ///
+ /// Manually map module into current process.
+ ///
+ /// Ruben Boonen (@FuzzySec)
+ /// Pointer to the module base.
+ /// Pointer to the PEINFO image.
+ /// PE_META_DATA of the module being mapped.
+ /// PE_MANUAL_MAP object
+ public static h_reprobate.PE.PE_MANUAL_MAP MapModuleToMemory(IntPtr pModule, IntPtr pImage, h_reprobate.PE.PE_META_DATA PEINFO)
+ {
+ // Check module matches the process architecture
+ if ((PEINFO.Is32Bit && IntPtr.Size == 8) || (!PEINFO.Is32Bit && IntPtr.Size == 4))
+ {
+ Marshal.FreeHGlobal(pModule);
+ throw new InvalidOperationException("The module architecture does not match the process architecture.");
+ }
+
+ // Write PE header to memory
+ UInt32 SizeOfHeaders = PEINFO.Is32Bit ? PEINFO.OptHeader32.SizeOfHeaders : PEINFO.OptHeader64.SizeOfHeaders;
+ UInt32 BytesWritten = h_reprobate.NtWriteVirtualMemory((IntPtr)(-1), pImage, pModule, SizeOfHeaders);
+
+ // Write sections to memory
+ foreach (h_reprobate.PE.IMAGE_SECTION_HEADER ish in PEINFO.Sections)
+ {
+ // Calculate offsets
+ IntPtr pVirtualSectionBase = (IntPtr)((UInt64)pImage + ish.VirtualAddress);
+ IntPtr pRawSectionBase = (IntPtr)((UInt64)pModule + ish.PointerToRawData);
+
+ // Write data
+ BytesWritten = h_reprobate.NtWriteVirtualMemory((IntPtr)(-1), pVirtualSectionBase, pRawSectionBase, ish.SizeOfRawData);
+ if (BytesWritten != ish.SizeOfRawData)
+ {
+ throw new InvalidOperationException("Failed to write to memory.");
+ }
+ }
+
+ // Perform relocations
+ RelocateModule(PEINFO, pImage);
+
+ // Rewrite IAT
+ RewriteModuleIAT(PEINFO, pImage);
+
+ // Set memory protections
+ SetModuleSectionPermissions(PEINFO, pImage);
+
+ // Free temp HGlobal
+ Marshal.FreeHGlobal(pModule);
+
+ // Prepare return object
+ h_reprobate.PE.PE_MANUAL_MAP ManMapObject = new h_reprobate.PE.PE_MANUAL_MAP
+ {
+ ModuleBase = pImage,
+ PEINFO = PEINFO
+ };
+
+ return ManMapObject;
+ }
+
+ ///
+ /// Free a module that was mapped into the current process.
+ ///
+ /// The Wover (@TheRealWover)
+ /// The metadata of the manually mapped module.
+ public static void FreeModule(h_reprobate.PE.PE_MANUAL_MAP PEMapped)
+ {
+ // Check if PE was mapped via module overloading
+ if (!string.IsNullOrEmpty(PEMapped.DecoyModule))
+ {
+ h_reprobate.NtUnmapViewOfSection((IntPtr)(-1), PEMapped.ModuleBase);
+ }
+ // If PE not mapped via module overloading, free the memory.
+ else
+ {
+ h_reprobate.PE.PE_META_DATA PEINFO = PEMapped.PEINFO;
+
+ // Get the size of the module in memory
+ IntPtr size = PEINFO.Is32Bit ? (IntPtr)PEINFO.OptHeader32.SizeOfImage : (IntPtr)PEINFO.OptHeader64.SizeOfImage;
+ IntPtr pModule = PEMapped.ModuleBase;
+
+ h_reprobate.NtFreeVirtualMemory((IntPtr)(-1), ref pModule, ref size, h_reprobate.Win32.Kernel32.AllocationType.Release);
+ }
+ }
+
+ ///
+ /// Locate a signed module with a minimum size which can be used for overloading.
+ ///
+ /// The Wover (@TheRealWover)
+ /// Minimum module byte size.
+ /// Whether to require that the module be legitimately signed.
+ ///
+ /// String, the full path for the candidate module if one is found, or an empty string if one is not found.
+ ///
+ public static string FindDecoyModule(long MinSize, bool LegitSigned = true)
+ {
+ string SystemDirectoryPath = Environment.GetEnvironmentVariable("WINDIR") + Path.DirectorySeparatorChar + "System32";
+ List files = new List(Directory.GetFiles(SystemDirectoryPath, "*.dll"));
+ foreach (ProcessModule Module in Process.GetCurrentProcess().Modules)
+ {
+ if (files.Any(s => s.Equals(Module.FileName, StringComparison.OrdinalIgnoreCase)))
+ {
+ files.RemoveAt(files.FindIndex(x => x.Equals(Module.FileName, StringComparison.OrdinalIgnoreCase)));
+ }
+ }
+
+ // Pick a random candidate that meets the requirements
+ Random r = new Random();
+ // List of candidates that have been considered and rejected
+ List candidates = new List();
+ while (candidates.Count != files.Count)
+ {
+ // Iterate through the list of files randomly
+ int rInt = r.Next(0, files.Count);
+ string currentCandidate = files[rInt];
+
+ // Check that the size of the module meets requirements
+ if (candidates.Contains(rInt) == false &&
+ new FileInfo(currentCandidate).Length >= MinSize)
+ {
+ // Check that the module meets signing requirements
+ if (LegitSigned == true)
+ {
+ if (FileHasValidSignature(currentCandidate) == true)
+ {
+ return currentCandidate;
+ }
+ else
+ {
+ candidates.Add(rInt);
+ }
+ }
+ else
+ {
+ return currentCandidate;
+ }
+ }
+ candidates.Add(rInt);
+ }
+ return string.Empty;
+ }
+
+ ///
+ /// Load a signed decoy module into memory, creating legitimate file-backed memory sections within the process. Afterwards overload that
+ /// module by manually mapping a payload in it's place causing the payload to execute from what appears to be file-backed memory.
+ ///
+ /// The Wover (@TheRealWover), Ruben Boonen (@FuzzySec)
+ /// Full path to the payload module on disk.
+ /// Optional, full path the decoy module to overload in memory.
+ /// PE.PE_MANUAL_MAP
+ public static h_reprobate.PE.PE_MANUAL_MAP OverloadModule(string PayloadPath, string DecoyModulePath = null)
+ {
+ // Verify process & architecture
+ bool isWOW64 = h_reprobate.NtQueryInformationProcessWow64Information((IntPtr)(-1));
+ if (IntPtr.Size == 4 && isWOW64)
+ {
+ throw new InvalidOperationException("Module overloading in WOW64 is not supported.");
+ }
+
+ // Get approximate size of Payload
+ if (!File.Exists(PayloadPath))
+ {
+ throw new InvalidOperationException("Payload filepath not found.");
+ }
+ byte[] Payload = File.ReadAllBytes(PayloadPath);
+
+ return OverloadModule(Payload, DecoyModulePath);
+ }
+
+ ///
+ /// Load a signed decoy module into memory creating legitimate file-backed memory sections within the process. Afterwards overload that
+ /// module by manually mapping a payload in it's place causing the payload to execute from what appears to be file-backed memory.
+ ///
+ /// The Wover (@TheRealWover), Ruben Boonen (@FuzzySec)
+ /// Full byte array for the payload module.
+ /// Optional, full path the decoy module to overload in memory.
+ /// PE.PE_MANUAL_MAP
+ public static h_reprobate.PE.PE_MANUAL_MAP OverloadModule(byte[] Payload, string DecoyModulePath = null)
+ {
+ // Verify process & architecture
+ bool isWOW64 = h_reprobate.NtQueryInformationProcessWow64Information((IntPtr)(-1));
+ if (IntPtr.Size == 4 && isWOW64)
+ {
+ throw new InvalidOperationException("Module overloading in WOW64 is not supported.");
+ }
+
+ // Did we get a DecoyModule?
+ if (!string.IsNullOrEmpty(DecoyModulePath))
+ {
+ if (!File.Exists(DecoyModulePath))
+ {
+ throw new InvalidOperationException("Decoy filepath not found.");
+ }
+ byte[] DecoyFileBytes = File.ReadAllBytes(DecoyModulePath);
+ if (DecoyFileBytes.Length < Payload.Length)
+ {
+ throw new InvalidOperationException("Decoy module is too small to host the payload.");
+ }
+ }
+ else
+ {
+ DecoyModulePath = FindDecoyModule(Payload.Length);
+ if (string.IsNullOrEmpty(DecoyModulePath))
+ {
+ throw new InvalidOperationException("Failed to find suitable decoy module.");
+ }
+ }
+
+ // Map decoy from disk
+ h_reprobate.PE.PE_MANUAL_MAP DecoyMetaData = MapModuleFromDisk(DecoyModulePath);
+ IntPtr RegionSize = DecoyMetaData.PEINFO.Is32Bit ? (IntPtr)DecoyMetaData.PEINFO.OptHeader32.SizeOfImage : (IntPtr)DecoyMetaData.PEINFO.OptHeader64.SizeOfImage;
+
+ // Change permissions to RW
+ h_reprobate.NtProtectVirtualMemory((IntPtr)(-1), ref DecoyMetaData.ModuleBase, ref RegionSize, h_reprobate.Win32.WinNT.PAGE_READWRITE);
+
+ // Zero out memory
+ h_reprobate.RtlZeroMemory(DecoyMetaData.ModuleBase, (int)RegionSize);
+
+ // Overload module in memory
+ h_reprobate.PE.PE_MANUAL_MAP OverloadedModuleMetaData = MapModuleToMemory(Payload, DecoyMetaData.ModuleBase);
+ OverloadedModuleMetaData.DecoyModule = DecoyModulePath;
+
+ return OverloadedModuleMetaData;
+ }
+
+ public static bool FileHasValidSignature(string FilePath)
+ {
+ X509Certificate2 FileCertificate;
+ try
+ {
+ X509Certificate signer = X509Certificate.CreateFromSignedFile(FilePath);
+ FileCertificate = new X509Certificate2(signer);
+ }
+ catch
+ {
+ return false;
+ }
+
+ X509Chain CertificateChain = new X509Chain();
+ CertificateChain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain;
+ CertificateChain.ChainPolicy.RevocationMode = X509RevocationMode.Offline;
+ CertificateChain.ChainPolicy.VerificationFlags = X509VerificationFlags.NoFlag;
+
+ return CertificateChain.Build(FileCertificate);
+ }
+ }
+}