Example #1
0
    public static List <ServiceInfo> GetServicesByPID(int pid)
    {
        bool doUpdate = false;

        if (pid == -1) // -1 means get all and we always want a fresh list
        {
            doUpdate = true;
        }
        else
        {
            ServiceCacheLock.EnterReadLock();
            doUpdate = ServiceCacheTime <= DateTime.FromFileTimeUtc(ProcFunc.GetProcessCreationTime(pid)).ToLocalTime();
            ServiceCacheLock.ExitReadLock();
        }
        if (doUpdate)
        {
            RefreshServices();
        }

        ServiceCacheLock.EnterReadLock();
        CloneableList <ServiceInfo> values;

        if (pid == -1)
        {
            values = ServiceCacheByPID.GetAllValues();
        }
        else if (!ServiceCacheByPID.TryGetValue(pid, out values))
        {
            values = null;
        }
        ServiceCacheLock.ExitReadLock();
        return((values != null && values.Count == 0) ? null : values);
    }
Example #2
0
    public static List <ServiceInfo> GetServicesByPID(int pid)
    {
        bool doUpdate = false;

        if (pid == -1) // -1 means get all and we always want a fresh list
        {
            doUpdate = true;
        }
        else
        {
            long RawCreationTime;
            long RawExitTime;
            long RawKernelTime;
            long RawUserTime;

            try
            {
                IntPtr processHandle = System.Diagnostics.Process.GetProcessById(pid).Handle;
                GetProcessTimes(processHandle, out RawCreationTime, out RawExitTime, out RawKernelTime, out RawUserTime);
            }
            catch
            {
                return(null);
            }
            ServiceCacheLock.EnterReadLock();
            doUpdate = ServiceCacheTime < DateTime.FromFileTimeUtc(RawCreationTime);
            ServiceCacheLock.ExitReadLock();
        }
        if (doUpdate)
        {
            RefreshServices();
        }

        ServiceCacheLock.EnterReadLock();
        List <ServiceInfo> values;

        if (pid == -1)
        {
            values = ServiceCacheByPID.GetAllValues();
        }
        else if (!ServiceCacheByPID.TryGetValue(pid, out values))
        {
            values = null;
        }
        ServiceCacheLock.ExitReadLock();
        return((values != null && values.Count == 0) ? null : values);
    }
