Paged Pool

Тема в разделе "WASM.WIN32", создана пользователем Ation, 18 авг 2005.

  1. Ation

    Ation New Member

    Публикаций:
    0
    Регистрация:
    6 авг 2005
    Сообщения:
    92
    Адрес:
    Zaporozhie
    Hi all.

    Pomogite reshit problemu odnu.

    Neobhodimo opredelit, gde nahoditsya, gde conchaetsya paged pool.

    I cto skolko, po kakim addresam iz nego vugruzil...

    Budu rad lubomu sovety...
     
  2. Broken Sword

    Broken Sword Robert

    Публикаций:
    0
    Регистрация:
    30 авг 2002
    Сообщения:
    433
    В Win support tools есть утилита poolmon. Перед ее использованием необходимо разрешить pool tagging с помощью утилиты gflags. После этого она покажет всю инфу о пулах.



    Программно тебе нужно копать в сторону ф-ций Mm* и ковырять структуру MDL (Memory Descriptor List) и сказать спасибо Four-F-у за его ntddk.inc.
     
  3. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    Как-то давно занимался этим вопросом - многое не помню. Начет начала и конца пулов не знаю, но вопрос "как определить размер" много раз задавался в конфе на osronline.com. Там через одного MVP мелькают, но никто так и не дал вразумительного ответа.



    Тебе нужно получить значения этих неэкспортируемых переменных ядра:



    MmSizeOfNonPagedPoolInBytes

    MmNonPagedPoolEnd

    MmNonPagedPoolStart



    MmSizeOfPagedPoolInBytes

    MmPagedPoolStart

    MmPagedPoolEnd



    В аттаче дока, рассказывающая, как они вычисляются. Также кое-что есть в книге "Внутренне устройство Windows". Но это всё теоретические измышления, к тому же применимые только к одной определенной версии системы. Опираться на них нельзя.



    Porocess Explorer в диалоге "System Information" показывает "Paged Limit" и "Nonpaged Limit". Делает он это путем доставания адресов MmSizeOfPagedPoolInBytes и MmMaximumNonPagedPoolInBytes из образа ntoskrnl.exe. Деталей не помню, кажется с помощью dbghelp.dll. Затем просит драйвер прочитать, что находится по этим адресам. То же самое, наверное, можно проделать и для MmPagedPoolStart и MmPagedPoolEnd.



    Если нужно чисто из драйвера, то, наверное, никак.



    Ну а кто и сколько определить вообще невозможно, только если выделение помечается тегом, а это не каждый делает.

    [​IMG] _2139892499__PagedPoolSizeAndNonPagedPoolSizeValuesInWindowsNT.rar
     
  4. Ation

    Ation New Member

    Публикаций:
    0
    Регистрация:
    6 авг 2005
    Сообщения:
    92
    Адрес:
    Zaporozhie
    to Broken Sword

    >В Win support tools есть утилита poolmon

    копал... тулза дает статистику, которую с легкостью можно получить с помощью NtQuerySystemInformation(). Можно получить сколько раз выделялись пулы(Paged,NonPeged),и каким размером. на ХР тулза глючит немного...

    >ковырять структуру MDL

    не поможет, это всего лишь описание для куска памяти... (

    а как описать память, если я не знаю даже базовый аддресс,

    да и зная его не поможет, это ИМХО, буду рад разочароватся



    to Four-F

    пасиба за инфу.

    >Ну а кто и сколько определить вообще невозможно

    не согласен, чисто интуитивно... довод н1 - ExFreePool().

    как-то ж работает... )
     
  5. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    Как-то раз, хотел писАть тул для поиска руткитов. Идея состояла в поиске скрытых объектов ядра путем анализа содержимого всех выделенных блоков памяти. Я тоже взял за основу "чисто интуитивный... довод": "функции ExAlloc/ExFree как-то работают и должны помнить выделенные блоки". После анализа исходного кода я понял, что довод был ошибочен.



    Для малых блоков памяти (меньше страницы) системные пулы работают как ассоциативные списки (look-aside lists). Имеется несколько списков с блоками разного размера. Блоки связаны посредством двусвязного списка. Когда приходит запрос на выделение памяти, система ищет блок подходящего размера и "отстегивает" его от списка. При этом LIST_ENTRY, в "отстегнутом" блоке, замыкается сам на себя. В начале блока имеется небольшая управляющая структура, в которую записывается тип пула, размер блока и ещё какая-то ерунда. За управляющей структурой идет собственно память доступная для использования - именно этот адрес возвращает ExAlloc. Т.о. можно пройтись по всем невыделенным блокам, но пройтись по выделенным невозможно, т.к. они просто "болтаются" сами по себе. Найти их в памяти тоже невозможно, т.к. отсутствует критерий поиска.



    Я анализировал код w2k. Возможно в ХР+ что-то и поменялось, но это очень маловероятно. Меня все это интересовало только применительно к объектам ядра, т.е. для блоков памяти меньше страницы. Как работает страничное выделение я не знаю. Может быть система и записывает где-то что она выделяет, но кому - вряд ли.
     
  6. Ms Rem

    Ms Rem New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2005
    Сообщения:
    1.057
    Адрес:
    С планеты "Земля"




    Можно просто загрузить свой драйвер как можно раньше (желательно boot) и просплайсить все функции создания/освобождения обьектов, а потом по их вызовам строить списки обьектов ядра.

    Главный недостаток этого метода в падении производительности системы (хотя это зависит от реализации), поэтому для постоянного применения не годиться.

    Будет время, напишу подобную тулзу.
     
  7. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    Любые активные методы противодействия плохи тем, что их можно обнаружить и обойти. "просплайсить все функции создания/освобождения обьектов" - грубый метод, к тому же обходится. У меня была задача сделать все очень культурно и незаметно. Даже если бы руткит убирал выделенные им блоки памяти из системных списков, то имея списки выделенных и свободных блоков, можно было бы составить карту памяти, найти в ней дыры и посмотреть что там. Сожно, но можно. И это всё чисто пассивно. Например, RootkitRevealer'у довольно трудно противостоять, хотя теоретически возможно, именно потому, что он пассивен. К тому же есть такое понятие как "гонка вооружений". Не хотелось бы её подстёгивать.
     
  8. Ms Rem

    Ms Rem New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2005
    Сообщения:
    1.057
    Адрес:
    С планеты "Земля"
    Есть еще один выход - создать тулзу на любом неизвестном ранее способе обнаружения (пусть даже легко обходимом), и сделать ее приватной. Пока разработчики руткитов ее не увидят, они не смогут ее обойти.

    А любая публичная тулза будет немедленно обойдена хотя-бы примитивным хуком на IOCTL ее драйвера и подтасовкой результата. Например так делает hxdef. Поэтому выход - приватная и малоизвестная тулза, ни в коем случае не opensource.
     
  9. Ation

    Ation New Member

    Публикаций:
    0
    Регистрация:
    6 авг 2005
    Сообщения:
    92
    Адрес:
    Zaporozhie
    Four-F Вы писали:

    > В начале блока имеется небольшая управляющая структура, в которую записывается тип пула, размер блока и ещё какая-то ерунда.

    Оччень хотелось бы посмотреть на эту структуру.

    Судя по тому, что Вы написали, то сам собой напрашывается такое решение -

    1. Выгружаемый и невыгружаемый пул имеет свои границы.

    2. Если просмотреть списки, то ессесно там окажутся не все блоки -> отсутствующие блоки представляют интерес )



    а критерием поиска может быть как раз та управляющая структура.
     
  10. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    Код (Text):
    1.  
    2. struct _POOL_HEADER {
    3.   /*<thisrel this+0x0>*/ /*|0x1|*/ unsigned char PreviousSize;
    4.   /*<thisrel this+0x1>*/ /*|0x1|*/ unsigned char PoolIndex;
    5.   /*<thisrel this+0x2>*/ /*|0x1|*/ unsigned char PoolType;
    6.   /*<thisrel this+0x3>*/ /*|0x1|*/ unsigned char BlockSize;
    7.   /*<thisrel this+0x0>*/ /*|0x4|*/ unsigned long Ulong1;
    8.   /*<thisrel this+0x4>*/ /*|0x4|*/ struct _EPROCESS* ProcessBilled;
    9.   /*<thisrel this+0x4>*/ /*|0x4|*/ unsigned long PoolTag;
    10.   /*<thisrel this+0x4>*/ /*|0x2|*/ unsigned short AllocatorBackTraceIndex;
    11.   /*<thisrel this+0x6>*/ /*|0x2|*/ unsigned short PoolTagHash;
    12. };
    13.  
    Если есть доступ к исходному коду w2k, то там более правильное определение ;)



    Не думаю, что имея эти 8 байт, можно что-то найти.
     
  11. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    Структура выдрана с помощью pdbdump из официальных символов. Кто никогда с ней не работал, её определения могут показаться странными. Вот по-человечески:
    Код (Text):
    1. typedef struct _POOL_HEADER {
    2.     union {
    3.         struct {
    4.             UCHAR  PreviousSize;
    5.             UCHAR  PoolIndex;
    6.             UCHAR  PoolType;
    7.             UCHAR  BlockSize;
    8.         };
    9.         ULONG      Ulong1;
    10.     };
    11.     union {
    12.         PEPROCESS  ProcessBilled;
    13.         ULONG      PoolTag;
    14.         struct {
    15.             USHORT AllocatorBackTraceIndex;
    16.             USHORT PoolTagHash;
    17.         };
    18.     };
    19. } POOL_HEADER, *PPOOL_HEADER;




    Этот хидер используется для выделений меньше страницы, для страничных выделений никакого оверхеда нет.



    Кстати, кроме границ пулов есть ещё масса интересных переменных, естественно не экспортируемых. Например, MmNonPagedPoolFreeListHead.



    Или


    Код (Text):
    1. POOL_DESCRIPTOR NonPagedPoolDescriptor;
    2. POOL_DESCRIPTOR PagedPoolDescriptor;
    3. POOL_DESCRIPTOR NonPagedPoolDescriptorMS;
    4. POOL_DESCRIPTOR PagedPoolDescriptorMS;
    5. POOL_DESCRIPTOR ExpPagedPoolDescriptor;
    6.  
    7. PPOOL_DESCRIPTOR PoolVector[MaxPoolType] = {
    8.     &NonPagedPoolDescriptor,
    9.     &PagedPoolDescriptor,
    10.     &NonPagedPoolDescriptorMS,
    11.     &PagedPoolDescriptorMS
    12.     };
    13.  
    14. struct _POOL_DESCRIPTOR {
    15.   /*<thisrel this+0x0>*/  /*|0x4|*/   int PoolType;
    16.   /*<thisrel this+0x4>*/  /*|0x4|*/   unsigned long PoolIndex;
    17.   /*<thisrel this+0x8>*/  /*|0x4|*/   unsigned long RunningAllocs;
    18.   /*<thisrel this+0xc>*/  /*|0x4|*/   unsigned long RunningDeAllocs;
    19.   /*<thisrel this+0x10>*/ /*|0x4|*/   unsigned long TotalPages;
    20.   /*<thisrel this+0x14>*/ /*|0x4|*/   unsigned long TotalBigPages;
    21.   /*<thisrel this+0x18>*/ /*|0x4|*/   unsigned long Threshold;
    22.   /*<thisrel this+0x1c>*/ /*|0x4|*/   void* LockAddress;
    23.   /*<thisrel this+0x20>*/ /*|0x400|*/ struct _LIST_ENTRY ListHeads[128];
    24. };
    Если есть исходники, то разобравшись с механизмом работы пулов, можно попытаться что-то замутить, хотя, будет очень сложно.
     
  12. Ation

    Ation New Member

    Публикаций:
    0
    Регистрация:
    6 авг 2005
    Сообщения:
    92
    Адрес:
    Zaporozhie
    Пасиба за инфу, в исходниках наверно покопатся придется...

    Одно но:

    на ХР перед началом пула, меньше страницы размером, стоит тэг, если выделялось с тэгом (проверено массу раз).

    Наверно структуры различаются... (
     
  13. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    Структуры запросто могут отличаться, но размер POOL_HEADER = 8 байт. Вторые 4 байта - это тэг. Дальше сразу идет собственно доступный для вызывателя блок памяти. Так что тэг как раз и будет сразу перед началом блока.