mirror of
https://github.com/reactos/reactos.git
synced 2024-07-11 23:25:09 +00:00
[NTOSKRNL]
patch by Samuel Serapion: Implement MemorySectionName case for NtQueryVirtualMemory. Protect buffer access with SEH. See issue #5753 for more details. svn path=/trunk/; revision=49898
This commit is contained in:
parent
ed5da47acd
commit
1a20b0bd9c
|
@ -2339,35 +2339,21 @@ NtResetWriteWatch(IN HANDLE ProcessHandle,
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
NtQueryVirtualMemory(IN HANDLE ProcessHandle,
|
MiQueryMemoryBasicInformation(IN HANDLE ProcessHandle,
|
||||||
IN PVOID BaseAddress,
|
IN PVOID BaseAddress,
|
||||||
IN MEMORY_INFORMATION_CLASS MemoryInformationClass,
|
OUT PVOID MemoryInformation,
|
||||||
OUT PVOID MemoryInformation,
|
IN SIZE_T MemoryInformationLength,
|
||||||
IN SIZE_T MemoryInformationLength,
|
OUT PSIZE_T ReturnLength)
|
||||||
OUT PSIZE_T ReturnLength)
|
|
||||||
{
|
{
|
||||||
PEPROCESS TargetProcess;
|
PEPROCESS TargetProcess;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
PMMVAD Vad = NULL;
|
PMMVAD Vad = NULL;
|
||||||
PVOID Address, NextAddress;
|
PVOID Address, NextAddress;
|
||||||
BOOLEAN Found = FALSE;
|
BOOLEAN Found = FALSE;
|
||||||
ULONG NewProtect, NewState, BaseVpn;
|
ULONG NewProtect, NewState, BaseVpn;
|
||||||
MEMORY_BASIC_INFORMATION MemoryInfo;
|
MEMORY_BASIC_INFORMATION MemoryInfo;
|
||||||
KAPC_STATE ApcState;
|
KAPC_STATE ApcState;
|
||||||
DPRINT("Querying class %d about address: %p\n", MemoryInformationClass, BaseAddress);
|
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
||||||
|
|
||||||
/* Only this class is supported for now */
|
|
||||||
ASSERT(MemoryInformationClass == MemoryBasicInformation);
|
|
||||||
|
|
||||||
/* Validate the size information of the class */
|
|
||||||
if (MemoryInformationLength < sizeof(MEMORY_BASIC_INFORMATION))
|
|
||||||
{
|
|
||||||
/* The size is invalid */
|
|
||||||
return STATUS_INFO_LENGTH_MISMATCH;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Bail out if the address is invalid */
|
|
||||||
if (BaseAddress > MM_HIGHEST_USER_ADDRESS) return STATUS_INVALID_PARAMETER;
|
|
||||||
|
|
||||||
/* Check for illegal addresses in user-space, or the shared memory area */
|
/* Check for illegal addresses in user-space, or the shared memory area */
|
||||||
if ((BaseAddress > MM_HIGHEST_VAD_ADDRESS) ||
|
if ((BaseAddress > MM_HIGHEST_VAD_ADDRESS) ||
|
||||||
|
@ -2396,11 +2382,27 @@ NtQueryVirtualMemory(IN HANDLE ProcessHandle,
|
||||||
MemoryInfo.RegionSize = (ULONG_PTR)MemoryInfo.AllocationBase - (ULONG_PTR)Address;
|
MemoryInfo.RegionSize = (ULONG_PTR)MemoryInfo.AllocationBase - (ULONG_PTR)Address;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the data (FIXME: Use SEH) */
|
/* Return the data, NtQueryInformation already probed it*/
|
||||||
*(PMEMORY_BASIC_INFORMATION)MemoryInformation = MemoryInfo;
|
if (PreviousMode != KernelMode)
|
||||||
if (ReturnLength) *ReturnLength = sizeof(MEMORY_BASIC_INFORMATION);
|
{
|
||||||
|
_SEH2_TRY
|
||||||
|
{
|
||||||
|
*(PMEMORY_BASIC_INFORMATION)MemoryInformation = MemoryInfo;
|
||||||
|
if (ReturnLength) *ReturnLength = sizeof(MEMORY_BASIC_INFORMATION);
|
||||||
|
}
|
||||||
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
Status = _SEH2_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH2_END;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*(PMEMORY_BASIC_INFORMATION)MemoryInformation = MemoryInfo;
|
||||||
|
if (ReturnLength) *ReturnLength = sizeof(MEMORY_BASIC_INFORMATION);
|
||||||
|
}
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if this is for a local or remote process */
|
/* Check if this is for a local or remote process */
|
||||||
|
@ -2507,11 +2509,27 @@ NtQueryVirtualMemory(IN HANDLE ProcessHandle,
|
||||||
MemoryInfo.Protect = PAGE_NOACCESS;
|
MemoryInfo.Protect = PAGE_NOACCESS;
|
||||||
MemoryInfo.Type = 0;
|
MemoryInfo.Type = 0;
|
||||||
|
|
||||||
/* Return the data (FIXME: Use SEH) */
|
/* Return the data, NtQueryInformation already probed it*/
|
||||||
*(PMEMORY_BASIC_INFORMATION)MemoryInformation = MemoryInfo;
|
if (PreviousMode != KernelMode)
|
||||||
if (ReturnLength) *ReturnLength = sizeof(MEMORY_BASIC_INFORMATION);
|
{
|
||||||
|
_SEH2_TRY
|
||||||
|
{
|
||||||
|
*(PMEMORY_BASIC_INFORMATION)MemoryInformation = MemoryInfo;
|
||||||
|
if (ReturnLength) *ReturnLength = sizeof(MEMORY_BASIC_INFORMATION);
|
||||||
|
}
|
||||||
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
Status = _SEH2_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH2_END;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*(PMEMORY_BASIC_INFORMATION)MemoryInformation = MemoryInfo;
|
||||||
|
if (ReturnLength) *ReturnLength = sizeof(MEMORY_BASIC_INFORMATION);
|
||||||
|
}
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This must be a VM VAD */
|
/* This must be a VM VAD */
|
||||||
|
@ -2539,7 +2557,7 @@ NtQueryVirtualMemory(IN HANDLE ProcessHandle,
|
||||||
Address = NextAddress;
|
Address = NextAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now that we know the last VA address, calculate hte region size */
|
/* Now that we know the last VA address, calculate the region size */
|
||||||
MemoryInfo.RegionSize = ((ULONG_PTR)Address - (ULONG_PTR)MemoryInfo.BaseAddress);
|
MemoryInfo.RegionSize = ((ULONG_PTR)Address - (ULONG_PTR)MemoryInfo.BaseAddress);
|
||||||
|
|
||||||
/* Check if we were attached */
|
/* Check if we were attached */
|
||||||
|
@ -2550,17 +2568,179 @@ NtQueryVirtualMemory(IN HANDLE ProcessHandle,
|
||||||
ObDereferenceObject(TargetProcess);
|
ObDereferenceObject(TargetProcess);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the data (FIXME: Use SEH) */
|
/* Return the data, NtQueryInformation already probed it*/
|
||||||
*(PMEMORY_BASIC_INFORMATION)MemoryInformation = MemoryInfo;
|
if (PreviousMode != KernelMode)
|
||||||
if (ReturnLength) *ReturnLength = sizeof(MEMORY_BASIC_INFORMATION);
|
{
|
||||||
|
_SEH2_TRY
|
||||||
|
{
|
||||||
|
*(PMEMORY_BASIC_INFORMATION)MemoryInformation = MemoryInfo;
|
||||||
|
if (ReturnLength) *ReturnLength = sizeof(MEMORY_BASIC_INFORMATION);
|
||||||
|
}
|
||||||
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
Status = _SEH2_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH2_END;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*(PMEMORY_BASIC_INFORMATION)MemoryInformation = MemoryInfo;
|
||||||
|
if (ReturnLength) *ReturnLength = sizeof(MEMORY_BASIC_INFORMATION);
|
||||||
|
}
|
||||||
|
|
||||||
/* All went well */
|
/* All went well */
|
||||||
DPRINT("Base: %p AllocBase: %p Protect: %lx AllocProtect: %lx "
|
DPRINT("Base: %p AllocBase: %p Protect: %lx AllocProtect: %lx "
|
||||||
"State: %lx Type: %lx Size: %lx\n",
|
"State: %lx Type: %lx Size: %lx\n",
|
||||||
MemoryInfo.BaseAddress, MemoryInfo.AllocationBase,
|
MemoryInfo.BaseAddress, MemoryInfo.AllocationBase,
|
||||||
MemoryInfo.AllocationProtect, MemoryInfo.Protect,
|
MemoryInfo.AllocationProtect, MemoryInfo.Protect,
|
||||||
MemoryInfo.State, MemoryInfo.Type, MemoryInfo.RegionSize);
|
MemoryInfo.State, MemoryInfo.Type, MemoryInfo.RegionSize);
|
||||||
return STATUS_SUCCESS;
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
MiQueryMemorySectionName(IN HANDLE ProcessHandle,
|
||||||
|
IN PVOID BaseAddress,
|
||||||
|
OUT PVOID MemoryInformation,
|
||||||
|
IN SIZE_T MemoryInformationLength,
|
||||||
|
OUT PSIZE_T ReturnLength)
|
||||||
|
{
|
||||||
|
PEPROCESS Process;
|
||||||
|
NTSTATUS Status;
|
||||||
|
WCHAR ModuleFileNameBuffer[MAX_PATH] = {0};
|
||||||
|
UNICODE_STRING ModuleFileName;
|
||||||
|
PMEMORY_SECTION_NAME SectionName = NULL;
|
||||||
|
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
||||||
|
|
||||||
|
Status = ObReferenceObjectByHandle(ProcessHandle,
|
||||||
|
PROCESS_QUERY_INFORMATION,
|
||||||
|
NULL,
|
||||||
|
PreviousMode,
|
||||||
|
(PVOID*)(&Process),
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("MiQueryMemorySectionName: ObReferenceObjectByHandle returned %x\n",Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
RtlInitEmptyUnicodeString(&ModuleFileName, ModuleFileNameBuffer, sizeof(ModuleFileNameBuffer));
|
||||||
|
Status = MmGetFileNameForAddress(BaseAddress, &ModuleFileName);
|
||||||
|
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
SectionName = MemoryInformation;
|
||||||
|
if (PreviousMode != KernelMode)
|
||||||
|
{
|
||||||
|
_SEH2_TRY
|
||||||
|
{
|
||||||
|
RtlInitUnicodeString(&SectionName->SectionFileName, SectionName->NameBuffer);
|
||||||
|
SectionName->SectionFileName.MaximumLength = MemoryInformationLength;
|
||||||
|
RtlCopyUnicodeString(&SectionName->SectionFileName, &ModuleFileName);
|
||||||
|
|
||||||
|
if (ReturnLength) *ReturnLength = ModuleFileName.Length;
|
||||||
|
|
||||||
|
}
|
||||||
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
Status = _SEH2_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH2_END;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RtlInitUnicodeString(&SectionName->SectionFileName, SectionName->NameBuffer);
|
||||||
|
SectionName->SectionFileName.MaximumLength = MemoryInformationLength;
|
||||||
|
RtlCopyUnicodeString(&SectionName->SectionFileName, &ModuleFileName);
|
||||||
|
|
||||||
|
if (ReturnLength) *ReturnLength = ModuleFileName.Length;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ObDereferenceObject(Process);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
NtQueryVirtualMemory(IN HANDLE ProcessHandle,
|
||||||
|
IN PVOID BaseAddress,
|
||||||
|
IN MEMORY_INFORMATION_CLASS MemoryInformationClass,
|
||||||
|
OUT PVOID MemoryInformation,
|
||||||
|
IN SIZE_T MemoryInformationLength,
|
||||||
|
OUT PSIZE_T ReturnLength)
|
||||||
|
{
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
KPROCESSOR_MODE PreviousMode;
|
||||||
|
|
||||||
|
DPRINT("Querying class %d about address: %p\n", MemoryInformationClass, BaseAddress);
|
||||||
|
|
||||||
|
/* Bail out if the address is invalid */
|
||||||
|
if (BaseAddress > MM_HIGHEST_USER_ADDRESS) return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
/* Probe return buffer */
|
||||||
|
PreviousMode = ExGetPreviousMode();
|
||||||
|
if (PreviousMode != KernelMode)
|
||||||
|
{
|
||||||
|
_SEH2_TRY
|
||||||
|
{
|
||||||
|
ProbeForWrite(MemoryInformation,
|
||||||
|
MemoryInformationLength,
|
||||||
|
sizeof(ULONG_PTR));
|
||||||
|
|
||||||
|
if (ReturnLength) ProbeForWriteSize_t(ReturnLength);
|
||||||
|
}
|
||||||
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
Status = _SEH2_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH2_END;
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(MemoryInformationClass)
|
||||||
|
{
|
||||||
|
case MemoryBasicInformation:
|
||||||
|
/* Validate the size information of the class */
|
||||||
|
if (MemoryInformationLength < sizeof(MEMORY_BASIC_INFORMATION))
|
||||||
|
{
|
||||||
|
/* The size is invalid */
|
||||||
|
return STATUS_INFO_LENGTH_MISMATCH;
|
||||||
|
}
|
||||||
|
Status = MiQueryMemoryBasicInformation(ProcessHandle,
|
||||||
|
BaseAddress,
|
||||||
|
MemoryInformation,
|
||||||
|
MemoryInformationLength,
|
||||||
|
ReturnLength);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MemorySectionName:
|
||||||
|
/* Validate the size information of the class */
|
||||||
|
if (MemoryInformationLength < sizeof(MEMORY_SECTION_NAME))
|
||||||
|
{
|
||||||
|
/* The size is invalid */
|
||||||
|
return STATUS_INFO_LENGTH_MISMATCH;
|
||||||
|
}
|
||||||
|
Status = MiQueryMemorySectionName(ProcessHandle,
|
||||||
|
BaseAddress,
|
||||||
|
MemoryInformation,
|
||||||
|
MemoryInformationLength,
|
||||||
|
ReturnLength);
|
||||||
|
break;
|
||||||
|
case MemoryWorkingSetList:
|
||||||
|
case MemoryBasicVlmInformation:
|
||||||
|
default:
|
||||||
|
DPRINT1("Unhandled memory information class %d\n", MemoryInformationClass);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
Loading…
Reference in a new issue