Example #3
0
        public void UpdateSockets()
        {
            UInt64 curTick  = MiscFunc.GetTickCount64();
            UInt64 Interval = curTick - LastUpdate;

            LastUpdate = curTick;

            List <IPHelper.I_SOCKET_ROW> Sockets = new List <IPHelper.I_SOCKET_ROW>();

            // enum all ockets
            IntPtr tcp4Table = IPHelper.GetTcpSockets(ref Sockets);
            IntPtr tcp6Table = IPHelper.GetTcp6Sockets(ref Sockets);
            IntPtr udp4Table = IPHelper.GetUdpSockets(ref Sockets);
            IntPtr udp6Table = IPHelper.GetUdp6Sockets(ref Sockets);

            MultiValueDictionary <UInt64, NetworkSocket> OldSocketList = SocketList.Clone();

            for (int i = 0; i < Sockets.Count; i++)
            {
                IPHelper.I_SOCKET_ROW SocketRow = Sockets[i];

                NetworkSocket Socket = FindSocket(OldSocketList, SocketRow.ProcessId, SocketRow.ProtocolType, SocketRow.LocalAddress, SocketRow.LocalPort, SocketRow.RemoteAddress, SocketRow.RemotePort, NetworkSocket.MatchMode.Strict);
                if (Socket != null)
                {
                    //AppLog.Debug("Found Socket {0}:{1} {2}:{3}", Socket.LocalAddress, Socket.LocalPort, Socket.RemoteAddress, Socket.RemotePort);
                    OldSocketList.Remove(Socket.HashID, Socket);
                }
                else
                {
                    Socket = new NetworkSocket(SocketRow.ProcessId, SocketRow.ProtocolType, SocketRow.LocalAddress, SocketRow.LocalPort, SocketRow.RemoteAddress, SocketRow.RemotePort);
                    //AppLog.Debug("Added Socket {0}:{1} {2}:{3}", Socket.LocalAddress, Socket.LocalPort, Socket.RemoteAddress, Socket.RemotePort);
                    SocketList.Add(Socket.HashID, Socket);
                }

                // Note: sockets observed using ETW are not yet initialized as we are missing owner informations there
                if (Socket.ProgID == null)
                {
                    Socket.CreationTime = SocketRow.CreationTime;

                    if (App.engine.DnsInspector != null && Socket.RemoteAddress != null)
                    {
                        App.engine.DnsInspector.GetHostName(Socket.ProcessId, Socket.RemoteAddress, Socket, NetworkSocket.HostSetter);
                    }

                    var moduleInfo = SocketRow.Module;
                    if (moduleInfo == null || moduleInfo.ModulePath.Equals("System", StringComparison.OrdinalIgnoreCase))
                    {
                        Socket.ProgID = ProgramID.NewID(ProgramID.Types.System);
                    }
                    else
                    {
                        string fileName   = moduleInfo.ModulePath;
                        string serviceTag = moduleInfo.ModuleName;

                        // Note: for services and system TCPIP_OWNER_MODULE_BASIC_INFO.pModuleName is the same TCPIP_OWNER_MODULE_BASIC_INFO.pModulePath
                        // hence we don't have the actuall exe path and we will have to resolve it.
                        if (serviceTag.Equals(fileName))
                        {
                            fileName = null; // filename not valid
                        }
                        else
                        {
                            serviceTag = null; // service tag not valid
                        }
                        Socket.ProgID = App.engine.GetProgIDbyPID(Socket.ProcessId, serviceTag, fileName);
                    }
                }

                Socket.Update(SocketRow, Interval);

                //IPHelper.ModuleInfo Info = SocketRow.Module;
                //AppLog.Debug("Socket {0}:{1} {2}:{3} {4}", Socket.LocalAddress, Socket.LocalPort, Socket.RemoteAddress, Socket.RemotePort, (Info != null ? (Info.ModulePath + " (" + Info.ModuleName + ")") : "") + " [PID: " + Socket.ProcessId + "]");
            }

            foreach (NetworkSocket Socket in OldSocketList.GetAllValues())
            {
                bool bIsUDPPseudoCon = (Socket.ProtocolType & (UInt32)IPHelper.AF_PROT.UDP) == (UInt32)IPHelper.AF_PROT.UDP && Socket.RemotePort != 0;

                // Note: sockets observed using ETW are not yet initialized as we are missing owner informations there
                if (Socket.ProgID == null)
                {
                    Socket.CreationTime = DateTime.Now;

                    if (App.engine.DnsInspector != null && Socket.RemoteAddress != null)
                    {
                        App.engine.DnsInspector.GetHostName(Socket.ProcessId, Socket.RemoteAddress, Socket, NetworkSocket.HostSetter);
                    }

                    // Note: etw captured connections does not handle services to well :/
                    Socket.ProgID = App.engine.GetProgIDbyPID(Socket.ProcessId, null, null);
                }

                Socket.Update(null, Interval);

                if (bIsUDPPseudoCon && (DateTime.Now - Socket.LastActivity).TotalMilliseconds < 5000) // 5 sec // todo: customize udp pseudo con time
                {
                    OldSocketList.Remove(Socket.HashID, Socket);

                    if (Socket.RemovedTimeStamp != 0)
                    {
                        Socket.RemovedTimeStamp = 0;
                    }
                }
                else
                {
                    Socket.State = (int)IPHelper.MIB_TCP_STATE.CLOSED;
                }
            }

            UInt64 CurTick = MiscFunc.GetCurTick();

            foreach (NetworkSocket Socket in OldSocketList.GetAllValues())
            {
                if (Socket.RemovedTimeStamp == 0)
                {
                    Socket.RemovedTimeStamp = CurTick;
                }
                else if (Socket.RemovedTimeStamp < CurTick + 3000) // todo: customize retention time
                {
                    SocketList.Remove(Socket.HashID, Socket);

                    Socket.Program?.RemoveSocket(Socket);
                }

                //AppLog.Debug("Removed Socket {0}:{1} {2}:{3}", CurSocket.LocalAddress, CurSocket.LocalPort, CurSocket.RemoteAddress, CurSocket.RemotePort);
            }

            // cleanup
            if (tcp4Table != IntPtr.Zero)
            {
                Marshal.FreeHGlobal(tcp4Table);
            }
            if (tcp6Table != IntPtr.Zero)
            {
                Marshal.FreeHGlobal(tcp6Table);
            }
            if (udp4Table != IntPtr.Zero)
            {
                Marshal.FreeHGlobal(udp4Table);
            }
            if (udp6Table != IntPtr.Zero)
            {
                Marshal.FreeHGlobal(udp6Table);
            }
        }
