Пока нет. Непонятно что за фигня лежит в стеке) Реальный EIP на котором поток прервали или чтото другое. И зачем вообще нужен адрес KiFastSystemCallRet ввиду того, что для обычных потоков сохраняется реальный EIP, а не всякий мухлеж со стеком и RET'ами
Ты заблуждаешься, причем очень сильно. "и в большинстве случаев" ситуация как раз и наоборот. И что это за "нормальные драйвера"? Так ты называешь legacy? "Т.е. в норме потоков в kernel mode - system и еще один два не более." Что это за поток такой system? Great Думаю надо поглядеть на поток планировщика, вообще советую дял такого дела взять winkd
Cock Или я что-то не понял или ... Вопрос 1 как по твоему называется потоко в котором выполняется DriverEntry ? Вопрос 2 как называется поток, работающий на самом низком уровне привелегий и обнуляющий вышедшие из использования страницы памяти ? Говоря о system я подразумевал 2 вид потока, можеш назвать его по другому, для меня важна суть, а не название.
Который странички обнуляет? Было бы логичнее его назвать MiZeroPagesThread, как он и в винде называется насколько я помню.. Такс, по теме.. Протестил на драйвере, который по запросу пользователя уходит в бесконечный цикл - для потоков юзермодных процессов PsGetContextThread() корректо получает ядерный EIP: Код (Text): EPROCESS = ffad9da0, Name = inflooptester.exe Threads [2]: ffb545b8, cs:eip 0008:fca8e2fb, esp f9fb3a44, [InitalKernelStack]: ffffffff 00000202 8054097f f9fb394c, [esp]: 8149d500 81336fd8 f9fb3b3c 804eddf9 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( ) отказывается получать корректный контекст потоков этого процесса, видимо это связано с тем, что они ни разу не были в юзермоде, и постоянно выполняются в режиме ядра.
Уфф, с ядерными потоками тоже разобрался. Пришлось копать сорс SwapContext все-таки из ke\i386\ctxswap.asm (из Windows Research Kernel). Нашлись занятные строчки: Код (Text): mov eax, [esi].ThInitialStack ; get initial stack address sub eax, NPX_FRAME_LENGTH .errnz (EFLAGS_V86_MASK AND 0FF00FFFFh) test byte ptr [eax] - KTRAP_FRAME_LENGTH + TsEFlags + 2, EFLAGS_V86_MASK / 10000h jnz short sc24 ; if nz, V86 frame, no adjustment sub eax, TsV86Gs - TsHardwareSegSs ; bias for missing fields sc24: mov ecx, [ebx]+PcTssCopy ; get TSS address mov [ecx]+TssEsp0, eax ; set initial kernel stack address Что в переводе на Си будет примерно так Код (Text): ULONG TrapFrame; PKTRAP_FRAME TestFrame; TrapFrame = (ULONG)NextThread->InitialStack - NPX_FRAME_LENGTH; TestFrame = (KTRAP_FRAME*)( TrapFrame - KTRAP_FRAME_LENGTH ); if( TrapFrame->EFlags & EFLAGS_V86_MASK == 0 ) { TrapFrame = TrapFrame - ( FIELD_OFFSET(KTRAP_FRAME,V86Gs) - FIELD_OFFSET(KTRAP_FRAME, HardwareSegSs); } Pcr->TssCopy->Esp0 = TrapFrame; Вообщем оказалось, что стоит копать в сторону ((KTRAP_FRAME*)KeGetPcr()->TSS->Esp0). Для получения контекста пришлось доставить Kernel APC нужному потоку. Экспериментально оказалось, что ((KTRAP_FRAME*)KeGetPcr()->TSS->Esp0)->DbgEip указывает на EIP потока в момент доставки APC. При отключенных прерываниях это то, что нужно. Исходный код, кому интересно, в аттаче.. Вывод DbgPrint: Как видно, выделенные адреса (реальное начало потока и полученный EIP) совпадают... ура =)