mirror of
https://github.com/reactos/reactos.git
synced 2024-07-05 20:25:17 +00:00
[NTDLL/LDR]
- Rewrite LdrImageMatchesChecksum, remove now outdated LdrpCheckImageChecksum. svn path=/trunk/; revision=51060
This commit is contained in:
parent
c396511623
commit
cfec4ed826
|
@ -246,4 +246,136 @@ Quickie:
|
||||||
return Status;
|
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 */
|
/* EOF */
|
||||||
|
|
|
@ -2950,76 +2950,6 @@ LdrQueryProcessModuleInformation(IN PRTL_PROCESS_MODULES ModuleInformation OPTIO
|
||||||
return(Status);
|
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
|
* Compute size of an image as it is actually present in virt memory
|
||||||
* (i.e. excluding NEVER_LOAD sections)
|
* (i.e. excluding NEVER_LOAD sections)
|
||||||
|
@ -3049,100 +2979,6 @@ LdrpGetResidentSize(PIMAGE_NT_HEADERS NTHeaders)
|
||||||
return ResidentSize;
|
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
|
PIMAGE_BASE_RELOCATION
|
||||||
NTAPI
|
NTAPI
|
||||||
LdrProcessRelocationBlock(
|
LdrProcessRelocationBlock(
|
||||||
|
|
Loading…
Reference in a new issue