[NTDLL/LDR]

- Rewrite LdrImageMatchesChecksum, remove now outdated LdrpCheckImageChecksum.

svn path=/trunk/; revision=51060
This commit is contained in:
Aleksey Bragin 2011-03-16 09:52:41 +00:00
parent c396511623
commit cfec4ed826
2 changed files with 132 additions and 164 deletions

View file

@ -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 */

View file

@ -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(