diff --git a/NOP.sln b/NOP.sln index 036cadd..7e7b09f 100644 --- a/NOP.sln +++ b/NOP.sln @@ -2,22 +2,13 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.7.34031.279 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "loader", "GDRVLoader.vcxproj", "{C2F662DB-3ED6-47EE-A331-2EBE11AA36C3}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "installer", "NOP\installer\installer.vcxproj", "{592D31AB-A734-4DEE-B85F-57BB67759963}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "worker", "NOP\worker\worker.vcxproj", "{8480DA70-45E9-4D91-A89C-24B27D0F4924}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "gui", "NOP\gui\gui.csproj", "{E109B8FE-CAD8-466A-9502-9AD85ED78B45}" ProjectSection(ProjectDependencies) = postProject - {592D31AB-A734-4DEE-B85F-57BB67759963} = {592D31AB-A734-4DEE-B85F-57BB67759963} {8480DA70-45E9-4D91-A89C-24B27D0F4924} = {8480DA70-45E9-4D91-A89C-24B27D0F4924} - {AAFAF49F-EE20-4E9F-AE53-5254457AB141} = {AAFAF49F-EE20-4E9F-AE53-5254457AB141} - {C2F662DB-3ED6-47EE-A331-2EBE11AA36C3} = {C2F662DB-3ED6-47EE-A331-2EBE11AA36C3} EndProjectSection EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "loader2", "NOP\loader2\DSE-Patcher.vcxproj", "{AAFAF49F-EE20-4E9F-AE53-5254457AB141}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -30,38 +21,6 @@ Global Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {C2F662DB-3ED6-47EE-A331-2EBE11AA36C3}.Debug|Any CPU.ActiveCfg = Debug|x64 - {C2F662DB-3ED6-47EE-A331-2EBE11AA36C3}.Debug|Any CPU.Build.0 = Debug|x64 - {C2F662DB-3ED6-47EE-A331-2EBE11AA36C3}.Debug|ARM64.ActiveCfg = Debug|x64 - {C2F662DB-3ED6-47EE-A331-2EBE11AA36C3}.Debug|ARM64.Build.0 = Debug|x64 - {C2F662DB-3ED6-47EE-A331-2EBE11AA36C3}.Debug|x64.ActiveCfg = Release|x64 - {C2F662DB-3ED6-47EE-A331-2EBE11AA36C3}.Debug|x64.Build.0 = Release|x64 - {C2F662DB-3ED6-47EE-A331-2EBE11AA36C3}.Debug|x86.ActiveCfg = Debug|x64 - {C2F662DB-3ED6-47EE-A331-2EBE11AA36C3}.Debug|x86.Build.0 = Debug|x64 - {C2F662DB-3ED6-47EE-A331-2EBE11AA36C3}.Release|Any CPU.ActiveCfg = Release|x64 - {C2F662DB-3ED6-47EE-A331-2EBE11AA36C3}.Release|Any CPU.Build.0 = Release|x64 - {C2F662DB-3ED6-47EE-A331-2EBE11AA36C3}.Release|ARM64.ActiveCfg = Release|x64 - {C2F662DB-3ED6-47EE-A331-2EBE11AA36C3}.Release|ARM64.Build.0 = Release|x64 - {C2F662DB-3ED6-47EE-A331-2EBE11AA36C3}.Release|x64.ActiveCfg = Release|x64 - {C2F662DB-3ED6-47EE-A331-2EBE11AA36C3}.Release|x64.Build.0 = Release|x64 - {C2F662DB-3ED6-47EE-A331-2EBE11AA36C3}.Release|x86.ActiveCfg = Release|x64 - {C2F662DB-3ED6-47EE-A331-2EBE11AA36C3}.Release|x86.Build.0 = Release|x64 - {592D31AB-A734-4DEE-B85F-57BB67759963}.Debug|Any CPU.ActiveCfg = Debug|x64 - {592D31AB-A734-4DEE-B85F-57BB67759963}.Debug|Any CPU.Build.0 = Debug|x64 - {592D31AB-A734-4DEE-B85F-57BB67759963}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {592D31AB-A734-4DEE-B85F-57BB67759963}.Debug|ARM64.Build.0 = Debug|ARM64 - {592D31AB-A734-4DEE-B85F-57BB67759963}.Debug|x64.ActiveCfg = Debug|x64 - {592D31AB-A734-4DEE-B85F-57BB67759963}.Debug|x64.Build.0 = Debug|x64 - {592D31AB-A734-4DEE-B85F-57BB67759963}.Debug|x86.ActiveCfg = Debug|x64 - {592D31AB-A734-4DEE-B85F-57BB67759963}.Debug|x86.Build.0 = Debug|x64 - {592D31AB-A734-4DEE-B85F-57BB67759963}.Release|Any CPU.ActiveCfg = Release|x64 - {592D31AB-A734-4DEE-B85F-57BB67759963}.Release|Any CPU.Build.0 = Release|x64 - {592D31AB-A734-4DEE-B85F-57BB67759963}.Release|ARM64.ActiveCfg = Release|ARM64 - {592D31AB-A734-4DEE-B85F-57BB67759963}.Release|ARM64.Build.0 = Release|ARM64 - {592D31AB-A734-4DEE-B85F-57BB67759963}.Release|x64.ActiveCfg = Release|x64 - {592D31AB-A734-4DEE-B85F-57BB67759963}.Release|x64.Build.0 = Release|x64 - {592D31AB-A734-4DEE-B85F-57BB67759963}.Release|x86.ActiveCfg = Release|x64 - {592D31AB-A734-4DEE-B85F-57BB67759963}.Release|x86.Build.0 = Release|x64 {8480DA70-45E9-4D91-A89C-24B27D0F4924}.Debug|Any CPU.ActiveCfg = Debug|x64 {8480DA70-45E9-4D91-A89C-24B27D0F4924}.Debug|Any CPU.Build.0 = Debug|x64 {8480DA70-45E9-4D91-A89C-24B27D0F4924}.Debug|ARM64.ActiveCfg = Debug|x64 @@ -94,22 +53,6 @@ Global {E109B8FE-CAD8-466A-9502-9AD85ED78B45}.Release|x64.Build.0 = Debug|Any CPU {E109B8FE-CAD8-466A-9502-9AD85ED78B45}.Release|x86.ActiveCfg = Release|Any CPU {E109B8FE-CAD8-466A-9502-9AD85ED78B45}.Release|x86.Build.0 = Release|Any CPU - {AAFAF49F-EE20-4E9F-AE53-5254457AB141}.Debug|Any CPU.ActiveCfg = Debug|x64 - {AAFAF49F-EE20-4E9F-AE53-5254457AB141}.Debug|Any CPU.Build.0 = Debug|x64 - {AAFAF49F-EE20-4E9F-AE53-5254457AB141}.Debug|ARM64.ActiveCfg = Debug|x64 - {AAFAF49F-EE20-4E9F-AE53-5254457AB141}.Debug|ARM64.Build.0 = Debug|x64 - {AAFAF49F-EE20-4E9F-AE53-5254457AB141}.Debug|x64.ActiveCfg = Debug|x64 - {AAFAF49F-EE20-4E9F-AE53-5254457AB141}.Debug|x64.Build.0 = Debug|x64 - {AAFAF49F-EE20-4E9F-AE53-5254457AB141}.Debug|x86.ActiveCfg = Debug|Win32 - {AAFAF49F-EE20-4E9F-AE53-5254457AB141}.Debug|x86.Build.0 = Debug|Win32 - {AAFAF49F-EE20-4E9F-AE53-5254457AB141}.Release|Any CPU.ActiveCfg = Release|x64 - {AAFAF49F-EE20-4E9F-AE53-5254457AB141}.Release|Any CPU.Build.0 = Release|x64 - {AAFAF49F-EE20-4E9F-AE53-5254457AB141}.Release|ARM64.ActiveCfg = Release|x64 - {AAFAF49F-EE20-4E9F-AE53-5254457AB141}.Release|ARM64.Build.0 = Release|x64 - {AAFAF49F-EE20-4E9F-AE53-5254457AB141}.Release|x64.ActiveCfg = Release|x64 - {AAFAF49F-EE20-4E9F-AE53-5254457AB141}.Release|x64.Build.0 = Release|x64 - {AAFAF49F-EE20-4E9F-AE53-5254457AB141}.Release|x86.ActiveCfg = Release|Win32 - {AAFAF49F-EE20-4E9F-AE53-5254457AB141}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/NOP/gui/Form1.Designer.cs b/NOP/gui/Form1.Designer.cs index f7ceb06..a22beca 100644 --- a/NOP/gui/Form1.Designer.cs +++ b/NOP/gui/Form1.Designer.cs @@ -48,6 +48,7 @@ private void InitializeComponent() chkF12 = new CheckBox(); label5 = new Label(); chkDisableToDoIcon = new CheckBox(); + btnUninstall = new Button(); SuspendLayout(); // // label1 @@ -183,7 +184,7 @@ private void InitializeComponent() btnApplyRestart.Name = "btnApplyRestart"; btnApplyRestart.Size = new Size(98, 29); btnApplyRestart.TabIndex = 11; - btnApplyRestart.Text = "&Patch"; + btnApplyRestart.Text = "&Install"; btnApplyRestart.UseVisualStyleBackColor = true; btnApplyRestart.Click += btnApplyRestart_Click; // @@ -245,7 +246,7 @@ private void InitializeComponent() label5.Name = "label5"; label5.Size = new Size(391, 33); label5.TabIndex = 16; - label5.Text = "Pressing \"Patch\" will close Outlook (olk.exe), apply your settings and restart Outlook (olk.exe) for you."; + label5.Text = "Pressing \"Install\" will close Outlook (olk.exe), apply your settings and restart Outlook (olk.exe) for you."; // // chkDisableToDoIcon // @@ -260,12 +261,25 @@ private void InitializeComponent() chkDisableToDoIcon.UseVisualStyleBackColor = true; chkDisableToDoIcon.CheckedChanged += chkDisableAll_CheckedChanged; // + // btnUninstall + // + btnUninstall.Anchor = AnchorStyles.Bottom | AnchorStyles.Left; + btnUninstall.Enabled = false; + btnUninstall.Location = new Point(196, 428); + btnUninstall.Name = "btnUninstall"; + btnUninstall.Size = new Size(98, 29); + btnUninstall.TabIndex = 18; + btnUninstall.Text = "&Uninstall"; + btnUninstall.UseVisualStyleBackColor = true; + btnUninstall.Click += btnApplyRestart_Click; + // // Form1 // AcceptButton = btnApplyRestart; AutoScaleDimensions = new SizeF(7F, 15F); AutoScaleMode = AutoScaleMode.Font; ClientSize = new Size(410, 469); + Controls.Add(btnUninstall); Controls.Add(chkDisableToDoIcon); Controls.Add(label5); Controls.Add(chkF12); @@ -320,5 +334,6 @@ private void InitializeComponent() private CheckBox chkF12; private Label label5; private CheckBox chkDisableToDoIcon; + private Button btnUninstall; } } diff --git a/NOP/gui/Form1.cs b/NOP/gui/Form1.cs index 222aa03..c6634e8 100644 --- a/NOP/gui/Form1.cs +++ b/NOP/gui/Form1.cs @@ -1,4 +1,5 @@ using Microsoft.VisualBasic.ApplicationServices; +using Microsoft.Win32; using System.Diagnostics; using System.IO; using System.Reflection; @@ -6,6 +7,7 @@ using System.Security.Principal; using System.Text; using System.Windows.Forms.VisualStyles; +using System.Xml.Linq; namespace gui { @@ -43,7 +45,7 @@ public static bool IsAdministrator() } // https://stackoverflow.com/questions/10702514/most-efficient-way-to-replace-one-sequence-of-the-bytes-with-some-other-sequence - private static byte[] BytesReplace(byte[] input, byte[] pattern, byte[] replacement, bool keepSize = true) + private static byte[] BytesReplace(byte[] input, byte[] pattern, byte[] replacement, ref int numMatches, bool keepSize = true) { if (pattern.Length == 0) { @@ -68,6 +70,7 @@ private static byte[] BytesReplace(byte[] input, byte[] pattern, byte[] replacem if (foundMatch) { + numMatches++; result.AddRange(replacement); i += keepSize ? (replacement.Length - 1) : (pattern.Length - 1); } @@ -85,14 +88,92 @@ private static byte[] BytesReplace(byte[] input, byte[] pattern, byte[] replacem return result.ToArray(); } + public static bool IsPatcherInstalled() + { + bool isFileDropped = File.Exists(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "NewOutlookPatcher.dll")); + bool isVerifierEnabled = false; + bool isSetAsVerifierDll = false; + + RegistryKey localMachine = RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, RegistryView.Registry64); + var reg = localMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\olk.exe", false); + if (reg != null) + { + var obj1 = reg.GetValue("GlobalFlag"); + if (obj1 != null) + { + isVerifierEnabled = ((((int)obj1) & 0x100) == 0x100); + } + var obj2 = reg.GetValue("VerifierDlls"); + if (obj2 != null) + { + string verifierDlls = (string)obj2; + isSetAsVerifierDll = verifierDlls.Contains("NewOutlookPatcher.dll"); + } + } + return isFileDropped && isVerifierEnabled && isSetAsVerifierDll; + } + + public void FormatUI(bool patcherInstalled) + { + if (patcherInstalled) + { + btnApplyRestart.Text = "&Apply"; + btnUninstall.Enabled = true; + label5.Text = label5.Text.Replace("Install", "Apply"); + } + else + { + btnApplyRestart.Text = "&Install"; + btnUninstall.Enabled = false; + label5.Text = label5.Text.Replace("Apply", "Install"); + } + } + public Form1() { InitializeComponent(); if (!IsAdministrator()) AddShieldToButton(btnApplyRestart); + if (!IsAdministrator()) AddShieldToButton(btnUninstall); } private void Form1_Load(object sender, EventArgs e) { + // Update UI to reflect install status + FormatUI(IsPatcherInstalled()); + + // Load current settings + if (IsPatcherInstalled()) + { + byte[] buffer = File.ReadAllBytes(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "NewOutlookPatcher.dll")); + int numMatches = 0; + buffer = BytesReplace(buffer, Encoding.Unicode.GetBytes("#OwaContainer, "), Encoding.Unicode.GetBytes(" "), ref numMatches); + chkDisableFirstMailAd.Checked = (numMatches > 0); + numMatches = 0; + buffer = BytesReplace(buffer, Encoding.Unicode.GetBytes(".syTot, "), Encoding.Unicode.GetBytes(" "), ref numMatches); + chkDisableOneDriveBanner.Checked = (numMatches > 0); + numMatches = 0; + buffer = BytesReplace(buffer, Encoding.Unicode.GetBytes("[id='34318026-c018-414b-abb3-3e32dfb9cc4c'], "), Encoding.Unicode.GetBytes(" "), ref numMatches); + chkDisableWordIcon.Checked = (numMatches > 0); + numMatches = 0; + buffer = BytesReplace(buffer, Encoding.Unicode.GetBytes("[id='c5251a9b-a95d-4595-91ee-a39e6eed3db2'], "), Encoding.Unicode.GetBytes(" "), ref numMatches); + chkDisableExcelIcon.Checked = (numMatches > 0); + numMatches = 0; + buffer = BytesReplace(buffer, Encoding.Unicode.GetBytes("[id='48cb9ead-1c19-4e1f-8ed9-3d60a7e52b18'], "), Encoding.Unicode.GetBytes(" "), ref numMatches); + chkDisablePowerPointIcon.Checked = (numMatches > 0); + numMatches = 0; + buffer = BytesReplace(buffer, Encoding.Unicode.GetBytes("[id='59391057-d7d7-49fd-a041-d8e4080f05ec'], "), Encoding.Unicode.GetBytes(" "), ref numMatches); + chkDisableToDoIcon.Checked = (numMatches > 0); + numMatches = 0; + buffer = BytesReplace(buffer, Encoding.Unicode.GetBytes("[id='39109bd4-9389-4731-b8d6-7cc1a128d0b3'], "), Encoding.Unicode.GetBytes(" "), ref numMatches); + chkDisableOneDriveIcon.Checked = (numMatches > 0); + numMatches = 0; + buffer = BytesReplace(buffer, Encoding.Unicode.GetBytes(".___1fkhojs.f22iagw.f122n59.f1vx9l62.f1c21dwh.fqerorx.f1i5mqs4, "), Encoding.Unicode.GetBytes(" "), ref numMatches); + chkDisableMoreAppsIcon.Checked = (numMatches > 0); + numMatches = 0; + buffer = BytesReplace(buffer, Encoding.Unicode.GetBytes("y_1A36CD25-E20F-4D0D-B1E6-3CC4307E1488"), Encoding.Unicode.GetBytes("n"), ref numMatches); + chkF12.Checked = (numMatches > 0); + } + Process[] processes = Process.GetProcessesByName("olk"); if (processes.Length > 0 && processes[0].MainModule != null) { @@ -145,7 +226,11 @@ private void btnApplyRestart_Click(object sender, EventArgs e) { this.TopMost = false; - bool uninstall = !chkDisableFirstMailAd.Checked && !chkDisableOneDriveBanner.Checked && !chkDisableWordIcon.Checked && !chkDisableExcelIcon.Checked && !chkDisablePowerPointIcon.Checked && !chkDisableToDoIcon.Checked && !chkDisableOneDriveIcon.Checked && !chkDisableMoreAppsIcon.Checked && !chkF12.Checked; + bool uninstall = ((!chkDisableFirstMailAd.Checked && !chkDisableOneDriveBanner.Checked && !chkDisableWordIcon.Checked && !chkDisableExcelIcon.Checked && !chkDisablePowerPointIcon.Checked && !chkDisableToDoIcon.Checked && !chkDisableOneDriveIcon.Checked && !chkDisableMoreAppsIcon.Checked && !chkF12.Checked) || (sender == btnUninstall)); + + string exeName = "Press Yes to apply new settings to olk.exe"; + if (!IsPatcherInstalled()) exeName = "Press Yes to install patcher in olk.exe"; + if (uninstall) exeName = "Press Yes to uninstall patcher from olk.exe"; // Create scratch dir string tempFolderPath = Path.GetTempPath(); @@ -161,110 +246,58 @@ private void btnApplyRestart_Click(object sender, EventArgs e) return; } - Assembly assembly = Assembly.GetExecutingAssembly(); - // Extract worker to scratch dir - string workerResourceName = "gui.dxgi.dll"; - string workerPath = Path.Combine(tempFolderName, "dxgi.dll"); - try - { - using (Stream resourceStream = assembly.GetManifestResourceStream(workerResourceName)) + if (!uninstall) { + Assembly assembly = Assembly.GetExecutingAssembly(); + string workerResourceName = "gui.dxgi.dll"; + string workerPath = Path.Combine(tempFolderName, "NewOutlookPatcher.dll"); + try { - if (resourceStream != null) + using (Stream resourceStream = assembly.GetManifestResourceStream(workerResourceName)) { - byte[] buffer = new byte[resourceStream.Length]; - resourceStream.Read(buffer, 0, buffer.Length); - if (!chkDisableFirstMailAd.Checked) + if (resourceStream != null) { - buffer = BytesReplace(buffer, Encoding.Unicode.GetBytes("#OwaContainer, "), Encoding.Unicode.GetBytes(" ")); - buffer = BytesReplace(buffer, Encoding.Unicode.GetBytes(".kk1xx._Bfyd.iIsOF.IjQyD, "), Encoding.Unicode.GetBytes(" ")); + int numMatches = 0; + byte[] buffer = new byte[resourceStream.Length]; + resourceStream.Read(buffer, 0, buffer.Length); + if (!chkDisableFirstMailAd.Checked) + { + buffer = BytesReplace(buffer, Encoding.Unicode.GetBytes("#OwaContainer, "), Encoding.Unicode.GetBytes(" "), ref numMatches); + buffer = BytesReplace(buffer, Encoding.Unicode.GetBytes(".kk1xx._Bfyd.iIsOF.IjQyD, "), Encoding.Unicode.GetBytes(" "), ref numMatches); + } + if (!chkDisableOneDriveBanner.Checked) + buffer = BytesReplace(buffer, Encoding.Unicode.GetBytes(".syTot, "), Encoding.Unicode.GetBytes(" "), ref numMatches); + if (!chkDisableWordIcon.Checked) + buffer = BytesReplace(buffer, Encoding.Unicode.GetBytes("[id='34318026-c018-414b-abb3-3e32dfb9cc4c'], "), Encoding.Unicode.GetBytes(" "), ref numMatches); + if (!chkDisableExcelIcon.Checked) + buffer = BytesReplace(buffer, Encoding.Unicode.GetBytes("[id='c5251a9b-a95d-4595-91ee-a39e6eed3db2'], "), Encoding.Unicode.GetBytes(" "), ref numMatches); + if (!chkDisablePowerPointIcon.Checked) + buffer = BytesReplace(buffer, Encoding.Unicode.GetBytes("[id='48cb9ead-1c19-4e1f-8ed9-3d60a7e52b18'], "), Encoding.Unicode.GetBytes(" "), ref numMatches); + if (!chkDisableToDoIcon.Checked) + buffer = BytesReplace(buffer, Encoding.Unicode.GetBytes("[id='59391057-d7d7-49fd-a041-d8e4080f05ec'], "), Encoding.Unicode.GetBytes(" "), ref numMatches); + if (!chkDisableOneDriveIcon.Checked) + buffer = BytesReplace(buffer, Encoding.Unicode.GetBytes("[id='39109bd4-9389-4731-b8d6-7cc1a128d0b3'], "), Encoding.Unicode.GetBytes(" "), ref numMatches); + if (!chkDisableMoreAppsIcon.Checked) + buffer = BytesReplace(buffer, Encoding.Unicode.GetBytes(".___1fkhojs.f22iagw.f122n59.f1vx9l62.f1c21dwh.fqerorx.f1i5mqs4, "), Encoding.Unicode.GetBytes(" "), ref numMatches); + if (!chkF12.Checked) + buffer = BytesReplace(buffer, Encoding.Unicode.GetBytes("y_1A36CD25-E20F-4D0D-B1E6-3CC4307E1488"), Encoding.Unicode.GetBytes("n"), ref numMatches); + + File.WriteAllBytes(workerPath, buffer); } - if (!chkDisableOneDriveBanner.Checked) - buffer = BytesReplace(buffer, Encoding.Unicode.GetBytes(".syTot, "), Encoding.Unicode.GetBytes(" ")); - if (!chkDisableWordIcon.Checked) - buffer = BytesReplace(buffer, Encoding.Unicode.GetBytes("[id='34318026-c018-414b-abb3-3e32dfb9cc4c'], "), Encoding.Unicode.GetBytes(" ")); - if (!chkDisableExcelIcon.Checked) - buffer = BytesReplace(buffer, Encoding.Unicode.GetBytes("[id='c5251a9b-a95d-4595-91ee-a39e6eed3db2'], "), Encoding.Unicode.GetBytes(" ")); - if (!chkDisablePowerPointIcon.Checked) - buffer = BytesReplace(buffer, Encoding.Unicode.GetBytes("[id='48cb9ead-1c19-4e1f-8ed9-3d60a7e52b18'], "), Encoding.Unicode.GetBytes(" ")); - if (!chkDisableToDoIcon.Checked) - buffer = BytesReplace(buffer, Encoding.Unicode.GetBytes("[id='59391057-d7d7-49fd-a041-d8e4080f05ec'], "), Encoding.Unicode.GetBytes(" ")); - if (!chkDisableOneDriveIcon.Checked) - buffer = BytesReplace(buffer, Encoding.Unicode.GetBytes("[id='39109bd4-9389-4731-b8d6-7cc1a128d0b3'], "), Encoding.Unicode.GetBytes(" ")); - if (!chkDisableMoreAppsIcon.Checked) - buffer = BytesReplace(buffer, Encoding.Unicode.GetBytes(".___1fkhojs.f22iagw.f122n59.f1vx9l62.f1c21dwh.fqerorx.f1i5mqs4, "), Encoding.Unicode.GetBytes(" ")); - if (!chkF12.Checked) - buffer = BytesReplace(buffer, Encoding.Unicode.GetBytes("y_1A36CD25-E20F-4D0D-B1E6-3CC4307E1488"), Encoding.Unicode.GetBytes("n")); - - File.WriteAllBytes(workerPath, buffer); - } - } - } - catch (Exception ex) - { - MessageBox.Show("Unable to extract worker resource.", "NewOutlookPatcher", MessageBoxButtons.OK, MessageBoxIcon.Error); - this.TopMost = true; - return; - } - - // Extract driver to scratch dir - string driverResourceName = "gui.installer.sys"; - string driverPath = Path.Combine(tempFolderName, "installer.sys"); - try - { - using (Stream resourceStream = assembly.GetManifestResourceStream(driverResourceName)) - { - if (resourceStream != null) - { - byte[] buffer = new byte[resourceStream.Length]; - resourceStream.Read(buffer, 0, buffer.Length); - File.WriteAllBytes(driverPath, BytesReplace(BytesReplace(buffer, Encoding.Unicode.GetBytes("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"), Encoding.Unicode.GetBytes(uninstall ? "ZwDeleteFile" : workerPath).Concat(new byte[2] { 0x00, 0x00 }).ToArray()), Encoding.Unicode.GetBytes("BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"), Encoding.Unicode.GetBytes(Path.Combine(txtPath.Text, "dxgi.dll")).Concat(new byte[2] { 0x00, 0x00 }).ToArray())); } } - } - catch (Exception ex) - { - MessageBox.Show("Unable to extract driver resource.", "NewOutlookPatcher", MessageBoxButtons.OK, MessageBoxIcon.Error); - this.TopMost = true; - return; - } - - // Extract loader to scratch dir - string loaderResourceName = "gui.loader.exe"; - string loaderPath = Path.Combine(tempFolderName, "loader.exe"); - try - { - using (Stream resourceStream = assembly.GetManifestResourceStream(loaderResourceName)) + catch (Exception ex) { - if (resourceStream != null) - { - byte[] buffer = new byte[resourceStream.Length]; - resourceStream.Read(buffer, 0, buffer.Length); - File.WriteAllBytes(loaderPath, BytesReplace(buffer, Encoding.Unicode.GetBytes("CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"), Encoding.Unicode.GetBytes(driverPath).Concat(new byte[2] { 0x00, 0x00 }).ToArray())); - } + MessageBox.Show("Unable to extract worker resource.", "NewOutlookPatcher", MessageBoxButtons.OK, MessageBoxIcon.Error); + this.TopMost = true; + return; } } - catch (Exception ex) - { - MessageBox.Show("Unable to extract driver resource.", "NewOutlookPatcher", MessageBoxButtons.OK, MessageBoxIcon.Error); - this.TopMost = true; - return; - } - // Extract loader2 to scratch dir - string loader2ResourceName = "gui.loader2.exe"; - string loader2Path = Path.Combine(tempFolderName, "Press Yes to apply settings to olk.exe"); + // Customize UAC prompt try { - using (Stream resourceStream = assembly.GetManifestResourceStream(loader2ResourceName)) - { - if (resourceStream != null) - { - byte[] buffer = new byte[resourceStream.Length]; - resourceStream.Read(buffer, 0, buffer.Length); - File.WriteAllBytes(loader2Path, BytesReplace(buffer, Encoding.Unicode.GetBytes("DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD"), Encoding.Unicode.GetBytes(loaderPath).Concat(new byte[2] { 0x00, 0x00 }).ToArray())); - } - } + File.Copy(Application.ExecutablePath, Path.Combine(tempFolderName, exeName), true); } catch (Exception ex) { @@ -284,7 +317,8 @@ private void btnApplyRestart_Click(object sender, EventArgs e) processes[0].Kill(); } ProcessStartInfo psi = new ProcessStartInfo(); - psi.FileName = loader2Path; + psi.FileName = Path.Combine(tempFolderName, exeName); + psi.Arguments = uninstall ? "--uninstall" : ("--install \"" + tempFolderName + "\""); psi.UseShellExecute = true; psi.Verb = "runas"; System.Diagnostics.Process.Start(psi).WaitForExit(); @@ -321,6 +355,9 @@ private void btnApplyRestart_Click(object sender, EventArgs e) } + // Update UI to reflect install status + FormatUI(IsPatcherInstalled()); + this.TopMost = true; } diff --git a/NOP/gui/Program.cs b/NOP/gui/Program.cs index 6e0596a..1dbdd4f 100644 --- a/NOP/gui/Program.cs +++ b/NOP/gui/Program.cs @@ -1,3 +1,5 @@ +using Microsoft.Win32; + namespace gui { internal static class Program @@ -6,8 +8,120 @@ internal static class Program /// The main entry point for the application. /// [STAThread] - static void Main() + static void Main(string[] args) { + string tempFolderName = ""; + foreach (var arg in args) + { + tempFolderName = arg; + } + if (tempFolderName != "") + { + if (tempFolderName == "--uninstall") + { + try + { + RegistryKey localMachine = RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, RegistryView.Registry64); + var reg = localMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\olk.exe", true); + if (reg != null) + { + bool stillIsVerified = false; + var obj2 = reg.GetValue("VerifierDlls"); + if (obj2 != null) + { + string verifierDlls = (string)obj2; + verifierDlls = verifierDlls.Replace(" NewOutlookPatcher.dll", ""); + verifierDlls = verifierDlls.Replace("NewOutlookPatcher.dll ", ""); + verifierDlls = verifierDlls.Replace("NewOutlookPatcher.dll", ""); + if (verifierDlls == "") + { + reg.DeleteValue("VerifierDlls"); + } + else + { + reg.SetValue("VerifierDlls", verifierDlls); + stillIsVerified = true; + } + } + + var obj1 = reg.GetValue("GlobalFlag"); + if (obj1 != null) + { + int val = (int)obj1; + if (!stillIsVerified) + { + val = val & ~0x100; + if (val == 0) + { + reg.DeleteValue("GlobalFlag"); + } + else + { + reg.SetValue("GlobalFlag", val); + } + } + } + + if (!(reg.SubKeyCount > 0 || reg.ValueCount > 0)) + { + reg.Close(); + localMachine.DeleteSubKeyTree("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\olk.exe", false); + } + } + File.Delete(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "NewOutlookPatcher.dll")); + } + catch { } + } + else + { + try + { + File.Copy(Path.Combine(tempFolderName, "NewOutlookPatcher.dll"), Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "NewOutlookPatcher.dll"), true); + } + catch { } + finally + { + try + { + RegistryKey localMachine = RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, RegistryView.Registry64); + var reg = localMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\olk.exe", true); + if (reg == null) + { + reg = localMachine.CreateSubKey("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\olk.exe"); + } + + var obj1 = reg.GetValue("GlobalFlag"); + if (obj1 != null) + { + int val = (int)obj1; + val = val | 0x100; + reg.SetValue("GlobalFlag", val); + } + else + { + reg.SetValue("GlobalFlag", 0x100); + } + + var obj2 = reg.GetValue("VerifierDlls"); + if (obj2 != null) + { + string verifierDlls = (string)obj2; + if (!verifierDlls.Contains(" NewOutlookPatcher.dll") && !verifierDlls.Contains("NewOutlookPatcher.dll ") && verifierDlls != "NewOutlookPatcher.dll") + { + verifierDlls += " NewOutlookPatcher.dll"; + reg.SetValue("VerifierDlls", verifierDlls); + } + } + else + { + reg.SetValue("VerifierDlls", "NewOutlookPatcher.dll"); + } + } + catch { } + } + } + Environment.Exit(0); + } // To customize application configuration such as set high DPI settings or default font, // see https://aka.ms/applicationconfiguration. ApplicationConfiguration.Initialize(); diff --git a/NOP/gui/gui.csproj b/NOP/gui/gui.csproj index d2e5182..dc8cc8f 100644 --- a/NOP/gui/gui.csproj +++ b/NOP/gui/gui.csproj @@ -3,17 +3,18 @@ WinExe net8.0-windows + win-x64 enable true enable true NewOutlookPatcher - 2024.03.15.03 - 2024.03.15.03 + 2024.06.24.01 + 2024.06.24.01 https://github.com/valinet/NewOutlookPatcher Copyright 2024 VALINET Solutions. All rights reserved. Disable ads and product placement in the new Outlook for Windows app. - 2024.03.15.03 + 2024.06.24.01 true NewOutlookPatcher NewOutlookPatcher @@ -30,9 +31,6 @@ - - - \ No newline at end of file diff --git a/NOP/worker/dllmain.cpp b/NOP/worker/dllmain.cpp index 724adaa..e7a903d 100644 --- a/NOP/worker/dllmain.cpp +++ b/NOP/worker/dllmain.cpp @@ -77,39 +77,76 @@ inline bool VnPatchIAT(HMODULE hMod, const char* libName, const char* funcName, ::FreeLibrary(module); return false; } -#pragma endregion -#pragma region "Exports" -/* -extern "C" { - static HRESULT(*__CreateDXGIFactory1)(void*, void**); - __declspec(dllexport) HRESULT _CreateDXGIFactory1(void* p1, void** p2) +inline BOOL VnPatchDelayIAT(HMODULE hMod, const char* libName, const char* funcName, uintptr_t hookAddr) { + // Increment module reference count to prevent other threads from unloading it while we're working with it + HMODULE lib; + if (!GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCWSTR)hMod, &lib)) return FALSE; + + PIMAGE_DOS_HEADER dos = (PIMAGE_DOS_HEADER)lib; + PIMAGE_NT_HEADERS nt = (PIMAGE_NT_HEADERS)((uintptr_t)lib + dos->e_lfanew); + PIMAGE_DELAYLOAD_DESCRIPTOR dload = (PIMAGE_DELAYLOAD_DESCRIPTOR)((uintptr_t)lib + + nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT].VirtualAddress); + while (dload->DllNameRVA) { - MessageBoxW(nullptr, L"Hello, world !", L"", 0); - return __CreateDXGIFactory1(p1, p2); + char* dll = (char*)((uintptr_t)lib + dload->DllNameRVA); + if (!_stricmp(dll, libName)) { +#ifdef _LIBVALINET_DEBUG_HOOKING_IATPATCH + printf("[PatchDelayIAT] Found %s in IAT.\n", libName); +#endif + + PIMAGE_THUNK_DATA firstthunk = (PIMAGE_THUNK_DATA)((uintptr_t)lib + dload->ImportNameTableRVA); + PIMAGE_THUNK_DATA functhunk = (PIMAGE_THUNK_DATA)((uintptr_t)lib + dload->ImportAddressTableRVA); + while (firstthunk->u1.AddressOfData) + { + if (firstthunk->u1.Ordinal & IMAGE_ORDINAL_FLAG) + { + if (!(*((WORD*)&(funcName)+1)) && IMAGE_ORDINAL32(firstthunk->u1.Ordinal) == (DWORD_PTR)funcName) + { + DWORD oldProtect; + if (VirtualProtect(&functhunk->u1.Function, sizeof(uintptr_t), PAGE_EXECUTE_READWRITE, &oldProtect)) + { + functhunk->u1.Function = (uintptr_t)hookAddr; + VirtualProtect(&functhunk->u1.Function, sizeof(uintptr_t), oldProtect, &oldProtect); +#ifdef _LIBVALINET_DEBUG_HOOKING_IATPATCH + printf("[PatchDelayIAT] Patched 0x%x in %s to 0x%p.\n", funcName, libName, hookAddr); +#endif + FreeLibrary(lib); + return TRUE; + } + FreeLibrary(lib); + return FALSE; + } + } + else + { + PIMAGE_IMPORT_BY_NAME byName = (PIMAGE_IMPORT_BY_NAME)((uintptr_t)lib + firstthunk->u1.AddressOfData); + if ((*((WORD*)&(funcName)+1)) && !_stricmp((char*)byName->Name, funcName)) + { + DWORD oldProtect; + if (VirtualProtect(&functhunk->u1.Function, sizeof(uintptr_t), PAGE_EXECUTE_READWRITE, &oldProtect)) + { + functhunk->u1.Function = (uintptr_t)hookAddr; + VirtualProtect(&functhunk->u1.Function, sizeof(uintptr_t), oldProtect, &oldProtect); +#ifdef _LIBVALINET_DEBUG_HOOKING_IATPATCH + printf("[PatchDelayIAT] Patched %s in %s to 0x%p.\n", funcName, libName, hookAddr); +#endif + FreeLibrary(lib); + return TRUE; + } + FreeLibrary(lib); + return FALSE; + } + } + functhunk++; + firstthunk++; + } + } + dload++; } + FreeLibrary(lib); + return FALSE; } -#pragma comment(linker, "/export:CreateDXGIFactory1=_CreateDXGIFactory1,@11") -*/ -#pragma comment(linker, "/export:ApplyCompatResolutionQuirking=C:\\Windows\\System32\\dxgi.dll.ApplyCompatResolutionQuirking,@1") -#pragma comment(linker, "/export:CompatString=C:\\Windows\\System32\\dxgi.dll.CompatString,@2") -#pragma comment(linker, "/export:CompatValue=C:\\Windows\\System32\\dxgi.dll.CompatValue,@3") -#pragma comment(linker, "/export:CreateDXGIFactory=C:\\Windows\\System32\\dxgi.dll.CreateDXGIFactory,@10") -#pragma comment(linker, "/export:CreateDXGIFactory1=C:\\Windows\\System32\\dxgi.dll.CreateDXGIFactory1,@11") -#pragma comment(linker, "/export:CreateDXGIFactory2=C:\\Windows\\System32\\dxgi.dll.CreateDXGIFactory2,@12") -#pragma comment(linker, "/export:DXGID3D10CreateDevice=C:\\Windows\\System32\\dxgi.dll.DXGID3D10CreateDevice,@13") -#pragma comment(linker, "/export:DXGID3D10CreateLayeredDevice=C:\\Windows\\System32\\dxgi.dll.DXGID3D10CreateLayeredDevice,@14") -#pragma comment(linker, "/export:DXGID3D10GetLayeredDeviceSize=C:\\Windows\\System32\\dxgi.dll.DXGID3D10GetLayeredDeviceSize,@15") -#pragma comment(linker, "/export:DXGID3D10RegisterLayers=C:\\Windows\\System32\\dxgi.dll.DXGID3D10RegisterLayers,@16") -#pragma comment(linker, "/export:DXGIDeclareAdapterRemovalSupport=C:\\Windows\\System32\\dxgi.dll.DXGIDeclareAdapterRemovalSupport,@17") -#pragma comment(linker, "/export:DXGIDumpJournal=C:\\Windows\\System32\\dxgi.dll.DXGIDumpJournal,@4") -#pragma comment(linker, "/export:DXGIGetDebugInterface1=C:\\Windows\\System32\\dxgi.dll.DXGIGetDebugInterface1,@18") -#pragma comment(linker, "/export:DXGIReportAdapterConfiguration=C:\\Windows\\System32\\dxgi.dll.DXGIReportAdapterConfiguration,@19") -#pragma comment(linker, "/export:PIXBeginCapture=C:\\Windows\\System32\\dxgi.dll.PIXBeginCapture,@5") -#pragma comment(linker, "/export:PIXEndCapture=C:\\Windows\\System32\\dxgi.dll.PIXEndCapture,@6") -#pragma comment(linker, "/export:PIXGetCaptureState=C:\\Windows\\System32\\dxgi.dll.PIXGetCaptureState,@7") -#pragma comment(linker, "/export:SetAppCompatStringPointer=C:\\Windows\\System32\\dxgi.dll.SetAppCompatStringPointer,@8") -#pragma comment(linker, "/export:UpdateHMDEmulationStatus=C:\\Windows\\System32\\dxgi.dll.UpdateHMDEmulationStatus,@9") #pragma endregion #pragma region "Hooks" @@ -251,14 +288,71 @@ STDAPI _CreateCoreWebView2EnvironmentWithOptions(PCWSTR browserExecutableFolder, } #pragma endregion +#pragma region "AppVerifier infrastructure" +#define DLL_PROCESS_VERIFIER 4 + +typedef struct _RTL_VERIFIER_THUNK_DESCRIPTOR { + PCHAR ThunkName; + PVOID ThunkOldAddress; + PVOID ThunkNewAddress; +} RTL_VERIFIER_THUNK_DESCRIPTOR, * PRTL_VERIFIER_THUNK_DESCRIPTOR; + +typedef struct _RTL_VERIFIER_DLL_DESCRIPTOR { + PWCHAR DllName; + ULONG DllFlags; + PVOID DllAddress; + PRTL_VERIFIER_THUNK_DESCRIPTOR DllThunks; +} RTL_VERIFIER_DLL_DESCRIPTOR, * PRTL_VERIFIER_DLL_DESCRIPTOR; + +typedef void (NTAPI* RTL_VERIFIER_DLL_LOAD_CALLBACK) ( + PWSTR DllName, + PVOID DllBase, + SIZE_T DllSize, + PVOID Reserved); +typedef void (NTAPI* RTL_VERIFIER_DLL_UNLOAD_CALLBACK) ( + PWSTR DllName, + PVOID DllBase, + SIZE_T DllSize, + PVOID Reserved); +typedef void (NTAPI* RTL_VERIFIER_NTDLLHEAPFREE_CALLBACK) ( + PVOID AllocationBase, + SIZE_T AllocationSize); + +typedef struct _RTL_VERIFIER_PROVIDER_DESCRIPTOR { + ULONG Length; + PRTL_VERIFIER_DLL_DESCRIPTOR ProviderDlls; + RTL_VERIFIER_DLL_LOAD_CALLBACK ProviderDllLoadCallback; + RTL_VERIFIER_DLL_UNLOAD_CALLBACK ProviderDllUnloadCallback; + + PWSTR VerifierImage; + ULONG VerifierFlags; + ULONG VerifierDebug; + + PVOID RtlpGetStackTraceAddress; + PVOID RtlpDebugPageHeapCreate; + PVOID RtlpDebugPageHeapDestroy; + + RTL_VERIFIER_NTDLLHEAPFREE_CALLBACK ProviderNtdllHeapFreeCallback; +} RTL_VERIFIER_PROVIDER_DESCRIPTOR; + +RTL_VERIFIER_DLL_DESCRIPTOR noHooks{}; +RTL_VERIFIER_PROVIDER_DESCRIPTOR desc = { + sizeof(desc), + &noHooks, + [](auto, auto, auto, auto) {}, + [](auto, auto, auto, auto) {}, + nullptr, 0, 0, + nullptr, nullptr, nullptr, + [](auto, auto) {}, +}; +#pragma endregion + BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { UNREFERENCED_PARAMETER(lpvReserved); switch (fdwReason) { case DLL_PROCESS_ATTACH: ::DisableThreadLibraryCalls(hinstDLL); - //__CreateDXGIFactory1 = (HRESULT(*)(void*, void**))::GetProcAddress(::GetModuleHandleW(L"C:\\Windows\\System32\\dxgi.dll"), "CreateDXGIFactory1"); - ::VnPatchIAT(::GetModuleHandleW(nullptr), "WebView2Loader.dll", "CreateCoreWebView2EnvironmentWithOptions", reinterpret_cast(_CreateCoreWebView2EnvironmentWithOptions)); break; case DLL_THREAD_ATTACH: break; @@ -266,6 +360,11 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { break; case DLL_PROCESS_DETACH: break; + case DLL_PROCESS_VERIFIER: + *(PVOID*)lpvReserved = &desc; + ::VnPatchIAT(::GetModuleHandleW(nullptr), "WebView2Loader.dll", "CreateCoreWebView2EnvironmentWithOptions", reinterpret_cast(_CreateCoreWebView2EnvironmentWithOptions)); + ::VnPatchDelayIAT(::GetModuleHandleW(nullptr), "WebView2Loader.dll", "CreateCoreWebView2EnvironmentWithOptions", reinterpret_cast(_CreateCoreWebView2EnvironmentWithOptions)); + break; } return true; }