From 48f7ca425192a2214030cd09e5691af02fe8d5d1 Mon Sep 17 00:00:00 2001 From: deadash Date: Wed, 3 Apr 2024 15:31:36 +0800 Subject: [PATCH] Add some API. GetQueuedCompletionStatusEx SetFileCompletionNotificationModes GetFinalPathNameByHandleW NtCancelIoFileEx Signed-off-by: deadash --- Build.ps1 | 71 +++ README.md | 4 +- modules/ntdll.txt | 1315 +++++++++++++++++++++++++++++++++++++++++++++ xpstub/vsenv.bat | 20 +- xpstub/xpstub.c | 601 +++++++++++++++++++++ xpstub/xpstub.def | 4 + 6 files changed, 2008 insertions(+), 7 deletions(-) create mode 100644 Build.ps1 create mode 100644 modules/ntdll.txt diff --git a/Build.ps1 b/Build.ps1 new file mode 100644 index 0000000..716604a --- /dev/null +++ b/Build.ps1 @@ -0,0 +1,71 @@ +param ( + [string]$action +) + +function Set-EnvironmentVariables { + if ($env:VS_ENV_SET -eq "true") { + Write-Host "Visual Studio environment variables have already been set." + return + } + + Write-Host "Locating Visual Studio installation..." + $vsWherePath = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" + $installationPath = & $vsWherePath -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath + + if ($installationPath -and (Test-Path "$installationPath\Common7\Tools\vsdevcmd.bat")) { + Write-Host "Setting environment variables using VsDevCmd.bat..." + # Set environment variables using VsDevCmd.bat and export them to JSON format + $json = & "${env:COMSPEC}" /s /c "`"$installationPath\Common7\Tools\vsdevcmd.bat`" -no_logo -arch=x86 && powershell -Command `"Get-ChildItem env: | Select-Object Name,Value | ConvertTo-Json`"" + + # Check if the command executed successfully + if ($LASTEXITCODE -ne 0) { + Write-Error "Failed to execute $installationPath\Common7\Tools\vsdevcmd.bat with error code: $LASTEXITCODE" + } else { + # Convert JSON string back to objects and update the environment variables in the current PowerShell session + $envVars = $json | ConvertFrom-Json + foreach ($envVar in $envVars) { + Set-Item -Path "env:$($envVar.Name)" -Value $envVar.Value + } + # Mark environment variables as set + $env:VS_ENV_SET = "true" + } + } else { + Write-Host "Visual Studio installation or VsDevCmd.bat not found." + } + + # Set additional environment variables + $env:PATH = "C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Bin;" + $env:PATH + $env:INCLUDE = "C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Include;" + $env:INCLUDE + $env:LIB = "C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Lib;" + $env:LIB + $env:CL = "/D_USING_V110_SDK71_" +} + +function Build { + Write-Host "Starting build process..." + Set-EnvironmentVariables + Push-Location xpstub + nmake + Pop-Location +} + +function Clean { + Write-Host "Starting clean process..." + Set-EnvironmentVariables + Push-Location xpstub + nmake clean + Pop-Location +} + +Switch ($action) { + "build" { + Build + } + "clean" { + Clean + } + Default { + Write-Host "Usage: Build.ps1 -action [build|clean]" + Write-Host "build: Compiles the project." + Write-Host "clean: Cleans the build artifacts." + } +} diff --git a/README.md b/README.md index aff8b52..19dc652 100644 --- a/README.md +++ b/README.md @@ -23,8 +23,8 @@ To compile the project, you need to execute two commands: 1. Build the native components with the batch script: - ```bash - make.bat + ```powershell + .\Build.ps1 build ``` 2. Then build the Rust components: diff --git a/modules/ntdll.txt b/modules/ntdll.txt new file mode 100644 index 0000000..a3b5d26 --- /dev/null +++ b/modules/ntdll.txt @@ -0,0 +1,1315 @@ +CsrAllocateCaptureBuffer +CsrAllocateMessagePointer +CsrCaptureMessageBuffer +CsrCaptureMessageMultiUnicodeStringsInPlace +CsrCaptureMessageString +CsrCaptureTimeout +CsrClientCallServer +CsrClientConnectToServer +CsrFreeCaptureBuffer +CsrGetProcessId +CsrIdentifyAlertableThread +CsrNewThread +CsrProbeForRead +CsrProbeForWrite +CsrSetPriorityClass +DbgBreakPoint +DbgPrint +DbgPrintEx +DbgPrintReturnControlC +DbgPrompt +DbgQueryDebugFilterState +DbgSetDebugFilterState +DbgUiConnectToDbg +DbgUiContinue +DbgUiConvertStateChangeStructure +DbgUiDebugActiveProcess +DbgUiGetThreadDebugObject +DbgUiIssueRemoteBreakin +DbgUiRemoteBreakin +DbgUiSetThreadDebugObject +DbgUiStopDebugging +DbgUiWaitStateChange +DbgUserBreakPoint +KiFastSystemCall +KiFastSystemCallRet +KiIntSystemCall +KiRaiseUserExceptionDispatcher +KiUserApcDispatcher +KiUserCallbackDispatcher +KiUserExceptionDispatcher +LdrAccessOutOfProcessResource +LdrAccessResource +LdrAddRefDll +LdrAlternateResourcesEnabled +LdrCreateOutOfProcessImage +LdrDestroyOutOfProcessImage +LdrDisableThreadCalloutsForDll +LdrEnumResources +LdrEnumerateLoadedModules +LdrFindCreateProcessManifest +LdrFindEntryForAddress +LdrFindResourceDirectory_U +LdrFindResourceEx_U +LdrFindResource_U +LdrFlushAlternateResourceModules +LdrGetDllHandle +LdrGetDllHandleEx +LdrGetProcedureAddress +LdrHotPatchRoutine +LdrInitShimEngineDynamic +LdrInitializeThunk +LdrLoadAlternateResourceModule +LdrLoadDll +LdrLockLoaderLock +LdrProcessRelocationBlock +LdrQueryImageFileExecutionOptions +LdrQueryProcessModuleInformation +LdrSetAppCompatDllRedirectionCallback +LdrSetDllManifestProber +LdrShutdownProcess +LdrShutdownThread +LdrUnloadAlternateResourceModule +LdrUnloadDll +LdrUnlockLoaderLock +LdrVerifyImageMatchesChecksum +NlsAnsiCodePage +NlsMbCodePageTag +NlsMbOemCodePageTag +NtAcceptConnectPort +NtAccessCheck +NtAccessCheckAndAuditAlarm +NtAccessCheckByType +NtAccessCheckByTypeAndAuditAlarm +NtAccessCheckByTypeResultList +NtAccessCheckByTypeResultListAndAuditAlarm +NtAccessCheckByTypeResultListAndAuditAlarmByHan +NtAddAtom +NtAddBootEntry +NtAdjustGroupsToken +NtAdjustPrivilegesToken +NtAlertResumeThread +NtAlertThread +NtAllocateLocallyUniqueId +NtAllocateUserPhysicalPages +NtAllocateUuids +NtAllocateVirtualMemory +NtAreMappedFilesTheSame +NtAssignProcessToJobObject +NtCallbackReturn +NtCancelDeviceWakeupRequest +NtCancelIoFile +NtCancelTimer +NtClearEvent +NtClose +NtCloseObjectAuditAlarm +NtCompactKeys +NtCompareTokens +NtCompleteConnectPort +NtCompressKey +NtConnectPort +NtContinue +NtCreateDebugObject +NtCreateDirectoryObject +NtCreateEvent +NtCreateEventPair +NtCreateFile +NtCreateIoCompletion +NtCreateJobObject +NtCreateJobSet +NtCreateKey +NtCreateKeyedEvent +NtCreateMailslotFile +NtCreateMutant +NtCreateNamedPipeFile +NtCreatePagingFile +NtCreatePort +NtCreateProcess +NtCreateProcessEx +NtCreateProfile +NtCreateSection +NtCreateSemaphore +NtCreateSymbolicLinkObject +NtCreateThread +NtCreateTimer +NtCreateToken +NtCreateWaitablePort +NtCurrentTeb +NtDebugActiveProcess +NtDebugContinue +NtDelayExecution +NtDeleteAtom +NtDeleteBootEntry +NtDeleteFile +NtDeleteKey +NtDeleteObjectAuditAlarm +NtDeleteValueKey +NtDeviceIoControlFile +NtDisplayString +NtDuplicateObject +NtDuplicateToken +NtEnumerateBootEntries +NtEnumerateKey +NtEnumerateSystemEnvironmentValuesEx +NtEnumerateValueKey +NtExtendSection +NtFilterToken +NtFindAtom +NtFlushBuffersFile +NtFlushInstructionCache +NtFlushKey +NtFlushVirtualMemory +NtFlushWriteBuffer +NtFreeUserPhysicalPages +NtFreeVirtualMemory +NtFsControlFile +NtGetContextThread +NtGetDevicePowerState +NtGetPlugPlayEvent +NtGetWriteWatch +NtImpersonateAnonymousToken +NtImpersonateClientOfPort +NtImpersonateThread +NtInitializeRegistry +NtInitiatePowerAction +NtIsProcessInJob +NtIsSystemResumeAutomatic +NtListenPort +NtLoadDriver +NtLoadKey +NtLoadKey2 +NtLockFile +NtLockProductActivationKeys +NtLockRegistryKey +NtLockVirtualMemory +NtMakePermanentObject +NtMakeTemporaryObject +NtMapUserPhysicalPages +NtMapUserPhysicalPagesScatter +NtMapViewOfSection +NtModifyBootEntry +NtNotifyChangeDirectoryFile +NtNotifyChangeKey +NtNotifyChangeMultipleKeys +NtOpenDirectoryObject +NtOpenEvent +NtOpenEventPair +NtOpenFile +NtOpenIoCompletion +NtOpenJobObject +NtOpenKey +NtOpenKeyedEvent +NtOpenMutant +NtOpenObjectAuditAlarm +NtOpenProcess +NtOpenProcessToken +NtOpenProcessTokenEx +NtOpenSection +NtOpenSemaphore +NtOpenSymbolicLinkObject +NtOpenThread +NtOpenThreadToken +NtOpenThreadTokenEx +NtOpenTimer +NtPlugPlayControl +NtPowerInformation +NtPrivilegeCheck +NtPrivilegeObjectAuditAlarm +NtPrivilegedServiceAuditAlarm +NtProtectVirtualMemory +NtPulseEvent +NtQueryAttributesFile +NtQueryBootEntryOrder +NtQueryBootOptions +NtQueryDebugFilterState +NtQueryDefaultLocale +NtQueryDefaultUILanguage +NtQueryDirectoryFile +NtQueryDirectoryObject +NtQueryEaFile +NtQueryEvent +NtQueryFullAttributesFile +NtQueryInformationAtom +NtQueryInformationFile +NtQueryInformationJobObject +NtQueryInformationPort +NtQueryInformationProcess +NtQueryInformationThread +NtQueryInformationToken +NtQueryInstallUILanguage +NtQueryIntervalProfile +NtQueryIoCompletion +NtQueryKey +NtQueryMultipleValueKey +NtQueryMutant +NtQueryObject +NtQueryOpenSubKeys +NtQueryPerformanceCounter +NtQueryPortInformationProcess +NtQueryQuotaInformationFile +NtQuerySection +NtQuerySecurityObject +NtQuerySemaphore +NtQuerySymbolicLinkObject +NtQuerySystemEnvironmentValue +NtQuerySystemEnvironmentValueEx +NtQuerySystemInformation +NtQuerySystemTime +NtQueryTimer +NtQueryTimerResolution +NtQueryValueKey +NtQueryVirtualMemory +NtQueryVolumeInformationFile +NtQueueApcThread +NtRaiseException +NtRaiseHardError +NtReadFile +NtReadFileScatter +NtReadRequestData +NtReadVirtualMemory +NtRegisterThreadTerminatePort +NtReleaseKeyedEvent +NtReleaseMutant +NtReleaseSemaphore +NtRemoveIoCompletion +NtRemoveProcessDebug +NtRenameKey +NtReplaceKey +NtReplyPort +NtReplyWaitReceivePort +NtReplyWaitReceivePortEx +NtReplyWaitReplyPort +NtRequestDeviceWakeup +NtRequestPort +NtRequestWaitReplyPort +NtRequestWakeupLatency +NtResetEvent +NtResetWriteWatch +NtRestoreKey +NtResumeProcess +NtResumeThread +NtSaveKey +NtSaveKeyEx +NtSaveMergedKeys +NtSecureConnectPort +NtSetBootEntryOrder +NtSetBootOptions +NtSetContextThread +NtSetDebugFilterState +NtSetDefaultHardErrorPort +NtSetDefaultLocale +NtSetDefaultUILanguage +NtSetEaFile +NtSetEvent +NtSetEventBoostPriority +NtSetHighEventPair +NtSetHighWaitLowEventPair +NtSetInformationDebugObject +NtSetInformationFile +NtSetInformationJobObject +NtSetInformationKey +NtSetInformationObject +NtSetInformationProcess +NtSetInformationThread +NtSetInformationToken +NtSetIntervalProfile +NtSetIoCompletion +NtSetLdtEntries +NtSetLowEventPair +NtSetLowWaitHighEventPair +NtSetQuotaInformationFile +NtSetSecurityObject +NtSetSystemEnvironmentValue +NtSetSystemEnvironmentValueEx +NtSetSystemInformation +NtSetSystemPowerState +NtSetSystemTime +NtSetThreadExecutionState +NtSetTimer +NtSetTimerResolution +NtSetUuidSeed +NtSetValueKey +NtSetVolumeInformationFile +NtShutdownSystem +NtSignalAndWaitForSingleObject +NtStartProfile +NtStopProfile +NtSuspendProcess +NtSuspendThread +NtSystemDebugControl +NtTerminateJobObject +NtTerminateProcess +NtTerminateThread +NtTestAlert +NtTraceEvent +NtTranslateFilePath +NtUnloadDriver +NtUnloadKey +NtUnloadKeyEx +NtUnlockFile +NtUnlockVirtualMemory +NtUnmapViewOfSection +NtVdmControl +NtWaitForDebugEvent +NtWaitForKeyedEvent +NtWaitForMultipleObjects +NtWaitForSingleObject +NtWaitHighEventPair +NtWaitLowEventPair +NtWriteFile +NtWriteFileGather +NtWriteRequestData +NtWriteVirtualMemory +NtYieldExecution +PfxFindPrefix +PfxInitialize +PfxInsertPrefix +PfxRemovePrefix +PropertyLengthAsVariant +RtlAbortRXact +RtlAbsoluteToSelfRelativeSD +RtlAcquirePebLock +RtlAcquireResourceExclusive +RtlAcquireResourceShared +RtlActivateActivationContext +RtlActivateActivationContextEx +RtlActivateActivationContextUnsafeFast +RtlAddAccessAllowedAce +RtlAddAccessAllowedAceEx +RtlAddAccessAllowedObjectAce +RtlAddAccessDeniedAce +RtlAddAccessDeniedAceEx +RtlAddAccessDeniedObjectAce +RtlAddAce +RtlAddActionToRXact +RtlAddAtomToAtomTable +RtlAddAttributeActionToRXact +RtlAddAuditAccessAce +RtlAddAuditAccessAceEx +RtlAddAuditAccessObjectAce +RtlAddCompoundAce +RtlAddRange +RtlAddRefActivationContext +RtlAddRefMemoryStream +RtlAddVectoredExceptionHandler +RtlAddressInSectionTable +RtlAdjustPrivilege +RtlAllocateAndInitializeSid +RtlAllocateHandle +RtlAllocateHeap +RtlAnsiCharToUnicodeChar +RtlAnsiStringToUnicodeSize +RtlAnsiStringToUnicodeString +RtlAppendAsciizToString +RtlAppendPathElement +RtlAppendStringToString +RtlAppendUnicodeStringToString +RtlAppendUnicodeToString +RtlApplicationVerifierStop +RtlApplyRXact +RtlApplyRXactNoFlush +RtlAreAllAccessesGranted +RtlAreAnyAccessesGranted +RtlAreBitsClear +RtlAreBitsSet +RtlAssert +RtlAssert2 +RtlCancelTimer +RtlCaptureContext +RtlCaptureStackBackTrace +RtlCaptureStackContext +RtlCharToInteger +RtlCheckForOrphanedCriticalSections +RtlCheckProcessParameters +RtlCheckRegistryKey +RtlClearAllBits +RtlClearBits +RtlCloneMemoryStream +RtlCommitMemoryStream +RtlCompactHeap +RtlCompareMemory +RtlCompareMemoryUlong +RtlCompareString +RtlCompareUnicodeString +RtlCompressBuffer +RtlComputeCrc32 +RtlComputeImportTableHash +RtlComputePrivatizedDllName_U +RtlConsoleMultiByteToUnicodeN +RtlConvertExclusiveToShared +RtlConvertLongToLargeInteger +RtlConvertPropertyToVariant +RtlConvertSharedToExclusive +RtlConvertSidToUnicodeString +RtlConvertToAutoInheritSecurityObject +RtlConvertUiListToApiList +RtlConvertUlongToLargeInteger +RtlConvertVariantToProperty +RtlCopyLuid +RtlCopyLuidAndAttributesArray +RtlCopyMemoryStreamTo +RtlCopyOutOfProcessMemoryStreamTo +RtlCopyRangeList +RtlCopySecurityDescriptor +RtlCopySid +RtlCopySidAndAttributesArray +RtlCopyString +RtlCopyUnicodeString +RtlCreateAcl +RtlCreateActivationContext +RtlCreateAndSetSD +RtlCreateAtomTable +RtlCreateBootStatusDataFile +RtlCreateEnvironment +RtlCreateHeap +RtlCreateProcessParameters +RtlCreateQueryDebugBuffer +RtlCreateRegistryKey +RtlCreateSecurityDescriptor +RtlCreateSystemVolumeInformationFolder +RtlCreateTagHeap +RtlCreateTimer +RtlCreateTimerQueue +RtlCreateUnicodeString +RtlCreateUnicodeStringFromAsciiz +RtlCreateUserProcess +RtlCreateUserSecurityObject +RtlCreateUserThread +RtlCustomCPToUnicodeN +RtlCutoverTimeToSystemTime +RtlDeNormalizeProcessParams +RtlDeactivateActivationContext +RtlDeactivateActivationContextUnsafeFast +RtlDebugPrintTimes +RtlDecodePointer +RtlDecodeSystemPointer +RtlDecompressBuffer +RtlDecompressFragment +RtlDefaultNpAcl +RtlDelete +RtlDeleteAce +RtlDeleteAtomFromAtomTable +RtlDeleteCriticalSection +RtlDeleteElementGenericTable +RtlDeleteElementGenericTableAvl +RtlDeleteNoSplay +RtlDeleteOwnersRanges +RtlDeleteRange +RtlDeleteRegistryValue +RtlDeleteResource +RtlDeleteSecurityObject +RtlDeleteTimer +RtlDeleteTimerQueue +RtlDeleteTimerQueueEx +RtlDeregisterWait +RtlDeregisterWaitEx +RtlDestroyAtomTable +RtlDestroyEnvironment +RtlDestroyHandleTable +RtlDestroyHeap +RtlDestroyProcessParameters +RtlDestroyQueryDebugBuffer +RtlDetermineDosPathNameType_U +RtlDllShutdownInProgress +RtlDnsHostNameToComputerName +RtlDoesFileExists_U +RtlDosApplyFileIsolationRedirection_Ustr +RtlDosPathNameToNtPathName_U +RtlDosSearchPath_U +RtlDosSearchPath_Ustr +RtlDowncaseUnicodeChar +RtlDowncaseUnicodeString +RtlDumpResource +RtlDuplicateUnicodeString +RtlEmptyAtomTable +RtlEnableEarlyCriticalSectionEventCreation +RtlEncodePointer +RtlEncodeSystemPointer +RtlEnlargedIntegerMultiply +RtlEnlargedUnsignedDivide +RtlEnlargedUnsignedMultiply +RtlEnterCriticalSection +RtlEnumProcessHeaps +RtlEnumerateGenericTable +RtlEnumerateGenericTableAvl +RtlEnumerateGenericTableLikeADirectory +RtlEnumerateGenericTableWithoutSplaying +RtlEnumerateGenericTableWithoutSplayingAvl +RtlEqualComputerName +RtlEqualDomainName +RtlEqualLuid +RtlEqualPrefixSid +RtlEqualSid +RtlEqualString +RtlEqualUnicodeString +RtlEraseUnicodeString +RtlExitUserThread +RtlExpandEnvironmentStrings_U +RtlExtendHeap +RtlExtendedIntegerMultiply +RtlExtendedLargeIntegerDivide +RtlExtendedMagicDivide +RtlFillMemory +RtlFillMemoryUlong +RtlFinalReleaseOutOfProcessMemoryStream +RtlFindActivationContextSectionGuid +RtlFindActivationContextSectionString +RtlFindCharInUnicodeString +RtlFindClearBits +RtlFindClearBitsAndSet +RtlFindClearRuns +RtlFindLastBackwardRunClear +RtlFindLeastSignificantBit +RtlFindLongestRunClear +RtlFindMessage +RtlFindMostSignificantBit +RtlFindNextForwardRunClear +RtlFindRange +RtlFindSetBits +RtlFindSetBitsAndClear +RtlFirstEntrySList +RtlFirstFreeAce +RtlFlushSecureMemoryCache +RtlFormatCurrentUserKeyPath +RtlFormatMessage +RtlFreeAnsiString +RtlFreeHandle +RtlFreeHeap +RtlFreeOemString +RtlFreeRangeList +RtlFreeSid +RtlFreeThreadActivationContextStack +RtlFreeUnicodeString +RtlFreeUserThreadStack +RtlGUIDFromString +RtlGenerate8dot3Name +RtlGetAce +RtlGetActiveActivationContext +RtlGetCallersAddress +RtlGetCompressionWorkSpaceSize +RtlGetControlSecurityDescriptor +RtlGetCurrentDirectory_U +RtlGetCurrentPeb +RtlGetDaclSecurityDescriptor +RtlGetElementGenericTable +RtlGetElementGenericTableAvl +RtlGetFirstRange +RtlGetFrame +RtlGetFullPathName_U +RtlGetGroupSecurityDescriptor +RtlGetLastNtStatus +RtlGetLastWin32Error +RtlGetLengthWithoutLastFullDosOrNtPathElement +RtlGetLengthWithoutTrailingPathSeperators +RtlGetLongestNtPathLength +RtlGetNativeSystemInformation +RtlGetNextRange +RtlGetNtGlobalFlags +RtlGetNtProductType +RtlGetNtVersionNumbers +RtlGetOwnerSecurityDescriptor +RtlGetProcessHeaps +RtlGetSaclSecurityDescriptor +RtlGetSecurityDescriptorRMControl +RtlGetSetBootStatusData +RtlGetUnloadEventTrace +RtlGetUserInfoHeap +RtlGetVersion +RtlHashUnicodeString +RtlIdentifierAuthoritySid +RtlImageDirectoryEntryToData +RtlImageNtHeader +RtlImageRvaToSection +RtlImageRvaToVa +RtlImpersonateSelf +RtlInitAnsiString +RtlInitCodePageTable +RtlInitMemoryStream +RtlInitNlsTables +RtlInitOutOfProcessMemoryStream +RtlInitString +RtlInitUnicodeString +RtlInitUnicodeStringEx +RtlInitializeAtomPackage +RtlInitializeBitMap +RtlInitializeContext +RtlInitializeCriticalSection +RtlInitializeCriticalSectionAndSpinCount +RtlInitializeGenericTable +RtlInitializeGenericTableAvl +RtlInitializeHandleTable +RtlInitializeRXact +RtlInitializeRangeList +RtlInitializeResource +RtlInitializeSListHead +RtlInitializeSid +RtlInitializeStackTraceDataBase +RtlInsertElementGenericTable +RtlInsertElementGenericTableAvl +RtlInt64ToUnicodeString +RtlIntegerToChar +RtlIntegerToUnicodeString +RtlInterlockedFlushSList +RtlInterlockedPopEntrySList +RtlInterlockedPushEntrySList +RtlInterlockedPushListSList +RtlInvertRangeList +RtlIpv4AddressToStringA +RtlIpv4AddressToStringExA +RtlIpv4AddressToStringExW +RtlIpv4AddressToStringW +RtlIpv4StringToAddressA +RtlIpv4StringToAddressExA +RtlIpv4StringToAddressExW +RtlIpv4StringToAddressW +RtlIpv6AddressToStringA +RtlIpv6AddressToStringExA +RtlIpv6AddressToStringExW +RtlIpv6AddressToStringW +RtlIpv6StringToAddressA +RtlIpv6StringToAddressExA +RtlIpv6StringToAddressExW +RtlIpv6StringToAddressW +RtlIsActivationContextActive +RtlIsDosDeviceName_U +RtlIsGenericTableEmpty +RtlIsGenericTableEmptyAvl +RtlIsNameLegalDOS8Dot3 +RtlIsRangeAvailable +RtlIsTextUnicode +RtlIsThreadWithinLoaderCallout +RtlIsValidHandle +RtlIsValidIndexHandle +RtlLargeIntegerAdd +RtlLargeIntegerArithmeticShift +RtlLargeIntegerDivide +RtlLargeIntegerNegate +RtlLargeIntegerShiftLeft +RtlLargeIntegerShiftRight +RtlLargeIntegerSubtract +RtlLargeIntegerToChar +RtlLeaveCriticalSection +RtlLengthRequiredSid +RtlLengthSecurityDescriptor +RtlLengthSid +RtlLocalTimeToSystemTime +RtlLockBootStatusData +RtlLockHeap +RtlLockMemoryStreamRegion +RtlLogStackBackTrace +RtlLookupAtomInAtomTable +RtlLookupElementGenericTable +RtlLookupElementGenericTableAvl +RtlMakeSelfRelativeSD +RtlMapGenericMask +RtlMapSecurityErrorToNtStatus +RtlMergeRangeLists +RtlMoveMemory +RtlMultiAppendUnicodeStringBuffer +RtlMultiByteToUnicodeN +RtlMultiByteToUnicodeSize +RtlNewInstanceSecurityObject +RtlNewSecurityGrantedAccess +RtlNewSecurityObject +RtlNewSecurityObjectEx +RtlNewSecurityObjectWithMultipleInheritance +RtlNormalizeProcessParams +RtlNtPathNameToDosPathName +RtlNtStatusToDosError +RtlNtStatusToDosErrorNoTeb +RtlNumberGenericTableElements +RtlNumberGenericTableElementsAvl +RtlNumberOfClearBits +RtlNumberOfSetBits +RtlOemStringToUnicodeSize +RtlOemStringToUnicodeString +RtlOemToUnicodeN +RtlOpenCurrentUser +RtlPcToFileHeader +RtlPinAtomInAtomTable +RtlPopFrame +RtlPrefixString +RtlPrefixUnicodeString +RtlProtectHeap +RtlPushFrame +RtlQueryAtomInAtomTable +RtlQueryDepthSList +RtlQueryEnvironmentVariable_U +RtlQueryHeapInformation +RtlQueryInformationAcl +RtlQueryInformationActivationContext +RtlQueryInformationActiveActivationContext +RtlQueryInterfaceMemoryStream +RtlQueryProcessBackTraceInformation +RtlQueryProcessDebugInformation +RtlQueryProcessHeapInformation +RtlQueryProcessLockInformation +RtlQueryRegistryValues +RtlQuerySecurityObject +RtlQueryTagHeap +RtlQueryTimeZoneInformation +RtlQueueApcWow64Thread +RtlQueueWorkItem +RtlRaiseException +RtlRaiseStatus +RtlRandom +RtlRandomEx +RtlReAllocateHeap +RtlReadMemoryStream +RtlReadOutOfProcessMemoryStream +RtlRealPredecessor +RtlRealSuccessor +RtlRegisterSecureMemoryCacheCallback +RtlRegisterWait +RtlReleaseActivationContext +RtlReleaseMemoryStream +RtlReleasePebLock +RtlReleaseResource +RtlRemoteCall +RtlRemoveVectoredExceptionHandler +RtlResetRtlTranslations +RtlRestoreLastWin32Error +RtlRevertMemoryStream +RtlRunDecodeUnicodeString +RtlRunEncodeUnicodeString +RtlSecondsSince1970ToTime +RtlSecondsSince1980ToTime +RtlSeekMemoryStream +RtlSelfRelativeToAbsoluteSD +RtlSelfRelativeToAbsoluteSD2 +RtlSetAllBits +RtlSetAttributesSecurityDescriptor +RtlSetBits +RtlSetControlSecurityDescriptor +RtlSetCriticalSectionSpinCount +RtlSetCurrentDirectory_U +RtlSetCurrentEnvironment +RtlSetDaclSecurityDescriptor +RtlSetEnvironmentVariable +RtlSetGroupSecurityDescriptor +RtlSetHeapInformation +RtlSetInformationAcl +RtlSetIoCompletionCallback +RtlSetLastWin32Error +RtlSetLastWin32ErrorAndNtStatusFromNtStatus +RtlSetMemoryStreamSize +RtlSetOwnerSecurityDescriptor +RtlSetProcessIsCritical +RtlSetSaclSecurityDescriptor +RtlSetSecurityDescriptorRMControl +RtlSetSecurityObject +RtlSetSecurityObjectEx +RtlSetThreadIsCritical +RtlSetThreadPoolStartFunc +RtlSetTimeZoneInformation +RtlSetTimer +RtlSetUnicodeCallouts +RtlSetUserFlagsHeap +RtlSetUserValueHeap +RtlSizeHeap +RtlSplay +RtlStartRXact +RtlStatMemoryStream +RtlStringFromGUID +RtlSubAuthorityCountSid +RtlSubAuthoritySid +RtlSubtreePredecessor +RtlSubtreeSuccessor +RtlSystemTimeToLocalTime +RtlTimeFieldsToTime +RtlTimeToElapsedTimeFields +RtlTimeToSecondsSince1970 +RtlTimeToSecondsSince1980 +RtlTimeToTimeFields +RtlTraceDatabaseAdd +RtlTraceDatabaseCreate +RtlTraceDatabaseDestroy +RtlTraceDatabaseEnumerate +RtlTraceDatabaseFind +RtlTraceDatabaseLock +RtlTraceDatabaseUnlock +RtlTraceDatabaseValidate +RtlTryEnterCriticalSection +RtlUlongByteSwap +RtlUlonglongByteSwap +RtlUnhandledExceptionFilter +RtlUnhandledExceptionFilter2 +RtlUnicodeStringToAnsiSize +RtlUnicodeStringToAnsiString +RtlUnicodeStringToCountedOemString +RtlUnicodeStringToInteger +RtlUnicodeStringToOemSize +RtlUnicodeStringToOemString +RtlUnicodeToCustomCPN +RtlUnicodeToMultiByteN +RtlUnicodeToMultiByteSize +RtlUnicodeToOemN +RtlUniform +RtlUnlockBootStatusData +RtlUnlockHeap +RtlUnlockMemoryStreamRegion +RtlUnwind +RtlUpcaseUnicodeChar +RtlUpcaseUnicodeString +RtlUpcaseUnicodeStringToAnsiString +RtlUpcaseUnicodeStringToCountedOemString +RtlUpcaseUnicodeStringToOemString +RtlUpcaseUnicodeToCustomCPN +RtlUpcaseUnicodeToMultiByteN +RtlUpcaseUnicodeToOemN +RtlUpdateTimer +RtlUpperChar +RtlUpperString +RtlUsageHeap +RtlUshortByteSwap +RtlValidAcl +RtlValidRelativeSecurityDescriptor +RtlValidSecurityDescriptor +RtlValidSid +RtlValidateHeap +RtlValidateProcessHeaps +RtlValidateUnicodeString +RtlVerifyVersionInfo +RtlWalkFrameChain +RtlWalkHeap +RtlWriteMemoryStream +RtlWriteRegistryValue +RtlZeroHeap +RtlZeroMemory +RtlZombifyActivationContext +RtlpApplyLengthFunction +RtlpEnsureBufferSize +RtlpNotOwnerCriticalSection +RtlpNtCreateKey +RtlpNtEnumerateSubKey +RtlpNtMakeTemporaryKey +RtlpNtOpenKey +RtlpNtQueryValueKey +RtlpNtSetValueKey +RtlpUnWaitCriticalSection +RtlpWaitForCriticalSection +RtlxAnsiStringToUnicodeSize +RtlxOemStringToUnicodeSize +RtlxUnicodeStringToAnsiSize +RtlxUnicodeStringToOemSize +VerSetConditionMask +ZwAcceptConnectPort +ZwAccessCheck +ZwAccessCheckAndAuditAlarm +ZwAccessCheckByType +ZwAccessCheckByTypeAndAuditAlarm +ZwAccessCheckByTypeResultList +ZwAccessCheckByTypeResultListAndAuditAlarm +ZwAccessCheckByTypeResultListAndAuditAlarmByHan +ZwAddAtom +ZwAddBootEntry +ZwAdjustGroupsToken +ZwAdjustPrivilegesToken +ZwAlertResumeThread +ZwAlertThread +ZwAllocateLocallyUniqueId +ZwAllocateUserPhysicalPages +ZwAllocateUuids +ZwAllocateVirtualMemory +ZwAreMappedFilesTheSame +ZwAssignProcessToJobObject +ZwCallbackReturn +ZwCancelDeviceWakeupRequest +ZwCancelIoFile +ZwCancelTimer +ZwClearEvent +ZwClose +ZwCloseObjectAuditAlarm +ZwCompactKeys +ZwCompareTokens +ZwCompleteConnectPort +ZwCompressKey +ZwConnectPort +ZwContinue +ZwCreateDebugObject +ZwCreateDirectoryObject +ZwCreateEvent +ZwCreateEventPair +ZwCreateFile +ZwCreateIoCompletion +ZwCreateJobObject +ZwCreateJobSet +ZwCreateKey +ZwCreateKeyedEvent +ZwCreateMailslotFile +ZwCreateMutant +ZwCreateNamedPipeFile +ZwCreatePagingFile +ZwCreatePort +ZwCreateProcess +ZwCreateProcessEx +ZwCreateProfile +ZwCreateSection +ZwCreateSemaphore +ZwCreateSymbolicLinkObject +ZwCreateThread +ZwCreateTimer +ZwCreateToken +ZwCreateWaitablePort +ZwDebugActiveProcess +ZwDebugContinue +ZwDelayExecution +ZwDeleteAtom +ZwDeleteBootEntry +ZwDeleteFile +ZwDeleteKey +ZwDeleteObjectAuditAlarm +ZwDeleteValueKey +ZwDeviceIoControlFile +ZwDisplayString +ZwDuplicateObject +ZwDuplicateToken +ZwEnumerateBootEntries +ZwEnumerateKey +ZwEnumerateSystemEnvironmentValuesEx +ZwEnumerateValueKey +ZwExtendSection +ZwFilterToken +ZwFindAtom +ZwFlushBuffersFile +ZwFlushInstructionCache +ZwFlushKey +ZwFlushVirtualMemory +ZwFlushWriteBuffer +ZwFreeUserPhysicalPages +ZwFreeVirtualMemory +ZwFsControlFile +ZwGetContextThread +ZwGetDevicePowerState +ZwGetPlugPlayEvent +ZwGetWriteWatch +ZwImpersonateAnonymousToken +ZwImpersonateClientOfPort +ZwImpersonateThread +ZwInitializeRegistry +ZwInitiatePowerAction +ZwIsProcessInJob +ZwIsSystemResumeAutomatic +ZwListenPort +ZwLoadDriver +ZwLoadKey +ZwLoadKey2 +ZwLockFile +ZwLockProductActivationKeys +ZwLockRegistryKey +ZwLockVirtualMemory +ZwMakePermanentObject +ZwMakeTemporaryObject +ZwMapUserPhysicalPages +ZwMapUserPhysicalPagesScatter +ZwMapViewOfSection +ZwModifyBootEntry +ZwNotifyChangeDirectoryFile +ZwNotifyChangeKey +ZwNotifyChangeMultipleKeys +ZwOpenDirectoryObject +ZwOpenEvent +ZwOpenEventPair +ZwOpenFile +ZwOpenIoCompletion +ZwOpenJobObject +ZwOpenKey +ZwOpenKeyedEvent +ZwOpenMutant +ZwOpenObjectAuditAlarm +ZwOpenProcess +ZwOpenProcessToken +ZwOpenProcessTokenEx +ZwOpenSection +ZwOpenSemaphore +ZwOpenSymbolicLinkObject +ZwOpenThread +ZwOpenThreadToken +ZwOpenThreadTokenEx +ZwOpenTimer +ZwPlugPlayControl +ZwPowerInformation +ZwPrivilegeCheck +ZwPrivilegeObjectAuditAlarm +ZwPrivilegedServiceAuditAlarm +ZwProtectVirtualMemory +ZwPulseEvent +ZwQueryAttributesFile +ZwQueryBootEntryOrder +ZwQueryBootOptions +ZwQueryDebugFilterState +ZwQueryDefaultLocale +ZwQueryDefaultUILanguage +ZwQueryDirectoryFile +ZwQueryDirectoryObject +ZwQueryEaFile +ZwQueryEvent +ZwQueryFullAttributesFile +ZwQueryInformationAtom +ZwQueryInformationFile +ZwQueryInformationJobObject +ZwQueryInformationPort +ZwQueryInformationProcess +ZwQueryInformationThread +ZwQueryInformationToken +ZwQueryInstallUILanguage +ZwQueryIntervalProfile +ZwQueryIoCompletion +ZwQueryKey +ZwQueryMultipleValueKey +ZwQueryMutant +ZwQueryObject +ZwQueryOpenSubKeys +ZwQueryPerformanceCounter +ZwQueryPortInformationProcess +ZwQueryQuotaInformationFile +ZwQuerySection +ZwQuerySecurityObject +ZwQuerySemaphore +ZwQuerySymbolicLinkObject +ZwQuerySystemEnvironmentValue +ZwQuerySystemEnvironmentValueEx +ZwQuerySystemInformation +ZwQuerySystemTime +ZwQueryTimer +ZwQueryTimerResolution +ZwQueryValueKey +ZwQueryVirtualMemory +ZwQueryVolumeInformationFile +ZwQueueApcThread +ZwRaiseException +ZwRaiseHardError +ZwReadFile +ZwReadFileScatter +ZwReadRequestData +ZwReadVirtualMemory +ZwRegisterThreadTerminatePort +ZwReleaseKeyedEvent +ZwReleaseMutant +ZwReleaseSemaphore +ZwRemoveIoCompletion +ZwRemoveProcessDebug +ZwRenameKey +ZwReplaceKey +ZwReplyPort +ZwReplyWaitReceivePort +ZwReplyWaitReceivePortEx +ZwReplyWaitReplyPort +ZwRequestDeviceWakeup +ZwRequestPort +ZwRequestWaitReplyPort +ZwRequestWakeupLatency +ZwResetEvent +ZwResetWriteWatch +ZwRestoreKey +ZwResumeProcess +ZwResumeThread +ZwSaveKey +ZwSaveKeyEx +ZwSaveMergedKeys +ZwSecureConnectPort +ZwSetBootEntryOrder +ZwSetBootOptions +ZwSetContextThread +ZwSetDebugFilterState +ZwSetDefaultHardErrorPort +ZwSetDefaultLocale +ZwSetDefaultUILanguage +ZwSetEaFile +ZwSetEvent +ZwSetEventBoostPriority +ZwSetHighEventPair +ZwSetHighWaitLowEventPair +ZwSetInformationDebugObject +ZwSetInformationFile +ZwSetInformationJobObject +ZwSetInformationKey +ZwSetInformationObject +ZwSetInformationProcess +ZwSetInformationThread +ZwSetInformationToken +ZwSetIntervalProfile +ZwSetIoCompletion +ZwSetLdtEntries +ZwSetLowEventPair +ZwSetLowWaitHighEventPair +ZwSetQuotaInformationFile +ZwSetSecurityObject +ZwSetSystemEnvironmentValue +ZwSetSystemEnvironmentValueEx +ZwSetSystemInformation +ZwSetSystemPowerState +ZwSetSystemTime +ZwSetThreadExecutionState +ZwSetTimer +ZwSetTimerResolution +ZwSetUuidSeed +ZwSetValueKey +ZwSetVolumeInformationFile +ZwShutdownSystem +ZwSignalAndWaitForSingleObject +ZwStartProfile +ZwStopProfile +ZwSuspendProcess +ZwSuspendThread +ZwSystemDebugControl +ZwTerminateJobObject +ZwTerminateProcess +ZwTerminateThread +ZwTestAlert +ZwTraceEvent +ZwTranslateFilePath +ZwUnloadDriver +ZwUnloadKey +ZwUnloadKeyEx +ZwUnlockFile +ZwUnlockVirtualMemory +ZwUnmapViewOfSection +ZwVdmControl +ZwWaitForDebugEvent +ZwWaitForKeyedEvent +ZwWaitForMultipleObjects +ZwWaitForSingleObject +ZwWaitHighEventPair +ZwWaitLowEventPair +ZwWriteFile +ZwWriteFileGather +ZwWriteRequestData +ZwWriteVirtualMemory +ZwYieldExecution +_CIcos +_CIlog +_CIpow +_CIsin +_CIsqrt +__isascii +__iscsym +__iscsymf +__toascii +_alldiv +_alldvrm +_allmul +_alloca_probe +_allrem +_allshl +_allshr +_atoi64 +_aulldiv +_aulldvrm +_aullrem +_aullshr +_chkstk +_fltused +_ftol +_i64toa +_i64tow +_itoa +_itow +_lfind +_ltoa +_ltow +_memccpy +_memicmp +_snprintf +_snwprintf +_splitpath +_strcmpi +_stricmp +_strlwr +_strnicmp +_strupr +_tolower +_toupper +_ui64toa +_ui64tow +_ultoa +_ultow +_vsnprintf +_vsnwprintf +_wcsicmp +_wcslwr +_wcsnicmp +_wcsupr +_wtoi +_wtoi64 +_wtol +abs +atan +atoi +atol +bsearch +ceil +cos +fabs +floor +isalnum +isalpha +iscntrl +isdigit +isgraph +islower +isprint +ispunct +isspace +isupper +iswalpha +iswctype +iswdigit +iswlower +iswspace +iswxdigit +isxdigit +labs +log +mbstowcs +memchr +memcmp +memcpy +memmove +memset +pow +qsort +sin +sprintf +sqrt +sscanf +strcat +strchr +strcmp +strcpy +strcspn +strlen +strncat +strncmp +strncpy +strpbrk +strrchr +strspn +strstr +strtol +strtoul +swprintf +tan +tolower +toupper +towlower +towupper +vDbgPrintEx +vDbgPrintExWithPrefix +vsprintf +wcscat +wcschr +wcscmp +wcscpy +wcscspn +wcslen +wcsncat +wcsncmp +wcsncpy +wcspbrk +wcsrchr +wcsspn +wcsstr +wcstol +wcstombs +wcstoul \ No newline at end of file diff --git a/xpstub/vsenv.bat b/xpstub/vsenv.bat index 9379fbc..2ea80fe 100644 --- a/xpstub/vsenv.bat +++ b/xpstub/vsenv.bat @@ -1,9 +1,19 @@ @echo off +setlocal enabledelayedexpansion -for /f "usebackq tokens=*" %%i in (`vswhere -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath`) do ( - set InstallDir=%%i -) +set VSWHERE="%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -if exist "%InstallDir%\Common7\Tools\vsdevcmd.bat" ( - "%InstallDir%\Common7\Tools\vsdevcmd.bat" %* +if exist %VSWHERE% ( + for /f "usebackq tokens=*" %%i in (`%VSWHERE% -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath`) do ( + set InstallDir=%%i + echo Found Visual Studio installation at: !InstallDir! + ) + + if exist "!InstallDir!\Common7\Tools\VsDevCmd.bat" ( + "!InstallDir!\Common7\Tools\VsDevCmd.bat" %* + ) else ( + echo VsDevCmd.bat not found. + ) +) else ( + echo vswhere.exe not found. Please refer to https://github.com/microsoft/vswhere for more information. ) \ No newline at end of file diff --git a/xpstub/xpstub.c b/xpstub/xpstub.c index 7a699e9..9938e0e 100644 --- a/xpstub/xpstub.c +++ b/xpstub/xpstub.c @@ -8,10 +8,22 @@ typedef PRTL_RUN_ONCE LPINIT_ONCE; #define STATUS_INVALID_PARAMETER_3 0xC00000F1 #define STATUS_INVALID_OWNER 0xC000005A #define STATUS_OBJECT_NAME_COLLISION 0xC0000035 +#define STATUS_BUFFER_OVERFLOW 0x80000005 // TODO: // from: https://github.com/Chuyu-Team/YY-Thunks/blob/master/ThunksList.md +typedef struct _IO_STATUS_BLOCK +{ + union + { + NTSTATUS Status; + PVOID Pointer; + } DUMMYUNIONNAME; + + ULONG_PTR Information; +} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK; + // NT FUNCTION // from: http://undocumented.ntinternals.net/index.html typedef struct _UNICODE_STRING { @@ -45,10 +57,113 @@ typedef NTSTATUS (WINAPI* NTWAITFORKEYEDEVENT)( IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL ); +typedef enum _OBJECT_INFORMATION_CLASS +{ + ObjectBasicInformation, + ObjectNameInformation, + ObjectTypeInformation, + ObjectAllInformation, + ObjectDataInformation +}OBJECT_INFORMATION_CLASS, *POBJECT_INFORMATION_CLASS; + +typedef enum _FILE_INFORMATION_CLASS +{ + FileDirectoryInformation = 1, + FileFullDirectoryInformation, // 2 + FileBothDirectoryInformation, // 3 + FileBasicInformation, // 4 + FileStandardInformation, // 5 + FileInternalInformation, // 6 + FileEaInformation, // 7 + FileAccessInformation, // 8 + FileNameInformation, // 9 + FileRenameInformation, // 10 + FileLinkInformation, // 11 + FileNamesInformation, // 12 + FileDispositionInformation, // 13 + FilePositionInformation, // 14 + FileFullEaInformation, // 15 + FileModeInformation, // 16 + FileAlignmentInformation, // 17 + FileAllInformation, // 18 + FileAllocationInformation, // 19 + FileEndOfFileInformation, // 20 + FileAlternateNameInformation, // 21 + FileStreamInformation, // 22 + FilePipeInformation, // 23 + FilePipeLocalInformation, // 24 + FilePipeRemoteInformation, // 25 + FileMailslotQueryInformation, // 26 + FileMailslotSetInformation, // 27 + FileCompressionInformation, // 28 + FileObjectIdInformation, // 29 + FileCompletionInformation, // 30 + FileMoveClusterInformation, // 31 + FileQuotaInformation, // 32 + FileReparsePointInformation, // 33 + FileNetworkOpenInformation, // 34 + FileAttributeTagInformation, // 35 + FileTrackingInformation, // 36 + FileIdBothDirectoryInformation, // 37 + FileIdFullDirectoryInformation, // 38 + FileValidDataLengthInformation, // 39 + FileShortNameInformation, // 40 + FileIoCompletionNotificationInformation, // 41 + FileIoStatusBlockRangeInformation, // 42 + FileIoPriorityHintInformation, // 43 + FileSfioReserveInformation, // 44 + FileSfioVolumeInformation, // 45 + FileHardLinkInformation, // 46 + FileProcessIdsUsingFileInformation, // 47 + FileNormalizedNameInformation, // 48 + FileNetworkPhysicalNameInformation, // 49 + FileIdGlobalTxDirectoryInformation, // 50 + FileIsRemoteDeviceInformation, // 51 + FileUnusedInformation, // 52 + FileNumaNodeInformation, // 53 + FileStandardLinkInformation, // 54 + FileRemoteProtocolInformation, // 55 + + // + // These are special versions of these operations (defined earlier) + // which can be used by kernel mode drivers only to bypass security + // access checks for Rename and HardLink operations. These operations + // are only recognized by the IOManager, a file system should never + // receive these. + // + FileRenameInformationBypassAccessCheck, // 56 + FileLinkInformationBypassAccessCheck, // 57 + FileVolumeNameInformation, // 58 + FileIdInformation, // 59 + FileIdExtdDirectoryInformation, // 60 + FileReplaceCompletionInformation, // 61 + FileHardLinkFullIdInformation, // 62 + FileIdExtdBothDirectoryInformation, // 63 + FileMaximumInformation + +} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS; + + +typedef NTSTATUS (NTAPI *pNtQueryObject)( + HANDLE Handle, + OBJECT_INFORMATION_CLASS ObjectInformationClass, + PVOID ObjectInformation, + ULONG ObjectInformationLength, + PULONG ReturnLength +); +typedef NTSTATUS (NTAPI *pNtQueryInformationFile)( + HANDLE FileHandle, + PIO_STATUS_BLOCK IoStatusBlock, + PVOID FileInformation, + ULONG Length, + FILE_INFORMATION_CLASS FileInformationClass +); NTOPENKEYEDEVENT NtOpenKeyedEvent; NTRELEASEKEYEDEVENT NtReleaseKeyedEvent; NTWAITFORKEYEDEVENT NtWaitForKeyedEvent; ULONG (NTAPI*RtlNtStatusToDosError)(IN NTSTATUS status); +pNtQueryObject NtQueryObject; +pNtQueryInformationFile NtQueryInformationFile; #define STATUS_RESOURCE_NOT_OWNED 0xC0000264 @@ -102,6 +217,17 @@ struct PROCESSOR_NUMBER_ BYTE Reserved; }; + +typedef struct _OBJECT_NAME_INFORMATION +{ + UNICODE_STRING Name; +} OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION; + +typedef struct _FILE_NAME_INFORMATION { + ULONG FileNameLength; + WCHAR FileName[1]; +} FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION; + struct GDI_TEB_BATCH_ { union @@ -1251,6 +1377,479 @@ InitOnceCompleteXP(LPINIT_ONCE lpInitOnce, DWORD dwFlags, LPVOID lpContext) } } +static BOOL __fastcall BasepGetVolumeGUIDFromNTName(const UNICODE_STRING* NtName, wchar_t szVolumeGUID[MAX_PATH]) +{ +#define __szVolumeMountPointPrefix__ L"\\\\?\\GLOBALROOT" + + //一个设备名称 512 长度够多了吧? + wchar_t szVolumeMountPoint[512]; + + //检查缓冲区是否充足 + auto cbBufferNeed = sizeof(__szVolumeMountPointPrefix__) + NtName->Length; + + if (cbBufferNeed > sizeof(szVolumeMountPoint)) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } + + memcpy(szVolumeMountPoint, __szVolumeMountPointPrefix__, sizeof(__szVolumeMountPointPrefix__) - sizeof(__szVolumeMountPointPrefix__[0])); + memcpy((char*)szVolumeMountPoint + sizeof(__szVolumeMountPointPrefix__) - sizeof(__szVolumeMountPointPrefix__[0]), NtName->Buffer, NtName->Length); + + szVolumeMountPoint[cbBufferNeed / 2 - 1] = L'\0'; + + return GetVolumeNameForVolumeMountPointW(szVolumeMountPoint, szVolumeGUID, MAX_PATH); + +#undef __szVolumeMountPointPrefix__ +} + +static BOOL __fastcall BasepGetVolumeDosLetterNameFromNTName(const UNICODE_STRING* NtName, wchar_t szVolumeDosLetter[MAX_PATH]) +{ + wchar_t szVolumeName[MAX_PATH]; + + if (!BasepGetVolumeGUIDFromNTName(NtName, szVolumeName)) + { + return FALSE; + } + + DWORD cchVolumePathName = 0; + + if (!GetVolumePathNamesForVolumeNameW(szVolumeName, szVolumeDosLetter + 4, MAX_PATH - 4, &cchVolumePathName)) + { + return FALSE; + } + + szVolumeDosLetter[0] = L'\\'; + szVolumeDosLetter[1] = L'\\'; + szVolumeDosLetter[2] = L'?'; + szVolumeDosLetter[3] = L'\\'; + + return TRUE; +} + +BOOL +WINAPI +GetQueuedCompletionStatusExXP(HANDLE CompletionPort, LPOVERLAPPED_ENTRY lpCompletionPortEntries, ULONG ulCount, PULONG ulNumEntriesRemoved, DWORD dwMilliseconds, BOOL fAlertable) +{ + if (ulCount == 0 || lpCompletionPortEntries == 0 || ulNumEntriesRemoved == 0) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + *ulNumEntriesRemoved = 0; + + OVERLAPPED_ENTRY _Entry = lpCompletionPortEntries[0]; + + if (fAlertable) + { + // 使用 WaitForSingleObjectEx 进行等待触发 APC + DWORD _uStartTick = GetTickCount(); + for (;;) + { + const DWORD _uResult = WaitForSingleObjectEx(CompletionPort, dwMilliseconds, TRUE); + if (_uResult == WAIT_OBJECT_0) + { + // 完成端口有数据了 + DWORD _bRet = GetQueuedCompletionStatus(CompletionPort, &_Entry.dwNumberOfBytesTransferred, &_Entry.lpCompletionKey, &_Entry.lpOverlapped, 0); + if (_bRet) + { + *ulNumEntriesRemoved = 1; + break; + } + + if (GetLastError() != WAIT_TIMEOUT) + { + return FALSE; + } + + // 无限等待时无脑继续等即可。 + if (dwMilliseconds == INFINITE) + { + continue; + } + + // 计算剩余等待时间,如果剩余等待时间归零则返回 + const DWORD _uTickSpan = GetTickCount() - _uStartTick; + if (_uTickSpan >= dwMilliseconds) + { + SetLastError(WAIT_TIMEOUT); + return FALSE; + } + dwMilliseconds -= _uTickSpan; + _uStartTick += _uTickSpan; + continue; + } + else if (_uResult == WAIT_IO_COMPLETION || _uResult == WAIT_TIMEOUT) + { + // 很奇怪,微软原版遇到 APC唤醒直接会设置 LastError WAIT_IO_COMPLETION + // 遇到超时,LastError WAIT_TIMEOUT(注意不是预期的 ERROR_TIMEOUT)不知道是故意还是有意。 + SetLastError(_uResult); + return FALSE; + } + else if (_uResult == WAIT_ABANDONED) + { + SetLastError(ERROR_ABANDONED_WAIT_0); + return FALSE; + } + else if (_uResult == WAIT_FAILED) + { + // LastError + return FALSE; + } + else + { + // LastError ??? + return FALSE; + } + } + + return TRUE; + } + else + { + DWORD _bRet = GetQueuedCompletionStatus(CompletionPort, &_Entry.dwNumberOfBytesTransferred, &_Entry.lpCompletionKey, &_Entry.lpOverlapped, dwMilliseconds); + if (_bRet) + { + *ulNumEntriesRemoved = 1; + } + return _bRet; + } +} + +BOOL +WINAPI +SetFileCompletionNotificationModesXP(HANDLE FileHandle, UCHAR Flags) +{ + // 初步看起来没有什么的,只是会降低完成端口的效率。 + // 至少需要 Vista才支持 FileIoCompletionNotificationInformation + // 只能假定先返回成功。 + return TRUE; +} + +DWORD +WINAPI +GetFinalPathNameByHandleWXP( + HANDLE hFile, + LPWSTR lpszFilePath, + DWORD cchFilePath, + DWORD dwFlags + ) +{ + //参数检查 + if (INVALID_HANDLE_VALUE == hFile) + { + SetLastError(ERROR_INVALID_HANDLE); + return 0; + } + + + switch (dwFlags & (VOLUME_NAME_DOS | VOLUME_NAME_GUID | VOLUME_NAME_NONE | VOLUME_NAME_NT)) + { + case VOLUME_NAME_DOS: + break; + case VOLUME_NAME_GUID: + break; + case VOLUME_NAME_NT: + break; + case VOLUME_NAME_NONE: + break; + default: + SetLastError(ERROR_INVALID_PARAMETER); + return 0; + break; + } + + UNICODE_STRING VolumeNtName = { 0 }; + + wchar_t szVolumeRoot[MAX_PATH]; + szVolumeRoot[0] = L'\0'; + + wchar_t* szLongPathNameBuffer = NULL; + + //目标所需的分区名称,不包含最后的 '\\' + UNICODE_STRING TargetVolumeName = { 0 }; + //目标所需的文件名,开始包含 '\\' + UNICODE_STRING TargetFileName = { 0 }; + + HANDLE ProcessHeap = ((struct TEB_*)NtTeb())->ProcessEnvironmentBlock->ProcessHeap; + LSTATUS lStatus = ERROR_SUCCESS; + DWORD cchReturn = 0; + + OBJECT_NAME_INFORMATION* pObjectName = NULL; + ULONG cbObjectName = 528; + + FILE_NAME_INFORMATION* pFileNameInfo = NULL; + ULONG cbFileNameInfo = 528; + + for (;;) + { + if (pObjectName) + { + OBJECT_NAME_INFORMATION* pNewBuffer = (OBJECT_NAME_INFORMATION*)(void *)HeapReAlloc(ProcessHeap, 0, pObjectName, cbObjectName); + + if (!pNewBuffer) + { + lStatus = ERROR_NOT_ENOUGH_MEMORY; + goto __Exit; + } + + pObjectName = pNewBuffer; + } + else + { + pObjectName = (OBJECT_NAME_INFORMATION*)HeapAlloc(ProcessHeap, 0, cbObjectName); + + if (!pObjectName) + { + //内存不足? + lStatus = ERROR_NOT_ENOUGH_MEMORY; + goto __Exit; + } + } + + NTSTATUS Status = NtQueryObject(hFile, ObjectNameInformation, pObjectName, cbObjectName, &cbObjectName); + + if (STATUS_BUFFER_OVERFLOW == Status) + { + continue; + } + else if (Status < 0) + { + lStatus = NtStatusToDosError(Status); + + goto __Exit; + } + else + { + break; + } + } + + for (;;) + { + if (pFileNameInfo) + { + FILE_NAME_INFORMATION* pNewBuffer = (FILE_NAME_INFORMATION*)HeapReAlloc(ProcessHeap, 0, pFileNameInfo, cbFileNameInfo); + if (!pNewBuffer) + { + lStatus = ERROR_NOT_ENOUGH_MEMORY; + goto __Exit; + } + + pFileNameInfo = pNewBuffer; + } + else + { + pFileNameInfo = (FILE_NAME_INFORMATION*)HeapAlloc(ProcessHeap, 0, cbFileNameInfo); + + if (!pFileNameInfo) + { + //内存不足? + lStatus = ERROR_NOT_ENOUGH_MEMORY; + goto __Exit; + } + } + + IO_STATUS_BLOCK IoStatusBlock; + + NTSTATUS Status = NtQueryInformationFile(hFile, &IoStatusBlock, pFileNameInfo, cbFileNameInfo, FileNameInformation); + + if (STATUS_BUFFER_OVERFLOW == Status) + { + cbFileNameInfo = pFileNameInfo->FileNameLength + sizeof(FILE_NAME_INFORMATION); + continue; + } + else if (Status < 0) + { + lStatus = NtStatusToDosError(Status); + + goto __Exit; + } + else + { + break; + } + } + + if (pFileNameInfo->FileName[0] != '\\') + { + lStatus = ERROR_ACCESS_DENIED; + goto __Exit; + } + + + + if (pFileNameInfo->FileNameLength >= pObjectName->Name.Length) + { + lStatus = ERROR_BAD_PATHNAME; + goto __Exit; + } + + VolumeNtName.Buffer = pObjectName->Name.Buffer; + VolumeNtName.Length = VolumeNtName.MaximumLength = pObjectName->Name.Length - pFileNameInfo->FileNameLength + sizeof(wchar_t); + + + if (VOLUME_NAME_NT & dwFlags) + { + //返回NT路径 + TargetVolumeName.Buffer = VolumeNtName.Buffer; + TargetVolumeName.Length = TargetVolumeName.MaximumLength = VolumeNtName.Length - sizeof(wchar_t); + } + else if (VOLUME_NAME_NONE & dwFlags) + { + //仅返回文件名 + } + else + { + if (VOLUME_NAME_GUID & dwFlags) + { + //返回分区GUID名称 + if (!BasepGetVolumeGUIDFromNTName(&VolumeNtName, szVolumeRoot)) + { + lStatus = GetLastError(); + goto __Exit; + } + } + else + { + //返回Dos路径 + if (!BasepGetVolumeDosLetterNameFromNTName(&VolumeNtName, szVolumeRoot)) + { + lStatus = GetLastError(); + goto __Exit; + } + } + + TargetVolumeName.Buffer = szVolumeRoot; + TargetVolumeName.Length = TargetVolumeName.MaximumLength = (wcslen(szVolumeRoot) - 1) * sizeof(szVolumeRoot[0]); + } + + //将路径进行规范化 + if ((FILE_NAME_OPENED & dwFlags) == 0) + { + //由于 Windows XP不支持 FileNormalizedNameInformation,所以我们直接调用 GetLongPathNameW 获取完整路径。 + + DWORD cbszVolumeRoot = TargetVolumeName.Length; + + if (szVolumeRoot[0] == L'\0') + { + //转换分区信息 + + if (!BasepGetVolumeDosLetterNameFromNTName(&VolumeNtName, szVolumeRoot)) + { + lStatus = GetLastError(); + + if(lStatus == ERROR_NOT_ENOUGH_MEMORY) + goto __Exit; + + if (!BasepGetVolumeGUIDFromNTName(&VolumeNtName, szVolumeRoot)) + { + lStatus = GetLastError(); + goto __Exit; + } + } + + cbszVolumeRoot = (wcslen(szVolumeRoot) - 1) * sizeof(szVolumeRoot[0]); + } + + + + DWORD cbLongPathNameBufferSize = cbszVolumeRoot + pFileNameInfo->FileNameLength + 1024; + + szLongPathNameBuffer = (wchar_t*)HeapAlloc(ProcessHeap, 0, cbLongPathNameBufferSize); + if (!szLongPathNameBuffer) + { + lStatus = ERROR_NOT_ENOUGH_MEMORY; + goto __Exit; + } + + DWORD cchLongPathNameBufferSize = cbLongPathNameBufferSize / sizeof(szLongPathNameBuffer[0]); + + memcpy(szLongPathNameBuffer, szVolumeRoot, cbszVolumeRoot); + memcpy((char*)szLongPathNameBuffer + cbszVolumeRoot, pFileNameInfo->FileName, pFileNameInfo->FileNameLength); + szLongPathNameBuffer[(cbszVolumeRoot + pFileNameInfo->FileNameLength) / sizeof(wchar_t)] = L'\0'; + + for (;;) + { + DWORD result = GetLongPathNameW(szLongPathNameBuffer, szLongPathNameBuffer, cchLongPathNameBufferSize); + + if (result == 0) + { + //失败 + lStatus = GetLastError(); + goto __Exit; + } + else if (result >= cchLongPathNameBufferSize) + { + cchLongPathNameBufferSize = result + 1; + + wchar_t* pNewLongPathName = (wchar_t*)HeapReAlloc(ProcessHeap, 0, szLongPathNameBuffer, cchLongPathNameBufferSize * sizeof(wchar_t)); + if (!pNewLongPathName) + { + lStatus = ERROR_NOT_ENOUGH_MEMORY; + goto __Exit; + } + + szLongPathNameBuffer = pNewLongPathName; + + } + else + { + //转换成功 + TargetFileName.Buffer = (wchar_t*)((char*)szLongPathNameBuffer + cbszVolumeRoot); + TargetFileName.Length = TargetFileName.MaximumLength = result * sizeof(wchar_t) - cbszVolumeRoot; + break; + } + } + } + else + { + //直接返回原始路径 + TargetFileName.Buffer = pFileNameInfo->FileName; + TargetFileName.Length = TargetFileName.MaximumLength = pFileNameInfo->FileNameLength; + } + + + //返回结果,根目录 + 文件名 的长度 + cchReturn = (TargetVolumeName.Length + TargetFileName.Length) / sizeof(wchar_t); + + if (cchFilePath <= cchReturn) + { + //长度不足…… + + cchReturn += 1; + } + else + { + //复制根目录 + memcpy(lpszFilePath, TargetVolumeName.Buffer, TargetVolumeName.Length); + //复制文件名 + memcpy((char*)lpszFilePath + TargetVolumeName.Length, TargetFileName.Buffer, TargetFileName.Length); + //保证字符串 '\0' 截断 + lpszFilePath[cchReturn] = L'\0'; + } + +__Exit: + if (pFileNameInfo) + HeapFree(ProcessHeap, 0, pFileNameInfo); + if (pObjectName) + HeapFree(ProcessHeap, 0, pObjectName); + if (szLongPathNameBuffer) + HeapFree(ProcessHeap, 0, szLongPathNameBuffer); + + if (lStatus != ERROR_SUCCESS) + { + SetLastError(lStatus); + return 0; + } + else + { + return cchReturn; + } +} + + VOID WINAPI stub() { RaiseStatus(STATUS_ACCESS_VIOLATION); } BOOL WINAPI DllMain( @@ -1267,6 +1866,8 @@ BOOL WINAPI DllMain( NtReleaseKeyedEvent = (NTRELEASEKEYEDEVENT)GetProcAddress(ntdll, "NtReleaseKeyedEvent"); NtWaitForKeyedEvent = (NTWAITFORKEYEDEVENT)GetProcAddress(ntdll, "NtWaitForKeyedEvent"); RtlNtStatusToDosError = (ULONG (NTAPI*)(IN NTSTATUS status))GetProcAddress(ntdll, "RtlNtStatusToDosError"); + NtQueryObject = (pNtQueryObject)GetProcAddress(ntdll, "NtQueryObject"); + NtQueryInformationFile = (pNtQueryInformationFile)GetProcAddress(ntdll, "NtQueryInformationFile"); } break; case DLL_PROCESS_DETACH: diff --git a/xpstub/xpstub.def b/xpstub/xpstub.def index 911795a..7ccad7f 100644 --- a/xpstub/xpstub.def +++ b/xpstub/xpstub.def @@ -9,6 +9,10 @@ EXPORTS AcquireSRWLockExclusive = AcquireSRWLockExclusiveXP InitOnceBeginInitialize = InitOnceBeginInitializeXP InitOnceComplete = InitOnceCompleteXP + GetQueuedCompletionStatusEx = GetQueuedCompletionStatusExXP + SetFileCompletionNotificationModes = SetFileCompletionNotificationModesXP + GetFinalPathNameByHandleW = GetFinalPathNameByHandleWXP + NtCancelIoFileEx = NTDLL.NtCancelIoFile ; forward to kernel32. ActivateActCtx = KERNEL32.ActivateActCtx