Программирование систем защиты

         

Функции работы с памятью

Из всего вышеизложенного нужно выделить основные моменты:

  1. 1. Все адресное пространство процесса (контекст памяти) делится на две области
    1. системное адресное пространство (верхние 2 Гб) и пользовательское адресное пространство (нижние 2 Гб):
    2. Системное адресное пространство всегда одинаково, вне зависимости от текущего контекста памяти.
    3. Пользовательское адресное пространство разное для каждого контекста памяти.
  2. 2. Код пользовательского режима и режима ядра пользуется для доступа к памяти разными селекторами:
    1. Для одного контекста памяти селекторы адресуют



      одну и ту же физическую память, но с разными режимами доступа.
    2. Селекторы не имеют ничего общего с контекстом памяти.
    3. По селекторам для ядра можно получить доступ (по крайней мере, для чтения) ко всему адресному пространству в данном контексте памяти, а по селекторам для ядра - только для пользовательской области памяти.
  3. 3. Код в пользовательском адресном пространстве всегда вытесняемый, если не предприняты меры по созданию новой записи в каталоге страниц, указывающих на невытесняемую память.
  4. 4. Код, работающий на уровне IRQL большем или равном DISPATCH_LEVEL, может использовать только невыгружаемую память (соответственно, сам код должен находиться в невыгружаемой памяти).
  5. 5. В ОС существуют функции для выполнения любой работы с памятью:
    1. Выделение/освобождение памяти в выгружаемой/невыгружаемой, кешируемой/некешируемой памяти.
    2. Преобразование адресов памяти (виртуальный в физический, физический в виртуальный).
    3. Проверка доступности памяти. Рассмотрим эти функции более подробно.

Выделение памяти

PVOID ExAllocatePool(
IN POOLJTYPE PoolType,
IN ULONG NumberOfBytes) ; PVOID ExAllocatePoolWithTag(
IN POOL_TYPE PoolType,
IN ULONG NumberOfBytes, IN ULONG Tag); Где: POOLJTYPE принимает следующие значения:

Тип памяти (PoolType)
Описание
NonPagedPool
Обычное выделение памяти из Nonpaged Pool.
NonPagedPoolCacheAligned
Выделение памяти из Nonpaged Pool будет выровнено по линии кеша.
NonPagedPooMustSucceed
Используется в специальных случаях драйверами, необходимыми для загрузки системы.
NonPagedPoolCacheAlignedMustSucceed
PagedPool
Обычное выделение памяти из Paged Pool.
PagedPoolCacheAligned
Выделение памяти из Paged Pool будет выровнено по линии кеша.

VOID ExFreePool(IN PVOID address);
PVOID MmAllocateNonCachedMemory(IN ULONG NumberOfBytes);
VOID MmFreeNonCachedMemory( IN PVOID BaseAddress,
IN ULONG NumberOfBytes); PVOID MmAllocateContiguousMemory(IN ULONG NumberOfBytes,
IN PHYSICAL_ADDRESS HighestAcceptableAddress); VOID MmFreeContiguousMemory(IN PVOID BaseAddress);

Список заранее выделенных блоков памяти (Lookaside List)

Во многих случаях, выделение и освобождение временного буфера памяти должно происходить очень часто, для уменьшения накладных расходов служит Lookaside List - список заранее выделенных блоков памяти фиксированного размера.
Первоначально, память выделяется только под небольшой заголовок со служебной информацией. При каждом запросе на выделение памяти проверяется, есть ли в списке свободные блоки. Если их нет - они выделяются из выгружаемой или невыгружаемой памяти. Если есть, то помечаются, как используемые и выдаются для использования.

VOID ExInitializeNPagedLookasideList(
IN PNPAGED_LOOKASIDE_LIST Lookaside,
IN PALLOCATE_FUNCTION Allocate OPTIONAL,
IN PFREE_FUNCTION Free OPTIONAL,
IN ULONG Flags,
IN ULONG Size,
IN ULONG Tag,
IN USHORT Depth ); . VOID ExInitializePagedLookasideList(
IN PPAGED_LOOKASIDE_LIST Lookaside,
IN PALLOCATE_FUNCTION Allocate OPTIONAL,
IN PFREE_FUNCTION Free OPTIONAL,
IN ULONG Flags,
IN ULONG Size,
IN ULONG Tag,
IN USHORT Depth );
PVOID ExAllocateFromNPagedLookasideList(IN PNPAGED_LOOKASIDE_LIST Lookaside) ; PVOID ExAllocateFromPagedLookasideList(IN PPAGED_LOOKASIDE_LIST Lookaside); VOID ExFreeToNPagedLookasideList(
IN PNPAGED_LOOKASIDE_LIST Lookaside,
IN PVOID Entry); VOID ExFreeToPagedLookasideList(
IN PPAGED_LOOKASIDE_LIST .Lookaside,
IN PVOID Entry);
VOID ExDeleteNPagedLookasideList(IN PNPAGED_LOOKASIDE_LIST Lookaside);
VOID ExDeletePagedLookasideList(IN PPAGED_LOOKASIDE_LIST Lookaside) ;

Пространства ввода/вывода и отображение памяти устройств

Смотри раздел «Типы адресов в NT».

BOOLEAN HalTranslateBusAddress(IN INTERFACE_TYPE InterfaceType,
IN ULONG BusNumber,
IN PHYSICAL_ADDRESS BusAddress,
IN OUT PULONG AddressSpace,
OUT PPHYSICAL_ADDRESS TranslatedAddress); PVOID MmMapIoSpace(IN PHYSICAL_ADDRESS PhysicalAddress,
IN ULONG NumberOfBytes,
IN BOOLEAN CacheEnable); VOID MmUnmapIoSpace(IN PVOID BaseAddress,
IN ULONG NumberOfBytes);

Управление памятью и MDL

BOOLEAN MmIsAddressValid(IN PVOID VirtualAddress )/ VOID MmProbeAndLockPages
(IN OUT PMDL Mdl,
IN KPROCESSOR_MODE AccessMode,
IN LOCK_OPERATION Operation); PVOID MmGetSystemAddressForMdl(IN PMDL Mdl) MmGetPhysicalAddress(IN PVOID BaseAddress); VOID MmUnlockPages(IN PMDL mdl) ;
PMDL loAllocateMdl(IN PVOID VirtualAddress,
IN ULONG Length,
IN BOOLEAN SecondaryBuffer,
IN BOOLEAN ChargeQuota,
IN OUT PIRP Irp) ;
VOID MmPrepareMdlForReuse(IN PMDL Mdl); VOID IoFreeMdl(IN PMDL Mdl);

Содержание раздела