3.1.6 系统调用NtAllocateVirtualMemory()1

系统调用NtAllocateVirtualMemory()详解

系列文章目录


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
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值