From cfec4ed82617aa194665683ee3bc904831cf2a00 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Wed, 16 Mar 2011 09:52:41 +0000 Subject: [PATCH] [NTDLL/LDR] - Rewrite LdrImageMatchesChecksum, remove now outdated LdrpCheckImageChecksum. svn path=/trunk/; revision=51060 --- reactos/dll/ntdll/ldr/ldrapi.c | 132 ++++++++++++++++++++++++++ reactos/dll/ntdll/ldr/utils.c | 164 --------------------------------- 2 files changed, 132 insertions(+), 164 deletions(-) diff --git a/reactos/dll/ntdll/ldr/ldrapi.c b/reactos/dll/ntdll/ldr/ldrapi.c index db71d74ca3c..55e1582a446 100644 --- a/reactos/dll/ntdll/ldr/ldrapi.c +++ b/reactos/dll/ntdll/ldr/ldrapi.c @@ -246,4 +246,136 @@ Quickie: return Status; } +/* + * @implemented + */ +NTSTATUS +NTAPI +LdrVerifyImageMatchesChecksum(IN HANDLE FileHandle, + IN PLDR_CALLBACK Callback, + IN PVOID CallbackContext, + OUT PUSHORT ImageCharacteristics) +{ + FILE_STANDARD_INFORMATION FileStandardInfo; + PIMAGE_IMPORT_DESCRIPTOR ImportData; + PIMAGE_SECTION_HEADER LastSection; + IO_STATUS_BLOCK IoStatusBlock; + PIMAGE_NT_HEADERS NtHeader; + HANDLE SectionHandle; + SIZE_T ViewSize = 0; + PVOID ViewBase = NULL; + BOOLEAN Result; + NTSTATUS Status; + PVOID ImportName; + ULONG Size; + + DPRINT("LdrVerifyImageMatchesChecksum() called\n"); + + /* Create the section */ + Status = NtCreateSection(&SectionHandle, + SECTION_MAP_EXECUTE, + NULL, + NULL, + PAGE_EXECUTE, + SEC_COMMIT, + FileHandle); + if (!NT_SUCCESS(Status)) + { + DPRINT1 ("NtCreateSection() failed (Status 0x%x)\n", Status); + return Status; + } + + /* Map the section */ + Status = NtMapViewOfSection(SectionHandle, + NtCurrentProcess(), + &ViewBase, + 0, + 0, + NULL, + &ViewSize, + ViewShare, + 0, + PAGE_EXECUTE); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtMapViewOfSection() failed (Status 0x%x)\n", Status); + NtClose(SectionHandle); + return Status; + } + + /* Get the file information */ + Status = NtQueryInformationFile(FileHandle, + &IoStatusBlock, + &FileStandardInfo, + sizeof(FILE_STANDARD_INFORMATION), + FileStandardInformation); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtMapViewOfSection() failed (Status 0x%x)\n", Status); + NtUnmapViewOfSection(NtCurrentProcess(), ViewBase); + NtClose(SectionHandle); + return Status; + } + + /* Protect with SEH */ + _SEH2_TRY + { + /* Verify the checksum */ + Result = LdrVerifyMappedImageMatchesChecksum(ViewBase, + ViewSize, + FileStandardInfo.EndOfFile.LowPart); + + /* Check if a callback was supplied */ + if (Result && Callback) + { + /* Get the NT Header */ + NtHeader = RtlImageNtHeader(ViewBase); + + /* Check if caller requested this back */ + if (ImageCharacteristics) + { + /* Return to caller */ + *ImageCharacteristics = NtHeader->FileHeader.Characteristics; + } + + /* Get the Import Directory Data */ + ImportData = RtlImageDirectoryEntryToData(ViewBase, + FALSE, + IMAGE_DIRECTORY_ENTRY_IMPORT, + &Size); + + /* Make sure there is one */ + if (ImportData) + { + /* Loop the imports */ + while (ImportData->Name) + { + /* Get the name */ + ImportName = RtlImageRvaToVa(NtHeader, + ViewBase, + ImportData->Name, + &LastSection); + + /* Notify the callback */ + Callback(CallbackContext, ImportName); + ImportData++; + } + } + } + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Fail the request returning STATUS_IMAGE_CHECKSUM_MISMATCH */ + Result = FALSE; + } + _SEH2_END; + + /* Unmap file and close handle */ + NtUnmapViewOfSection(NtCurrentProcess(), ViewBase); + NtClose(SectionHandle); + + /* Return status */ + return !Result ? STATUS_IMAGE_CHECKSUM_MISMATCH : Status; +} + /* EOF */ diff --git a/reactos/dll/ntdll/ldr/utils.c b/reactos/dll/ntdll/ldr/utils.c index cd7c7d69023..e03cb12a3d2 100644 --- a/reactos/dll/ntdll/ldr/utils.c +++ b/reactos/dll/ntdll/ldr/utils.c @@ -2950,76 +2950,6 @@ LdrQueryProcessModuleInformation(IN PRTL_PROCESS_MODULES ModuleInformation OPTIO return(Status); } - -static BOOLEAN -LdrpCheckImageChecksum (IN PVOID BaseAddress, - IN ULONG ImageSize) -{ - PIMAGE_NT_HEADERS Header; - PUSHORT Ptr; - ULONG Sum; - ULONG CalcSum; - ULONG HeaderSum; - ULONG i; - - Header = RtlImageNtHeader (BaseAddress); - if (Header == NULL) - return FALSE; - - HeaderSum = Header->OptionalHeader.CheckSum; - if (HeaderSum == 0) - return TRUE; - - Sum = 0; - Ptr = (PUSHORT) BaseAddress; - for (i = 0; i < ImageSize / sizeof (USHORT); i++) - { - Sum += (ULONG)*Ptr; - if (HIWORD(Sum) != 0) - { - Sum = LOWORD(Sum) + HIWORD(Sum); - } - Ptr++; - } - - if (ImageSize & 1) - { - Sum += (ULONG)*((PUCHAR)Ptr); - if (HIWORD(Sum) != 0) - { - Sum = LOWORD(Sum) + HIWORD(Sum); - } - } - - CalcSum = (USHORT)(LOWORD(Sum) + HIWORD(Sum)); - - /* Subtract image checksum from calculated checksum. */ - /* fix low word of checksum */ - if (LOWORD(CalcSum) >= LOWORD(HeaderSum)) - { - CalcSum -= LOWORD(HeaderSum); - } - else - { - CalcSum = ((LOWORD(CalcSum) - LOWORD(HeaderSum)) & 0xFFFF) - 1; - } - - /* fix high word of checksum */ - if (LOWORD(CalcSum) >= HIWORD(HeaderSum)) - { - CalcSum -= HIWORD(HeaderSum); - } - else - { - CalcSum = ((LOWORD(CalcSum) - HIWORD(HeaderSum)) & 0xFFFF) - 1; - } - - /* add file length */ - CalcSum += ImageSize; - - return (BOOLEAN)(CalcSum == HeaderSum); -} - /* * Compute size of an image as it is actually present in virt memory * (i.e. excluding NEVER_LOAD sections) @@ -3049,100 +2979,6 @@ LdrpGetResidentSize(PIMAGE_NT_HEADERS NTHeaders) return ResidentSize; } - -/*************************************************************************** - * NAME EXPORTED - * LdrVerifyImageMatchesChecksum - * - * DESCRIPTION - * - * ARGUMENTS - * - * RETURN VALUE - * - * REVISIONS - * - * NOTE - * - * @implemented - */ -NTSTATUS NTAPI -LdrVerifyImageMatchesChecksum (IN HANDLE FileHandle, - IN PLDR_CALLBACK Callback, - IN PVOID CallbackContext, - OUT PUSHORT ImageCharacterstics) -{ - FILE_STANDARD_INFORMATION FileInfo; - IO_STATUS_BLOCK IoStatusBlock; - HANDLE SectionHandle; - SIZE_T ViewSize; - PVOID BaseAddress; - BOOLEAN Result; - NTSTATUS Status; - - DPRINT ("LdrVerifyImageMatchesChecksum() called\n"); - - Status = NtCreateSection (&SectionHandle, - SECTION_MAP_READ, - NULL, - NULL, - PAGE_READONLY, - SEC_COMMIT, - FileHandle); - if (!NT_SUCCESS(Status)) - { - DPRINT1 ("NtCreateSection() failed (Status %lx)\n", Status); - return Status; - } - - ViewSize = 0; - BaseAddress = NULL; - Status = NtMapViewOfSection (SectionHandle, - NtCurrentProcess (), - &BaseAddress, - 0, - 0, - NULL, - &ViewSize, - ViewShare, - 0, - PAGE_READONLY); - if (!NT_SUCCESS(Status)) - { - DPRINT1 ("NtMapViewOfSection() failed (Status %lx)\n", Status); - NtClose (SectionHandle); - return Status; - } - - Status = NtQueryInformationFile(FileHandle, - &IoStatusBlock, - &FileInfo, - sizeof (FILE_STANDARD_INFORMATION), - FileStandardInformation); - if (!NT_SUCCESS(Status)) - { - DPRINT1 ("NtMapViewOfSection() failed (Status %lx)\n", Status); - NtUnmapViewOfSection (NtCurrentProcess(), - BaseAddress); - NtClose (SectionHandle); - return Status; - } - - Result = LdrpCheckImageChecksum(BaseAddress, - FileInfo.EndOfFile.u.LowPart); - if (Result == FALSE) - { - Status = STATUS_IMAGE_CHECKSUM_MISMATCH; - } - - NtUnmapViewOfSection (NtCurrentProcess(), - BaseAddress); - - NtClose(SectionHandle); - - return Status; -} - PIMAGE_BASE_RELOCATION NTAPI LdrProcessRelocationBlock(