Example #4
0
        public void SyncCache()
        {
            var dnsCacheDataTable = IntPtr.Zero;

            if (DnsGetCacheDataTable_I == null || !DnsGetCacheDataTable_I(out dnsCacheDataTable))
            {
                return;
            }

            DateTime CurrentTime = DateTime.Now;

            // cache domains
            //var oldCache = new HashSet<string>(dnsCache.Keys);

            foreach (DnsCacheEntry cacheEntry in dnsCache.GetAllValues())
            {
                if (cacheEntry.ExpirationTime > CurrentTime)
                {
                    cacheEntry.ExpirationTime = CurrentTime;
                }
                // will be reset in the loop, efectivly timeouting all flushed entries imminetly
            }

            for (var tablePtr = dnsCacheDataTable; tablePtr != IntPtr.Zero;)
            {
                var entry = (DnsApi.DnsCacheEntry)Marshal.PtrToStructure(tablePtr, typeof(DnsApi.DnsCacheEntry));
                tablePtr = entry.Next;

                // Note: DnsGetCacheDataTable_I should only return one result per domain name in cache mo mater how many entries there are
                //          DnsQuery wil retrive all entries of any type for a given domain name thanks to DNS_QUERY_UN_DOCUMENTED

                var  resultPtr = IntPtr.Zero;
                uint ret       = DnsApi.DnsQuery(entry.Name, entry.Type, DnsApi.DnsQueryType.DNS_QUERY_NO_WIRE_QUERY | DnsApi.DnsQueryType.DNS_QUERY_UN_DOCUMENTED, IntPtr.Zero, ref resultPtr, IntPtr.Zero);
                if (ret != DnsApi.ERROR_SUCCESS)
                {
                    continue;
                }

                //AppLog.Debug("DnsEntries: " + entry.Name);

                // get all entries for thisdomain name

                /*CloneableList<DnsCacheEntry> curEntries = null;
                 * if (!dnsCache.TryGetValue(entry.Name, out curEntries))
                 * {
                 *  curEntries = new CloneableList<DnsCacheEntry>();
                 *  dnsCache.Add(entry.Name, curEntries);
                 * }
                 * else
                 *  oldCache.Remove(entry.Name);*/

                for (var recordIndexPtr = resultPtr; recordIndexPtr != IntPtr.Zero;)
                {
                    var    record = (DnsApi.DnsRecord)Marshal.PtrToStructure(recordIndexPtr, typeof(DnsApi.DnsRecord));
                    int    offset = Marshal.OffsetOf(typeof(DnsApi.DnsRecord), "Data").ToInt32();
                    IntPtr data   = recordIndexPtr + offset;
                    recordIndexPtr = record.Next;

                    string    HostName       = record.Name;
                    IPAddress Address        = null;
                    string    ResolvedString = null;

                    CloneableList <DnsCacheEntry> curEntries = GetEntriesFor(HostName);

                    DnsCacheEntry curEntry = null;

                    if (record.Type == DnsApi.DnsRecordType.A || record.Type == DnsApi.DnsRecordType.AAAA)
                    {
                        switch (record.Type)
                        {
                        case DnsApi.DnsRecordType.A:
                        {
                            var ptr = (DnsApi.DnsARecord)Marshal.PtrToStructure(data, typeof(DnsApi.DnsARecord));
                            Address = new IPAddress((UInt32)ptr.IpAddress);
                            break;
                        }

                        case DnsApi.DnsRecordType.AAAA:
                        {
                            var ptr = (DnsApi.DnsAAAARecord)Marshal.PtrToStructure(data, typeof(DnsApi.DnsAAAARecord));
                            Address = new IPAddress(ptr.IpAddress);
                            break;
                        }
                        }

                        if (Address.Equals(IPAddress.Any) || Address.Equals(IPAddress.IPv6Any)) // thats wht we get from a pi hole dns proxy if the domain is blocked
                        {
                            Address = null;
                        }

                        curEntry = curEntries.FirstOrDefault(e => { return(e.RecordType == record.Type && MiscFunc.IsEqual(e.Address, Address)); });
                    }
                    else // CNAME, SRV, MX, DNAME
                    {
                        switch (record.Type)
                        {
                        //case DnsApi.DnsRecordType.PTR:
                        //    Address = RevDnsHost2Address(HostName);
                        //    goto case DnsApi.DnsRecordType.CNAME;
                        //case DnsApi.DnsRecordType.DNAME: // entire zone
                        case DnsApi.DnsRecordType.CNAME:     // one host
                        {
                            var ptr = (DnsApi.DnsPTRRecord)Marshal.PtrToStructure(data, typeof(DnsApi.DnsPTRRecord));
                            ResolvedString = ptr.NameHost;
                            break;
                        }

                        /*case DnsApi.DnsRecordType.SRV:
                         * {
                         *  var ptr = (DnsApi.DnsSRVRecord)Marshal.PtrToStructure(data, typeof(DnsApi.DnsSRVRecord));
                         *  ResolvedString = ptr.NameTarget + ":" + ptr.Port;
                         *  break;
                         * }
                         * case DnsApi.DnsRecordType.MX:
                         * {
                         *  var ptr = (DnsApi.DnsMXRecord)Marshal.PtrToStructure(data, typeof(DnsApi.DnsMXRecord));
                         *  ResolvedString = ptr.NameExchange;
                         *  break;
                         * }*/
                        default:
                            continue;
                        }

                        if (ResolvedString.Equals("null.arpa")) // I invented that or the DnsProxyServer so probably no one else uses it
                        {
                            ResolvedString = null;
                        }

                        curEntry = curEntries.FirstOrDefault(e => { return(e.RecordType == record.Type && MiscFunc.IsEqual(e.ResolvedString, ResolvedString)); });
                    }

                    if (curEntry == null)
                    {
                        curEntry = new DnsCacheEntry()
                        {
                            HostName = HostName, RecordType = record.Type
                        };
                        curEntry.ExpirationTime = CurrentTime.AddSeconds(record.Ttl);
                        if (Address == null && ResolvedString == null)
                        {
                            curEntry.State = DnsCacheEntry.States.Blocked;
                        }
                        else
                        {
                            curEntry.State = DnsCacheEntry.States.Resolved;
                        }
                        curEntry.Address        = Address;
                        curEntry.ResolvedString = ResolvedString;

                        AddCacheEntry(curEntries, curEntry);
                    }
                    else // just update
                    {
                        curEntry.ExpirationTime = CurrentTime.AddSeconds(record.Ttl);
                    }
                }

                if (resultPtr != IntPtr.Zero)
                {
                    DnsApi.DnsRecordListFree(resultPtr, DnsApi.DnsFreeType.DnsFreeRecordList);
                }
            }

            /*DateTime ExpirationLimit = CurrentTime.AddMinutes(App.GetConfigInt("DnsInspector", "CacheRetention", 15));
             * // remove old entries
             * foreach (var Name in oldCache)
             * {
             *  CloneableList<DnsCacheEntry> curEntries = dnsCache[Name];
             *  for (int i = 0; i < curEntries.Count; i++)
             *  {
             *      DnsCacheEntry curEntry = curEntries[i];
             *      if (curEntry.ExpirationTime < ExpirationLimit)
             *      {
             *          if (curEntry.RecordType == DnsApi.DnsRecordType.A || curEntry.RecordType == DnsApi.DnsRecordType.AAAA)
             *              cacheByIP.Remove(curEntry.Address, curEntry);
             *          else // CNAME, SRV, MX, DNAME
             *              cacheByStr.Remove(curEntry.ResolvedString, curEntry);
             *
             *          curEntries.RemoveAt(i--);
             *      }
             *  }
             *  if (curEntries.Count == 0)
             *      dnsCache.Remove(Name);
             * }*/

            DnsApi.DnsRecordListFree(dnsCacheDataTable, DnsApi.DnsFreeType.DnsFreeRecordList);
        }
