Вызовы для выделения и освобождения областей виртуальной памяти
Для манипуляций с областями памяти (выделение и освобождение) в режиме ядра используются специальные системные вызовы, отличающиеся от API вызовов режима ядра: ExAllocatePool, ExAllocatePoolWithTag, ExFreePool. В режиме ядра возможно выделение и освобождение области физически непрерывной памяти, что выполняется при помощи вызовов MmAllocateContiguousMemory
и, соответственно, MmFreeContiguousMemory. Эти вызовы рассмотрены ниже.
Таблица 7.2. Прототип вызова ExAllocatePool
PVOID ExAllocatePool | IRQL < DISPATCH_LEVEL | |
Параметры | Выполняет выделение области памяти | |
IN POOL_TYPE PoolType | Тип виртуальной памяти, в которой следует выделять область. Наиболее употребительны значения: • PagedPool — страничная • NonPagedPool — нестраничная, тогда данную функцию можно вызывать при любом уровне IRQL | |
IN ULONG NumberOfBytes | Размер запрашиваемой области | |
Возвращаемое значение | Указатель на выделенную область либо NULL (в случае, если память выделить невозможно). Выделенная область всегда выравнивается на 8 байт. В случае, если запрашиваемый размер превышает PAGE_SIZE, то выделяемая область выравнивается на размер страницы. |
Таблица 7.3. Прототип вызова ExAllocatePoolWithTag
PVOID ExAllocatePoolWithTag | IRQL < DISPATCH_LEVEL |
Параметры | Выполняет выделение области памяти |
IN POOL_TYPE PoolType | См. описание ExAllocatePool
выше. |
IN ULONG NumberOfBytes | Размер запрашиваемой области |
IN ULONG Tag | Метка (тег) для данной области, можно задавать как 4 символа, например, 'ABCD'. Удобно для отладки. |
Возвращаемое значение | См. описание ExAllocatePool
выше. |
Таблица 7.4. Прототип вызова ExFreePool
VOID ExFreePool | IRQL < DISPATCH_LEVEL |
Параметры | Выполняет освобождение области памяти |
IN PVOID pBuffer | Указатель на освобождаемую область памяти, выделенную вызовами ExAllocatePool или ExAllocatePoolWithTag. Если освобождается нестраничная память, вызов может быть сделан из кода на уровне DISPATCH_LEVEL IRQL |
Возвращаемое значение | void |
Таблица 7.5. Прототип вызова MmAllocateContiguousMemory
PVOID MmAllocateContiguousMemory | IRQL == PASSIVE_LEVEL |
Параметры | Выполняет выделение физически непрерывной области памяти |
IN ULONG NumberOfBytes | Размер запрашиваемой области |
IN PHYSICAL_ADDRESS maxAcceptableAddress | Верхний предел адресов для запрашиваемой области. Поле HighPart=0, поле LowPart принимает значения, например: • 0x000FFFFF (до 1 МБ) • 0x00FFFFFF (до 16 МБ) • 0xFFFFFFFF(до 4ГБ) |
Возвращаемое значение | Виртуальный адрес или NULL (при неудаче). (Для повышения вероятности успешного завершения рекомендуется выполнять вызов в DriverEntry, поскольку память при работе системы быстро становится сильно дефрагментированной) |
VOID MmFreeContiguousMemory | IRQL == PASSIVE_LEVEL |
Параметры | Выполняет освобождение области памяти |
IN PVOID pBuffer | Указатель на область памяти, выделенную ранее с использованием системного вызова MmAllocateContiguousMemory |
Возвращаемое значение | void |
BOOLEAN MmlsAddressValid | IRQL <= DISPATCH_LEVEL |
Параметры | Выполняет проверку виртуального адреса |
IN PVOID VirtualAddress | Виртуальный адрес, который следует проверить |
Возвращаемое значение | TRUE — если присутствует в оперативной памяти FALSE — если вызовет прерывание PAGE FAULT Замечание. Если адрес не находится в нестраничной памяти (или не зафиксирован в оперативной памяти), возврат TRUE не гарантирует отсутствие проблем при работе на повышенных уровнях IRQL (поскольку к моменту использования данного виртуального адреса ситуация может измениться). |
PHYSICAL_ADDRESS MmGetPhysicalAddress | IRQL — любой |
Параметры | Определяет физический адрес, соответствующий данному виртуальному |
IN PVOID VirtualAddress | Анализируемый виртуальный адрес |
Возвращаемое значение | Физический адрес. Перед данным вызовом следует воспользоваться MmlsAddressValid |