FlashPatcher/FlashPatcher/FlashPatcherForm.cs

331 lines
13 KiB
C#

using Microsoft.Win32.TaskScheduler;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Security.AccessControl;
using System.Security.Principal;
using System.Text.RegularExpressions;
using System.Windows.Forms;
namespace FlashPatcher
{
public partial class FlashPatcherForm : Form
{
public FlashPatcherForm()
{
InitializeComponent();
}
public byte[] Timestamp = new byte[] { 0x00, 0x00, 0x40, 0x46, 0x3E, 0x6F, 0x77, 0x42 };
public byte[] Infintiy = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x7F };
/// <summary>
/// Locates a byte array inside a byte array,
/// used for finding the timestamp bytes
/// </summary>
/// <param name="data">data to search</param>
/// <param name="pattern">bytes to find</param>
/// <returns>Location of the found bytes, -1 if not found.</returns>
public Int64 GetPositionAfterMatch(byte[] data, byte[] pattern)
{
for (Int64 i = 0; i < data.LongLength - pattern.LongLength; i++)
{
bool match = true;
for (Int64 k = 0; k < pattern.LongLength; k++)
{
if (data[i + k] != pattern[k])
{
match = false;
break;
}
}
if (match)
{
return i;
}
}
return -1;
}
/// <summary>
/// Uses windows security api's to give program access to the files
/// this is required becuase by default the ActiveX controls are owned by TrustedInstaller.
/// </summary>
/// <param name="filepath">the file to get access to</param>
public void TakeOwn(string filepath)
{
FileSecurity fileS = File.GetAccessControl(filepath);
SecurityIdentifier cu = WindowsIdentity.GetCurrent().User;
SecurityIdentifier everyone = new SecurityIdentifier(WellKnownSidType.WorldSid, null);
try
{
Privileges.EnablePrivilege(SecurityEntity.SE_TAKE_OWNERSHIP_NAME);
}
catch(Exception)
{
console.AppendText("Failed to get SeTakeOwnershipPrivledge\r\n");
}
fileS.SetOwner(cu);
File.SetAccessControl(filepath, fileS);
fileS.SetAccessRuleProtection(false, false);
fileS.RemoveAccessRuleAll(new FileSystemAccessRule(everyone, FileSystemRights.FullControl, AccessControlType.Deny));
fileS.RemoveAccessRuleAll(new FileSystemAccessRule(cu, FileSystemRights.FullControl, AccessControlType.Deny));
fileS.SetAccessRule(new FileSystemAccessRule(everyone, FileSystemRights.FullControl, AccessControlType.Allow));
fileS.SetAccessRule(new FileSystemAccessRule(cu, FileSystemRights.FullControl, AccessControlType.Allow));
File.SetAccessControl(filepath, fileS);
File.SetAttributes(filepath, FileAttributes.Normal);
}
/// <summary>
/// Checks if a given file contains a killswitch timestamp.
/// </summary>
/// <param name="filepath">File to check.</param>
/// <returns></returns>
public bool CheckFileAndAdd(string filepath)
{
try
{
byte[] fileData = File.ReadAllBytes(filepath);
Int64 timestampLocation = GetPositionAfterMatch(fileData, Timestamp);
if (timestampLocation != -1)
{
flashExes.Items.Add(filepath);
console.AppendText("Found killswitch timestamp in " + Path.GetFileName(filepath) + " @ 0x" + timestampLocation.ToString("X") + "\r\n");
return true;
}
return false;
}
catch(Exception)
{
return false;
}
}
/// <summary>
/// Scans a folder for flash exectables, (OCX/DLL/EXE)
/// </summary>
/// <param name="path">Path to the folder</param>
public void ScanFolder(string path)
{
if(Directory.Exists(path))
{
String[] fileList = Directory.GetFiles(path, "*", SearchOption.AllDirectories);
foreach (string file in fileList)
{
if (file.ToLower().EndsWith(".ocx") || file.ToLower().EndsWith(".dll") || file.ToLower().EndsWith(".exe"))
{
CheckFileAndAdd(file);
}
}
}
}
/// <summary>
/// Patches a given Portable Executable (PE) file
/// </summary>
/// <param name="filepath">The path to the executable.</param>
/// <returns></returns>
public bool PatchExe(string filepath)
{
try
{
Process[] lockingProcesses = FileUtil.WhoIsLocking(filepath).ToArray();
foreach(Process proc in lockingProcesses)
{
DialogResult res = MessageBox.Show("Flash is currently in use by (" + proc.Id.ToString() + ")" + proc.ProcessName + "\nEnd Process?", "File in use :/", MessageBoxButtons.YesNo, MessageBoxIcon.Information);
if (res == DialogResult.Yes)
proc.Kill(); // DIE HHAHA
else
return true;
}
byte[] fileData = File.ReadAllBytes(filepath);
Int64 timestampLocation = GetPositionAfterMatch(fileData, Timestamp);
TakeOwn(filepath);
FileStream fs = File.OpenWrite(filepath);
fs.Seek(timestampLocation, SeekOrigin.Begin);
fs.Write(Infintiy, 0x00, Infintiy.Length);
fs.Close();
console.AppendText("Patched: " + Path.GetFileName(filepath) + ".\r\n");
flashExes.Items.Remove(filepath);
Application.DoEvents();
progressBar.Increment(1);
return false;
}
catch(Exception e)
{
MessageBox.Show(e.Message, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
return true;
}
}
/// <summary>
/// Locates Portable Executables (PE) files
/// of adobe flash player.
/// </summary>
public void LocateExes()
{
string windir = Environment.GetEnvironmentVariable("WINDIR");
string localappdata = Environment.GetEnvironmentVariable("LOCALAPPDATA");
// Firefox / Internet Explorer
string flashPath = Path.Combine(windir, "System32", "Macromed", "Flash"); // Win64 in win64 mode, Win32 in win32 mode
ScanFolder(flashPath);
flashPath = Path.Combine(windir, "Sysnative", "Macromed", "Flash"); // Win64 in win32 mode.
ScanFolder(flashPath);
flashPath = Path.Combine(windir, "SysWOW64", "Macromed", "Flash"); // Win32 in win64 mode
ScanFolder(flashPath);
// Chrome (<88)
flashPath = Path.Combine(localappdata, "Google", "Chrome", "User Data", "PepperFlash");
ScanFolder(flashPath);
// Edge
flashPath = Path.Combine(localappdata, "Microsoft", "Edge", "User Data", "PepperFlash");
ScanFolder(flashPath);
// Opera
flashPath = Path.Combine(localappdata, "Microsoft", "Opera Software", "Opera GX Stable", "User Data", "PepperFlash");
ScanFolder(flashPath);
flashPath = Path.Combine(localappdata, "Microsoft", "Opera Software", "Opera Stable", "User Data", "PepperFlash");
ScanFolder(flashPath);
}
private void FlashPwner_Load(object sender, EventArgs e)
{
LocateExes();
ScheduledTasksCheck();
}
private void defuseBomb_Click(object sender, EventArgs e)
{
defuseBomb.Enabled = false;
if(flashExes.Items.Count > 0)
{
progressBar.Maximum = flashExes.Items.Count;
List<string> copyFlashExes = new List<string>();
foreach (string flashExe in flashExes.Items)
{
copyFlashExes.Add(flashExe);
}
bool errored = false;
foreach (string flashExe in copyFlashExes)
{
errored = PatchExe(flashExe);
}
if(!errored)
MessageBox.Show("Patched! Your flash should work again!!!", "SUCCESS", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
MessageBox.Show("No files to patch!", "File Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
defuseBomb.Enabled = true;
}
private void addFile_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Title = "Flash Executable";
ofd.Filter = "PE Executables (*.exe, *.ocx, *.dll)|*.dll;*.exe;*.ocx|ELF Executables (*.so, *.elf, *.dylib)|*.so;*.elf;*.dylib";
DialogResult res = ofd.ShowDialog();
if(res == DialogResult.OK)
{
if (!CheckFileAndAdd(ofd.FileName))
{
MessageBox.Show("File selected does not contain the killswitch timestamp, cannot patch!", "Timestamp Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private void patchProjetor(string path)
{
byte[] projBytes = File.ReadAllBytes(path);
byte[] getUrlPattern = new byte[] { 0xF4, 0xE8, 0xBE, 0xFE, 0xFF, 0xFF };
byte[] nops = new byte[] { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 };
Int64 getUrlLocation = GetPositionAfterMatch(projBytes, getUrlPattern);
if (getUrlLocation == -1)
return;
FileStream fs = File.OpenWrite(path);
fs.Seek(getUrlLocation+1, SeekOrigin.Begin);
fs.Write(nops, 0x00, nops.Length);
fs.Close();
}
private void deleteFile_Click(object sender, EventArgs e)
{
if(flashExes.SelectedIndex >= 0)
flashExes.Items.RemoveAt(flashExes.SelectedIndex);
}
private void projectorPatch_Click(object sender, EventArgs e)
{
MessageBox.Show("This is a patch for the standalone \"projector\" program from adobe, it stops it opening your browser whenever a game tries to call javascript with getURL()\n\nNote: the projector DOES NOT HAVE A KILLSWITCH/TIMEBOMB and this is not needed to use the Flash Projector.", "Projector", MessageBoxButtons.OK, MessageBoxIcon.Information);
OpenFileDialog ofd = new OpenFileDialog();
ofd.Title = "Flash Projector";
ofd.Filter = "PE Executables (*.exe)|*.exe;|ELF Executables (*.elf)|*.elf";
DialogResult res = ofd.ShowDialog();
if(res == DialogResult.OK)
{
patchProjetor(ofd.FileName);
MessageBox.Show("Patched! Projector should no longer open the browser!!!", "SUCCESS", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
private void ScheduledTasksCheck()
{
TaskService service = new TaskService();
TaskCollection collection = service.RootFolder.GetTasks(new Regex("Adobe Flash Player .* Notifier"));
foreach(Task task in collection)
{
if (task.Enabled)
{
UninstallNag.Checked = true;
break;
}
}
this.UninstallNag.CheckedChanged += new EventHandler(this.UninstallNag_CheckedChanged);
}
private void UninstallNag_CheckedChanged(object sender, EventArgs e)
{
TaskService service = new TaskService();
TaskCollection collection = service.RootFolder.GetTasks(new Regex("Adobe Flash Player .* Notifier"));
foreach (Task task in collection)
task.Enabled = UninstallNag.Checked;
if(!UninstallNag.Checked)
MessageBox.Show("\"Please Uninstall Flash\" Nag Messages DISABLED.", "Nag Messages",MessageBoxButtons.OK, MessageBoxIcon.Information);
else
MessageBox.Show("\"Please Uninstall Flash\" Nag Messages ENABLED.", "Nag Messages", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
}