Example #1
0
        /// <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);
        }
Example #2
0
        /// <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;
                }
            }
        }
Example #3
0
        /// <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());
            }
        }
Example #4
0
        /// <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);
            }
        }
Example #5
0
        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);
            }
        }
Example #6
0
        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));
            }
        }
Example #7
0
        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));
            }
        }
Example #8
0
        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);
            }
        }
Example #9
0
        /// <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();
            }
        }
Example #10
0
        /// <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);
        }
Example #11
0
        /// <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;
        }
Example #13
0
        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;
                    }
                }
            }
        }
Example #14
0
        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);
        }