#include #ifndef NT_SUCCESS #define NT_SUCCESS(x) ((x)>=0) #define STATUS_SUCCESS ((NTSTATUS)0) #endif typedef enum _SYSTEM_INFORMATION_CLASS { SystemBasicInformation = 0, SystemCpuInformation = 1, SystemPerformanceInformation = 2, SystemTimeOfDayInformation = 3, /* was SystemTimeInformation */ SystemPathInformation = 4, SystemProcessInformation = 5, SystemCallCountInformation = 6, SystemDeviceInformation = 7, SystemProcessorPerformanceInformation = 8, 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, SystemInterruptInformation = 23, SystemDpcBehaviorInformation = 24, SystemFullMemoryInformation = 25, SystemNotImplemented6 = 25, SystemLoadGdiDriverInformation = 26, SystemUnloadGdiDriverInformation = 27, SystemTimeAdjustmentInformation = 28, SystemTimeAdjustment = 28, SystemSummaryMemoryInformation = 29, SystemMirrorMemoryInformation = 30, SystemPerformanceTraceInformation = 31, SystemObsolete0 = 32, SystemExceptionInformation = 33, SystemCrashDumpStateInformation = 34, SystemKernelDebuggerInformation = 35, SystemContextSwitchInformation = 36, SystemRegistryQuotaInformation = 37, SystemExtendServiceTableInformation = 38, SystemPrioritySeparation = 39, SystemVerifierAddDriverInformation = 40, SystemVerifierRemoveDriverInformation = 41, SystemProcessorIdleInformation = 42, SystemLegacyDriverInformation = 43, SystemCurrentTimeZoneInformation = 44, SystemLookasideInformation = 45, SystemTimeSlipNotification = 46, SystemSessionCreate = 47, SystemSessionDetach = 48, SystemSessionInformation = 49, SystemRangeStartInformation = 50, SystemVerifierInformation = 51, SystemVerifierThunkExtend = 52, SystemSessionProcessesInformation = 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, SystemCodeIntegrityInformation = 103, SystemProcessorMicrocodeUpdateInformation = 104, SystemProcessorBrandString = 105, SystemVirtualAddressInformation = 106, SystemLogicalProcessorInformationEx = 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, SystemPolicyInformation = 134, 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, SystemSpacesBootInformation = 214, SystemFwRamdiskInformation = 215, SystemWheaIpmiHardwareInformation = 216, SystemDifSetRuleClassInformation = 217, SystemDifClearRuleClassInformation = 218, SystemDifApplyPluginVerificationOnDriver = 219, SystemDifRemovePluginVerificationOnDriver = 220, SystemShadowStackInformation = 221, SystemBuildVersionInformation = 222, #ifdef __WINESRC__ SystemWineVersionInformation = 1000, #endif } SYSTEM_INFORMATION_CLASS, * PSYSTEM_INFORMATION_CLASS; typedef struct _LSA_UNICODE_STRING { USHORT Length; USHORT MaximumLength; PWSTR Buffer; } LSA_UNICODE_STRING, * PLSA_UNICODE_STRING, UNICODE_STRING, * PUNICODE_STRING; typedef struct _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; LONG BasePriority; HANDLE UniqueProcessId; HANDLE InheritedFromUniqueProcessId; ULONG HandleCount; ULONG SessionId; ULONG_PTR PageDirectoryBase; SIZE_T PeakVirtualSize; SIZE_T VirtualSize; ULONG PageFaultCount; SIZE_T PeakWorkingSetSize; SIZE_T WorkingSetSize; SIZE_T QuotaPeakPagedPoolUsage; SIZE_T QuotaPagedPoolUsage; SIZE_T QuotaPeakNonPagedPoolUsage; SIZE_T QuotaNonPagedPoolUsage; SIZE_T PagefileUsage; SIZE_T PeakPagefileUsage; SIZE_T PrivatePageCount; LARGE_INTEGER ReadOperationCount; LARGE_INTEGER WriteOperationCount; LARGE_INTEGER OtherOperationCount; LARGE_INTEGER ReadTransferCount; LARGE_INTEGER WriteTransferCount; LARGE_INTEGER OtherTransferCount; } SYSTEM_PROCESS_INFORMATION, * PSYSTEM_PROCESS_INFORMATION; typedef NTSTATUS(NTAPI* NTQUERYSYSTEMINFORMATION)(SYSTEM_INFORMATION_CLASS, PVOID, ULONG, PULONG); INT StringCompareW(_In_ LPCWSTR String1, _In_ LPCWSTR String2) { for (; *String1 == *String2; String1++, String2++) { if (*String1 == '\0') return 0; } return ((*(LPCWSTR)String1 < *(LPCWSTR)String2) ? -1 : +1); } DWORD QueryBufferSize(_In_ NTQUERYSYSTEMINFORMATION NtQuerySystemInformation) { DWORD dwSize = ERROR_SUCCESS; NtQuerySystemInformation(SystemProcessInformation, NULL, 0, &dwSize); return (dwSize + 0x1000); } DWORD GetPidFromNtQuerySystemInformationW(_In_ PWCHAR BinaryNameWithFileExtension) { NTQUERYSYSTEMINFORMATION NtQuerySystemInformation = NULL; DWORD ProcessId = 0, Length = 0, dwOffset = 0; PSYSTEM_PROCESS_INFORMATION ProcessInformationPointer = NULL; HMODULE hModule = NULL; NTSTATUS Status = STATUS_SUCCESS; PSYSTEM_PROCESS_INFORMATION Process = NULL; hModule = GetModuleHandleW(L"ntdll.dll"); if (hModule == NULL) goto EXIT_ROUTINE; NtQuerySystemInformation = (NTQUERYSYSTEMINFORMATION)GetProcAddress(hModule, "NtQuerySystemInformation"); if (!NtQuerySystemInformation) goto EXIT_ROUTINE; Length = QueryBufferSize(NtQuerySystemInformation); if (Length == 0) goto EXIT_ROUTINE; Process = (PSYSTEM_PROCESS_INFORMATION)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Length); if (Process == NULL) goto EXIT_ROUTINE; Status = NtQuerySystemInformation(SystemProcessInformation, Process, Length, &Length); if (!NT_SUCCESS(Status)) goto EXIT_ROUTINE; ProcessInformationPointer = Process; do { if (ProcessInformationPointer->ImageName.Buffer) { if (StringCompareW(BinaryNameWithFileExtension, ProcessInformationPointer->ImageName.Buffer) == ERROR_SUCCESS) ProcessId = HandleToLong(ProcessInformationPointer->UniqueProcessId); } if (ProcessId != 0) break; ProcessInformationPointer = (PSYSTEM_PROCESS_INFORMATION)(((PBYTE)ProcessInformationPointer) + ProcessInformationPointer->NextEntryOffset); } while (ProcessInformationPointer->NextEntryOffset); EXIT_ROUTINE: if (Process) HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, Process); return ProcessId; } BOOL CreateProcessWithSpoofedParentProcessIdW(_Inout_ PPROCESS_INFORMATION Pi, _In_ PWCHAR Path, _In_ DWORD dwParentProcessId) { BOOL bFlag = FALSE; PPROC_THREAD_ATTRIBUTE_LIST ThreadAttributes = NULL; SIZE_T dwAttributeSize = 0; HANDLE hHandle = NULL; STARTUPINFOEXW Si = { 0 }; Si.StartupInfo.cb = sizeof(STARTUPINFOEXW); hHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwParentProcessId); if (hHandle == NULL) goto EXIT_ROUTINE; InitializeProcThreadAttributeList(NULL, 1, 0, &dwAttributeSize); if (dwAttributeSize == 0) goto EXIT_ROUTINE; ThreadAttributes = (PPROC_THREAD_ATTRIBUTE_LIST)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwAttributeSize); if (ThreadAttributes == NULL) goto EXIT_ROUTINE; if (!InitializeProcThreadAttributeList(ThreadAttributes, 1, 0, &dwAttributeSize)) goto EXIT_ROUTINE; if (!UpdateProcThreadAttribute(ThreadAttributes, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, &hHandle, sizeof(HANDLE), NULL, NULL)) goto EXIT_ROUTINE; Si.lpAttributeList = ThreadAttributes; if (!CreateProcessW(Path, NULL, NULL, NULL, TRUE, EXTENDED_STARTUPINFO_PRESENT, NULL, NULL, &Si.StartupInfo, Pi)) goto EXIT_ROUTINE; Si.lpAttributeList = ThreadAttributes; bFlag = TRUE; EXIT_ROUTINE: if (ThreadAttributes) HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, (PPROC_THREAD_ATTRIBUTE_LIST)ThreadAttributes); return bFlag; } INT main(VOID) { WCHAR wSpoofedParentProcessBinaryImage[MAX_PATH * sizeof(WCHAR)] = { 0 }; PPROCESS_INFORMATION Pi = NULL; DWORD dwParentProcessId = 0; WCHAR ExampleBinaryPath[MAX_PATH * sizeof(WCHAR)] = L"C:\\Windows\\System32\\notepad.exe"; //generic error handling variables BOOL bFlag = FALSE; DWORD dwError = ERROR_SUCCESS; //allocate memory for process information structure Pi = (PPROCESS_INFORMATION)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PROCESS_INFORMATION)); if (Pi == NULL) goto EXIT_ROUTINE; dwParentProcessId = GetPidFromNtQuerySystemInformationW((PWCHAR)L"firefox.exe"); if (dwParentProcessId == 0) goto EXIT_ROUTINE; if (!CreateProcessWithSpoofedParentProcessIdW(Pi, ExampleBinaryPath, dwParentProcessId)) goto EXIT_ROUTINE; //set flag, code exiting without failure bFlag = TRUE; EXIT_ROUTINE: if (!bFlag) //if flag is false, code exited with an error, set return code to last error dwError = GetLastError(); return dwError; //return error code, or ERROR_SUCCESS depending on bFlag }