//Timer function used to get data from Performance Counters private void OnTimerMonitor() { //empty the list to prevent duplicate, and thus failed deletions _finishedInstances.Clear(); lock (_PruneInstances) { foreach (KeyValuePair <int, PruneProcessInstance> entry in _PruneInstances) { //try to get data bool getDataSuccessful = entry.Value.GetData(); //If there was an error or if the process is marked as finished, // we need to stop monitoring it if (!getDataSuccessful) { _finishedInstances.Add(entry.Key); } else { } } //Loop through the finished instances and remove them from the active instance list foreach (int i in _finishedInstances) { _PruneInstances.Remove(i); _processIdToWhitelistEntry.Remove(i); Prune.RemoveEtwCounter(i); } } }
//Timer function used to get data from Performance Counters private void OnTimerMonitor() { //empty the list to prevent duplicate, and thus failed deletions _finishedInstances.Clear(); lock (_PruneInstances) { foreach (KeyValuePair <int, PruneProcessInstance> entry in _PruneInstances) { //If the instance has been flagged as finished, add it to a list if (entry.Value.ProcessFinished) { _finishedInstances.Add(entry.Key); } else //Otherwise, we can call the get data method { entry.Value.GetData(); } } //Loop through the finished instances and remove them from the active instance list foreach (int i in _finishedInstances) { _PruneInstances.Remove(i); _processIdToWhitelistEntry.Remove(i); Prune.RemoveEtwCounter(i); } } }
private Dictionary <int, PruneProcessInstance> ParseWhitelist() { Dictionary <int, PruneProcessInstance> newInstances = new Dictionary <int, PruneProcessInstance>(); if (File.Exists(WhitelistPath)) { try { //if it does, read in all of it's lines string[] lines = File.ReadAllLines(WhitelistPath); //A dictionary so we know which of the currently monitored processes are in the whitelist Dictionary <string, bool> programFoundInWhitelist = new Dictionary <string, bool>(); //initialize all members of the list to false foreach (string value in _processIdToWhitelistEntry.Values) { if (!programFoundInWhitelist.ContainsKey(value)) { programFoundInWhitelist.Add(value, false); } } Process[] runningProcesses = Process.GetProcesses("."); //look at each line of the whitelist foreach (string line in lines) { if (!string.IsNullOrWhiteSpace(line)) { //remove starting and ending whitespace string processName = line.Trim(); //the idle and system "processes" should not be monitored, so if they are included they get skipped if (processName.Equals("0") || processName.Equals("4") || processName.Equals("idle", StringComparison.OrdinalIgnoreCase) || processName.Equals("system", StringComparison.OrdinalIgnoreCase)) { PruneEvents.PRUNE_EVENT_PROVIDER.EventWriteDISALLOWED_PROCESS_EVENT(); continue; } //if the line isn't a comment if (processName.ToCharArray()[0] != '#') { if (processName.Contains("module=") || processName.Contains("Module=")) { //Split 'module=' off, then trim white space string moduleName = processName.Split('.')[0].Trim(); //module=test.dll -> module=test string moduleFileTemp = processName.Split('=')[1].Trim(); //module=test.dll -> test.dll string moduleFile = null; string moduleProcess = null; if (moduleFileTemp.Contains(",")) { string[] moduleTempSplit = moduleFileTemp.Split(','); //module=test.dll,svchost -> test.dll,svchost moduleFile = moduleTempSplit[0].Trim(); //module=test.dll,svchost -> test.dll moduleProcess = moduleTempSplit[1].Trim(); //module=test.dll,svchost -> svchost } else { moduleFile = moduleFileTemp; } if (_processIdToWhitelistEntry.ContainsValue(moduleName)) { programFoundInWhitelist[moduleName] = true; //TODO: Continue here? If it is already in the list, we can skip this } foreach (Process proc in runningProcesses) { //ensure we don't already monitor this process and that this process is not the system or idle process if (proc.Id != 4 && proc.Id != 0 && !_processIdToWhitelistEntry.ContainsKey(proc.Id)) { if (moduleProcess == null || moduleProcess == proc.ProcessName) { try { //collect the modules from for the process List <Prune.Module> moduleList = Prune.NativeMethods.CollectModules(proc); foreach (Prune.Module module in moduleList) { //Check if this module is the one we are looking for if (module.ModuleName.Equals(moduleFile, StringComparison.OrdinalIgnoreCase)) { //It is, so add a new instances and log that it was created newInstances.Add(proc.Id, new PruneProcessInstance(true, proc.Id, moduleName, _writeCacheInterval, _logInterval, DirectoryPath)); _processIdToWhitelistEntry.Add(proc.Id, moduleName); PruneEvents.PRUNE_EVENT_PROVIDER.EventWriteCREATING_INSTANCE_EVENT(moduleName + "_" + proc.Id); //We don't need to look at the rest of the modules break; } } } catch (Exception) { //If we fail to get any modules for some reason, we need to keep going //We also don't need to report the error, because this will happen any time we try for a protected processes, // which may be often continue; } } else { } } } } else { if (_processIdToWhitelistEntry.ContainsValue(processName)) { programFoundInWhitelist[processName] = true; } string tempProcName; bool nameIsId = false; //If the name is all digits, it is treated as an ID if (processName.All(char.IsDigit)) { nameIsId = true; //Get the process name from the ID to ensure there is a process tied to this ID currently active tempProcName = Prune.GetProcessNameFromProcessId(int.Parse(processName)); if (tempProcName == null) { //Could not find a name for the given process ID. // Assume the process is not active and skip it. continue; } } else //Otherwise it is treated as a process name { tempProcName = processName; } //Get all system process objects that have the specified name Process[] processes = Prune.GetProcessesFromProcessName(tempProcName); if (processes == null || processes.Length == 0) { //Could not find any processes that have the provided name. // Assume the process is not started and skip it. continue; } if (nameIsId) { int procId = int.Parse(processName); processName = Prune.GetProcessNameFromProcessId(procId); if (!_processIdToWhitelistEntry.ContainsKey(procId)) { //Because an ID was provided, use the ID for the new instance newInstances.Add(procId, new PruneProcessInstance(true, procId, processName, _writeCacheInterval, _logInterval, DirectoryPath)); _processIdToWhitelistEntry.Add(procId, processName); PruneEvents.PRUNE_EVENT_PROVIDER.EventWriteCREATING_INSTANCE_EVENT(processName + "_" + procId); } } else { //We were given a process name, so we create a Prune instance for each process instances foreach (Process proc in processes) { int procId = proc.Id; if (!_processIdToWhitelistEntry.ContainsKey(procId)) { newInstances.Add(procId, new PruneProcessInstance(true, procId, processName, _writeCacheInterval, _logInterval, DirectoryPath)); _processIdToWhitelistEntry.Add(procId, processName); PruneEvents.PRUNE_EVENT_PROVIDER.EventWriteCREATING_INSTANCE_EVENT(processName + "_" + procId); } } } } } } } //Loop through to see which Prune instances are tied to processes no longer in the whitelist foreach (string key in programFoundInWhitelist.Keys) { if (!programFoundInWhitelist[key]) { //Make a copy of the list to iterate over so that we can remove elements from the original list Dictionary <int, string> tempList = new Dictionary <int, string>(_processIdToWhitelistEntry); lock (_PruneInstances) { //loop through the copied list of all elements that we have Prune instances for that are no longer in the whitelist foreach (KeyValuePair <int, string> entry in tempList) { if (entry.Value == key) { //call the finish monitoring method to wrap everything up _PruneInstances[entry.Key].FinishMonitoring(); //Remove the process from the list of processes monitored by ETW Prune.RemoveEtwCounter(entry.Key); //remove it form the active Prune instances _PruneInstances.Remove(entry.Key); //remove it from the active whitelist entries _processIdToWhitelistEntry.Remove(entry.Key); } } } } } } catch (Exception e) { Prune.HandleError(true, 1, "Error while reading and parsing the whitelist file\n" + e.Message); } } else { try { //If the whitelist file does not exist, create a blank text file for future use File.CreateText(WhitelistPath); PruneEvents.PRUNE_EVENT_PROVIDER.EventWriteNO_WHITELIST_EVENT(); } catch (Exception e) { Prune.HandleError(true, 1, "Error creating whitelist file\n" + e.Message); } } return(newInstances); }