系列文章目录
文章目录
3.1.6 系统调用NtAllocateVirtualMemory()
在前面各节的基础上,现在可以用一个完整的情景加以贯穿和综合了,这个情景就是系统调用NtAllocateVirtualMemory()。
凡是用户空间的程序向内核要求分配空间,无论是只要求一个指标即保留一片区间,还是要求交割兑现已经保留的一片区间,还是二者兼有,都可以通过系统调用ZwAllocateVirtualMemory()即NtAllocateVirtualMemory()实现。实际上还有别的功能也可以通过这个系统调用实现,但是在这里我们并不关心。当然,所分配的仅限于用户空间,用户空间的程序是无法要求内核分配系统空间的。NtAllocateVirtualMemory()是个不小的系统调用,我们分段阅读其代码:
NtAllocateVirtualMemory()
/*
* @implemented
*/
NTSTATUS STDCALL
NtAllocateVirtualMemory(IN HANDLE ProcessHandle,
IN OUT PVOID* UBaseAddress,
IN ULONG ZeroBits,
IN OUT PULONG URegionSize,
IN ULONG AllocationType,
IN ULONG Protect)
/*
* FUNCTION: Allocates a block of virtual memory in the process address space
* ARGUMENTS:
* ProcessHandle = The handle of the process which owns the virtual memory
* BaseAddress = A pointer to the virtual memory allocated. If you
* supply a non zero value the system will try to
* allocate the memory at the address supplied. It round
* it down to a multiple of the page size.
* ZeroBits = (OPTIONAL) You can specify the number of high order bits
* that must be zero, ensuring that the memory will be
* allocated at a address below a certain value.
* RegionSize = The number of bytes to allocate
* AllocationType = Indicates the type of virtual memory you like to
* allocated, can be a combination of MEM_COMMIT,
* MEM_RESERVE, MEM_RESET, MEM_TOP_DOWN.
* Protect = Indicates the protection type of the pages allocated, can be
* a combination of PAGE_READONLY, PAGE_READWRITE,
* PAGE_EXECUTE_READ, PAGE_EXECUTE_READWRITE, PAGE_GUARD,
* PAGE_NOACCESS
* RETURNS: Status
*/
{
PEPROCESS Process;
MEMORY_AREA* MemoryArea;
ULONG_PTR MemoryAreaLength;
ULONG Type;
NTSTATUS Status;
PMADDRESS_SPACE AddressSpace;
PVOID BaseAddress;
ULONG RegionSize;
PVOID PBaseAddress;
ULONG PRegionSize;
PHYSICAL_ADDRESS BoundaryAddressMultiple;
....
/* Check for valid protection flags */
if ((Protect & PAGE_FLAGS_VALID_FROM_USER_MODE) != Protect)
{
DPRINT1("Invalid page protection\n");
return STATUS_INVALID_PAGE_PROTECTION;
}
/* Check for valid Zero bits */
if (ZeroBits > 21)
{
DPRINT1("Too many zero bits\n");
return STATUS_INVALID_PARAMETER_3;
}
/* Check for valid Allocation Types */
if ((AllocationType &~ (MEM_COMMIT | MEM_RESERVE | MEM_RESET | MEM_PHYSICAL |
MEM_TOP_DOWN | MEM_WRITE_WATCH)))
{
DPRINT1("Invalid Allocation Type\n");
return STATUS_INVALID_PARAMETER_5;
}
/* Check for at least one of these Allocation Types to be set */
if (!(AllocationType & (MEM_COMMIT | MEM_RESERVE | MEM_RESET)))
{
DPRINT1("No memory allocation base type\n");
return STATUS_INVALID_PARAMETER_5;
}
/* MEM_RESET is an exclusive flag, make sure that is valid too */
if ((AllocationType & MEM_RESET) && (AllocationType != MEM_RESET))
{
DPRINT1("MEM_RESET used illegaly\n");
return STATUS_INVALID_PARAMETER_5;
}
/* MEM_WRITE_WATCH can only be used if MEM_RESERVE is also used */
if ((AllocationType & MEM_WRITE_WATCH) && !(AllocationType & MEM_RESERVE))
{
DPRINT1("MEM_WRITE_WATCH used without MEM_RESERVE\n");
return STATUS_INVALID_PARAMETER_5;
}
/* MEM_PHYSICAL can only be used with MEM_RESERVE, and can only be R/W */
if (AllocationType & MEM_PHYSICAL)
{
/* First check for MEM_RESERVE exclusivity */
if (AllocationType != (MEM_RESERVE | MEM_PHYSICAL))
{
DPRINT1("MEM_PHYSICAL used with other flags then MEM_RESERVE or"
"MEM_RESERVE was not present at all\n");
return STATUS_INVALID_PARAMETER_5;
}
/* Then make sure PAGE_READWRITE is used */
if (Protect != PAGE_READWRITE)
{
DPRINT1("MEM_PHYSICAL used without PAGE_READWRITE\n");
return STATUS_INVALID_PAGE_PROTECTION;
}
}
PBaseAddress = *UBaseAddress;
PRegionSize = *URegionSize;
BoundaryAddressMultiple.QuadPart = 0;
BaseAddress = (PVOID
系统调用NtAllocateVirtualMemory()详解

最低0.47元/天 解锁文章
242

被折叠的 条评论
为什么被折叠?



