Soyez le premier à donner votre avis sur cette source.
Vue 11 636 fois - Téléchargée 1 614 fois
Option Explicit 'module ermettant d'obtenir une liste des handles de tous les processus du systeme 'structure contenant des infos sur un handle d'un processus Public Type HandleInfo ProcessId As Long 'ID du processus propriétaire Flags As Byte ' 0x01 = PROTECT_FROM_CLOSE, 0x02 = INHERIT Handle As Integer 'valeur du handle ObjectName As String 'nom de l'objet NameInformation As String 'type de l'ojet Object As Long 'adresse de l'objet GrantedAccess As Long 'accès autorisés à l'objet Attributes As Long 'attributs HandleCount As Long 'nombre de handle de ce type dans le système PointerCount As Long 'nombre de références pointeurs à cet objet dans le système CreateTime As Currency 'date de création de l'objet GenericRead As Long 'accès générique GenericWrite As Long GenericExecute As Long GenericAll As Long ObjectCount As Long ' PeakObjectCount As Long ' PeakHandleCount As Long ' InvalidAttributes As Long 'définit les attributs invalides pour ce type d'objet ValidAccess As Long ' Unknown As Byte MaintainHandleDatabase As Byte ' PoolType As Long 'type de pool utilisé par l'objet PagedPoolUsage As Long 'paged pool utilisé NonPagedPoolUsage As Long 'non-paged pool utilisé End Type 'structure de donnée de handle renvoyée par NtQuerySystemInformation Private Type SYSTEM_HANDLE_INFORMATION ' Information Class 16 ProcessId As Long ObjectTypeNumber As Byte Flags As Byte ' 0x01 = PROTECT_FROM_CLOSE, 0x02 = INHERIT Handle As Integer Object As Long GrantedAccess As Long End Type 'constante pour NtQuerySystemInformation Private Const SystemHandleInformation As Long = 16& Private Const STATUS_INFO_LENGTH_MISMATCH As Long = &HC0000004 Private Const STATUS_SUCCESS As Long = &H0& 'constante pour NtQueryObject Private Const ObjectBasicInformation As Long = 0 ' 0 Y N Private Const ObjectNameInformation As Long = 1 ' 1 Y N Private Const ObjectTypeInformation As Long = 2 ' 2 Y N Private Const ObjectAllTypesInformation As Long = 3 ' 3 Y N Private Const ObjectHandleInformation As Long = 4 ' 4 Y Y 'structure contenant des infos sur les type d'objet du systeme Private Type OBJECT_BASIC_INFORMATION ' Information Class 0 Attributes As Long GrantedAccess As Long HandleCount As Long PointerCount As Long PagedPoolUsage As Long NonPagedPoolUsage As Long Reserved1 As Long Reserved2 As Long Reserved3 As Long NameInformationLength As Long TypeInformationLength As Long SecurityDescriptorLength As Long CreateTime As Currency End Type 'structure contenant une chaine de caractere UNICODE Private Type UNICODE_STRING Length As Integer MaximumLength As Integer Buffer As Long End Type 'structure contenant le nom d'un type d'objet Private Type OBJECT_NAME_INFORMATION ' Information Class 1 Name As UNICODE_STRING End Type Private Type GENERIC_MAPPING GenericRead As Long GenericWrite As Long GenericExecute As Long GenericAll As Long End Type 'information sur un type d'objet Private Type OBJECT_TYPE_INFORMATION ' Information Class 2 Name As UNICODE_STRING ObjectCount As Long HandleCount As Long Reserved1 As Long Reserved2 As Long Reserved3 As Long Reserved4 As Long PeakObjectCount As Long PeakHandleCount As Long Reserved5 As Long Reserved6 As Long Reserved7 As Long Reserved8 As Long InvalidAttributes As Long GenericMapping As GENERIC_MAPPING ValidAccess As Long Unknown As Byte MaintainHandleDatabase As Byte PoolType As Long PagedPoolUsage As Long NonPagedPoolUsage As Long End Type 'information sur les attributs de handles Private Type OBJECT_HANDLE_ATTRIBUTE_INFORMATION ' Information Class 4 Inherit As Byte ProtectFromClose As Byte End Type 'renvoie des informations sur le systeme Private Declare Function NtQuerySystemInformation Lib "ntdll" ( _ ByVal SystemInformationClass As Long, _ ByVal SystemInformation As Long, _ ByVal SystemInformationLength As Long, _ ReturnLength As Long _ ) As Long 'renvoie le handle du processus appelant (-1) Private Declare Function GetCurrentProcess Lib "kernel32.dll" () As Long 'permet de dupliquer un handle d'un prosessus vers un autre Private Declare Function DuplicateHandle Lib "kernel32.dll" (ByVal hSourceProcessHandle As Long, ByVal hSourceHandle As Long, ByVal hTargetProcessHandle As Long, ByRef lpTargetHandle As Long, ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwOptions As Long) As Long 'autorise à dupliquer un handle Private Const PROCESS_DUP_HANDLE As Long = (&H40) 'avec le même accès que dans le processus original Private Const DUPLICATE_SAME_ACCESS As Long = &H2 'ouvrir le processus Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessID As Long) As Long 'fermer un handle Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long 'renvoie des infos sur un type d'objet Private Declare Function NtQueryObject Lib "ntdll" ( _ ByVal ObjectHandle As Long, _ ByVal ObjectInformationClass As Long, _ ByVal ObjectInformation As Long, _ ByVal ObjectInformationLength As Long, _ ReturnLength As Long _ ) As Long 'renvoie l'addresse de l'entête de tableau SAFEARRAY Private Declare Function VarPtrArray Lib "msvbvm60.dll" Alias "VarPtr" (Arr() As Any) As Long Private Type SafeArray1d cDims As Integer 'nombre de dimension fFeatures As Integer 'falgs cbElements As Long 'taille des elements du tableau cLocks As Long 'tableau non redimensionnable pvData As Long 'pointeur vers les données du tableau cElements As Long 'nombre d'elements lLbound As Long 'limite basse End Type 'copie une zone mémoire dans une autre Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long) 'attributs des entêtes de tableau SAFEARRAY Private Const FADF_AUTO = 1 Private Const FADF_FIXEDSIZE = 16 Private Const FADF_STATIC = 2 'buffer contenant les infos sur les handles Dim BufferHandles() As Byte Dim Handles() As SYSTEM_HANDLE_INFORMATION Dim ArrHandles As SafeArray1d 'contient des infos sur un objet Dim ObjBasic As OBJECT_BASIC_INFORMATION 'renvoie le type d'un objet Dim BufferObjType() As Byte Dim ObjType() As OBJECT_TYPE_INFORMATION Dim ArrObjType As SafeArray1d Dim m_ObjectTypeName As String 'renvoie le nom d'un objet Dim BufferObjName() As Byte Dim ObjName() As OBJECT_NAME_INFORMATION Dim ArrObjName As SafeArray1d Dim m_ObjectName As String 'nombre de handles Dim m_cHandles As Long Dim hProcess As Long 'crée le buffer contenant les handles 'doit etre libérer avec DestroyHandlesBuffer avant de quitter l'application Public Sub CreateQueryHandlesBuffer() Dim Length As Long 'longueur du buffer Dim X As Long 'compteur Dim ret As Long 'valeur de retour des fonctions utilisées Dim ret2 As Long 'valeur de retour des fonctions utilisées Length = &H100& 'longueur minimale du buffer ReDim BufferHandles(Length) 'redimensionne le buffer 'tant que la longueur n'est pas suffisante Do While NtQuerySystemInformation( _ SystemHandleInformation, _ ByVal VarPtr(BufferHandles(0)), _ Length, _ ret _ ) = STATUS_INFO_LENGTH_MISMATCH 'on multiplie la taille du buffer par 2 Length = Length * 2 'on réalloue le buffer ReDim BufferHandles(Length) Loop 'on réduit la taille du buffer à la taille des données contenus dans ce buffer ReDim Preserve BufferHandles(ret + 1) 'demande le nombre de handles CopyMemory ByVal VarPtr(m_cHandles), ByVal VarPtr(BufferHandles(0)), 4 'initilise le tableau des handles With ArrHandles .cbElements = 16 'taille des elements du tableau .cDims = 1 '1 dimension .cElements = m_cHandles 'nombre d'elements .fFeatures = FADF_AUTO Or FADF_FIXEDSIZE 'flag .lLbound = 0 'option base 0 'fait pointer le tableau sur les données du buffer .pvData = VarPtr(BufferHandles(4)) End With 'copie l'entête dans le pointeur tableau CopyMemory ByVal VarPtrArray(Handles), VarPtr(ArrHandles), 4 End Sub 'remplit un buffer avec les infos sur l'objet spécifié par l'index '============================================================== 'lIndex : index du handle dans le tableau de handles 'hProcess : handle du processus dans lequel le handle se trouve (<> du PID) Private Sub RetrieveObject(lIndex As Long, hProcess As Long) Dim Length As Long 'longueur Dim ret As Long 'valeur de retour des fonctions utilisées Dim ret2 As Long 'valeur de retour des fonctions utilisées Dim hHandle As Long 'handle dupliqué dans notre processus ' on copie le handle recherché dans notre processus avec les mêmes droits d'accès DuplicateHandle hProcess, Handles(lIndex).Handle, _ GetCurrentProcess, hHandle, 0&, 0&, DUPLICATE_SAME_ACCESS 'renvoie des infos Basic sur l'objet ret2 = NtQueryObject(hHandle, ObjectBasicInformation, VarPtr(ObjBasic), Len(ObjBasic), ret) 'alloue un buffer à la taille des données Type ReDim BufferObjType(ObjBasic.TypeInformationLength + 2) 'initialise le descripteur de tableau Type With ArrObjType .cbElements = 94 'taille des elements du tableau .cDims = 1 'dimension .cElements = 1 'nombre d'elements .fFeatures = FADF_AUTO Or FADF_FIXEDSIZE 'flag .lLbound = 0 'option base 0 'fait pointer le tableau vers les données de Type .pvData = VarPtr(BufferObjType(0)) End With 'demande les infos Type de l'objet ret2 = NtQueryObject(hHandle, ObjectTypeInformation, VarPtr(BufferObjType(0)), ObjBasic.TypeInformationLength + 2, ret) 'copie le descripteur dans le pointeur de tableau CopyMemory ByVal VarPtrArray(ObjType), VarPtr(ArrObjType), 4 'alloue l'espace pour le nom de l'objet m_ObjectTypeName = Space$(ObjType(0).Name.Length \ 2) 'copie les données du nom dans le buffer alloué CopyMemory ByVal StrPtr(m_ObjectTypeName), ByVal ObjType(0).Name.Buffer, ObjType(0).Name.Length 'si la longueur du nom est 0 If ObjBasic.NameInformationLength = 0 Then 'on la met à MAX_PATH (en UNICODE = MAX_PATH * 2) 'cela veut dire que le NtQueryObject ne sait la longueur de la chaine Length = 512 Else 'si on longueur est spécifié on l'utilise Length = ObjBasic.NameInformationLength + 2 End If 'on alloue le buffer pour le nom de l'object ReDim BufferObjName(Length) 'on initialise le descripteur de tableau Name With ArrObjName .cbElements = 8 'taille des elements du tableau .cDims = 1 '1 dimension .cElements = 1 'nombre d'elements .fFeatures = FADF_AUTO Or FADF_FIXEDSIZE 'flags .lLbound = 0 'option base 0 'fait pointer vers le buffer Name .pvData = VarPtr(BufferObjName(0)) End With 'on demande le nom de l'objet ret2 = NtQueryObject(hHandle, ObjectNameInformation, VarPtr(BufferObjName(0)), Length, ret) 'on copie les descripteur dans le pointeur de tableau CopyMemory ByVal VarPtrArray(ObjName), VarPtr(ArrObjName), 4 'convertit le nom en String VB 'alloue un buffer chaine m_ObjectName = Space$(ObjName(0).Name.Length \ 2) 'copie les données UNICODE du nom dans le buffer chaine CopyMemory ByVal StrPtr(m_ObjectName), ByVal ObjName(0).Name.Buffer, ObjName(0).Name.Length ' on ferme la copie du handle recherché CloseHandle hHandle End Sub 'renvoie le nombre de handles pour le proicessus spécifié '======================================================== 'PID : Process ID du processus pour lequel on veut le nombre de handle Public Function GetCountOfHandlesForProcessID(pid As Long) As Long Dim X As Long 'compteur 'initielise GetCountOfHandlesForProcessID = 0 'pour chaque handle du tableau For X = 0 To m_cHandles - 1 'si le handle appartient au processus, on ajoute 1 If Handles(X).ProcessId = pid Then GetCountOfHandlesForProcessID = GetCountOfHandlesForProcessID + 1 Next End Function 'renvoie les infos sur le premier handle du processus spécifié '============================================================== 'IN PID : Process ID du processus pour lequel on demande les infos du premier handle 'OUT retHandle : contient des infos sur le premier handle du processus 'renvoie 0 si succès, -1 si pas de handle pour ce processus Public Function GetHandlesForProcessIDFirst(pid As Long, retHandle As HandleInfo) As Long Dim X As Long 'compteur 'si le handle de processus n'est pas ouvert pour le processus pid If hProcess = 0 Then 'on ouvre le processus demandé pour dupliquer des handles hProcess = OpenProcess(PROCESS_DUP_HANDLE, 0&, pid) End If 'pour chaque handle For X = 0 To m_cHandles - 1 'si le handle appartient au processus If Handles(X).ProcessId = pid Then 'rmplit les buffer avec des informations sur le handle RetrieveObject X, hProcess 'renvoie les données des infos du handle With retHandle .Attributes = ObjBasic.Attributes .CreateTime = ObjBasic.CreateTime .Flags = Handles(X).Flags .GenericAll = ObjType(0).GenericMapping.GenericAll .GenericExecute = ObjType(0).GenericMapping.GenericExecute .GenericRead = ObjType(0).GenericMapping.GenericRead .GenericWrite = ObjType(0).GenericMapping.GenericWrite .GrantedAccess = Handles(X).GrantedAccess .Handle = Handles(X).Handle .HandleCount = ObjType(0).HandleCount .InvalidAttributes = ObjType(0).InvalidAttributes .MaintainHandleDatabase = ObjType(0).MaintainHandleDatabase .NameInformation = m_ObjectTypeName .NonPagedPoolUsage = ObjType(0).NonPagedPoolUsage .Object = Handles(X).Object .ObjectCount = ObjType(0).ObjectCount .ObjectName = m_ObjectName .PagedPoolUsage = ObjType(0).PagedPoolUsage .PeakHandleCount = ObjType(0).PeakHandleCount .PeakObjectCount = ObjType(0).PeakObjectCount .PointerCount = ObjBasic.PointerCount .PoolType = ObjType(0).PoolType .ProcessId = Handles(X).ProcessId .Unknown = ObjType(0).Unknown .ValidAccess = ObjType(0).ValidAccess End With 'renvoie SUCCESS GetHandlesForProcessIDFirst = 0 Exit Function End If Next 'renvoie pas de handle pour le processus GetHandlesForProcessIDFirst = -1 End Function 'ferme le handle du processus 'à appeler dès que l'on a plus besoin de l'énumération de handles '============================================================== 'renvoie le résultat de CloseHandle Public Function GetHandlesForProcessIDClose() As Long 'on ferme le handle GetHandlesForProcessIDClose = CloseHandle(hProcess) 'on indique qu'il est fermé hProcess = 0 End Function 'renvoie les infos sur le handle suivant du processus spécifié '============================================================== 'IN PID : Process ID du processus pour lequel on demande les infos du premier handle 'IN Handle : handle précédent 'OUT retHandle : contient des infos sur le premier handle du processus 'renvoie 0 si succès, -1 si pas de handle pour ce processus Public Function GetHandlesForProcessIDNext(pid As Long, Handle As Long, retHandle As HandleInfo) As Long Dim X As Long 'compteur Dim Before As Boolean 'indique si on a trouvé le handle précédent Before = False 'pour chaque handle For X = 0 To m_cHandles - 1 'si on a trouvé le handle précédent et que le handle appartient au processus If (Handles(X).ProcessId = pid) And (Before = True) Then 'on remplit les buffer avec les informations sur le handle RetrieveObject X, hProcess 'on revnoie les infos sur le handle With retHandle .Attributes = ObjBasic.Attributes .CreateTime = ObjBasic.CreateTime .Flags = Handles(X).Flags .GenericAll = ObjType(0).GenericMapping.GenericAll .GenericExecute = ObjType(0).GenericMapping.GenericExecute .GenericRead = ObjType(0).GenericMapping.GenericRead .GenericWrite = ObjType(0).GenericMapping.GenericWrite .GrantedAccess = Handles(X).GrantedAccess .Handle = Handles(X).Handle .HandleCount = ObjType(0).HandleCount .InvalidAttributes = ObjType(0).InvalidAttributes .MaintainHandleDatabase = ObjType(0).MaintainHandleDatabase .NameInformation = m_ObjectTypeName .NonPagedPoolUsage = ObjType(0).NonPagedPoolUsage .Object = Handles(X).Object .ObjectCount = ObjType(0).ObjectCount .ObjectName = m_ObjectName .PagedPoolUsage = ObjType(0).PagedPoolUsage .PeakHandleCount = ObjType(0).PeakHandleCount .PeakObjectCount = ObjType(0).PeakObjectCount .PointerCount = ObjBasic.PointerCount .PoolType = ObjType(0).PoolType .ProcessId = Handles(X).ProcessId .Unknown = ObjType(0).Unknown .ValidAccess = ObjType(0).ValidAccess End With 'on renvoie SUCCES GetHandlesForProcessIDNext = 0 Exit Function End If 'si on a trouvé le handle précédent on l'indique If (Handles(X).ProcessId = pid) And (Handles(X).Handle = Handle) Then Before = True Next 'on renvoie pas de handle suivant GetHandlesForProcessIDNext = -1 'on ferme le processus CloseHandle hProcess hProcess = 0 End Function 'libère les buffers des tableaus alloué pour eviter le plantages Public Sub DestroyHandlesBuffer() With ArrHandles .cbElements = 0 .cDims = 0 .pvData = 0 End With With ArrObjType .cbElements = 0 .cDims = 0 .pvData = 0 End With With ArrObjName .cbElements = 0 .cDims = 0 .pvData = 0 End With End Sub
3 sept. 2004 à 23:20
Quand tu dis que certains handle sont identifiés, c'est à dire que tu sais si tel handle pointe vers un icone etc.... ?
sinon c'est un très bon code.
@ +
4 sept. 2004 à 11:27
non, déjà les icones (ou bitmap) ne font pas partie des objets du kernel, une icone (HICON), c'est une zone mémoire global au système (d'après mes tests) et le handle HICON serait un pointeur...
Un fichier est un handle nommé (on connait son chemin), par contre, un pipe ou un event peut ou non avoir un nom suivant son utilisation...
par contre qu'un handle aie un nom ou pas, on connait son type : fichier, section, mutex, pipe, event,...
ShareVB
4 sept. 2004 à 12:18
7 sept. 2004 à 01:01
Sa ma l'air detre une tres bonne source mais bon jai pas XP donc je peut pas tester , mais je vais te mettre 8/10 , histoire de remonter ta note ;)
@++
22 sept. 2004 à 23:28
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.