Accueil > > > win32lsof\COpenedHandles.cs
LISTER LES HANDLES (FICHIERS, CLÉ DE REGISTRES,...) OUVERTS PAR UN PROGRAMME (NT/2000/XP)
win32lsof\COpenedHandles.cs
Informations sur ce code source
Ce code permet d'obtenir la liste des handles ouverts par un programme :
- fichiers
- sections
- clé de registre
- événement
- mutex
- ...
Ce code permet aussi de recherché un nom de handle dans tous les processus, pour savoir, par exemple,
Fichier : win32lsof\COpenedHandles.cs
Nombre de lignes : 1009 lignes
Afficher ce fichier en plein écran
- using System;
- using System.Collections.Generic;
- using System.Text;
- using System.Diagnostics;
- using System.Runtime.InteropServices;
- using System.Runtime.InteropServices.ComTypes;
- using System.Windows.Forms;
- using System.Collections;
-
- namespace win32lsof
- {
- class COpenedHandles: IEnumerator,IEnumerable
- {
- //dérive du contrôle de driver pour avoir le total des appels à StartService et StopService
- //module ermettant d//obtenir une liste des handles de tous les processus du systeme
-
- //==========================================================================================
- //const intantes
- //==========================================================================================
-
- //const intante pour NtQuerySystemInformation
- private const int SystemHandleInformation = 16;
- private const uint STATUS_INFO_LENGTH_MISMATCH = 0xC0000004;
- private const int STATUS_SUCCESS = 0x0;
-
- //const intante pour NtQueryObject
- private const int ObjectBasicInformation = 0; // 0 Y N
- private const int ObjectNameInformation = 1; // 1 Y N
- private const int ObjectTypeInformation = 2; // 2 Y N
- private const int ObjectAllTypesInformation = 3; // 3 Y N
- private const int ObjectHandleInformation = 4; // 4 Y Y
-
- //autorise à créer un thread dans le processus
- private const int PROCESS_CREATE_THREAD = 0x2;
- //autorise les opérations sur la mémoire du processus
- private const int PROCESS_VM_OPERATION = 0x8;
- //autorise les lectures sur la mémoire du processus
- private const int PROCESS_VM_READ = 0x10;
- //autorise les écritures sur la mémoire du processus
- private const int PROCESS_VM_WRITE = 0x20;
- //autorise à dupliquer un handle (pour OpenProcess)
- private const int PROCESS_DUP_HANDLE = (0x40);
- //avec le même accès que dans le processus original (pour DuplicateHandle)
- private const int DUPLICATE_SAME_ACCESS = 0x2;
- //inclure les processus dans la vue (pour CreateToolhelp32Snapshot)
- private const int TH32CS_SNAPPROCESS = 0x2;
-
- private const int PIPE_NOWAIT = 0x1;
- private const int PIPE_WAIT = 0x0;
- private const int PIPE_READMODE_MESSAGE = 0x2;
- private const int PIPE_READMODE_BYTE = 0x0;
-
- //const intantes pour OBJECT_ATTRIBUTES
- private const int OBJ_INHERIT = 0x2;
- private const int OBJ_PERMANENT = 0x10;
- private const int OBJ_EXCLUSIVE = 0x20;
- private const int OBJ_CASE_INSENSITIVE = 0x40;
- private const int OBJ_OPENIF = 0x80;
- private const int OBJ_OPENLINK = 0x100;
- private const int OBJ_KERNEL_HANDLE = 0x200;
-
- //accès aux dossiers
- private const int DIRECTORY_QUERY = 0x1;
- private const int DIRECTORY_TRAVERSE = 0x2;
- private const int DIRECTORY_CREATE_OBJECT = 0x4;
- private const int DIRECTORY_CREATE_SUBDIRECTORY = 0x8;
-
- //accès au liens symboliques
- private const int SYMBOLIC_LINK_QUERY = 0x1;
-
- //const intantes d//erreur
- private const uint STATUS_NO_MORE_ENTRIES = 0x8000001A;
- private const uint STATUS_BUFFER_TOO_SMALL = 0xC0000023;
-
- //==========================================================================================
- //structures perso
- //==========================================================================================
-
- /// <summary>
- /// structure contenant des infos sur un handle d'un processus
- /// </summary>
- public struct HandleInfo
- {
- public int ProcessID; //ID du processus propriétaire
- public byte Flags; // 0x01 = PROTECT_FROM_CLOSE, 0x02 = INHERIT
- public ushort Handle; //valeur du handle
- public string ObjectName; //nom de l//objet
- public string NameInformation; //type de l//ojet
- //UPGRADE_NOTE: Objecta été mis à niveau vers Object_Renamed. Cliquez ici : //ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="vbup1061"//
- public int Object_Renamed; //adresse de l//objet
- public int GrantedAccess; //accès autorisés à l//objet
- public int Attributes; //attributs
- public int HandleCount; //nombre de handle de ce type dans le système
- public int PointerCount; //nombre de références pointeurs à cet objet dans le système
- public System.Runtime.InteropServices.ComTypes.FILETIME CreateTime; //date de création de l//objet
- public int GenericRead; //accès générique
- public int GenericWrite;
- public int GenericExecute;
- public int GenericAll;
- public int ObjectCount; //
- public int PeakObjectCount; //
- public int PeakHandleCount; //
- public int InvalidAttributes; //définit les attributs invalides pour ce type d//objet
- public int ValidAccess; //
- public byte Unknown;
- public byte MaintainHandleDatabase; //
- public int PoolType; //type de pool utilisé par l//objet
- public int PagedPoolUsage; //paged pool utilisé
- public int NonPagedPoolUsage; //non-paged pool utilisé
- }
-
- //==========================================================================================
- //structures Windows
- //==========================================================================================
-
- //structure contenant une chaine de caractere UNICODE
- [StructLayout(LayoutKind.Sequential, Pack = 1)]
- private struct UNICODE_STRING
- {
- public ushort Length;
- public ushort MaximumLength;
- public IntPtr Buffer;
- }
-
- [StructLayout(LayoutKind.Sequential)]
- private struct GENERIC_MAPPING
- {
- public int GenericRead;
- public int GenericWrite;
- public int GenericExecute;
- public int GenericAll;
- }
-
- //==========================================================================================
- //structures non documentées
- //==========================================================================================
-
- //structure de donnée de handle renvoyée par NtQuerySystemInformation
- [StructLayout(LayoutKind.Sequential, Pack = 1)]
- private struct SYSTEM_HANDLE_INFORMATION
- { // Information Class 16
- public int ProcessID;
- public byte ObjectTypeNumber;
- public byte Flags; // 0x01 = PROTECT_FROM_CLOSE, 0x02 = INHERIT
- public ushort Handle;
- public int Object_Pointer;
- public int GrantedAccess;
- }
-
- //informations sur une entrée du contenu d//un dossier
- [StructLayout(LayoutKind.Sequential)]
- private struct DIRECTORY_BASIC_INFORMATION
- {
- public UNICODE_STRING ObjectName;
- public UNICODE_STRING ObjectTypeName;
- }
-
- //structure contenant des infos sur les type d//objet du systeme
- [StructLayout(LayoutKind.Sequential)]
- private struct OBJECT_BASIC_INFORMATION
- { // Information Class 0
- public int Attributes;
- public int GrantedAccess;
- public int HandleCount;
- public int PointerCount;
- public int PagedPoolUsage;
- public int NonPagedPoolUsage;
- public int Reserved1;
- public int Reserved2;
- public int Reserved3;
- public int NameInformationLength;
- public int TypeInformationLength;
- public int SecurityDescriptorLength;
- public System.Runtime.InteropServices.ComTypes.FILETIME CreateTime;
- }
-
- //structure contenant le nom d//un type d//objet
- [StructLayout(LayoutKind.Sequential)]
- private struct OBJECT_NAME_INFORMATION
- { // Information Class 1
- public UNICODE_STRING Name;
- }
-
- //attributs d//un objet
- [StructLayout(LayoutKind.Sequential)]
- private struct OBJECT_ATTRIBUTES
- {
- public int Length;
- public int RootDirectoryHandle;
- public IntPtr ObjectName; //PUNICODE_STRING
- public int Attributes;
- public int SecurityDescriptor;
- public int SecurityQualityOfService;
- }
-
- //information sur un type d//objet
- [StructLayout(LayoutKind.Sequential)]
- private struct OBJECT_TYPE_INFORMATION
- { // Information Class 2
- public UNICODE_STRING Name;
- public int ObjectCount;
- public int HandleCount;
- public int Reserved1;
- public int Reserved2;
- public int Reserved3;
- public int Reserved4;
- public int PeakObjectCount;
- public int PeakHandleCount;
- public int Reserved5;
- public int Reserved6;
- public int Reserved7;
- public int Reserved8;
- public int InvalidAttributes;
- public GENERIC_MAPPING GenericMapping;
- public int ValidAccess;
- public byte Unknown;
- public byte MaintainHandleDatabase;
- public int PoolType;
- public int PagedPoolUsage;
- public int NonPagedPoolUsage;
- }
-
- //information sur les types d//objets
- [StructLayout(LayoutKind.Sequential)]
- private struct OBJECT_ALL_TYPES_INFORMATION
- { //Information Class 3
- public int NumberOfTypes;
- public OBJECT_TYPE_INFORMATION TypeInformation;
- }
-
- //information sur les attributs de handles
- [StructLayout(LayoutKind.Sequential)]
- private struct OBJECT_HANDLE_ATTRIBUTE_INFORMATION
- { // Information Class 4
- public byte Inherit;
- public byte ProtectFromClose;
- }
-
- //==========================================================================================
- //API natives (non documentées)
- //==========================================================================================
-
- //renvoie des informations sur le systeme
- [DllImport("ntdll.dll")]
- private static extern uint NtQuerySystemInformation(int SystemInformationClass, IntPtr SystemInformation, int SystemInformationLength, ref int returnLength);
-
- //renvoie des infos sur un type d//objet
- [DllImport("ntdll.dll")]
- private static extern int NtQueryObject(int ObjectHandle, int ObjectInformationClass, IntPtr ObjectInformation, int ObjectInformationLength, ref int returnLength);
-
- //ouvre un dossier
- [DllImport("ntdll.dll")]
- private static extern int NtOpenDirectoryObject(ref int hDirectoryHandle, int DesiredAccess, ref OBJECT_ATTRIBUTES ObjectAttributes);
-
- //liste le contenu d//un dossier
- [DllImport("ntdll.dll")]
- private static extern int NtQueryDirectoryObject(int hDirectoryHandle, IntPtr lpBuffer, int cbBufferLength, int breturnSingleEntry, int bRestartScan, ref int lpContext, ref int lpreturnLength);
-
- //ouvre un lien symbolique
- [DllImport("ntdll.dll")]
- private static extern int NtOpenSymbolicLinkObject(ref int hSymbolicLinkHandle, int DesiredAccess, ref OBJECT_ATTRIBUTES ObjectAttributes);
-
- //permet d//obtenir le nom de l//objet pointé par le lien
- [DllImport("ntdll.dll")]
- private static extern int NtQuerySymbolicLinkObject(int hSymbolicLinkHandle, IntPtr lpTargetName, ref int lpreturnLength);
-
- //ferme un handle ouvert avec NtOpenXXX
- [DllImport("ntdll.dll")]
- private static extern int NtClose(int hHandle);
-
-
- //==========================================================================================
- //API documentées
- //==========================================================================================
- [DllImport("kernel32.dll", EntryPoint = "GetNamedPipeHandleStateA", CharSet = CharSet.Ansi)]
- private static extern int GetNamedPipeHandleState(int hNamedPipe, ref int lpState, int lpCurInstances, int lpMaxCollectionCount, int lpCollectDataTimeout, int lpUserName, int nMaxUserNameSize);
-
- //attendre indéfiniment après un handle
- private const int INFINITE = 0xFFFF;
- //attend après un objet
- [DllImport("kernel32.dll")]
- private static extern int WaitForSingleObject(int hHandle, int dwMilliseconds);
-
- //renvoie une liste des lecteurs du système
- [DllImport("kernel32.dll", EntryPoint = "GetLogicalDriveStringsA", CharSet = CharSet.Ansi)]
- private static extern int GetLogicalDriveStrings(int nBufferLength,[MarshalAs(UnmanagedType.LPArray)] byte[] lpBuffer);
- //copie une zone mémoire dans une autre
-
- //renvoie le handle d//un module
- [DllImport("kernel32.dll", EntryPoint = "GetModuleHandleA", CharSet = CharSet.Ansi)]
- private static extern int GetModuleHandle(string lpModuleName);
- //récupère l//adresse d//une API
- [DllImport("kernel32.dll")]
- private static extern int GetProcAddress(int hModule, string lpProcName);
-
- //crée un thread dans un autre processus
- [DllImport("kernel32.dll")]
- private static extern int CreateRemoteThread(int hProcess, int lpThreadAttributes, int dwStackSize, int lpStartAddress, int lpParameter, int dwCreationFlags, int lpThreadId);
- //renvoit l//ID du thread et du processus de la fenêtre spécifiée
- [DllImport("kernel32.dll")]
- private static extern int GetWindowThreadProcessId(int hwnd, ref int lpdwProcessId);
- //renvoie le code de retour d//un thread
- [DllImport("kernel32.dll")]
- private static extern int GetExitCodeThread(int hThread, ref int lpExitCode);
- //renvoie le handle du processus appelant (-1)
- [DllImport("kernel32.dll")]
- private static extern int GetCurrentProcess();
- //ouvrir le processus
- [DllImport("kernel32.dll")]
- private static extern int OpenProcess(uint dwDesiredAccess, int bInheritHandle, int dwProcessID);
-
- //permet de dupliquer un handle d//un prosessus vers un autre
- [DllImport("kernel32.dll")]
- private static extern int DuplicateHandle(int hSourceProcessHandle, int hSourceHandle, int hTargetProcessHandle, ref int lpTargetHandle, int dwDesiredAccess, int bInheritHandle, int dwOptions);
-
- //fermer un handle
- [DllImport("kernel32.dll")]
- private static extern int CloseHandle(int hObject);
-
- //donne le nom interne d//un lettre de lecteur
- [DllImport("kernel32.dll", EntryPoint = "QueryDosDeviceA", CharSet = CharSet.Ansi)]
- private static extern int QueryDosDevice(string lpDeviceName, StringBuilder lpTargetPath, int ucchMax);
-
- //==========================================================================================
- //Variables globales à la classe
- //==========================================================================================
-
- //handle du processus actuellement ouvert
- private int hProcess;
- //PID du processus actuellement ouvert
- private int lastPID;
-
- //listes des fichiers ouverts du système
- HandleInfo[] m_Files;
- //nombres de fichiers ouverts dans le système
- private int m_cHandles;
- //index of the currently enumered Handle
- private int iHandleEnumerator;
-
-
- //handle vers le driver
- private int hDriver;
- CDriverController driver = null;
-
- //numéro de type des objets de type "File"
- private int m_ObjectTypeNumber;
-
- //==========================================================================================
- //pour envoyer une requête au driver
- //==========================================================================================
-
- //crée ou ouvre un fichier ou pilote
- [DllImport("kernel32.dll", EntryPoint = "CreateFileA", CharSet = CharSet.Ansi)]
- private static extern int CreateFile(string lpFileName, uint dwDesiredAccess, int dwShareMode, int lpSecurityAttributes, int dwCreationDisposition, int dwFlagsAndAttributes, int hTemplateFile);
- //permet d//envoyer des requêtes à un pilote
- [DllImport("kernel32.dll")]
- private static extern int DeviceIoControl(int hDevice, uint dwIoControlCode, ref SYSTEM_HANDLE_INFORMATION lpInBuffer, int nInBufferSize, IntPtr lpOutBuffer, int nOutBufferSize, ref int lpBytesreturned, int lpOverlapped);
- //accès en lecture
- private const uint GENERIC_READ = 0x80000000;
- //accès en écriture
- private const int GENERIC_WRITE = 0x40000000;
- //partage de lecture
- private const int FILE_SHARE_READ = 0x1;
- //partage d//écriture
- private const int FILE_SHARE_WRITE = 0x2;
- //ouvrir seulement si existant
- private const int OPEN_EXISTING = 3;
-
-
- //requête pour obtenir le nom d//un handle
- //hDevice : handle du driver KernelMemory
- //dwIoControlCode : IOCTL_KERNELMEMORY_GETOBJECTNAME
- //lpInBuffer : une structure SYSTEM_HANDLE_INFORMATION contenant les infos sur le handle
- //nInBufferSize : taille de la structure SYSTEM_HANDLE_INFORMATION
- //lpOutBuffer : tampon d//une taille suffisante pour contenir le nom du handle (au moins MAX_PATH caractères)
- //nOutBufferSize : taille de ce tampon
- //lpBytesreturned : taille des données retournée (sauf erreur : nOutBufferSize)
- //lpOverlapped : nul
- //renvoie ERROR_SUCCESS ou ERROR_BUFFER_TOO_SMALL
- private const uint IOCTL_KERNELMEMORY_GETOBJECTNAME = 0x80002004;
-
- //==========================================================================================
- //pour obtenir le privilège Debug
- //==========================================================================================
-
- //const intantes
- //demande l//ajustement des privilèges
- private const int TOKEN_ADJUST_PRIVILEGES = 0x20;
- //demande d//infos sur un token privilege
- private const int TOKEN_QUERY = 0x8;
- //demande l//autorisation d//activer un privilège
- private const int SE_PRIVILEGE_ENABLED = 0x2;
-
- //type de Local Unique ID pour le token
- private struct LUID
- {
- public int LowPart;
- public int HighPart;
- }
- //LUID + attributs
- private struct LUID_AND_ATTRIBUTES
- {
- public LUID pLuid;
- public int Attributes;
- }
- //structure de privilèges de token
- private struct TOKEN_PRIVILEGES
- {
- public int PrivilegeCount;
- public LUID_AND_ATTRIBUTES Privileges;
- }
- //ouvre le token du processus
- [DllImport("advapi32.dll")]
- private static extern int OpenProcessToken(int ProcessHandle, uint DesiredAccess, ref int TokenHandle);
- //ajuste les privilèges
- [DllImport("advapi32.dll")]
- private static extern int AdjustTokenPrivileges(int TokenHandle, int DisableAllPrivileges, ref TOKEN_PRIVILEGES NewState, int BufferLength, ref TOKEN_PRIVILEGES PreviousState, ref int returnLength);
- //regarde la valeur du privilèges
- [DllImport("advapi32.dll", EntryPoint = "LookupPrivilegeValueA", CharSet = CharSet.Ansi)]
- private static extern int LookupPrivilegeValue(string lpSystemName, string lpName, ref LUID lpLuid);
-
- [DllImport("kernel32.dll", EntryPoint = "RtlZeroMemory")]
- private static extern void ZeroMemory(IntPtr Destination, int Length);
-
- //on ouvre un handle du driver KernelMemory
- private int OpenDriver()
- {
- return CreateFile(@"\\.\KernelMemory",
- GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- 0,
- OPEN_EXISTING,
- 0,
- 0);
- }
-
- /// <summary>
- /// renvoie le nombre de handles
- /// </summary>
- /// <returns>nombre de handles</returns>
- public int Count()
- {
- //utilisé lors de la lecture de la valeur de la propriété, du coté droit de l//instruction.
- //Syntax: Debug.Print X.Count
- return m_cHandles;
- }
-
- /// <summary>
- /// rafraîchir la liste des handles
- /// </summary>
- public void Refresh()
- {
- CreateQueryHandlesBuffer();
- }
-
- //crée le buffer contenant les handles
- //doit etre libérer avec DestroyHandlesBuffer avant de quitter l//application
- private void CreateQueryHandlesBuffer()
- {
- int Length; //longueur du buffer
- int X; //compteur
- int ret = 0; //valeur de retour des fonctions utilisées
- IntPtr lpBufferHandles; //pointeur vers le buffer BufferHandles
- SYSTEM_HANDLE_INFORMATION Handle = new SYSTEM_HANDLE_INFORMATION(); //un handle
-
- Length = 0x100; //longueur minimale du buffer
- lpBufferHandles = Marshal.AllocHGlobal(Length); //redimensionne le buffer
- //tant que la longueur n//est pas suffisante
- while (NtQuerySystemInformation(SystemHandleInformation, lpBufferHandles, Length, ref ret) == STATUS_INFO_LENGTH_MISMATCH)
- {
- //on multiplie la taille du buffer par 2
- Length *= 2;
- //on réalloue le buffer
- Marshal.FreeHGlobal(lpBufferHandles);
- lpBufferHandles = Marshal.AllocHGlobal(Length);
- }
-
- //demande le nombre de handles
- m_cHandles = Marshal.ReadInt32(lpBufferHandles);
-
- //on fait de la place pour un handle de fichier
- m_Files = new HandleInfo[m_cHandles];
- //pour chaque handle
- for (X = 0; X < m_cHandles; X++)
- {
- //on copie les informations sur le handle
- Handle = (SYSTEM_HANDLE_INFORMATION)Marshal.PtrToStructure(new IntPtr(lpBufferHandles.ToInt32() + 4 + 16 * X), Handle.GetType());
- //on demande plus d//informations sur le handle de fichier
- m_Files[X] = RetrieveObject(ref Handle);
- }
- //on ferme le handle du dernier processus ouvert
- CloseProcessForHandle();
-
- Marshal.FreeHGlobal(lpBufferHandles);
- }
-
- //ouvre un handle du processus ProcessID s//il n//est pas déjà ouvert
- private void OpenProcessForHandle(int ProcessID)
- {
- //s//il n//est pas ouvert
- if (ProcessID != lastPID)
- {
- //on ferme le précédent
- CloseHandle(hProcess);
- //on ouvre le processus demandé pour dupliquer des handles
- hProcess = OpenProcess(PROCESS_DUP_HANDLE, 0, ProcessID);
- //on stocke le PID du processus ouvert
- lastPID = ProcessID;
- }
- }
-
- //ferme le handle du dernier processus ouvert
- private void CloseProcessForHandle()
- {
- //on le ferme
- CloseHandle(hProcess);
- //on l//indique
- hProcess = 0;
- lastPID = 0;
- }
-
- //remplit un buffer avec les infos sur l//objet spécifié par l//index
- //==============================================================
- private HandleInfo RetrieveObject(ref SYSTEM_HANDLE_INFORMATION Handle)
- {
- int Length = 0; //longueur
- int ret = 0; //valeur de retour des fonctions utilisées
- int ret2 = 0; //valeur de retour des fonctions utilisées
- int hHandle = 0; //handle dupliqué dans notre processus
- //contient des infos sur un objet
- OBJECT_BASIC_INFORMATION ObjBasic = new OBJECT_BASIC_INFORMATION();
- OBJECT_TYPE_INFORMATION ObjType = new OBJECT_TYPE_INFORMATION();
- OBJECT_NAME_INFORMATION ObjName = new OBJECT_NAME_INFORMATION();
- //renvoie le type d//un objet
- string m_ObjectTypeName;
- //renvoie le nom d//un objet
- string m_ObjectName;
- IntPtr BufferObjType;
- IntPtr BufferObjName;
- IntPtr BufferObjBasic;
- HandleInfo h = new HandleInfo();
-
- //on ouvre un handle du processus propriétaire du handle si ce n//est pas déjà fait
- OpenProcessForHandle(Handle.ProcessID);
-
- // on copie le handle recherché dans notre processus avec les mêmes droits d//accès
- DuplicateHandle(hProcess, Handle.Handle, GetCurrentProcess(), ref hHandle, 0, 0, DUPLICATE_SAME_ACCESS);
-
- //si pas de handle
- if (hHandle == 0)
- return h;
-
- //on fait de la place pour les informations de bases de l//objet
- BufferObjBasic = Marshal.AllocHGlobal(Marshal.SizeOf(ObjBasic));
-
- //renvoie des infos Basic sur l//objet
- ret2 = NtQueryObject(hHandle, ObjectBasicInformation, BufferObjBasic, Marshal.SizeOf(ObjBasic), ref ret);
- ObjBasic = (OBJECT_BASIC_INFORMATION)Marshal.PtrToStructure(BufferObjBasic, ObjBasic.GetType());
-
- Marshal.FreeHGlobal(BufferObjBasic);
-
- //alloue un buffer à la taille des données Type
- BufferObjType = Marshal.AllocHGlobal(ObjBasic.TypeInformationLength + 2);
-
- //demande les infos Type de l//objet
- ret2 = NtQueryObject(hHandle, ObjectTypeInformation, BufferObjType, ObjBasic.TypeInformationLength + 2, ref ret);
- //copie le descripteur dans le pointeur de tableau
- ObjType = (OBJECT_TYPE_INFORMATION)Marshal.PtrToStructure(BufferObjType, ObjType.GetType());
-
- //copie les données du nom dans le buffer alloué
- m_ObjectTypeName = Marshal.PtrToStringUni(ObjType.Name.Buffer);
-
- Marshal.FreeHGlobal(BufferObjType);
-
- //si la longueur du nom est 0
- if (ObjBasic.NameInformationLength == 0)
- {
- //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;
- }
- //on alloue le buffer pour le nom de l//object
- BufferObjName = Marshal.AllocCoTaskMem(Length);
- //Dim x As Integer
- //For x = 0 To Length - 1
- //Marshal.WriteByte(BufferObjName, x, CByte(0))
- //Next
- ZeroMemory(BufferObjName, Length);
-
- //on demande le nom de l//objet
- //si c//est un fichier
- if (m_ObjectTypeName.Equals("File"))
- {
- //on envoit notre requête au driver
- //seul le mode kernel permet d//accéder à la zone mémoire des objets 2K
- ret2 = DeviceIoControl(hDriver, IOCTL_KERNELMEMORY_GETOBJECTNAME, ref Handle, 16, BufferObjName, Length, ref ret, 0);
- //sinon
- }
- else
- {
- //on demande le nom du handle directement
- ret2 = NtQueryObject(hHandle, ObjectNameInformation, BufferObjName, Length, ref ret);
- }
- //on copie les descripteur dans le pointeur de tableau
- ObjName = (OBJECT_NAME_INFORMATION)Marshal.PtrToStructure(BufferObjName, ObjName.GetType());
-
- //convertit le nom en String VB
- //alloue un buffer chaine
- //copie les données UNICODE du nom dans le buffer chaine
- m_ObjectName = Marshal.PtrToStringUni(new IntPtr(BufferObjName.ToInt32() + 8));
- //}
-
- Marshal.FreeCoTaskMem(BufferObjName);
-
- //si c//est un fichier, on fournit le nom DOS
- if (m_ObjectTypeName.Equals("File"))
- {
- m_ObjectName = GetDosFileName(m_ObjectName);
- //si c//est une clé de registre on fournit son nom classique
- }
- else if (m_ObjectTypeName.Equals("Key"))
- {
- m_ObjectName = GetKeyName(m_ObjectName);
- }
-
- // on ferme la copie du handle recherché
- CloseHandle(hHandle);
-
- //on stocke les infos
- h.Attributes = ObjBasic.Attributes;
- h.CreateTime = ObjBasic.CreateTime;
- h.Flags = Handle.Flags;
- h.GenericAll = ObjType.GenericMapping.GenericAll;
- h.GenericExecute = ObjType.GenericMapping.GenericExecute;
- h.GenericRead = ObjType.GenericMapping.GenericRead;
- h.GenericWrite = ObjType.GenericMapping.GenericWrite;
- h.GrantedAccess = Handle.GrantedAccess;
- h.Handle = Handle.Handle;
- h.HandleCount = ObjType.HandleCount;
- h.InvalidAttributes = ObjType.InvalidAttributes;
- h.MaintainHandleDatabase = ObjType.MaintainHandleDatabase;
- h.NameInformation = m_ObjectTypeName;
- h.NonPagedPoolUsage = ObjType.NonPagedPoolUsage;
- h.Object_Renamed = Handle.Object_Pointer;
- h.ObjectCount = ObjType.ObjectCount;
- h.ObjectName = m_ObjectName;
- h.PagedPoolUsage = ObjType.PagedPoolUsage;
- h.PeakHandleCount = ObjType.PeakHandleCount;
- h.PeakObjectCount = ObjType.PeakObjectCount;
- h.PointerCount = ObjBasic.PointerCount;
- h.PoolType = ObjType.PoolType;
- h.ProcessID = Handle.ProcessID;
- h.Unknown = ObjType.Unknown;
- h.ValidAccess = ObjType.ValidAccess;
-
- return h;
- }
-
- /// <summary>
- /// renvoie le nom DOS d'un nom de fichier interne à Windows
- /// </summary>
- /// <param name="strInternalFilename">nom interne d'un fichier</param>
- /// <returns>renvoie une chaine contenant le nom de fichier style DOS</returns>
- public static string GetDosFileName(string strInternalFilename)
- {
- byte[] bBuff; //buffer chaine pour les lettres de lecteur du système
- string strBuff;
- //Dim SymNames() As String
- //Dim ubSym As Integer //liste de liens symboliques correspondant et taille de cette liste
- int X; //var de contrôle
- //Dim ObjName, objSymName As String //nom de l//objet et nom du lien
- string[] strLetters;
- string strLetter;
- StringBuilder strInt;
- int ret;
-
- //si pas de nom spécifié
- if (strInternalFilename.Length == 0)
- return string.Empty;
-
- //on prépare le buffer
- bBuff = new byte[256];
- //on demande la liste des lecteurs
- GetLogicalDriveStrings(256, bBuff);
- //la liste est séparée par des nul et terminée par deux nuls
- //on les remplace par des "|"
- X = 0;
- while (bBuff[X] != 0 || bBuff[X+1] != 0)
- {
- if (bBuff[X] == 0)
- bBuff[X] = (byte)'|';
- X++;
- }
- strBuff = System.Text.ASCIIEncoding.ASCII.GetString(bBuff,0,X);
- strLetters = strBuff.Split('|');
-
- for (X = 0; X < strLetters.Length; X++)
- {
- strInt = new StringBuilder(256);
- strLetter = strLetters[X].Substring(0, 2);
- ret = QueryDosDevice(strLetter, strInt, 256);
- //strIntString = strInt.ToString().Remove(strInt.ToString().IndexOf('\0'));
- if (strInternalFilename.StartsWith(strInt.ToString(), StringComparison.OrdinalIgnoreCase))
- {
- return strInternalFilename.Replace(strInt + @"\", strLetters[X]);
- }
- }
- return strInternalFilename;
- }
-
- /// <summary>
- /// renvoie le nom de clé de registre à partir du nom interne
- /// </summary>
- /// <param name="strInternalKey">nom interne de la clé</param>
- /// <returns>renvoie une chaine contenant uniquement des noms de clés de registres telles que courantes</returns>
- public static string GetKeyName(string strInternalKey)
- {
- //HKEY_CURRENT_CONFIG
- strInternalKey = strInternalKey.Replace(@"\REGISTRY\MACHINE\SYSTEM\CURRENTCONTROLSET\HARDWARE PROFILES\CURRENT", "HKCC");
- //HKEY_CLASSES_ROOT
- strInternalKey = strInternalKey.Replace(@"\REGISTRY\MACHINE\SOFTWARE\CLASSES", "HKCR");
- //HKEY_USERS
- strInternalKey = strInternalKey.Replace(@"\REGISTRY\USER\S", @"HKU\S");
- //HKEY_LOCAL_MACHINE
- strInternalKey = strInternalKey.Replace(@"\REGISTRY\MACHINE", "HKLM");
- //HKEY_CURRENT_USER
- strInternalKey = strInternalKey.Replace(@"\REGISTRY\USER", "HKCU");
- //on renvoie
- return strInternalKey;
- }
-
- //==========================================================================================
- //informations sur un processus
- //==========================================================================================
-
- /// <summary>
- /// renvoie le nom d'un processus d'après son PID
- /// </summary>
- /// <param name="ProcessID">ID du processus dont on veut connaitre le nom d'exe (nom seulement)</param>
- /// <returns>renvoie le nom du processus sans le chemin et l'extension d'après "<paramref name="ProcessID"/>"</returns>
- public static string GetProcessNameFromPID(int ProcessID)
- {
- return Process.GetProcessById(ProcessID).ProcessName;
- }
-
- /// <summary>
- /// constructeur de l'énumérateur de handle
- /// </summary>
- public COpenedHandles()
- {
- int ret;
- driver = new CDriverController();
- //autorise le privilège Debug afin de pouvoir ouvrir des handles vers les processus systèmes
- EnableDebug();
- //init des infos sur le driver
- driver.ServiceDisplayName = "KernelMemory";
- driver.ServiceErrorType = 1;
- driver.ServiceFileName = Application.StartupPath + @"\KernelMemory.sys";
- driver.ServiceName = "KernelMemory";
- driver.ServiceStartType = 3; //DEMAND
- driver.ServiceType = 1; //KERNEL DRIVER
-
- //enregistre le driver dans le registre si pas déjà enregistré
- ret = driver.InstallService();
- //if (ret != 0)
- // MessageBox.Show(CDriverController.FormatErrorMessage(ret));
- //démarre le driver
- ret = driver.StartService();
- if (ret != 0)
- MessageBox.Show(CDriverController.FormatErrorMessage(ret));
-
- //uvre un handle vers le driver
- hDriver = OpenDriver();
- //demande le numéro du type "File" pour les objets File de cette version système
- //cela permet d//être indépendant de la version de NT/2K/XP : numéros différents suivant la version
- m_ObjectTypeNumber = GetObjectTypeNumber("File");
- }
-
- /// <summary>
- /// ferme tous les handles ouvert par l'énumérateur
- /// </summary>
- public void Close()
- {
- //ferme un éventuel handle de processus ouvert
- CloseProcessForHandle();
- //ferme le handle du driver KernelMemory
- CloseHandle(hDriver);
- //arrête le driver KernelMemory
- driver.StopService();
- //ferme le contrôleur de driver
- driver.Close();
- driver = null;
- }
-
- //renvoie le numéro de type d//objet pour un nom de type d//objet textuel
- //=====================================================================
- //strTypeName : nom du type d//objet
- //renvoie un long
- private int GetObjectTypeNumber(string strTypeName)
- {
- //buffer pour les données de nom de types d//objet, taille requise pour stocker les infos de type
- IntPtr buffObjTypes = IntPtr.Zero;
- int cbReqLength = 0;
- //nombre de type dans la liste
- int cTypeCount = 0;
- //var de contrôle
- int X;
- //pointeur vers la prochaine information de type
- IntPtr lpTypeInfo;
- //informations sur un type
- OBJECT_TYPE_INFORMATION TypeInfo = new OBJECT_TYPE_INFORMATION();
- //nom d//un type
- string strType;
-
- if (IsWindowsVista())
- {
- IntPtr b = Marshal.AllocHGlobal(4);
- //on demande la taille requise pour la liste des infos de type
- NtQueryObject(0, ObjectAllTypesInformation, b, 4, ref cbReqLength);
- Marshal.FreeHGlobal(b);
- }
- else
- {
- //on demande la taille requise pour la liste des infos de type
- NtQueryObject(0, ObjectAllTypesInformation, IntPtr.Zero, 0, ref cbReqLength);
- }
-
- //on prépare le buffer
- buffObjTypes = Marshal.AllocHGlobal(cbReqLength);
-
- //on demande la liste des informations de type
- NtQueryObject(0, ObjectAllTypesInformation, buffObjTypes, cbReqLength, ref cbReqLength);
-
- //on copie le nombre d//informations de type contenu dans la liste : le premier double mot
- cTypeCount = Marshal.ReadInt32(buffObjTypes, 0);
-
- //on fait pointer la prochaine information de type sur le début de la liste
- lpTypeInfo = new IntPtr(buffObjTypes.ToInt32() + 4);
- //pour chaque info de type
- for (X = 0; X < cTypeCount; X++)
- {
- //on copie les informations sur le type
- TypeInfo = (OBJECT_TYPE_INFORMATION)Marshal.PtrToStructure(lpTypeInfo, TypeInfo.GetType());
- //on fait de la place pour le nom du type (en UNICODE)
- //strType = Space(TypeInfo.Name.Length / 2)
- //on copie la chaine UNICODE du nom de type
- strType = Marshal.PtrToStringUni(TypeInfo.Name.Buffer, TypeInfo.Name.Length >> 1);
- //si elle correspond au nom recherché
- if (strTypeName.Equals(strType))
- {
- //le numéro de type d//objet est l//index dans la liste de type + 1
- return X + 1;
- }
- //sinon, on fait pointer la prochaine information de type
- //à un décalage de la taille des informations + la taille du nom de type en UNICODE
- lpTypeInfo = new IntPtr(lpTypeInfo.ToInt32() + 96 + TypeInfo.Name.MaximumLength);
- //et on l//aligne sur le prochain dword
- lpTypeInfo = new IntPtr(lpTypeInfo.ToInt32() + (lpTypeInfo.ToInt32() % 4));
- }
- Marshal.FreeHGlobal(buffObjTypes);
-
- //si windows 2000 alors bug : NtQueryObject ne renvoie que 23 types au lieu de 26
- if (strTypeName.Equals("Driver"))
- {
- return 24;
- }
- else if (strTypeName.Equals("IoCompletion"))
- {
- return 25;
- }
- else if (strTypeName.Equals("File"))
- {
- return 26;
- }
-
- //si on arrive ici, c//est que le type n//a pas été trouvé, alors 0
- return 0;
- }
-
- //autorise le privilège SeDebugPrivilege
- private void EnableDebug()
- {
- int hProc; //handle du processus actuel
- int hToken = 0; //handle du token
- LUID mLUID = new LUID(); //LUID du privilège
- TOKEN_PRIVILEGES mPriv = new TOKEN_PRIVILEGES(); //privilèges
- TOKEN_PRIVILEGES mNewPriv = new TOKEN_PRIVILEGES(); //nouveaux privilèges
- int retlen = 0;
-
- //renvoie le processus actuel
- hProc = GetCurrentProcess();
- //ouvre le token
- OpenProcessToken(hProc, TOKEN_ADJUST_PRIVILEGES + TOKEN_QUERY, ref hToken);
- //regarde la valeur du privilège
- LookupPrivilegeValue(string.Empty, "SeDebugPrivilege", ref mLUID);
- //nombre de privilèges
- mPriv.PrivilegeCount = 1;
- //attribut ENABLED
- mPriv.Privileges.Attributes = SE_PRIVILEGE_ENABLED;
- //LUID de privilège
- mPriv.Privileges.pLuid = mLUID;
- //ajuste le token
- retlen = 4 + (12 * mNewPriv.PrivilegeCount);
- AdjustTokenPrivileges(hToken, 0, ref mPriv, 4 + (12 * mPriv.PrivilegeCount), ref mNewPriv, ref retlen);
- //ferme le handle de token
- CloseHandle(hToken);
- }
-
- //indique s//il s//agit de Vista
- private bool IsWindowsVista()
- {
- return ((Environment.OSVersion.Platform == PlatformID.Win32NT) && (Environment.OSVersion.Version.Major == 6) && (Environment.OSVersion.Version.Minor == 0));
- }
-
- /// <summary>
- /// permet de fermer un handle <paramref name="hHandle"/> dans le processus <paramref name="dwProcessID"/>
- /// </summary>
- /// <param name="dwProcessID">process id du processus contenant le handle <paramref name="dwProcessId"/></param>
- /// <param name="hHandle">handle à fermer</param>
- /// <returns>renvoie le résultat de l'exécution de CloseHandle dans le processus <paramref name="dwProcessId"/></returns>
- public int CloseProcessLocalHandle(int dwProcessID, int hHandle)
- {
- int hMod;
- int lpProc;
- int hThread;
- int hProcess;
- int ret = 0;
-
- hMod = GetModuleHandle("kernel32.dll");
- lpProc = GetProcAddress(hMod, "CloseHandle");
- hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, 0, dwProcessID);
- if (hProcess != 0)
- {
- hThread = CreateRemoteThread(hProcess, 0, 0, lpProc, hHandle, 0, 0);
- if (hThread != 0)
- {
- WaitForSingleObject(hThread, INFINITE);
- GetExitCodeThread(hThread, ref ret);
- CloseHandle(hThread);
- }
- CloseHandle(hProcess);
- }
- return ret;
- }
-
- /// <summary>
- /// permet de récupèrer le <paramref name="index"/> ième handle de la liste
- /// </summary>
- /// <param name="index">index du handle à récupérer</param>
- /// <returns>renvoie les informations d'un handle dans un HandleInfo</returns>
- public HandleInfo this[int index]
- {
- get
- {
- return m_Files[index];
- }
- }
-
- #region IEnumerable Membres
-
- public IEnumerator GetEnumerator()
- {
- return this;
- }
-
- #endregion
-
- #region IEnumerable Membres
-
- IEnumerator IEnumerable.GetEnumerator()
- {
- return this;
- }
-
- #endregion
-
- #region IEnumerator Membres
-
- object IEnumerator.Current
- {
- get { return m_Files[iHandleEnumerator]; }
- }
-
- void IEnumerator.Reset()
- {
- iHandleEnumerator = 0;
- }
-
- bool IEnumerator.MoveNext()
- {
- iHandleEnumerator++;
- if (iHandleEnumerator < m_Files.Length)
- return true;
- else
- {
- iHandleEnumerator = 0;
- return false;
- }
- }
-
- #endregion
- }
- }
|