processes: Only kill processes that contain loaded Flash modules

This commit is contained in:
Disyer
2022-06-17 12:44:02 +03:00
parent 3a2615c988
commit 420aa8ac66
7 changed files with 147 additions and 58 deletions
+1 -1
View File
@@ -57,7 +57,7 @@
</Compile>
<Compile Include="InstallException.cs" />
<Compile Include="IProgressForm.cs" />
<Compile Include="ProcessRunner.cs" />
<Compile Include="ProcessUtils.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
-46
View File
@@ -1,46 +0,0 @@
using System.Diagnostics;
using System.Text;
namespace CleanFlashCommon {
public class ProcessRunner {
public static ExitedProcess RunProcess(ProcessStartInfo startInfo) {
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
StringBuilder outputBuilder = new StringBuilder();
Process process = new Process {
StartInfo = startInfo
};
DataReceivedEventHandler outputHandler = new DataReceivedEventHandler(
delegate (object sender, DataReceivedEventArgs e) {
outputBuilder.AppendLine(e.Data);
}
);
process.OutputDataReceived += outputHandler;
process.ErrorDataReceived += outputHandler;
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
process.WaitForExit();
process.CancelOutputRead();
process.CancelErrorRead();
return new ExitedProcess {
ExitCode = process.ExitCode,
Output = outputBuilder.ToString().Trim()
};
}
public static Process RunUnmanagedProcess(ProcessStartInfo startInfo) {
Process process = new Process {
StartInfo = startInfo
};
process.Start();
process.WaitForExit();
return process;
}
}
}
+115
View File
@@ -0,0 +1,115 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
namespace CleanFlashCommon {
public class ProcessUtils {
class Native {
internal enum ModuleFilter {
ListModulesDefault = 0x0,
ListModules32Bit = 0x01,
ListModules64Bit = 0x02,
ListModulesAll = 0x03,
}
[DllImport("psapi.dll")]
public static extern bool EnumProcessModulesEx(IntPtr hProcess, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.U4)][In][Out] IntPtr[] lphModule, int cb, [MarshalAs(UnmanagedType.U4)] out int lpcbNeeded, uint dwFilterFlag);
[DllImport("psapi.dll")]
public static extern bool EnumProcessModules(IntPtr hProcess, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.U4)][In][Out] IntPtr[] lphModule, int cb, [MarshalAs(UnmanagedType.U4)] out int lpcbNeeded);
[DllImport("psapi.dll")]
public static extern uint GetModuleFileNameEx(IntPtr hProcess, IntPtr hModule, [Out] StringBuilder lpBaseName, [In][MarshalAs(UnmanagedType.U4)] uint nSize);
}
public static List<string> CollectModules(Process process) {
List<string> collectedModules = new List<string>();
bool ex = true;
IntPtr[] modulePointers = new IntPtr[0];
int bytesNeeded;
// Determine number of modules
try {
if (!Native.EnumProcessModulesEx(process.Handle, modulePointers, 0, out bytesNeeded, (uint)Native.ModuleFilter.ListModulesAll)) {
return collectedModules;
}
} catch (EntryPointNotFoundException) {
if (!Native.EnumProcessModules(process.Handle, modulePointers, 0, out bytesNeeded)) {
return collectedModules;
}
ex = false;
} catch {
return collectedModules;
}
int totalModules = bytesNeeded / IntPtr.Size;
modulePointers = new IntPtr[totalModules];
// Collect modules from the process
if ((ex && !Native.EnumProcessModulesEx(process.Handle, modulePointers, bytesNeeded, out bytesNeeded, (uint) Native.ModuleFilter.ListModulesAll)) || (!ex && !Native.EnumProcessModules(process.Handle, modulePointers, bytesNeeded, out bytesNeeded))) {
return collectedModules;
}
for (int i = 0; i < totalModules; ++i) {
StringBuilder moduleFilePath = new StringBuilder(1024);
Native.GetModuleFileNameEx(process.Handle, modulePointers[i], moduleFilePath, (uint) moduleFilePath.Capacity);
string moduleName = Path.GetFileName(moduleFilePath.ToString());
collectedModules.Add(moduleName);
}
return collectedModules;
}
public static ExitedProcess RunProcess(ProcessStartInfo startInfo)
{
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
StringBuilder outputBuilder = new StringBuilder();
Process process = new Process
{
StartInfo = startInfo
};
DataReceivedEventHandler outputHandler = new DataReceivedEventHandler(
delegate (object sender, DataReceivedEventArgs e) {
outputBuilder.AppendLine(e.Data);
}
);
process.OutputDataReceived += outputHandler;
process.ErrorDataReceived += outputHandler;
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
process.WaitForExit();
process.CancelOutputRead();
process.CancelErrorRead();
return new ExitedProcess
{
ExitCode = process.ExitCode,
Output = outputBuilder.ToString().Trim()
};
}
public static Process RunUnmanagedProcess(ProcessStartInfo startInfo)
{
Process process = new Process
{
StartInfo = startInfo
};
process.Start();
process.WaitForExit();
return process;
}
}
}
+1 -1
View File
@@ -14,7 +14,7 @@ namespace CleanFlashCommon {
Directory.SetCurrentDirectory(Path.GetDirectoryName(filename));
ExitedProcess process = ProcessRunner.RunProcess(
ExitedProcess process = ProcessUtils.RunProcess(
new ProcessStartInfo {
FileName = "reg.exe",
Arguments = "import " + Path.GetFileName(filename),
+27 -7
View File
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
namespace CleanFlashCommon {
public class Uninstaller {
@@ -12,10 +13,14 @@ namespace CleanFlashCommon {
"flashcenterservice", "flashcenteruninst", "flashplay", "update", "wow_helper",
"dummy_cmd", "flashhelperservice",
// Flash Player-related processes
"flashplayerapp", "flashplayer_sa", "flashplayer_sa_debug",
"flashplayerapp", "flashplayer_sa", "flashplayer_sa_debug"
};
private static string[] CONDITIONAL_PROCESSES = new string[]
{
// Plugin container for Firefox
"plugin-container",
// Browsers that might be using Flash Player right now
"opera", "iexplore", "chrome", "chromium", "brave", "vivaldi", "basilisk", "msedge",
"seamonkey", "palemoon", "k-meleon", "plugin-container", "waterfox"
"opera", "iexplore", "chrome", "chromium", "brave", "vivaldi", "msedge"
};
static Uninstaller() {
@@ -31,7 +36,7 @@ namespace CleanFlashCommon {
}
public static void DeleteTask(string task) {
ProcessRunner.RunUnmanagedProcess(
ProcessUtils.RunUnmanagedProcess(
new ProcessStartInfo {
FileName = "schtasks.exe",
Arguments = "/delete /tn \"" + task + "\" /f",
@@ -42,7 +47,7 @@ namespace CleanFlashCommon {
}
public static void StopService(string service) {
ProcessRunner.RunUnmanagedProcess(
ProcessUtils.RunUnmanagedProcess(
new ProcessStartInfo {
FileName = "net.exe",
Arguments = "stop \"" + service + "\"",
@@ -56,7 +61,7 @@ namespace CleanFlashCommon {
// First, stop the service.
StopService(service);
ProcessRunner.RunUnmanagedProcess(
ProcessUtils.RunUnmanagedProcess(
new ProcessStartInfo {
FileName = "sc.exe",
Arguments = "delete \"" + service + "\"",
@@ -125,10 +130,25 @@ namespace CleanFlashCommon {
}
}
public static bool ShouldKillConditionalProcess(Process process) {
if (!CONDITIONAL_PROCESSES.Contains(process.ProcessName.ToLower())) {
return false;
}
foreach (string module in ProcessUtils.CollectModules(process)) {
if (Regex.IsMatch(module, "^(flash(32|64)|libpepflash|npswf)", RegexOptions.Compiled | RegexOptions.IgnoreCase)) {
return true;
}
}
return false;
}
public static void StopProcesses() {
// Stop all processes that might interfere with the install process
List<Process> processes = Process.GetProcesses()
.Where(process => PROCESSES_TO_KILL.Contains(process.ProcessName.ToLower()))
.Where(process => PROCESSES_TO_KILL.Contains(process.ProcessName.ToLower()) || ShouldKillConditionalProcess(process))
.OrderBy(o => o.StartTime)
.ToList();