Как найти GDT из системного потока выполняемого из сегмента в LDT ?

Тема в разделе "WASM.NT.KERNEL", создана пользователем Charlief, 6 сен 2010.

  1. Charlief

    Charlief New Member

    Публикаций:
    0
    Регистрация:
    17 авг 2010
    Сообщения:
    129
    В DriverEntry в регистре Cs флаг TI=1, значит код выполняется из сегмента описаного в LDT, в скрытой части регистра Cs содержится база сегмента - выходит что процессору не обязательно знать линейный адрес GDT чтобы выполнить мою DriverEntry и тот код который вызвал DriverEntry ? Выходит что из DriverEntry база хранящаяся в регистре GDTR может отображатся (в контексте данного процесса) на совсем другие физические страницы, тоесть не те где действительно записана GDT ? Тоесть тот код, назовём его планировщиком, который вызвал ту функцию которая вызвала мою DriverEntry мог изменить регистр CR3(PDBR) где хранится Page Directory отображающая базу GDT на физические страницы в контексте планировщика ?

    И ещё, какой тогда смысл в содержимом fs:3Ch - KPCR (KGDTENTRY*) GDT ?
     
  2. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Charlief
    Дескриптор TSS может быть только в GDT. Иначе трап-процессинг работать не будет(при смене CPL камень уйдёт в ступор или сгенерит #DF).

    PCR это блок содержащий инфу уникальную для процессора, в частности базы GDT, IDT, TSS.
     
  3. Charlief

    Charlief New Member

    Публикаций:
    0
    Регистрация:
    17 авг 2010
    Сообщения:
    129
    Clerk
    Спасибо за информацию.
    Линейный адрес сегмента TSS не даёт информации о расположении GDT.
    А вот указатель в KPCR на GDT-entry - это только копия дескриптора из GDT или это собственно и есть сама GDT (так сказать непосредственная часть её тела) ?
    - вы имли в виду KGDTENTRY* и KIDTENTRY* ?
     
  4. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Charlief
    База GDT находится в регистре GDTR.
    Сказал ведь что база таблицы.
     
  5. Charlief

    Charlief New Member

    Публикаций:
    0
    Регистрация:
    17 авг 2010
    Сообщения:
    129
    Clerk
    - это я знаю, просто (я в первом сообщении написал) я думал что эта база может быть не действительна в контексте моего драйвера.
    Кажется всё прояснилось, похоже что база GDT в GDTR - это виртуальный адрес в адрессном пространстве моего драйвера, совпадает с полем GDT в KPCR.
    DebugView:

    00000000 0.00000000 DriverEntry
    00000001 0.00000166
    00000002 0.00000299 Cs=b704
    00000003 0.00000420 GDTR Limit=3ff
    00000004 0.00000556 GDTR Base=ba34c190
    00000005 0.00000639
    00000006 0.00000771 KPCR SelfPcr=ba348000
    00000007 0.00000861
    00000008 0.00000990 KPCR IDT=ba34c590
    00000009 0.00001116 KPCR GDT=ba34c190
    00000010 0.00001238 KPCR TSS=ba348d70

    Спасибо за помощь !!!
     
  6. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Charlief
    Интересно узнать почему у вас такое значение в Cs ?
     
  7. Charlief

    Charlief New Member

    Публикаций:
    0
    Регистрация:
    17 авг 2010
    Сообщения:
    129
    Clerk
    В obj файле скомпилированом NASM:
    Код (Text):
    1. _AReadCsGDTR@4:
    2.     mov   eax, [esp+4]
    3.     mov   WORD [eax], cx
    4.     sgdt  [eax+2]
    5.     ret   4
    В DriverEntry:
    Код (Text):
    1. ...
    2. AReadCsGDTR(&sCsGDTR);
    3. ...
    4. DbgPrint("Cs=%x", sCsGDTR.Cs);
    5. ...
    Что-то не так ?
     
  8. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Charlief
    Имел ввиду что я хочу узнать почему у вас используется LDT.
     
  9. Charlief

    Charlief New Member

    Публикаций:
    0
    Регистрация:
    17 авг 2010
    Сообщения:
    129
    Clerk
    Без понятия. WinXp sp3.
    А что, у всех используется GDT ?
    Не знаю, мож вирус ? )
     
  10. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Charlief
    хм. Как это может быть. Сдампите из дрова контекст/трап-фрейм не средствами отладчика.
     
  11. Charlief

    Charlief New Member

    Публикаций:
    0
    Регистрация:
    17 авг 2010
    Сообщения:
    129
    Clerk
    Тоесть мне скопировать содержимое всех регистров из DriverEntry - написать такую прцедуру на ассемблере ?
    А что ещё кроме регистров ? Где можно прочитать что ещё нужно копировать ?
     
  12. Charlief

    Charlief New Member

    Публикаций:
    0
    Регистрация:
    17 авг 2010
    Сообщения:
    129
    Кажется я нашёл причину, все вызовы своих функций у меня были помещены внутри блока __try.
    Убрал всё оттуда, вот что вышло:
    DebugView:
    00000000 0.00000000 DriverEntry
    00000001 0.00000156
    00000002 0.00000287 Cs=e64e
    00000003 0.00000409 GDTR Limit=3ff
    00000004 0.00000548 GDTR Base=8003f000
    00000005 0.00000631
    00000006 0.00000757 KPCR SelfPcr=ffdff000
    00000007 0.00000842
    00000008 0.00000971 KPCR IDT=8003f400
    00000009 0.00001092 KPCR GDT=8003f000
    00000010 0.00001214 KPCR TSS=80042000

    Затем снова всё поместил в болк __try
    DebugView:
    00000000 0.00000000 DriverEntry
    00000001 0.00000152
    00000002 0.00000285 Cs=b704
    00000003 0.00000407 GDTR Limit=3ff
    00000004 0.00000546 GDTR Base=8003f000
    00000005 0.00000631
    00000006 0.00000758 KPCR SelfPcr=ffdff000
    00000007 0.00000844
    00000008 0.00000968 KPCR IDT=8003f400
    00000009 0.00001090 KPCR GDT=8003f000
    00000010 0.00001214 KPCR TSS=80042000

    Наверное какое-то переключение контекста внутри __try если cs меняется...
     
  13. 0x6b65

    0x6b65 Забанен

    Публикаций:
    0
    Регистрация:
    8 окт 2009
    Сообщения:
    92
    А может просто опечатка?
     
  14. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    0x6b65
    Точно, а я не заметил. Инвалидные значения в дампе :)
     
  15. Charlief

    Charlief New Member

    Публикаций:
    0
    Регистрация:
    17 авг 2010
    Сообщения:
    129
    0x6b65
    Какая ещё опечатка ? Вы о чем ? Где опечатка ?
    Я в функцию передаю адрес структуры, а потом по этому адресу записываю CS ! Эта функция ничего не возвращает в регистре ax, смотрите выше код на С++.
    IDA:
    Код (Text):
    1. ; __stdcall AReadCsGDTR(x)
    2. public _AReadCsGDTR@4
    3. _AReadCsGDTR@4 proc near
    4.  
    5. arg_0= dword ptr  4
    6.  
    7. mov     eax, [esp+arg_0]
    8. mov     [eax], cx
    9. sgdt    fword ptr [eax+2]
    10. retn    4
    11. _AReadCsGDTR@4 endp
    2.2.3 NASM не хранит типы переменных

    NASM не запоминает определямые вами типы переменных. Поскольку MASM эти вещи запоминает, то при встрече var dw 0 он запомнит, что вы определили var как пременную размером в слово и затем будет способен разрешить неопределенность при появлении инструкции mov var,2. NASM же преднамеренно не будет помнить ничто относительно символа var за исключением того, где он начинается, поэтому вы должны явно указывать mov word [var],2.
     
  16. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Charlief
    Значение селектора больше чем лимит GDT. Уверен что LDTR(селектор дескриптора LDT в GDT) = 0. Это инвалидные данные. Опкод mov word ptr ds:[eax],cs: 8C 08. Вы читаете регистр Cx.
     
  17. Charlief

    Charlief New Member

    Публикаций:
    0
    Регистрация:
    17 авг 2010
    Сообщения:
    129
    Точно - надо отдохнуть.
    Приношу извинения. Куда я смотрел.
     
  18. Charlief

    Charlief New Member

    Публикаций:
    0
    Регистрация:
    17 авг 2010
    Сообщения:
    129
    Теперь Cs=8.
    Ещё наверное нужно в драйвере в прототипе импортируемой ассемблерной функции указывать что она что-то возвращает если я в этой функции перед использованием eax не сохраняю его в стеке ? Тогда компилятор С++ поймёт что я затираю eax ? Так сказать во избежание всяких неприятностей.