Приветствую всех! Задача такая: надо найти ETHREAD всех потоков процесса. Делаю так: Нахожу EPROCESS нужного процесса и из него по Proc.ThreadListHead пытаюсь получать ETHREAD для его потоков. Для системного потока, все ОК, а для потока юзермодного приложения явно что-то не то... У системного потока в начале ETHREAD видно _DISPATCHER_HEADER, а в юзермодном лежит какой-то ядерный адрес... Может у юзермодных процессов ThreadListHead указывает на что-то другое?
Вопрос решился Я протупил конкретно EPROCESS.ThreadListEntry.FLink(BLink) указывает не ETHREAD.ThreadListEntry (ETHREAD + 0x22C) а я думал, что он указывает на ETHREAD.Tcb.ThreadListEntry (ETHREAD + 0x1B0)
А почему не пользуешь ZwQuerySystemInformation, подкласс SystemProcessesAndThreadsInformation? Вобще, использования жестких оффсетов в недокументированных структурах, это, конечно, круто. Но, технически не грамотно
Дело не в крутости, а в интересе Тем более, что в WDK про ZwQuerySystemInformation тоже ничего не написано
Понимаешь, с этими сраными списками процессов(потоков) есть одна жопа. Заключается она в следующем - Windows >=5.1 (XP) не убирает из списка завершившиеся/прибитые процессы(потоки). У них будет Process.Flags.ProcessExiting==TRUE (у потоков Thread.State==Terminated) и мусор в других полях. В 2000й такого нет (с Cr4sh'ем с этим ковырялись, подтвердит). Придетс парсить поразному флаги в разных версиях. Во-вторых, формат этих структур меняется от версии к версии. ПРидется зашивать разные оффсеты. Универсальнее использовать ZwQuerySystemInformation(), геморроя на порядок меньше.
IceStudent Ну вероятно как раз изза того, что ктото удерживает хендл после закрытия процесса. Причин не знаю) Сам факт лишь видел - прибиваешь процесс или он сам завершается, а EPROCESS висит с ProcessExiting=TRUE и мусором во всех остальных полях. В 2000й не наблюдалось. Видимо, это сделано специально. Если присмотреться к коду ExpGetProcessInformation (которая вызывается из NtQuerySystemInformation при соотв. InfoClass), то можно найти в XP следующее (в 2000й - нет): Код (Text): .text:80533602 ; Attributes: bp-based frame .text:80533602 .text:80533602 ; int __stdcall ExpGetProcessInformation(PVOID Base,SIZE_T Length,int,int,char) .text:80533602 _ExpGetProcessInformation@20 proc near ; CODE XREF: NtQuerySystemInformation(x,x,x,x):loc_80606A61p ... .text:80533669 mov esi, _PsIdleProcess ; очевидно, перебор процессов вида: .text:80533669 ; .text:80533669 ; EPROCESS* ep = PsIdleProcess; .text:80533669 ; .text:80533669 ; do .text:80533669 ; { .text:80533669 ; ... .text:80533669 ; ep = PsGetNextProcess(); .text:80533669 ; } .text:80533669 ; while(ep!=PsIdleProcess); .text:80533669 ; .text:8053366F mov [ebp+ep], esi .text:80533672 .text:80533672 ProcessEnumLoop: ; CODE XREF: ExpGetProcessInformation(x,x,x,x,x)+2DBj .text:80533672 cmp esi, edi .text:80533674 jz loc_805338E2 .text:8053367A test byte ptr [esi+248h], 4 ; !!!!!! if( ep->Flags.ProcessExiting ) goto SkipProcess; .text:80533681 jnz SkipProcess .... ExpCopyProcessInfo ... .text:805338C4 SkipProcess: ; CODE XREF: ExpGetProcessInformation(x,x,x,x,x)+7Fj .text:805338C4 ; ExpGetProcessInformation(x,x,x,x,x)+90j ... .text:805338C4 mov eax, esi .text:805338C6 sub eax, _PsIdleProcess .text:805338CC neg eax .text:805338CE sbb eax, eax .text:805338D0 and eax, esi .text:805338D2 push eax .text:805338D3 call _PsGetNextProcess@4 ; PsGetNextProcess(x) .text:805338D8 mov [ebp+ep], eax .text:805338DB mov esi, eax .text:805338DD jmp ProcessEnumLoop .... То есть блоки EPROCESS с флагом ProcessExiting пропускаются
Great спасибо за информацию Тут нашел ресурс с литературой в электронном виде, может комуинтересно будет: book.1gb.ru