企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持知识库和私有化部署方案 广告
https://docs.microsoft.com/zh-cn/windows/desktop/api/memoryapi/nf-memoryapi-virtualalloc [TOC] Reserves, commits, or changes the state of a region of pages in the virtual address space of the calling process. Memory allocated by this function is automatically initialized to zero. To allocate memory in the address space of another process, use the VirtualAllocEx function. # Syntax ``` LPVOID VirtualAlloc( LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect ); ``` # Parameters ## lpAddress 保留页面的内存地址;一般用NULL自动分配 。 The starting address of the region to allocate. If the memory is being reserved, the specified address is rounded down to the nearest multiple of the allocation granularity. If the memory is already reserved and is being committed, the address is rounded down to the next page boundary. To determine the size of a page and the allocation granularity on the host computer, use the GetSystemInfo function. ``` If this parameter is NULL, the system determines where to allocate the region. ``` If this address is within an enclave that you have not initialized by calling InitializeEnclave, VirtualAlloc allocates a page of zeros for the enclave at that address. The page must be previously uncommitted, and will not be measured with the EEXTEND instruction of the Intel Software Guard Extensions programming model. If the address in within an enclave that you initialized, then the allocation operation fails with the ERROR_INVALID_ADDRESS error. ## dwSize 欲分配的内存大小,字节单位;注意实际分 配的内存大小是页内存大小的整数倍 The size of the region, in bytes. If the lpAddress parameter is NULL, this value is rounded up to the next page boundary. Otherwise, the allocated pages include all pages containing one or more bytes in the range from lpAddress to lpAddress+dwSize. This means that a 2-byte range straddling a page boundary causes both pages to be included in the allocated region. ## flAllocationType The type of memory allocation. This parameter must contain one of the following values. ### MEM_COMMIT 0x00001000 为特定的页面区域分配内存中或磁盘的页面文件中的物理存储 这里保证内存初始化为0 Allocates memory charges (from the overall size of memory and the paging files on disk) for the specified reserved memory pages. The function also guarantees that when the caller later initially accesses the memory, the contents will be zero. Actual physical pages are not allocated unless/until the virtual addresses are actually accessed. To reserve and commit pages in one step, call VirtualAlloc with MEM_COMMIT | MEM_RESERVE. (访问内存时才分配) Attempting to commit a specific address range by specifying MEM_COMMIT without MEM_RESERVE and a non-NULL lpAddress fails unless the entire range has already been reserved. The resulting error code is ERROR_INVALID_ADDRESS. An attempt to commit a page that is already committed does not cause the function to fail. This means that you can commit pages without first determining the current commitment state of each page. If lpAddress specifies an address within an enclave, flAllocationType must be MEM_COMMIT. ### MEM_RESERVE 0x00002000 保留进程的虚拟地址空间,而不分配任何物理存储。保留页面可通过继续调用VirtualAlloc()而被占用 这里是访问时才分配 Reserves a range of the process's virtual address space without allocating any actual physical storage in memory or in the paging file on disk. You can commit reserved pages in subsequent calls to the VirtualAlloc function. To reserve and commit pages in one step, call VirtualAlloc with MEM_COMMIT | MEM_RESERVE. Other memory allocation functions, such as malloc and LocalAlloc, cannot use a reserved range of memory until it is released. ### MEM_RESET 0x00080000 指明在内存中由参数lpAddress和dwSize指定的数据无效 Indicates that data in the memory range specified by lpAddress and dwSize is no longer of interest. The pages should not be read from or written to the paging file. However, the memory block will be used again later, so it should not be decommitted. This value cannot be used with any other value. Using this value does not guarantee that the range operated on with MEM_RESET will contain zeros. If you want the range to contain zeros, decommit the memory and then recommit it. When you specify MEM_RESET, the VirtualAlloc function ignores the value of flProtect. However, you must still set flProtect to a valid protection value, such as PAGE_NOACCESS. VirtualAlloc returns an error if you use MEM_RESET and the range of memory is mapped to a file. A shared view is only acceptable if it is mapped to a paging file. ### MEM_RESET_UNDO 0x1000000 MEM_RESET_UNDO should only be called on an address range to which MEM_RESET was successfully applied earlier. It indicates that the data in the specified memory range specified by lpAddress and dwSize is of interest to the caller and attempts to reverse the effects of MEM_RESET. If the function succeeds, that means all data in the specified address range is intact. If the function fails, at least some of the data in the address range has been replaced with zeroes. This value cannot be used with any other value. If MEM_RESET_UNDO is called on an address range which was not MEM_RESET earlier, the behavior is undefined. When you specify MEM_RESET, the VirtualAlloc function ignores the value of flProtect. However, you must still set flProtect to a valid protection value, such as PAGE_NOACCESS. Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP: The MEM_RESET_UNDO flag is not supported until Windows 8 and Windows Server 2012. ***** This parameter can also specify the following values as indicated. ### MEM_LARGE_PAGES 0x20000000 分配大页支持的内存 Allocates memory using large page support. The size and alignment must be a multiple of the large-page minimum. To obtain this value, use the GetLargePageMinimum function. 这个功能必须同时使用MEM_RESERVE和MEM_COMMIT. If you specify this value, you must also specify MEM_RESERVE and MEM_COMMIT. ### MEM_PHYSICAL 0x00400000 分配物理内存(仅用于地址窗口扩展内存) 这个标识是使用AWE页面时使用。(暂时不用理,好像很旧的东西了) Reserves an address range that can be used to map Address Windowing Extensions (AWE) pages. This value must be used with MEM_RESERVE and no other values. ### MEM_TOP_DOWN 0x00100000 在尽可能高的地址上分配内存(Windows 98忽略此标志) Allocates memory at the highest possible address. This can be slower than regular allocations, especially when there are many allocations. ### MEM_WRITE_WATCH 0x00200000 必须与MEM_RESERVE一起指定,使系统跟踪那些被写入分配区域的页面(仅针对Windows 98) Causes the system to track pages that are written to in the allocated region. If you specify this value, you must also specify MEM_RESERVE. To retrieve the addresses of the pages that have been written to since the region was allocated or the write-tracking state was reset, call the GetWriteWatch function. To reset the write-tracking state, call GetWriteWatch or ResetWriteWatch. The write-tracking feature remains enabled for the memory region until the region is freed. ## flProtect The memory protection for the region of pages to be allocated. If the pages are being committed, you can specify any one of the ### Memory Protection Constants The following are the memory-protection options; you must specify one of the following values when allocating or protecting a page in memory. Protection attributes cannot be assigned to a portion of a page; they can only be assigned to a whole page. https://docs.microsoft.com/zh-cn/windows/desktop/Memory/memory-protection-constants Requirements * Minimum supported client :Windows XP [desktop apps only] * Minimum supported server :Windows Server 2003 [desktop apps only] * Header :WinNT.h (include Windows.h) #### PAGE_EXECUTE 0x10 区域包含可被系统执行的代码。试图读写该区域的操作将被拒绝。 Enables execute access to the committed region of pages. An attempt to write to the committed region results in an access violation. This flag is not supported by the CreateFileMapping function. #### PAGE_EXECUTE_READ 0x20 :区域包含可执行代码,应用程序可以读该区域。 Enables execute or read-only access to the committed region of pages. An attempt to write to the committed region results in an access violation. Windows Server 2003 and Windows XP: This attribute is not supported by the CreateFileMapping function until Windows XP with SP2 and Windows Server 2003 with SP1. #### PAGE_EXECUTE_READWRITE 0x40 区域包含可执行代码,应用程序可以读写该区域。 Enables execute, read-only, or read/write access to the committed region of pages. Windows Server 2003 and Windows XP: This attribute is not supported by the CreateFileMapping function until Windows XP with SP2 and Windows Server 2003 with SP1. #### PAGE_EXECUTE_WRITECOPY 0x80 Enables execute, read-only, or copy-on-write access to a mapped view of a file mapping object. An attempt to write to a committed copy-on-write page results in a private copy of the page being made for the process. The private page is marked as PAGE_EXECUTE_READWRITE, and the change is written to the new page. This flag is not supported by the VirtualAlloc or VirtualAllocEx functions. Windows Vista, Windows Server 2003 and Windows XP: This attribute is not supported by the CreateFileMapping function until Windows Vista with SP1 and Windows Server 2008. #### PAGE_NOACCESS 0x01 任何访问该区域的操作将被拒绝 Disables all access to the committed region of pages. An attempt to read from, write to, or execute the committed region results in an access violation. This flag is not supported by the CreateFileMapping function. #### PAGE_READONLY 0x02 该区域为只读。如果应用程序试图访问区域中的页的时候,将会被拒绝访 Enables read-only access to the committed region of pages. An attempt to write to the committed region results in an access violation. If Data Execution Prevention is enabled, an attempt to execute code in the committed region results in an access violation. #### PAGE_READWRITE 0x04 区域可被应用程序读写 Enables read-only or read/write access to the committed region of pages. If Data Execution Prevention is enabled, attempting to execute code in the committed region results in an access violation. #### PAGE_WRITECOPY 0x08 Enables read-only or copy-on-write access to a mapped view of a file mapping object. An attempt to write to a committed copy-on-write page results in a private copy of the page being made for the process. The private page is marked as PAGE_READWRITE, and the change is written to the new page. If Data Execution Prevention is enabled, attempting to execute code in the committed region results in an access violation. This flag is not supported by the VirtualAlloc or VirtualAllocEx functions. #### PAGE_TARGETS_INVALID 0x40000000 Sets all locations in the pages as invalid targets for CFG. Used along with any execute page protection like PAGE_EXECUTE, PAGE_EXECUTE_READ, PAGE_EXECUTE_READWRITE and PAGE_EXECUTE_WRITECOPY. Any indirect call to locations in those pages will fail CFG checks and the process will be terminated. The default behavior for executable pages allocated is to be marked valid call targets for CFG. This flag is not supported by the VirtualProtect or CreateFileMapping functions. #### PAGE_TARGETS_NO_UPDATE 0x40000000 Pages in the region will not have their CFG information updated while the protection changes for VirtualProtect. For example, if the pages in the region was allocated using PAGE_TARGETS_INVALID, then the invalid information will be maintained while the page protection changes. This flag is only valid when the protection changes to an executable type like PAGE_EXECUTE, PAGE_EXECUTE_READ, PAGE_EXECUTE_READWRITE and PAGE_EXECUTE_WRITECOPY. The default behavior for VirtualProtect protection change to executable is to mark all locations as valid call targets for CFG. ***** The following are modifiers that can be used in addition to the options provided in the previous table, except as noted. #### PAGE_GUARD 0x100 区域第一次被访问时进入一个STATUS_GUARD_PAGE异常,这个标志要和其他保护标志合并使用,表明区域被第一次访问的权限 Pages in the region become guard pages. Any attempt to access a guard page causes the system to raise a STATUS_GUARD_PAGE_VIOLATION exception and turn off the guard page status. Guard pages thus act as a one-time access alarm. For more information, see Creating Guard Pages. When an access attempt leads the system to turn off guard page status, the underlying page protection takes over. If a guard page exception occurs during a system service, the service typically returns a failure status indicator. This value cannot be used with PAGE_NOACCESS. This flag is not supported by the CreateFileMapping function. #### PAGE_NOCACHE (重点关注) 0x200 RAM中的页映射到该区域时将不会被微处理器缓存(cached) PAGE_NOCACHE防止当它映射到虚拟页的时候被微处理器缓存。这个标志方便设备驱动使用直接内存访问方式(DMA)来共享内存块。 Sets all pages to be non-cachable. Applications should not use this attribute except when explicitly required for a device. Using the interlocked functions with memory that is mapped with SEC_NOCACHE can result in an EXCEPTION_ILLEGAL_INSTRUCTION exception. The PAGE_NOCACHE flag cannot be used with the PAGE_GUARD, PAGE_NOACCESS, or PAGE_WRITECOMBINE flags. The PAGE_NOCACHE flag can be used only when allocating private memory with the VirtualAlloc, VirtualAllocEx, or VirtualAllocExNuma functions. To enable non-cached memory access for shared memory, specify the SEC_NOCACHE flag when calling the CreateFileMapping function. #### PAGE_WRITECOMBINE 0x400 Sets all pages to be write-combined. Applications should not use this attribute except when explicitly required for a device. Using the interlocked functions with memory that is mapped as write-combined can result in an EXCEPTION_ILLEGAL_INSTRUCTION exception. The PAGE_WRITECOMBINE flag cannot be specified with the PAGE_NOACCESS, PAGE_GUARD, and PAGE_NOCACHE flags. The PAGE_WRITECOMBINE flag can be used only when allocating private memory with the VirtualAlloc, VirtualAllocEx, or VirtualAllocExNuma functions. To enable write-combined memory access for shared memory, specify the SEC_WRITECOMBINE flag when calling the CreateFileMapping function. Windows Server 2003 and Windows XP: This flag is not supported until Windows Server 2003 with SP1. ***** The following constants can only be used with the LoadEnclaveData function when you specify an enclave that has the Intel Software Guard Extensions (SGX) architecture. #### PAGE_ENCLAVE_THREAD_CONTROL The page contains a thread control structure (TCS). #### PAGE_ENCLAVE_UNVALIDATED The page contents that you supply are excluded from measurement with the EEXTEND instruction of the Intel SGX programming model. ***** If lpAddress specifies an address within an enclave, flProtect cannot be any of the following values: * PAGE_NOACCESS * PAGE_GUARD * PAGE_NOCACHE * PAGE_WRITECOMBINE # Return Value If the function succeeds, the return value is the base address of the allocated region of pages. If the function fails, the return value is NULL. To get extended error information, call GetLastError. # Remarks Each page has an associated page state. The VirtualAlloc function can perform the following operations: Commit a region of reserved pages Reserve a region of free pages Simultaneously reserve and commit a region of free pages VirtualAlloc cannot reserve a reserved page. It can commit a page that is already committed. This means you can commit a range of pages, regardless of whether they have already been committed, and the function will not fail. You can use VirtualAlloc to reserve a block of pages and then make additional calls to VirtualAlloc to commit individual pages from the reserved block. This enables a process to reserve a range of its virtual address space without consuming physical storage until it is needed. If the lpAddress parameter is not NULL, the function uses the lpAddress and dwSize parameters to compute the region of pages to be allocated. The current state of the entire range of pages must be compatible with the type of allocation specified by the flAllocationType parameter. Otherwise, the function fails and none of the pages are allocated. This compatibility requirement does not preclude committing an already committed page, as mentioned previously. To execute dynamically generated code, use VirtualAlloc to allocate memory and the VirtualProtect function to grant PAGE_EXECUTE access. The VirtualAlloc function can be used to reserve an Address Windowing Extensions (AWE) region of memory within the virtual address space of a specified process. This region of memory can then be used to map physical pages into and out of virtual memory as required by the application. The MEM_PHYSICAL and MEM_RESERVE values must be set in the AllocationType parameter. The MEM_COMMIT value must not be set. The page protection must be set to PAGE_READWRITE. The VirtualFree function can decommit a committed page, releasing the page's storage, or it can simultaneously decommit and release a committed page. It can also release a reserved page, making it a free page. When creating a region that will be executable, the calling program bears responsibility for ensuring cache coherency via an appropriate call to FlushInstructionCache once the code has been set in place. Otherwise attempts to execute code out of the newly executable region may produce unpredictable results. # Requirements * Minimum supported client Windows XP [desktop apps only] * Minimum supported server Windows Server 2003 [desktop apps only] * Target Platform Windows * Header memoryapi.h (include Windows.h, Memoryapi.h) * Library Kernel32.lib * DLL Kernel32.dll