[NTDLL:LDR] Little fixes about SAL annotation and behavior (#5793)

- Uniform function declarations in .c and .h with fixes and SAL2 improvements.
- Use LDR_[UN]LOCK_LOADER_LOCK_FLAG_XXX correctly.
- Fix incorrect UsedSize calculation in LdrQueryProcessModuleInformationEx (caught by ThFabba).
- Whatever the callback request stop the enumeration or not in LdrEnumerateLoadedModules, the following operations should be the same.
- Fix 2 incorrect DPRINT1 that printed incorrect parameter.
- Return error if RtlAllocateHeap failed in LdrpGetProcedureAddress, and add comments about NT6.2 new changes.
This commit is contained in:
Ratin Gao 2023-11-16 03:59:32 +08:00 committed by GitHub
parent bd9e2d6beb
commit bd0a5498b0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 120 additions and 103 deletions

View file

@ -309,10 +309,11 @@ LdrLockLoaderLock(
NTSTATUS
NTAPI
DECLSPEC_HOTPATCH
LdrLoadDll(IN PWSTR SearchPath OPTIONAL,
IN PULONG DllCharacteristics OPTIONAL,
IN PUNICODE_STRING DllName,
OUT PVOID *BaseAddress)
LdrLoadDll(
_In_opt_ PWSTR SearchPath,
_In_opt_ PULONG DllCharacteristics,
_In_ PUNICODE_STRING DllName,
_Out_ PVOID *BaseAddress)
{
WCHAR StringBuffer[MAX_PATH];
UNICODE_STRING DllString1, DllString2;
@ -426,7 +427,7 @@ LdrLoadDll(IN PWSTR SearchPath OPTIONAL,
LdrpTopLevelDllBeingLoaded = OldTldDll;
/* Release the lock */
LdrUnlockLoaderLock(LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS, Cookie);
LdrUnlockLoaderLock(LDR_UNLOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS, Cookie);
}
_SEH2_END;
@ -793,7 +794,7 @@ Quickie:
/* Release lock */
if (Locked)
{
LdrUnlockLoaderLock(LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS,
LdrUnlockLoaderLock(LDR_UNLOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS,
Cookie);
}
@ -840,10 +841,11 @@ LdrGetProcedureAddress(
*/
NTSTATUS
NTAPI
LdrVerifyImageMatchesChecksum(IN HANDLE FileHandle,
IN PLDR_CALLBACK Callback,
IN PVOID CallbackContext,
OUT PUSHORT ImageCharacteristics)
LdrVerifyImageMatchesChecksum(
_In_ HANDLE FileHandle,
_In_ PLDR_CALLBACK Callback,
_In_ PVOID CallbackContext,
_Out_ PUSHORT ImageCharacteristics)
{
FILE_STANDARD_INFORMATION FileStandardInfo;
PIMAGE_IMPORT_DESCRIPTOR ImportData;
@ -982,18 +984,19 @@ LdrVerifyImageMatchesChecksum(IN HANDLE FileHandle,
NTSTATUS
NTAPI
LdrQueryProcessModuleInformationEx(IN ULONG ProcessId,
IN ULONG Reserved,
OUT PRTL_PROCESS_MODULES ModuleInformation,
IN ULONG Size,
OUT PULONG ReturnedSize OPTIONAL)
LdrQueryProcessModuleInformationEx(
_In_opt_ ULONG ProcessId,
_Reserved_ ULONG Reserved,
_Out_writes_bytes_to_(Size, *ReturnedSize) PRTL_PROCESS_MODULES ModuleInformation,
_In_ ULONG Size,
_Out_opt_ PULONG ReturnedSize)
{
PLIST_ENTRY ModuleListHead, InitListHead;
PLIST_ENTRY Entry, InitEntry;
PLDR_DATA_TABLE_ENTRY Module, InitModule;
PRTL_PROCESS_MODULE_INFORMATION ModulePtr = NULL;
NTSTATUS Status = STATUS_SUCCESS;
ULONG UsedSize = sizeof(ULONG);
ULONG UsedSize = FIELD_OFFSET(RTL_PROCESS_MODULES, Modules);
ANSI_STRING AnsiString;
PCHAR p;
@ -1110,9 +1113,10 @@ LdrQueryProcessModuleInformationEx(IN ULONG ProcessId,
*/
NTSTATUS
NTAPI
LdrQueryProcessModuleInformation(IN PRTL_PROCESS_MODULES ModuleInformation,
IN ULONG Size,
OUT PULONG ReturnedSize OPTIONAL)
LdrQueryProcessModuleInformation(
_Out_writes_bytes_to_(Size, *ReturnedSize) PRTL_PROCESS_MODULES ModuleInformation,
_In_ ULONG Size,
_Out_opt_ PULONG ReturnedSize)
{
/* Call Ex version of the API */
return LdrQueryProcessModuleInformationEx(0, 0, ModuleInformation, Size, ReturnedSize);
@ -1123,9 +1127,10 @@ LdrQueryProcessModuleInformation(IN PRTL_PROCESS_MODULES ModuleInformation,
*/
NTSTATUS
NTAPI
LdrEnumerateLoadedModules(IN BOOLEAN ReservedFlag,
IN PLDR_ENUM_CALLBACK EnumProc,
IN PVOID Context)
LdrEnumerateLoadedModules(
_Reserved_ ULONG ReservedFlag,
_In_ PLDR_ENUM_CALLBACK EnumProc,
_In_opt_ PVOID Context)
{
PLIST_ENTRY ListHead, ListEntry;
PLDR_DATA_TABLE_ENTRY LdrEntry;
@ -1161,28 +1166,24 @@ LdrEnumerateLoadedModules(IN BOOLEAN ReservedFlag,
/* Break if we were asked to stop enumeration */
if (Stop)
{
/* Release loader lock */
Status = LdrUnlockLoaderLock(0, Cookie);
/* Reset any successful status to STATUS_SUCCESS, but leave
failure to the caller */
if (NT_SUCCESS(Status))
Status = STATUS_SUCCESS;
/* Return any possible failure status */
return Status;
break;
}
/* Advance to the next module */
ListEntry = ListEntry->Flink;
}
/* Release loader lock, it must succeed this time */
/* Release loader lock */
Status = LdrUnlockLoaderLock(0, Cookie);
ASSERT(NT_SUCCESS(Status));
/* Return success */
return STATUS_SUCCESS;
/* Reset any successful status to STATUS_SUCCESS,
* but leave failure to the caller */
if (NT_SUCCESS(Status))
Status = STATUS_SUCCESS;
/* Return any possible failure status */
return Status;
}
/*
@ -1190,7 +1191,8 @@ LdrEnumerateLoadedModules(IN BOOLEAN ReservedFlag,
*/
NTSTATUS
NTAPI
LdrDisableThreadCalloutsForDll(IN PVOID BaseAddress)
LdrDisableThreadCalloutsForDll(
_In_ PVOID BaseAddress)
{
PLDR_DATA_TABLE_ENTRY LdrEntry;
NTSTATUS Status;
@ -1240,8 +1242,9 @@ LdrDisableThreadCalloutsForDll(IN PVOID BaseAddress)
*/
NTSTATUS
NTAPI
LdrAddRefDll(IN ULONG Flags,
IN PVOID BaseAddress)
LdrAddRefDll(
_In_ ULONG Flags,
_In_ PVOID BaseAddress)
{
PLDR_DATA_TABLE_ENTRY LdrEntry;
NTSTATUS Status = STATUS_SUCCESS;
@ -1316,7 +1319,7 @@ quickie:
}
/* Release the lock if needed */
if (Locked) LdrUnlockLoaderLock(LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS, Cookie);
if (Locked) LdrUnlockLoaderLock(LDR_UNLOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS, Cookie);
return Status;
}
@ -1325,7 +1328,8 @@ quickie:
*/
NTSTATUS
NTAPI
LdrUnloadDll(IN PVOID BaseAddress)
LdrUnloadDll(
_In_ PVOID BaseAddress)
{
NTSTATUS Status = STATUS_SUCCESS;
PPEB Peb = NtCurrentPeb();
@ -1601,10 +1605,11 @@ RtlDllShutdownInProgress(VOID)
*/
PIMAGE_BASE_RELOCATION
NTAPI
LdrProcessRelocationBlock(IN ULONG_PTR Address,
IN ULONG Count,
IN PUSHORT TypeOffset,
IN LONG_PTR Delta)
LdrProcessRelocationBlock(
_In_ ULONG_PTR Address,
_In_ ULONG Count,
_In_ PUSHORT TypeOffset,
_In_ LONG_PTR Delta)
{
return LdrProcessRelocationBlockLongLong(Address, Count, TypeOffset, Delta);
}
@ -1617,8 +1622,9 @@ LdrProcessRelocationBlock(IN ULONG_PTR Address,
*/
NTSTATUS
NTAPI
LdrLoadAlternateResourceModule(IN PVOID Module,
IN PWSTR Buffer)
LdrLoadAlternateResourceModule(
_In_ PVOID Module,
_In_ PWSTR Buffer)
{
/* Is MUI Support enabled? */
if (!LdrAlternateResourcesEnabled()) return STATUS_SUCCESS;
@ -1632,7 +1638,8 @@ LdrLoadAlternateResourceModule(IN PVOID Module,
*/
BOOLEAN
NTAPI
LdrUnloadAlternateResourceModule(IN PVOID BaseAddress)
LdrUnloadAlternateResourceModule(
_In_ PVOID BaseAddress)
{
ULONG_PTR Cookie;
@ -1646,7 +1653,7 @@ LdrUnloadAlternateResourceModule(IN PVOID BaseAddress)
}
/* Release the loader lock */
LdrUnlockLoaderLock(1, Cookie);
LdrUnlockLoaderLock(LDR_UNLOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS, Cookie);
/* All done */
return TRUE;

View file

@ -109,9 +109,10 @@ extern BOOLEAN RtlpUse16ByteSLists;
*/
NTSTATUS
NTAPI
LdrOpenImageFileOptionsKey(IN PUNICODE_STRING SubKey,
IN BOOLEAN Wow64,
OUT PHANDLE NewKeyHandle)
LdrOpenImageFileOptionsKey(
_In_ PUNICODE_STRING SubKey,
_In_ BOOLEAN Wow64,
_Out_ PHANDLE NewKeyHandle)
{
PHANDLE RootKeyLocation;
HANDLE RootKey;
@ -181,12 +182,13 @@ LdrOpenImageFileOptionsKey(IN PUNICODE_STRING SubKey,
*/
NTSTATUS
NTAPI
LdrQueryImageFileKeyOption(IN HANDLE KeyHandle,
IN PCWSTR ValueName,
IN ULONG Type,
OUT PVOID Buffer,
IN ULONG BufferSize,
OUT PULONG ReturnedLength OPTIONAL)
LdrQueryImageFileKeyOption(
_In_ HANDLE KeyHandle,
_In_ PCWSTR ValueName,
_In_ ULONG Type,
_Out_ PVOID Buffer,
_In_ ULONG BufferSize,
_Out_opt_ PULONG ReturnedLength)
{
ULONG KeyInfo[256];
UNICODE_STRING ValueNameString, IntegerString;
@ -345,13 +347,14 @@ LdrQueryImageFileKeyOption(IN HANDLE KeyHandle,
*/
NTSTATUS
NTAPI
LdrQueryImageFileExecutionOptionsEx(IN PUNICODE_STRING SubKey,
IN PCWSTR ValueName,
IN ULONG Type,
OUT PVOID Buffer,
IN ULONG BufferSize,
OUT PULONG ReturnedLength OPTIONAL,
IN BOOLEAN Wow64)
LdrQueryImageFileExecutionOptionsEx(
_In_ PUNICODE_STRING SubKey,
_In_ PCWSTR ValueName,
_In_ ULONG Type,
_Out_ PVOID Buffer,
_In_ ULONG BufferSize,
_Out_opt_ PULONG ReturnedLength,
_In_ BOOLEAN Wow64)
{
NTSTATUS Status;
HANDLE KeyHandle;
@ -383,12 +386,13 @@ LdrQueryImageFileExecutionOptionsEx(IN PUNICODE_STRING SubKey,
*/
NTSTATUS
NTAPI
LdrQueryImageFileExecutionOptions(IN PUNICODE_STRING SubKey,
IN PCWSTR ValueName,
IN ULONG Type,
OUT PVOID Buffer,
IN ULONG BufferSize,
OUT PULONG ReturnedLength OPTIONAL)
LdrQueryImageFileExecutionOptions(
_In_ PUNICODE_STRING SubKey,
_In_ PCWSTR ValueName,
_In_ ULONG Type,
_Out_ PVOID Buffer,
_In_ ULONG BufferSize,
_Out_opt_ PULONG ReturnedLength)
{
/* Call the newer function */
return LdrQueryImageFileExecutionOptionsEx(SubKey,
@ -1879,7 +1883,7 @@ LdrpInitializeProcess(IN PCONTEXT Context,
HeapParameters.Length = sizeof(HeapParameters);
/* Check if we have Configuration Data */
#define VALID_CONFIG_FIELD(Name) (ConfigSize >= (FIELD_OFFSET(IMAGE_LOAD_CONFIG_DIRECTORY, Name) + sizeof(LoadConfig->Name)))
#define VALID_CONFIG_FIELD(Name) (ConfigSize >= RTL_SIZEOF_THROUGH_FIELD(IMAGE_LOAD_CONFIG_DIRECTORY, Name))
/* The 'original' load config ends after SecurityCookie */
if ((LoadConfig) && ConfigSize && (VALID_CONFIG_FIELD(SecurityCookie) || ConfigSize == LoadConfig->Size))
{
@ -2327,7 +2331,7 @@ LdrpInitializeProcess(IN PCONTEXT Context,
if (!NT_SUCCESS(Status))
{
if (ShowSnaps)
DPRINT1("LDR: Unable to find post-import process init function, Status=0x%08lx\n", &Kernel32String, Status);
DPRINT1("LDR: Unable to find post-import process init function, Status=0x%08lx\n", Status);
return Status;
}
Kernel32ProcessInitPostImportFunction = FunctionAddress;
@ -2340,7 +2344,7 @@ LdrpInitializeProcess(IN PCONTEXT Context,
if (!NT_SUCCESS(Status))
{
if (ShowSnaps)
DPRINT1("LDR: Unable to find BaseQueryModuleData, Status=0x%08lx\n", &Kernel32String, Status);
DPRINT1("LDR: Unable to find BaseQueryModuleData, Status=0x%08lx\n", Status);
return Status;
}
Kernel32BaseQueryModuleData = FunctionAddress;

View file

@ -2257,7 +2257,7 @@ LdrpGetProcedureAddress(
_In_ BOOLEAN ExecuteInit)
{
NTSTATUS Status = STATUS_SUCCESS;
UCHAR ImportBuffer[64];
UCHAR ImportBuffer[64]; // 128 since NT6.2
PLDR_DATA_TABLE_ENTRY LdrEntry;
IMAGE_THUNK_DATA Thunk;
PVOID ImageBase;
@ -2292,6 +2292,11 @@ LdrpGetProcedureAddress(
ImportName = RtlAllocateHeap(RtlGetProcessHeap(),
0,
Length);
if (!ImportName)
{
/* Return STATUS_INSUFFICIENT_RESOURCES since NT6.2 */
return STATUS_INVALID_PARAMETER;
}
}
else
{

View file

@ -657,7 +657,7 @@ GetModuleFileNameW(HINSTANCE hModule,
} _SEH2_END
/* Release the loader lock */
LdrUnlockLoaderLock(LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS, Cookie);
LdrUnlockLoaderLock(LDR_UNLOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS, Cookie);
return Length / sizeof(WCHAR);
}

View file

@ -97,8 +97,8 @@ LdrGetProcedureAddress(
ULONG
NTAPI
LdrRelocateImage(
_In_ PVOID NewBase,
_In_ PCCH LoaderName,
_In_ PVOID BaseAddress,
_In_opt_ PCSTR LoaderName,
_In_ ULONG Success,
_In_ ULONG Conflict,
_In_ ULONG Invalid
@ -139,9 +139,9 @@ LdrProcessRelocationBlockLongLong(
NTSTATUS
NTAPI
LdrEnumerateLoadedModules(
_In_ BOOLEAN ReservedFlag,
_Reserved_ ULONG ReservedFlag,
_In_ PLDR_ENUM_CALLBACK EnumProc,
_In_ PVOID Context
_In_opt_ PVOID Context
);
#endif

View file

@ -238,7 +238,7 @@ typedef struct _ALT_RESOURCE_MODULE
//
// Callback function for LdrEnumerateLoadedModules
//
typedef VOID (NTAPI LDR_ENUM_CALLBACK)(_In_ PLDR_DATA_TABLE_ENTRY ModuleInformation, _In_ PVOID Parameter, _Out_ BOOLEAN *Stop);
typedef VOID (NTAPI LDR_ENUM_CALLBACK)(_In_ PLDR_DATA_TABLE_ENTRY ModuleInformation, _In_opt_ PVOID Context, _Out_ BOOLEAN *Stop);
typedef LDR_ENUM_CALLBACK *PLDR_ENUM_CALLBACK;
//

View file

@ -3975,13 +3975,12 @@ RtlImageRvaToSection(
_In_ ULONG Rva
);
NTSYSAPI
ULONG
NTAPI
LdrRelocateImageWithBias(
_In_ PVOID NewAddress,
_In_ PVOID BaseAddress,
_In_ LONGLONG AdditionalBias,
_In_ PCCH LoaderName,
_In_opt_ PCSTR LoaderName,
_In_ ULONG Success,
_In_ ULONG Conflict,
_In_ ULONG Invalid

View file

@ -158,9 +158,9 @@ NTSTATUS
NTAPI
LdrLoadDll(
_In_opt_ PWSTR SearchPath,
_In_opt_ PULONG LoadFlags,
_In_ PUNICODE_STRING Name,
_Out_opt_ PVOID *BaseAddress
_In_opt_ PULONG DllCharacteristics,
_In_ PUNICODE_STRING DllName,
_Out_ PVOID *BaseAddress
);
PIMAGE_BASE_RELOCATION
@ -177,18 +177,18 @@ NTAPI
LdrQueryImageFileExecutionOptions(
_In_ PUNICODE_STRING SubKey,
_In_ PCWSTR ValueName,
_In_ ULONG ValueSize,
_In_ ULONG Type,
_Out_ PVOID Buffer,
_In_ ULONG BufferSize,
_Out_opt_ PULONG RetunedLength
_Out_opt_ PULONG ReturnedLength
);
NTSTATUS
NTAPI
LdrQueryProcessModuleInformation(
_In_opt_ PRTL_PROCESS_MODULES ModuleInformation,
_In_opt_ ULONG Size,
_Out_ PULONG ReturnedSize
_Out_writes_bytes_to_(Size, *ReturnedSize) PRTL_PROCESS_MODULES ModuleInformation,
_In_ ULONG Size,
_Out_opt_ PULONG ReturnedSize
);
VOID
@ -221,7 +221,7 @@ LdrVerifyImageMatchesChecksum(
_In_ HANDLE FileHandle,
_In_ PLDR_CALLBACK Callback,
_In_ PVOID CallbackContext,
_Out_ PUSHORT ImageCharacterstics
_Out_ PUSHORT ImageCharacteristics
);
NTSTATUS

View file

@ -460,11 +460,11 @@ LdrProcessRelocationBlockLongLong(
ULONG
NTAPI
LdrRelocateImage(
IN PVOID BaseAddress,
IN PCCH LoaderName,
IN ULONG Success,
IN ULONG Conflict,
IN ULONG Invalid)
_In_ PVOID BaseAddress,
_In_opt_ PCSTR LoaderName,
_In_ ULONG Success,
_In_ ULONG Conflict,
_In_ ULONG Invalid)
{
return LdrRelocateImageWithBias(BaseAddress, 0, LoaderName, Success, Conflict, Invalid);
}
@ -472,12 +472,12 @@ LdrRelocateImage(
ULONG
NTAPI
LdrRelocateImageWithBias(
IN PVOID BaseAddress,
IN LONGLONG AdditionalBias,
IN PCCH LoaderName,
IN ULONG Success,
IN ULONG Conflict,
IN ULONG Invalid)
_In_ PVOID BaseAddress,
_In_ LONGLONG AdditionalBias,
_In_opt_ PCSTR LoaderName,
_In_ ULONG Success,
_In_ ULONG Conflict,
_In_ ULONG Invalid)
{
PIMAGE_NT_HEADERS NtHeaders;
PIMAGE_DATA_DIRECTORY RelocationDDir;
@ -487,6 +487,8 @@ LdrRelocateImageWithBias(
PUSHORT TypeOffset;
LONGLONG Delta;
UNREFERENCED_PARAMETER(LoaderName);
NtHeaders = RtlImageNtHeader(BaseAddress);
if (NtHeaders == NULL)