PsLookupProcessByProcessId возвращает c000000d, в списке, который она перебирает, IDLE нет... Но мне доводится оказываться в контексте этого процесса, и PsGetCurrentProcess возвращает EPROCESS, в котором видно имя - "IDLE"... Как его найти?
Можно из текущего (из любого) KPRCB взять указатель на KPRCB.IdleThread а оттуда поле KTHREAD.Process. Только эти структуры очень зависят от версии и sp Кстати, а ZwQuerySystemInformation не перечисляет Idle?
>Можно из текущего (из любого) KPRCB взять указатель на KPRCB.IdleThread а оттуда поле KTHREAD.Process. а можно поподробнее? >Только эти структуры очень зависят от версии и sp это вообще не вопрос, все равно приходится собирать все смещения для каждой винды, и какждого сп... >Кстати, а ZwQuerySystemInformation не перечисляет Idle? Да, я так и делаю, конечно перечисляет - там в структуре много полезной инфы, но eprocess нет...
kd> dd 0xFFDFF020 l1 ffdff020 ffdff120 kd> dt nt!_KPRCB ffdff120 +0x000 MinorVersion : 1 +0x002 MajorVersion : 1 +0x004 CurrentThread : 0x80559320 _KTHREAD +0x008 NextThread : (null) +0x00c IdleThread : 0x80559320 _KTHREAD <------------------ +0x010 Number : 0 '' +0x011 Reserved : 0 '' +0x012 BuildType : 2 .......... +0x918 UpdateSignature : _LARGE_INTEGER 0x0 +0x920 NpxSaveArea : _FX_SAVE_AREA +0xb30 PowerState : _PROCESSOR_POWER_STATE kd> dt nt!_KTHREAD 0x80559320 +0x000 Header : _DISPATCHER_HEADER +0x010 MutantListHead : _LIST_ENTRY [ 0x80559330 - 0x80559330 ] +0x018 InitialStack : 0x80550b80 +0x01c StackLimit : 0x8054db80 +0x020 Teb : (null) +0x024 TlsArray : (null) +0x028 KernelStack : 0x805508cc +0x02c DebugActive : 0 '' +0x02d State : 0x2 '' +0x02e Alerted : [2] "" +0x030 Iopl : 0 '' +0x031 NpxState : 0xa '' +0x032 Saturation : 0 '' +0x033 Priority : 16 '' +0x034 ApcState : _KAPC_STATE +0x04c ContextSwitches : 0x1fe4f +0x050 IdleSwapBlock : 0 '' +0x051 Spare0 : [3] "" +0x054 WaitStatus : 0 +0x058 WaitIrql : 0x2 '' +0x059 WaitMode : 0 '' +0x05a WaitNext : 0 '' +0x05b WaitReason : 0 '' +0x05c WaitBlockList : 0x80559390 _KWAIT_BLOCK +0x060 WaitListEntry : _LIST_ENTRY [ 0x0 - 0x0 ] +0x060 SwapListEntry : _SINGLE_LIST_ENTRY +0x068 WaitTime : 0x27d2a +0x06c BasePriority : 0 '' +0x06d DecrementCount : 0 '' +0x06e PriorityDecrement : 0 '' +0x06f Quantum : -128 '' +0x070 WaitBlock : [4] _KWAIT_BLOCK +0x0d0 LegoData : (null) +0x0d4 KernelApcDisable : 0 +0x0d8 UserAffinity : 0xffffffff +0x0dc SystemAffinityActive : 0 '' +0x0dd PowerState : 0 '' +0x0de NpxIrql : 0 '' +0x0df InitialNode : 0 '' +0x0e0 ServiceTable : 0x80559b80 +0x0e4 Queue : (null) +0x0e8 ApcQueueLock : 0 +0x0f0 Timer : _KTIMER +0x118 QueueListEntry : _LIST_ENTRY [ 0x0 - 0x0 ] +0x120 SoftAffinity : 1 +0x124 Affinity : 1 +0x128 Preempted : 0 '' +0x129 ProcessReadyQueue : 0 '' +0x12a KernelStackResident : 0x1 '' +0x12b NextProcessor : 0 '' +0x12c CallbackStack : (null) +0x130 Win32Thread : (null) +0x134 TrapFrame : (null) +0x138 ApcStatePointer : [2] 0x80559354 _KAPC_STATE +0x140 PreviousMode : 0 '' +0x141 EnableStackSwap : 0x1 '' +0x142 LargeStack : 0 '' +0x143 ResourceIndex : 0 '' +0x144 KernelTime : 0x2437d +0x148 UserTime : 0 +0x14c SavedApcState : _KAPC_STATE +0x164 Alertable : 0 '' +0x165 ApcStateIndex : 0 '' +0x166 ApcQueueable : 0x1 '' +0x167 AutoAlignment : 0 '' +0x168 StackBase : 0x80550b80 +0x16c SuspendApc : _KAPC +0x19c SuspendSemaphore : _KSEMAPHORE +0x1b0 ThreadListEntry : _LIST_ENTRY [ 0x805595d0 - 0x805595d0 ] +0x1b8 FreezeCount : 0 '' +0x1b9 SuspendCount : 0 '' +0x1ba IdealProcessor : 0 '' +0x1bb DisableBoost : 0 '' что то не видно... kd> !thread 0x80559320 THREAD 80559320 Cid 0000.0000 Teb: 00000000 Win32Thread: 00000000 RUNNING on processor 0 Not impersonating Owning Process 80559580 Image: Idle <------------------ !thread както видит !! Wait Start TickCount 163114 Ticks: 895 (0:00:00:13.984) Context Switch Count 130639 UserTime 00:00:00.0000 KernelTime 00:38:37.0953 Start Address 0x00000000 Stack Init 80550b80 Current 805508cc Base 80550b80 Limit 8054db80 Call 0 Priority 16 BasePriority 0 PriorityDecrement 0 DecrementCount 0 ChildEBP RetAddr Args to Child 8055082c 804e38a2 00000001 81ee8f02 000000d1 nt!RtlpBreakWithStatusInstruction (FPO: [1,0,0]) 8055082c fc55d062 00000001 81ee8f02 000000d1 nt!KeUpdateSystemTime+0x165 (FPO: [0,2] TrapFrame @ 80550840) WARNING: Frame IP not in any known module. Following frames may be wrong. 805508d0 804dc0d7 00000000 0000000e 00000000 0xfc55d062 805508d4 00000000 0000000e 00000000 00000000 nt!KiIdleLoop+0x10 (FPO: [0,0,0]) KTHREAD.Process недокументированное поле, а где можно узнать его смещение?
Хм. У меня на W2k3 sp2 KTHREAD.Process находится по смещению 0х128 между UserAffinity и Affinity. На остальных чуть позже посмотрю...
EPROCESS IDLE? Это первоапрельская шутка чтоль? Процесса Idle не существует. То что можно увидеть в ProcessExplorer/TaskManager - это псевдопроцесс, фактически показывающий "занятость ядра бездействием"...
Twister, и тем не менее у этого псевдопроцесса есть блок EPROCESS, который человек и хочет получить. Для чего ему это нужно, здесь не обсуждается. Может быть как раз счетчики и нужны. В чем тут шутка?
Нет у него блока EPROCESS (я не так давно занимался именно "прогулками по PsActiveProcesses")! Возможно вы спутали с PsActiveProcessesHead. Короче, читайте Руссиновича.
гм... И правда. Дал айсу команду proc и в самом конце увидел Idle... Дал dd <eprocess_addr> и оказался действительно в блоке EPROCESS, о чем красноречиво свидетельствует надпись "Idle" где-то по-середине окна дампа. Проверил - EPROCESS Idle не соответствует PsActiveProcessesHead. Попробую поискать способ найти его программно, позже отпишусь...
В ядре есть неэкспортируемая переменная PsIdleProcess - в ней храниться указатель на блок EPROCESS процесса Idle. Единственная экспортируемая ядром функция, которая работает с этой переменной - NtQuerySystemInformation. Но обращение к PsIdleProcess зарыто в ней достаточно глубоко (у меня по смещению 2CDh) и полный анализ кода от начала функции был бы слишком сложным - поэтому над общим решением для любой оси следует немного покумекать. А вот решение для моей WinXP SP2 Home (потребуется любой дизассемблер длин, я юзал VirXAsm v1.5 от malum): Код (Text): GetIdleProcess PROC push esi mov esi, dword ptr[NtQuerySystemInformation + 2] mov esi, dword ptr[esi] add esi, 2CDh call VirXasm32 ;Узнаем длину инструкции .if (eax == 5) && (byte ptr[esi] == 0A1h) ;0A1h - опкод команды mov eax, <some_offset> mov eax, dword ptr[esi+1] mov eax, dword ptr[eax] .else xor eax, eax .endif pop esi ret GetIdleProcess EndP Надеюсь что кому-нибудь эта информация окажется полезной.
Twister , жжош нафига такие сложности? В отличии от W2K3, в XP действительно недокументировано поле KTRHEAD.Process Однако там есть KTHREAD.ApcState, из которого, если приглядеться, и берется этот Process. Код для XP Sp2 выглядит примерно так: Код (Text): mov eax,fs:[20h] ; current PRCB mov ecx,[eax+0ch] ; KPRCB.IdleThread mov edx,[ecx+44h] ; KTHREAD.ApcState.Process получается чуть-чуть проще, чем у Twister-а