SDT

Тема в разделе "WASM.NT.KERNEL", создана пользователем sasha_s, 9 июн 2009.

  1. sasha_s

    sasha_s New Member

    Публикаций:
    0
    Регистрация:
    21 дек 2005
    Сообщения:
    165
    Адрес:
    Belarus
    "Найти таблицу системных вызовов в памяти очень просто. "Скармливаем" NTOSKRNL.EXE функции LoadLibrary и, используя возвращенный ей дескриптор, определяем адрес экспортируемой переменной KeServiceDescriptorTable через GetProcAddress (или разбираем таблицу экспорта вручную). Первое же двойное слово содержит указатель на SST, поэтому эффективный адрес требуемого системного сервиса по его "магическому" номеру определяется так: addr == *(DWORD *)(KeServiceDescriptorTable[0] + N*sizeof(DWORD)), где N - номер сервиса, а addr - его эффективный адрес."
    Это отсюда http://www.insidepro.com/kk/132/132r.shtml

    Но! Сие не пашет. По адресу, который выдает GetProcAddress все нули.

    В чем упущение автора, кто знает?
     
  2. AntiFreeze

    AntiFreeze Дмитрий

    Публикаций:
    0
    Регистрация:
    26 июн 2008
    Сообщения:
    65
    Всё должно работать так, как описано. Давай код в студию.
     
  3. sasha_s

    sasha_s New Member

    Публикаций:
    0
    Регистрация:
    21 дек 2005
    Сообщения:
    165
    Адрес:
    Belarus
    Дык там код-то проще некуда:

    Код (Text):
    1. typedef struct _SERVICE_DESCRIPTOR_TABLE {
    2.     /*
    3.     * Table containing cServices elements of pointers to service handler
    4.     * functions, indexed by service ID.
    5.     */
    6.     PVOID   *ServiceTable;
    7.     /*
    8.     * Table that counts how many times each service is used. This table
    9.     * is only updated in checked builds.
    10.     */
    11.     PULONG  CounterTable;
    12.     /*
    13.     * Number of services contained in this table.
    14.     */
    15.     ULONG   TableSize;
    16.     /*
    17.     * Table containing the number of bytes of parameters the handler
    18.     * function takes.
    19.     */
    20.     PUCHAR  ArgumentTable;
    21. } SERVICE_DESCRIPTOR_TABLE, *PSERVICE_DESCRIPTOR_TABLE;
    22.  
    23. HMODULE ntoskrnl = LoadLibrary("C:\\WINDOWS\\system32\\ntoskrnl.exe");
    24. PSERVICE_DESCRIPTOR_TABLE SDT_ptr = (PSERVICE_DESCRIPTOR_TABLE)GetProcAddress(ntoskrnl, "KeServiceDescriptorTable");
    и соотв. все поля у SDT_ptr равны 0!
     
  4. Forever

    Forever Виталий

    Публикаций:
    0
    Регистрация:
    12 апр 2008
    Сообщения:
    244
    Ну так правильно. Эти поля инициализируются на этапе загрузки.
     
  5. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Там массив описателей для каждой сст. Разумеется там нули, он же не инициализирован в KeAddSystemServiceTable()/KiInitSystem().
     
  6. sasha_s

    sasha_s New Member

    Публикаций:
    0
    Регистрация:
    21 дек 2005
    Сообщения:
    165
    Адрес:
    Belarus
    А вычитать родные адреса (саму таблицу ф-ций) с файла ntoskrnl.exe можно?
     
  7. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Ищут следующими способами:
    1. Дизассемблировать KeAddSystemServiceTable().
    2. Поиск KiInitSystem() и дизассемблирование её.
    3. Парсинг релоков ядра, отлично подходит для ядра на диске, ибо в загруженном ядре секция релоков выгружена.
    4. Сигнатурный поиск в секции кода. Некоторые сервисы экспортируются, поиск нескольких указателей в таблице.
     
  8. je_

    je_ New Member

    Публикаций:
    0
    Регистрация:
    27 янв 2004
    Сообщения:
    143
    у мя прямо в файле лежит SDT.
    а с какой версии так иницелуется?!
     
  9. AntiFreeze

    AntiFreeze Дмитрий

    Публикаций:
    0
    Регистрация:
    26 июн 2008
    Сообщения:
    65
    Этот метод хорошо работал, когда был доступ к PhysicalMemory из третьего кольца. Указанным в начале страницы способом искался RVA KeServiceDescriptorTable (тут это SDT_ptr - ntoskrnl), а потом уже непосредственно из "ядерной" памяти выдирались реальные таблицы.
    Автору советую глянуть исходники SDTrestore, там реализовано 2 метода поиска - через KiInitSystem и релоки.
     
  10. AntiFreeze

    AntiFreeze Дмитрий

    Публикаций:
    0
    Регистрация:
    26 июн 2008
    Сообщения:
    65
    Обманул. KiInitSystem дописывал сам и к SDTrestore отношения это не имеет.
     
  11. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    AntiFreeze
    4-й способ самый оптимальный, например часть сст на диске:
    Код (Text):
    1. 00456084  005EA597  ntoskrnl.NtOpenProcess
    2. 00456088  00620C89  ntoskrnl.NtOpenProcessToken
    3. 0045608C  0061BDD0  ntoskrnl.NtOpenProcessTokenEx
    Таблица выравнена на 4 байта в памяти в XP, Vista и Win7, тоесть находим адреса этих трёх функций, находим адрес секции кода и выполняем поиск указателя на NtOpenProcess посредством repne scasd. Прверяем следующий дворд, если он указывает на NtOpenProcessToken то сканим память вниз для поиска начала сст.
     
  12. AntiFreeze

    AntiFreeze Дмитрий

    Публикаций:
    0
    Регистрация:
    26 июн 2008
    Сообщения:
    65
    Clerk, в принципе у всех способов есть свои плюсы и минусы. nt!KeAddSystemServiceTable() хорош тем, что можно сразу выдрать и указатель на nt!KeServiceDescriptorTableShadow. Или например, когда я гружу модуль, я сразу фикшу релоки, мне не сложно ещё параллельно что-то найти.
    Но предложенный тобой способ, несомненно, интересен.