/// <summary> /// Enumerates the handles opened by every running process. /// </summary> /// <returns>An array containing information about the handles.</returns> public static SystemHandleEntry[] GetHandles() { int retLength = 0; int handleCount = 0; SystemHandleEntry[] returnHandles; if (_handlesBuffer == null) { _handlesBuffer = new MemoryAlloc(0x1000); } MemoryAlloc data = _handlesBuffer; NtStatus status; // This is needed because NtQuerySystemInformation with SystemHandleInformation doesn't // actually give a real return length when called with an insufficient buffer. This code // tries repeatedly to call the function, doubling the buffer size each time it fails. while ((status = Win32.NtQuerySystemInformation( SystemInformationClass.SystemHandleInformation, data, data.Size, out retLength) ) == NtStatus.InfoLengthMismatch) { data.ResizeNew(data.Size * 2); // Fail if we've resized it to over 16MB - protect from infinite resizing if (data.Size > 16 * 1024 * 1024) { throw new OutOfMemoryException(); } } if (status >= NtStatus.Error) { Win32.Throw(status); } // The structure of the buffer is the handle count plus an array of SYSTEM_HANDLE_INFORMATION // structures. handleCount = data.ReadStruct <SystemHandleInformation>().NumberOfHandles; returnHandles = new SystemHandleEntry[handleCount]; // Unsafe code for speed. unsafe { SystemHandleEntry *handlesPtr = (SystemHandleEntry *)((byte *)data.Memory + SystemHandleInformation.HandlesOffset); for (int i = 0; i < handleCount; i++) { //returnHandles[i] = data.ReadStruct<SystemHandleEntry>(SystemHandleInformation.HandlesOffset, i); returnHandles[i] = handlesPtr[i]; } } return(returnHandles); }
/// <summary> /// Enumerates the modules loaded by the kernel. /// </summary> /// <param name="enumCallback">A callback for the enumeration.</param> public static void EnumKernelModules(EnumKernelModulesDelegate enumCallback) { NtStatus status; int retLength; if (_kernelModulesBuffer == null) { _kernelModulesBuffer = new MemoryAlloc(0x1000); } status = Win32.NtQuerySystemInformation( SystemInformationClass.SystemModuleInformation, _kernelModulesBuffer, _kernelModulesBuffer.Size, out retLength ); if (status == NtStatus.InfoLengthMismatch) { _kernelModulesBuffer.ResizeNew(retLength); status = Win32.NtQuerySystemInformation( SystemInformationClass.SystemModuleInformation, _kernelModulesBuffer, _kernelModulesBuffer.Size, out retLength ); } if (status >= NtStatus.Error) { Win32.Throw(status); } RtlProcessModules modules = _kernelModulesBuffer.ReadStruct <RtlProcessModules>(); for (int i = 0; i < modules.NumberOfModules; i++) { var module = _kernelModulesBuffer.ReadStruct <RtlProcessModuleInformation>(RtlProcessModules.ModulesOffset, i); var moduleInfo = new Debugging.ModuleInformation(module); if (!enumCallback(new KernelModule( moduleInfo.BaseAddress, moduleInfo.Size, moduleInfo.Flags, moduleInfo.BaseName, FileUtils.GetFileName(moduleInfo.FileName) ))) { break; } } }
/// <summary> /// Gets the page files currently active. /// </summary> /// <returns>A collection of page file information structures.</returns> public static SystemPagefile[] GetPagefiles() { int retLength; List <SystemPagefile> pagefiles = new List <SystemPagefile>(); using (MemoryAlloc data = new MemoryAlloc(0x200)) { NtStatus status; while ((status = Win32.NtQuerySystemInformation( SystemInformationClass.SystemPageFileInformation, data, data.Size, out retLength) ) == NtStatus.InfoLengthMismatch) { data.ResizeNew(data.Size * 2); // Fail if we've resized it to over 16MB - protect from infinite resizing if (data.Size > 16 * 1024 * 1024) { throw new OutOfMemoryException(); } } if (status >= NtStatus.Error) { Win32.Throw(status); } pagefiles = new List <SystemPagefile>(2); int i = 0; SystemPagefileInformation currentPagefile; do { currentPagefile = data.ReadStruct <SystemPagefileInformation>(i, 0); pagefiles.Add(new SystemPagefile( currentPagefile.TotalSize, currentPagefile.TotalInUse, currentPagefile.PeakUsage, FileUtils.GetFileName(currentPagefile.PageFileName.Read()) )); i += currentPagefile.NextEntryOffset; } while (currentPagefile.NextEntryOffset != 0); return(pagefiles.ToArray()); } }
/// <summary> /// Gets a dictionary containing the services on the system. /// </summary> /// <returns>A dictionary, indexed by service name.</returns> public static Dictionary <string, EnumServiceStatusProcess> GetServices() { using (ServiceManagerHandle manager = new ServiceManagerHandle(ScManagerAccess.EnumerateService)) { int requiredSize; int servicesReturned; int resume = 0; if (_servicesBuffer == null) { _servicesBuffer = new MemoryAlloc(0x10000); } MemoryAlloc data = _servicesBuffer; if (!Win32.EnumServicesStatusEx(manager, IntPtr.Zero, ServiceQueryType.Win32 | ServiceQueryType.Driver, ServiceQueryState.All, data, data.Size, out requiredSize, out servicesReturned, ref resume, null)) { // resize buffer data.ResizeNew(requiredSize); if (!Win32.EnumServicesStatusEx(manager, IntPtr.Zero, ServiceQueryType.Win32 | ServiceQueryType.Driver, ServiceQueryState.All, data, data.Size, out requiredSize, out servicesReturned, ref resume, null)) { Win32.Throw(); } } var dictionary = new Dictionary <string, EnumServiceStatusProcess>(servicesReturned); for (int i = 0; i < servicesReturned; i++) { var service = data.ReadStruct <EnumServiceStatusProcess>(i); dictionary.Add(service.ServiceName, service); } return(dictionary); } }
public static string FindFileWin32(string fileName) { using (MemoryAlloc data = new MemoryAlloc(0x400)) { IntPtr filePart; int retLength = Win32.SearchPath(null, fileName, null, data.Size / 2, data, out filePart); if (retLength * 2 > data.Size) { data.ResizeNew(retLength * 2); retLength = Win32.SearchPath(null, fileName, null, data.Size / 2, data, out filePart); } if (retLength == 0) return null; return data.ReadUnicodeString(0, retLength); } }
public static string FindFileWin32(string fileName) { using (MemoryAlloc data = new MemoryAlloc(0x400)) { IntPtr filePart; int retLength = Win32.SearchPath(null, fileName, null, data.Size / 2, data, out filePart); if (retLength * 2 > data.Size) { data.ResizeNew(retLength * 2); retLength = Win32.SearchPath(null, fileName, null, data.Size / 2, data, out filePart); } if (retLength == 0) { return(null); } return(data.ReadUnicodeString(0, retLength)); } }
public static unsafe string GetVistaFileName(int pid) { using (MemoryAlloc buffer = new MemoryAlloc(0x100)) { SystemProcessImageNameInformation info; info.ProcessId = pid; info.ImageName.Length = 0; info.ImageName.MaximumLength = 0x100; info.ImageName.Buffer = buffer; NtStatus status = Win32.NtQuerySystemInformation( SystemInformationClass.SystemProcessImageName, &info, SystemProcessImageNameInformation.SizeOf, null ); if (status == NtStatus.InfoLengthMismatch) { // Our buffer was too small. The required buffer length is stored in MaximumLength. buffer.ResizeNew(info.ImageName.MaximumLength); status = Win32.NtQuerySystemInformation( SystemInformationClass.SystemProcessImageName, &info, SystemProcessImageNameInformation.SizeOf, null ); } status.ThrowIf(); return(GetFileName(info.ImageName.Text)); } }
public static unsafe string GetVistaFileName(int pid) { using (MemoryAlloc buffer = new MemoryAlloc(0x100)) { SystemProcessImageNameInformation info; info.ProcessId = pid; info.ImageName.Length = 0; info.ImageName.MaximumLength = 0x100; info.ImageName.Buffer = buffer; NtStatus status = Win32.NtQuerySystemInformation( SystemInformationClass.SystemProcessImageName, &info, SystemProcessImageNameInformation.SizeOf, null ); if (status == NtStatus.InfoLengthMismatch) { // Our buffer was too small. The required buffer length is stored in MaximumLength. buffer.ResizeNew(info.ImageName.MaximumLength); status = Win32.NtQuerySystemInformation( SystemInformationClass.SystemProcessImageName, &info, SystemProcessImageNameInformation.SizeOf, null ); } status.ThrowIf(); return GetFileName(info.ImageName.Text); } }
/// <summary> /// Gets the page files currently active. /// </summary> /// <returns>A collection of page file information structures.</returns> public static SystemPagefile[] GetPagefiles() { int retLength; using (MemoryAlloc data = new MemoryAlloc(0x200)) { NtStatus status; while ((status = Win32.NtQuerySystemInformation( SystemInformationClass.SystemPageFileInformation, data, data.Size, out retLength) ) == NtStatus.InfoLengthMismatch) { data.ResizeNew(data.Size * 2); // Fail if we've resized it to over 16MB - protect from infinite resizing if (data.Size > 16 * 1024 * 1024) throw new OutOfMemoryException(); } status.ThrowIf(); List<SystemPagefile> pagefiles = new List<SystemPagefile>(2); int i = 0; SystemPagefileInformation currentPagefile; do { currentPagefile = data.ReadStruct<SystemPagefileInformation>(i, SystemPagefileInformation.SizeOf, 0); pagefiles.Add(new SystemPagefile( currentPagefile.TotalSize, currentPagefile.TotalInUse, currentPagefile.PeakUsage, FileUtils.GetFileName(currentPagefile.PageFileName.Text) )); i += currentPagefile.NextEntryOffset; } while (currentPagefile.NextEntryOffset != 0); return pagefiles.ToArray(); } }
/// <summary> /// Gets a dictionary containing the threads owned by the specified process. /// </summary> /// <param name="pid">A process ID.</param> /// <returns>A dictionary, indexed by thread ID.</returns> public static Dictionary <int, SystemThreadInformation> GetProcessThreads(int pid) { int retLength; if (_processesBuffer == null) { _processesBuffer = new MemoryAlloc(0x10000); } MemoryAlloc data = _processesBuffer; NtStatus status; int attempts = 0; while (true) { attempts++; if ((status = Win32.NtQuerySystemInformation(SystemInformationClass.SystemProcessInformation, data.Memory, data.Size, out retLength)) >= NtStatus.Error) { if (attempts > 3) { Win32.Throw(status); } data.ResizeNew(retLength); } else { break; } } int i = 0; SystemProcessInformation process; do { unsafe { //process = data.ReadStruct<SystemProcessInformation>(i, 0); process = *(SystemProcessInformation *)((byte *)data.Memory + i); } if (process.ProcessId == pid) { var threads = new Dictionary <int, SystemThreadInformation>(); for (int j = 0; j < process.NumberOfThreads; j++) { var thread = data.ReadStruct <SystemThreadInformation>(i + Marshal.SizeOf(typeof(SystemProcessInformation)), j); if (pid != 0) { threads.Add(thread.ClientId.ThreadId, thread); } else { // Fix System Idle Process threads. // There is one thread per CPU, but they // all have a TID of 0. Assign unique TIDs. threads.Add(j, thread); } } return(threads); } i += process.NextEntryOffset; } while (process.NextEntryOffset != 0); return(null); }
/// <summary> /// Gets a dictionary containing the currently running processes. /// </summary> /// <param name="getThreads">Whether to get thread information.</param> /// <returns>A dictionary, indexed by process ID.</returns> public static Dictionary <int, SystemProcess> GetProcesses(bool getThreads) { int retLength; Dictionary <int, SystemProcess> returnProcesses; if (_processesBuffer == null) { _processesBuffer = new MemoryAlloc(0x10000); } MemoryAlloc data = _processesBuffer; NtStatus status; int attempts = 0; while (true) { attempts++; if ((status = Win32.NtQuerySystemInformation( SystemInformationClass.SystemProcessInformation, data, data.Size, out retLength )) >= NtStatus.Error) { if (attempts > 3) { Win32.Throw(status); } data.ResizeNew(retLength); } else { break; } } returnProcesses = new Dictionary <int, SystemProcess>(32); // 32 processes on a computer? int i = 0; SystemProcess currentProcess = new SystemProcess(); do { //currentProcess.Process = data.ReadStruct<SystemProcessInformation>(i, 0); unsafe { currentProcess.Process = *(SystemProcessInformation *)((byte *)data.Memory + i); } currentProcess.Name = currentProcess.Process.ImageName.Read(); if (getThreads && currentProcess.Process.ProcessId != 0) { currentProcess.Threads = new Dictionary <int, SystemThreadInformation>(); for (int j = 0; j < currentProcess.Process.NumberOfThreads; j++) { var thread = data.ReadStruct <SystemThreadInformation>(i + Marshal.SizeOf(typeof(SystemProcessInformation)), j); currentProcess.Threads.Add(thread.ClientId.ThreadId, thread); } } returnProcesses.Add(currentProcess.Process.ProcessId, currentProcess); i += currentProcess.Process.NextEntryOffset; } while (currentProcess.Process.NextEntryOffset != 0); return(returnProcesses); }
private static string GetSignerNameFromStateData(IntPtr stateData) { // Well, here's a shitload of indirection for you... // 1. State data -> Provider data IntPtr provData = Win32.WTHelperProvDataFromStateData(stateData); if (provData == IntPtr.Zero) return null; // 2. Provider data -> Provider signer IntPtr signerInfo = Win32.WTHelperGetProvSignerFromChain(provData, 0, false, 0); if (signerInfo == IntPtr.Zero) return null; CryptProviderSgnr sngr = (CryptProviderSgnr)Marshal.PtrToStructure(signerInfo, typeof(CryptProviderSgnr)); if (sngr.CertChain == IntPtr.Zero) return null; if (sngr.CertChainCount == 0) return null; // 3. Provider signer -> Provider cert CryptProviderCert cert = (CryptProviderCert)Marshal.PtrToStructure(sngr.CertChain, typeof(CryptProviderCert)); if (cert.Cert == IntPtr.Zero) return null; // 4. Provider cert -> Cert context CertContext context = (CertContext)Marshal.PtrToStructure(cert.Cert, typeof(CertContext)); if (context.CertInfo != IntPtr.Zero) { // 5. Cert context -> Cert info CertInfo certInfo = (CertInfo)Marshal.PtrToStructure(context.CertInfo, typeof(CertInfo)); unsafe { using (MemoryAlloc buffer = new MemoryAlloc(0x200)) { int length; // 6. Cert info subject -> Subject X.500 string length = Win32.CertNameToStr( 1, new IntPtr(&certInfo.Subject), 3, buffer, buffer.Size / 2 ); if (length > buffer.Size / 2) { buffer.ResizeNew(length * 2); length = Win32.CertNameToStr( 1, new IntPtr(&certInfo.Subject), 3, buffer, buffer.Size / 2 ); } string name = buffer.ReadUnicodeString(0); // 7. Subject X.500 string -> CN or OU value string value = GetX500Value(name, "CN"); if (string.IsNullOrEmpty(value)) value = GetX500Value(name, "OU"); return value; } } } return null; }
public static string GetVolumeName(string deviceName) { using (var data = new MemoryAlloc(MountMgrMountPoint.Size + deviceName.Length * 2)) { MountMgrMountPoint mountPoint = new MountMgrMountPoint(); mountPoint.DeviceNameLength = (ushort)(deviceName.Length * 2); mountPoint.DeviceNameOffset = MountMgrMountPoint.Size; data.WriteStruct<MountMgrMountPoint>(mountPoint); data.WriteUnicodeString(mountPoint.DeviceNameOffset, deviceName); using (var fhandle = OpenMountManager((FileAccess)StandardRights.Synchronize)) { NtStatus status; int retLength; using (var outData = new MemoryAlloc(0x100)) { while (true) { status = fhandle.IoControl( IoCtlQueryPoints, data.Memory, data.Size, outData.Memory, outData.Size, out retLength ); if (status == NtStatus.BufferOverflow) { outData.ResizeNew(Marshal.ReadInt32(outData.Memory)); // read Size field continue; } else { break; } } if (status >= NtStatus.Error) Win32.Throw(status); MountMgrMountPoints mountPoints = outData.ReadStruct<MountMgrMountPoints>(); // Go through the mount points given and return the first symbolic link that seems // to be a volume name. for (int i = 0; i < mountPoints.NumberOfMountPoints; i++) { MountMgrMountPoint mp = outData.ReadStruct<MountMgrMountPoint>( MountMgrMountPoints.MountPointsOffset, i ); string symLinkName; symLinkName = Marshal.PtrToStringUni( outData.Memory.Increment(mp.SymbolicLinkNameOffset), mp.SymbolicLinkNameLength / 2 ); if (IsVolumePath(symLinkName)) return symLinkName; } return null; } } } }
private static string GetSignerNameFromStateData(IntPtr stateData) { // Well, here's a shitload of indirection for you... // 1. State data -> Provider data IntPtr provData = Win32.WTHelperProvDataFromStateData(stateData); if (provData == IntPtr.Zero) { return(null); } // 2. Provider data -> Provider signer IntPtr signerInfo = Win32.WTHelperGetProvSignerFromChain(provData, 0, false, 0); if (signerInfo == IntPtr.Zero) { return(null); } CryptProviderSgnr sngr = (CryptProviderSgnr)Marshal.PtrToStructure(signerInfo, typeof(CryptProviderSgnr)); if (sngr.CertChain == IntPtr.Zero) { return(null); } if (sngr.CertChainCount == 0) { return(null); } // 3. Provider signer -> Provider cert CryptProviderCert cert = (CryptProviderCert)Marshal.PtrToStructure(sngr.CertChain, typeof(CryptProviderCert)); if (cert.Cert == IntPtr.Zero) { return(null); } // 4. Provider cert -> Cert context CertContext context = (CertContext)Marshal.PtrToStructure(cert.Cert, typeof(CertContext)); if (context.CertInfo != IntPtr.Zero) { // 5. Cert context -> Cert info CertInfo certInfo = (CertInfo)Marshal.PtrToStructure(context.CertInfo, typeof(CertInfo)); unsafe { using (MemoryAlloc buffer = new MemoryAlloc(0x200)) { int length; // 6. Cert info subject -> Subject X.500 string length = Win32.CertNameToStr( 1, new IntPtr(&certInfo.Subject), 3, buffer, buffer.Size / 2 ); if (length > buffer.Size / 2) { buffer.ResizeNew(length * 2); length = Win32.CertNameToStr( 1, new IntPtr(&certInfo.Subject), 3, buffer, buffer.Size / 2 ); } string name = buffer.ReadUnicodeString(0); // 7. Subject X.500 string -> CN or OU value string value = GetX500Value(name, "CN"); if (string.IsNullOrEmpty(value)) { value = GetX500Value(name, "OU"); } return(value); } } } return(null); }