Example #5
0
        public void UpdateSockets()
        {
            UInt64 curTick  = MiscFunc.GetTickCount64();
            UInt64 Interval = curTick - LastUpdate;

            LastUpdate = curTick;

            List <IPHelper.I_SOCKET_ROW> Sockets = new List <IPHelper.I_SOCKET_ROW>();

            // enum all ockets
            IntPtr tcp4Table = IPHelper.GetTcpSockets(ref Sockets);
            IntPtr tcp6Table = IPHelper.GetTcp6Sockets(ref Sockets);
            IntPtr udp4Table = IPHelper.GetUdpSockets(ref Sockets);
            IntPtr udp6Table = IPHelper.GetUdp6Sockets(ref Sockets);

            MultiValueDictionary <UInt64, NetworkSocket> OldSocketList = SocketList.Clone();

            for (int i = 0; i < Sockets.Count; i++)
            {
                IPHelper.I_SOCKET_ROW SocketRow = Sockets[i];

                NetworkSocket Socket = FindSocket(OldSocketList, SocketRow.ProcessId, SocketRow.ProtocolType, SocketRow.LocalAddress, SocketRow.LocalPort, SocketRow.RemoteAddress, SocketRow.RemotePort, NetworkSocket.MatchMode.Strict);
                if (Socket != null)
                {
                    //AppLog.Debug("Found Socket {0}:{1} {2}:{3}", Socket.LocalAddress, Socket.LocalPort, Socket.RemoteAddress, Socket.RemotePort);
                    OldSocketList.Remove(Socket.HashID, Socket);
                }
                else
                {
                    Socket = new NetworkSocket(SocketRow.ProcessId, SocketRow.ProtocolType, SocketRow.LocalAddress, SocketRow.LocalPort, SocketRow.RemoteAddress, SocketRow.RemotePort);
                    //AppLog.Debug("Added Socket {0}:{1} {2}:{3}", Socket.LocalAddress, Socket.LocalPort, Socket.RemoteAddress, Socket.RemotePort);
                    SocketList.Add(Socket.HashID, Socket);
                }

                // Note: sockets observed using ETW are not yet initialized as we are missing owner informations there
                if (Socket.ProgID == null)
                {
                    Socket.CreationTime = SocketRow.CreationTime;

                    if (Socket.RemoteAddress != null)
                    {
                        App.engine.DnsInspector.GetHostName(Socket.ProcessId, Socket.RemoteAddress, Socket, NetworkSocket.HostSetter);
                    }

                    var moduleInfo = SocketRow.Module;
                    if (moduleInfo == null || moduleInfo.ModulePath.Equals("System", StringComparison.OrdinalIgnoreCase))
                    {
                        Socket.ProgID = ProgramID.NewID(ProgramID.Types.System);
                    }
                    else
                    {
                        string fileName   = moduleInfo.ModulePath;
                        string serviceTag = moduleInfo.ModuleName;

                        // Note: for services and system TCPIP_OWNER_MODULE_BASIC_INFO.pModuleName is the same TCPIP_OWNER_MODULE_BASIC_INFO.pModulePath
                        // hence we don't have the actuall exe path and we will have to resolve it.
                        if (serviceTag.Equals(fileName))
                        {
                            fileName = null; // filename not valid
                        }
                        else
                        {
                            serviceTag = null; // service tag not valid
                        }
                        Socket.ProgID = App.engine.GetProgIDbyPID(Socket.ProcessId, serviceTag, fileName);
                    }
                }

                // a program may have been removed than the sockets get unasigned and has to be re asigned
                if (Socket.Assigned == false)
                {
                    Program prog = Socket.ProgID == null ? null : App.engine.ProgramList.GetProgram(Socket.ProgID, true, ProgramList.FuzzyModes.Any);
                    prog?.AddSocket(Socket);
                    if (prog != null)
                    {
                        Socket.Access = prog.LookupRuleAccess(Socket);
                    }
                }

                Socket.Update(SocketRow, Interval);

                //IPHelper.ModuleInfo Info = SocketRow.Module;
                //AppLog.Debug("Socket {0}:{1} {2}:{3} {4}", Socket.LocalAddress, Socket.LocalPort, Socket.RemoteAddress, Socket.RemotePort, (Info != null ? (Info.ModulePath + " (" + Info.ModuleName + ")") : "") + " [PID: " + Socket.ProcessId + "]");
            }

            UInt64 CurTick = MiscFunc.GetCurTick();

            foreach (NetworkSocket Socket in OldSocketList.GetAllValues())
            {
                if (Socket.RemovedTimeStamp == 0)
                {
                    Socket.RemovedTimeStamp = CurTick;
                }
                else if (Socket.RemovedTimeStamp < CurTick + 3000) // todo: customize retention time
                {
                    SocketList.Remove(Socket.HashID, Socket);

                    Program prog = Socket.ProgID == null ? null : App.engine.ProgramList.GetProgram(Socket.ProgID);
                    prog?.RemoveSocket(Socket);
                }

                //AppLog.Debug("Removed Socket {0}:{1} {2}:{3}", CurSocket.LocalAddress, CurSocket.LocalPort, CurSocket.RemoteAddress, CurSocket.RemotePort);
            }

            // cleanup
            if (tcp4Table != IntPtr.Zero)
            {
                Marshal.FreeHGlobal(tcp4Table);
            }
            if (tcp6Table != IntPtr.Zero)
            {
                Marshal.FreeHGlobal(tcp6Table);
            }
            if (udp4Table != IntPtr.Zero)
            {
                Marshal.FreeHGlobal(udp4Table);
            }
            if (udp6Table != IntPtr.Zero)
            {
                Marshal.FreeHGlobal(udp6Table);
            }
        }