samedi 6 septembre 2008

List Hidden Pocesses suite... (KiWaitListHead method)

Mon précédent article finissait sur un échec mais grâce à Ivanlef0u je peux continuer :). Heureusement puisque la première technique que je présentais dans cet article, technique qui m'avais pris plusieurs heures à mettre en place, n'a pas résisté plus de 10 minutes à Overclok :(.
Nous nous étions arrêté à la récupération d'un pointeur sur la table KiWaitListHead après avoir scanné la fonction KeWaitForSingleObject() exportée par ntoskrnl.exe.
Mon problème était de savoir par quelles structures était composée cette table. Je n'est pas la réponse exacte mais j'ai pu recueillir les infos nécessaire ici
On peut imaginer cette structure de cette façon :


...
offset : x-0x60 PETHREAD Thread
...
offset : x LIST_ENTRY KiWaitListHead
...

Pour certaines version de windows autres que XP l'offset de Thread sera x-0x70 d'après le liens ci-dessus.
La table KiWaitListHead est donc une liste double-chainée de structures décrivant les threads et contenant un pointeur vers la structure ETHREAD du thread courant. On va donc pouvoir lister nos threads en parcourant cette table, ce qui confirme ce que je supposais dans mon article précédent :)

Une fois la structure ETHREAD récupérée il nous est facile de remonter au processus par le biais de l'EPROCESS. Voici à quoi ressemble l'ETHREAD :


+0x000 Tcb : _KTHREAD
+0x1c0 CreateTime : _LARGE_INTEGER
+0x1c0 NestedFaultCount : Pos 0, 2 Bits
+0x1c0 ApcNeeded : Pos 2, 1 Bit
+0x1c8 ExitTime : _LARGE_INTEGER
+0x1c8 LpcReplyChain : _LIST_ENTRY
+0x1c8 KeyedWaitChain : _LIST_ENTRY
+0x1d0 ExitStatus : Int4B
+0x1d0 OfsChain : Ptr32 Void
+0x1d4 PostBlockList : _LIST_ENTRY
+0x1dc TerminationPort : Ptr32 _TERMINATION_PORT
+0x1dc ReaperLink : Ptr32 _ETHREAD
+0x1dc KeyedWaitValue : Ptr32 Void
+0x1e0 ActiveTimerListLock : Uint4B
+0x1e4 ActiveTimerListHead : _LIST_ENTRY
+0x1ec Cid : _CLIENT_ID
+0x1f4 LpcReplySemaphore : _KSEMAPHORE
+0x1f4 KeyedWaitSemaphore : _KSEMAPHORE
+0x208 LpcReplyMessage : Ptr32 Void
+0x208 LpcWaitingOnPort : Ptr32 Void
+0x20c ImpersonationInfo : Ptr32 _PS_IMPERSONATION_INFORMATION
+0x210 IrpList : _LIST_ENTRY
+0x218 TopLevelIrp : Uint4B
+0x21c DeviceToVerify : Ptr32 _DEVICE_OBJECT
+0x220 ThreadsProcess : Ptr32 _EPROCESS
+0x224 StartAddress : Ptr32 Void
+0x228 Win32StartAddress : Ptr32 Void
+0x228 LpcReceivedMessageId : Uint4B
+0x22c ThreadListEntry : _LIST_ENTRY
+0x234 RundownProtect : _EX_RUNDOWN_REF
+0x238 ThreadLock : _EX_PUSH_LOCK
+0x23c LpcReplyMessageId : Uint4B
+0x240 ReadClusterSize : Uint4B
+0x244 GrantedAccess : Uint4B
+0x248 CrossThreadFlags : Uint4B
+0x248 Terminated : Pos 0, 1 Bit
+0x248 DeadThread : Pos 1, 1 Bit
+0x248 HideFromDebugger : Pos 2, 1 Bit
+0x248 ActiveImpersonationInfo : Pos 3, 1 Bit
+0x248 SystemThread : Pos 4, 1 Bit
+0x248 HardErrorsAreDisabled : Pos 5, 1 Bit
+0x248 BreakOnTermination : Pos 6, 1 Bit
+0x248 SkipCreationMsg : Pos 7, 1 Bit
+0x248 SkipTerminationMsg : Pos 8, 1 Bit
+0x24c SameThreadPassiveFlags : Uint4B
+0x24c ActiveExWorker : Pos 0, 1 Bit
+0x24c ExWorkerCanWaitUser : Pos 1, 1 Bit
+0x24c MemoryMaker : Pos 2, 1 Bit
+0x250 SameThreadApcFlags : Uint4B
+0x250 LpcReceivedMsgIdValid : Pos 0, 1 Bit
+0x250 LpcExitThreadCalled : Pos 1, 1 Bit
+0x250 AddressSpaceOwner : Pos 2, 1 Bit
+0x254 ForwardClusterOnly : UChar
+0x255 DisablePageFaultClustering : UChar



Et le membre qui nous intéresse :
+0x220 ThreadsProcess : Ptr32 _EPROCESS


Maintenant je pense que l'unlink de la table KiWaitListHead est possible, j'attends que Overclok s'en charge.
Cependant le paper sur lequel je me suis appuyé parle d'une autre table, la KiDispatcherReadListHead que je tenterais d'explorer dans un prochain article. Donc je vous laisse sur le mot de la fin :
A suivre...


Le code + binaire ici

Remerciements à Overclok et Ivanlef0u qui nous surveille :)

Lilxam.

Aucun commentaire: