Получить EIP потока

Тема в разделе "WASM.NT.KERNEL", создана пользователем wasm_test, 30 июл 2007.

  1. PROFi

    PROFi New Member

    Публикаций:
    0
    Регистрация:
    13 июл 2003
    Сообщения:
    690
    Great

    Ну а конечная цель - получение eip хоть решена ?
     
  2. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Пока нет. Непонятно что за фигня лежит в стеке) Реальный EIP на котором поток прервали или чтото другое. И зачем вообще нужен адрес KiFastSystemCallRet ввиду того, что для обычных потоков сохраняется реальный EIP, а не всякий мухлеж со стеком и RET'ами
     
  3. PROFi

    PROFi New Member

    Публикаций:
    0
    Регистрация:
    13 июл 2003
    Сообщения:
    690
    Great

    А что SoftIce не рулит в данной проблеме.
     
  4. Cock

    Cock New Member

    Публикаций:
    0
    Регистрация:
    9 фев 2007
    Сообщения:
    148
    Ты заблуждаешься, причем очень сильно. "и в большинстве случаев" ситуация как раз и наоборот. И что это за "нормальные драйвера"? Так ты называешь legacy?

    "Т.е. в норме потоков в kernel mode - system и еще один два не более."
    Что это за поток такой system?

    Great
    Думаю надо поглядеть на поток планировщика, вообще советую дял такого дела взять winkd
     
  5. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Что-то я ничего про такой поток не слышал
     
  6. PROFi

    PROFi New Member

    Публикаций:
    0
    Регистрация:
    13 июл 2003
    Сообщения:
    690
    Cock

    Или я что-то не понял или ...
    Вопрос 1 как по твоему называется потоко в котором выполняется DriverEntry ?
    Вопрос 2 как называется поток, работающий на самом низком уровне привелегий и обнуляющий вышедшие из использования страницы памяти ?


    Говоря о system я подразумевал 2 вид потока, можеш назвать его по другому, для меня важна суть, а не название.
     
  7. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Который странички обнуляет? Было бы логичнее его назвать MiZeroPagesThread, как он и в винде называется насколько я помню..

    Такс, по теме.. Протестил на драйвере, который по запросу пользователя уходит в бесконечный цикл - для потоков юзермодных процессов PsGetContextThread() корректо получает ядерный EIP:

    Код (Text):
    1. EPROCESS = ffad9da0, Name = inflooptester.exe
    2. Threads [2]:
    3. ffb545b8, cs:eip 0008:fca8e2fb, esp f9fb3a44, [InitalKernelStack]: ffffffff 00000202 8054097f f9fb394c, [esp]: 8149d500 81336fd8 f9fb3b3c 804eddf9
    4. ffb6cc18, cs:eip 001b:7c90eb94, esp 0037fa6c, [InitalKernelStack]: ffffffff 00000246 805409e2 f9e6bcfc, [esp]: 77d493f5 77d6ea24 00000000 00000000
    Первый поток ушел в режим ядра к драйверу и уже никогда не вернется... EIP верный. А второй поток просто пользовательский, ждет кого-то.

    Дальше, стало ясно, почему у 99% потоков EIP = ntdll.KiFastSystemCallRet. Как показал полный дамп потоков, у этих же 99% потоков ETHREAD->Tcb.State == Waiting, то есть преобладающее большинство потоков находятся в режиме ожидания.. оно и понятно - почти все они ожидают, например, события от окна или чего-либо еще. Если поток искуственно прервать, то EIP будет корректный и у этого KTHREAD State будет равен Ready.

    Зато теперь получилась жопа с потоками "загадочного" процесса System. PsGetContextThread( ) отказывается получать корректный контекст потоков этого процесса, видимо это связано с тем, что они ни разу не были в юзермоде, и постоянно выполняются в режиме ядра.
     
  8. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Уфф, с ядерными потоками тоже разобрался. Пришлось копать сорс SwapContext все-таки из ke\i386\ctxswap.asm (из Windows Research Kernel).
    Нашлись занятные строчки:
    Код (Text):
    1.         mov     eax, [esi].ThInitialStack ; get initial stack address
    2.         sub     eax, NPX_FRAME_LENGTH
    3. .errnz (EFLAGS_V86_MASK AND 0FF00FFFFh)
    4.         test    byte ptr [eax] - KTRAP_FRAME_LENGTH + TsEFlags + 2, EFLAGS_V86_MASK / 10000h
    5.         jnz     short sc24              ; if nz, V86 frame, no adjustment
    6.         sub     eax, TsV86Gs - TsHardwareSegSs ; bias for missing fields
    7. sc24:   mov     ecx, [ebx]+PcTssCopy    ; get TSS address
    8.         mov     [ecx]+TssEsp0, eax      ; set initial kernel stack address
    Что в переводе на Си будет примерно так

    Код (Text):
    1. ULONG TrapFrame;
    2. PKTRAP_FRAME TestFrame;
    3.  
    4. TrapFrame = (ULONG)NextThread->InitialStack - NPX_FRAME_LENGTH;
    5. TestFrame = (KTRAP_FRAME*)( TrapFrame - KTRAP_FRAME_LENGTH );
    6.  
    7. if( TrapFrame->EFlags & EFLAGS_V86_MASK == 0 )
    8. {
    9.   TrapFrame = TrapFrame - ( FIELD_OFFSET(KTRAP_FRAME,V86Gs) - FIELD_OFFSET(KTRAP_FRAME, HardwareSegSs);
    10. }
    11.  
    12. Pcr->TssCopy->Esp0 = TrapFrame;
    Вообщем оказалось, что стоит копать в сторону ((KTRAP_FRAME*)KeGetPcr()->TSS->Esp0).

    Для получения контекста пришлось доставить Kernel APC нужному потоку. Экспериментально оказалось, что ((KTRAP_FRAME*)KeGetPcr()->TSS->Esp0)->DbgEip указывает на EIP потока в момент доставки APC.
    При отключенных прерываниях это то, что нужно.

    Исходный код, кому интересно, в аттаче..

    Вывод DbgPrint:
    Как видно, выделенные адреса (реальное начало потока и полученный EIP) совпадают... ура =)
     
  9. TheDeath

    TheDeath New Member

    Публикаций:
    0
    Регистрация:
    20 июл 2003
    Сообщения:
    66
    Адрес:
    Russia,Новосибирск
    И это единственный способ?