├── media └── guiscreenshot.png ├── ChromePatcherDll ├── dllmain.hpp ├── threads.hpp ├── simplepatternsearcher.hpp ├── stdafx.h ├── simdpatternsearcher.hpp ├── resource.h ├── simplepatternsearcher.cpp ├── patches.hpp ├── threads.cpp ├── ChromePatcherDll.vcxproj.filters ├── simdpatternsearcher.cpp ├── ChromePatcherDll.rc ├── dllmain.cpp ├── patches.cpp └── ChromePatcherDll.vcxproj ├── ChromeDevExtWarningPatcher ├── App.xaml.cs ├── localsignall.bat ├── localreadme.txt ├── ComponentViews │ ├── SelectionListView.xaml.cs │ └── SelectionListView.xaml ├── ComponentModels │ ├── MainModel.cs │ ├── PatchGroupElement.cs │ ├── SelectionListModel.cs │ ├── InstallationElement.cs │ └── SelectionListElement.cs ├── Patches │ ├── BytePatchPattern.cs │ ├── BytePatch.cs │ └── BytePatchManager.cs ├── AssemblyInfo.cs ├── app.manifest ├── InstallationFinder │ ├── Defaults │ │ ├── Yandex.cs │ │ ├── Brave.cs │ │ ├── Edge.cs │ │ ├── Chrome.cs │ │ └── CustomPath.cs │ ├── InstallationPaths.cs │ ├── Installation.cs │ └── InstallationManager.cs ├── App.xaml ├── CommandLineOptions.cs ├── Properties │ ├── Resources.Designer.cs │ └── Resources.resx ├── ChromeDevExtWarningPatcher.csproj ├── MainView.xaml ├── MainClass.cs ├── MainView.xaml.cs └── PatcherInstaller.cs ├── ChromePatcherDllUnitTests ├── pch.cpp ├── pch.h ├── ChromePatcherDllUnitTests.vcxproj.filters ├── patterntests.cpp └── ChromePatcherDllUnitTests.vcxproj ├── ChromeDllInjector ├── IProcessListener.cs ├── app.manifest ├── ChromeDllInjector.csproj ├── ProcessListeners │ ├── CompatibleListener.cs │ └── EtwListener.cs ├── Injector.cs └── Program.cs ├── sign.bat ├── .github ├── ISSUE_TEMPLATE │ ├── outdated-patterns-or-patches.md │ ├── bug-report---patch-not-working.md │ └── feature-request.md └── workflows │ └── buildandrelease.yml ├── signall.bat ├── ChromeDllInjectorBuildZipper ├── ChromeDllInjectorBuildZipper.csproj ├── ZipArchiveExtension.cs ├── ProjectFileFinders.cs └── Program.cs ├── README.md ├── ChromeDevExtWarningPatcher.sln ├── .gitignore ├── patterns.xml └── LICENSE /media/guiscreenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ceiridge/Chrome-Developer-Mode-Extension-Warning-Patcher/HEAD/media/guiscreenshot.png -------------------------------------------------------------------------------- /ChromePatcherDll/dllmain.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Header file for the injector 4 | 5 | //_declspec(dllexport) bool InstallWinHook(); 6 | //_declspec(dllexport) bool UnInstallWinHook(); 7 | -------------------------------------------------------------------------------- /ChromeDevExtWarningPatcher/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows; 3 | using ChromeDevExtWarningPatcher.Patches; 4 | 5 | namespace ChromeDevExtWarningPatcher { 6 | public partial class App : Application { } 7 | } 8 | -------------------------------------------------------------------------------- /ChromeDevExtWarningPatcher/localsignall.bat: -------------------------------------------------------------------------------- 1 | REM Copy a helpful README 2 | copy /b/v/y localreadme.txt bin\Release\net6.0-windows10.0.17763.0\README.txt 3 | 4 | REM Also sign the release 5 | cd bin\Release 6 | ..\..\..\signall.bat 7 | -------------------------------------------------------------------------------- /ChromePatcherDll/threads.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace ChromePatch { 4 | inline std::vector suspendedThreads; 5 | inline HANDLE mainThreadHandle; 6 | 7 | void SuspendOtherThreads(); 8 | void ResumeOtherThreads(); 9 | } -------------------------------------------------------------------------------- /ChromePatcherDllUnitTests/pch.cpp: -------------------------------------------------------------------------------- 1 | // pch.cpp: Quelldatei, die dem vorkompilierten Header entspricht 2 | 3 | #include "pch.h" 4 | 5 | // Bei der Verwendung vorkompilierter Header ist diese Quelldatei für eine erfolgreiche Kompilierung erforderlich. 6 | -------------------------------------------------------------------------------- /ChromeDllInjector/IProcessListener.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ChromeDllInjector { 4 | public interface IProcessListener { 5 | 6 | // This function should block the thread after being called 7 | void StartListener(Action callback); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /ChromeDevExtWarningPatcher/localreadme.txt: -------------------------------------------------------------------------------- 1 | This tool requires the .NET 6 DESKTOP Runtime. Download it here: https://dotnet.microsoft.com/download/dotnet/6.0/runtime 2 | Start ChromeDevExtWarningPatcher.exe. 3 | 4 | https://github.com/Ceiridge/Chrome-Developer-Mode-Extension-Warning-Patcher 5 | -------------------------------------------------------------------------------- /sign.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | signtool.exe sign /f %CodeSignFile% /as /seal /d "Executable of the Chrome Developer Mode Extension Warning Patcher" /du "https://github.com/Ceiridge/Chrome-Developer-Mode-Extension-Warning-Patcher" /tr http://freetsa.org/tsr %FileLoc%\*.dll %FileLoc%\*.exe 3 | exit /b 0 4 | -------------------------------------------------------------------------------- /ChromeDevExtWarningPatcher/ComponentViews/SelectionListView.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace ChromeDevExtWarningPatcher.ComponentViews { 4 | public partial class SelectionListView : UserControl { 5 | public SelectionListView() { 6 | this.InitializeComponent(); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /ChromeDevExtWarningPatcher/ComponentModels/MainModel.cs: -------------------------------------------------------------------------------- 1 | namespace ChromeDevExtWarningPatcher.ComponentModels { 2 | public class MainModel { 3 | public SelectionListModel BrowserListModel { get; set; } = new SelectionListModel(); 4 | public SelectionListModel PatchListModel { get; set; } = new SelectionListModel(); 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /ChromePatcherDll/simplepatternsearcher.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace ChromePatch { 4 | class 5 | #ifdef _DEBUG 6 | __declspec(dllexport) 7 | #endif 8 | SimplePatternSearcher : public PatternSearcher { 9 | public: 10 | byte* SearchBytePattern(Patch& patch, byte* startAddr, size_t length) override; 11 | }; 12 | } 13 | -------------------------------------------------------------------------------- /ChromePatcherDllUnitTests/pch.h: -------------------------------------------------------------------------------- 1 | #ifndef PCH_H 2 | #define PCH_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /ChromePatcherDll/stdafx.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | inline HMODULE module; 16 | -------------------------------------------------------------------------------- /ChromePatcherDll/simdpatternsearcher.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace ChromePatch { 4 | class 5 | #ifdef _DEBUG 6 | __declspec(dllexport) 7 | #endif 8 | SimdPatternSearcher : public PatternSearcher { 9 | public: 10 | byte* SearchBytePattern(Patch& patch, byte* startAddr, size_t length) override; 11 | static bool IsCpuSupported(); 12 | }; 13 | } 14 | -------------------------------------------------------------------------------- /ChromeDevExtWarningPatcher/Patches/BytePatchPattern.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace ChromeDevExtWarningPatcher.Patches { 4 | public class BytePatchPattern { 5 | public string Name; 6 | public List AlternativePatternsX64 = new List(); 7 | 8 | public BytePatchPattern(string name) { 9 | this.Name = name; 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /ChromeDevExtWarningPatcher/ComponentModels/PatchGroupElement.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace ChromeDevExtWarningPatcher.ComponentModels { 4 | public class PatchGroupElement : SelectionListElement { 5 | [Required] 6 | public int Group { get; set; } 7 | 8 | public PatchGroupElement(string name, int group) : base(name) { 9 | this.Group = group; 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /ChromeDevExtWarningPatcher/ComponentModels/SelectionListModel.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.ObjectModel; 2 | using System.ComponentModel.DataAnnotations; 3 | 4 | namespace ChromeDevExtWarningPatcher.ComponentModels { 5 | public class SelectionListModel { 6 | [Required] 7 | public ObservableCollection ElementList { get; set; } = new ObservableCollection(); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /ChromeDevExtWarningPatcher/ComponentModels/InstallationElement.cs: -------------------------------------------------------------------------------- 1 | using ChromeDevExtWarningPatcher.InstallationFinder; 2 | 3 | namespace ChromeDevExtWarningPatcher.ComponentModels { 4 | public class InstallationElement : SelectionListElement { 5 | public InstallationPaths Paths { get; set; } 6 | 7 | public InstallationElement(string name, InstallationPaths paths) : base(name) { 8 | this.Paths = paths; 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /ChromePatcherDll/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by ChromePatcherDll.rc 4 | 5 | 6 | #ifdef APSTUDIO_INVOKED 7 | #ifndef APSTUDIO_READONLY_SYMBOLS 8 | #define _APS_NEXT_RESOURCE_VALUE 101 9 | #define _APS_NEXT_COMMAND_VALUE 40001 10 | #define _APS_NEXT_CONTROL_VALUE 1001 11 | #define _APS_NEXT_SYMED_VALUE 101 12 | #endif 13 | #endif 14 | -------------------------------------------------------------------------------- /ChromeDevExtWarningPatcher/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | 3 | [assembly: ThemeInfo( 4 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located 5 | //(used if a resource is not found in the page, 6 | // or application resource dictionaries) 7 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located 8 | //(used if a resource is not found in the page, 9 | // app, or any theme specific resource dictionaries) 10 | )] 11 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/outdated-patterns-or-patches.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Outdated patterns or patches 3 | about: Patterns become outdated sometimes, mostly after new major browser updates 4 | title: Outdated patterns for Chromium XX 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | Chromium (probably works on no browser based on Chromium anymore): 11 | - Example Patch 1 12 | - Example Patch 2 13 | 14 | Chrome: 15 | - Chromium issues 16 | - Help me complete this list by adding a comment! 17 | 18 | Edge: 19 | - Chromium issues 20 | - Help me complete this list by adding a comment! 21 | 22 | Brave: 23 | - Chromium issues 24 | - Help me complete this list by adding a comment! 25 | -------------------------------------------------------------------------------- /ChromeDevExtWarningPatcher/app.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /ChromeDllInjector/app.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /ChromeDevExtWarningPatcher/InstallationFinder/Defaults/Yandex.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | 5 | namespace ChromeDevExtWarningPatcher.InstallationFinder.Defaults { 6 | internal class Yandex : Installation { 7 | public Yandex() : base("Yandex") { } 8 | 9 | public override List FindInstallationPaths() { 10 | List dllFiles = new List(); 11 | 12 | string appDataLocal = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); 13 | AddDllAndExeToList(dllFiles, this.GetLatestDllAndExe(new DirectoryInfo(Path.Combine(appDataLocal, @"Yandex\YandexBrowser\Application")), "browser.dll", "browser.exe")); 14 | 15 | return dllFiles; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug-report---patch-not-working.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug Report / Patch not working 3 | about: Report a patch / thing that is not working correctly 4 | title: 'Bug Report: ' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe your problem in one sentence:** 11 | One short sentence please. 12 | 13 | **Name the affected patch/problem (if available)** 14 | Name 15 | 16 | **Your used browser** 17 | Keep in mind that only 64-bit browsers based on Chromium are supported. Ex.: Chrome 85.12.1234 18 | 19 | **Screenshots (optional)** 20 | If applicable, add screenshots to help explain your problem. 21 | 22 | **Longer description (optional)** 23 | Explain how you encountered the bug or what it is about in detail. 24 | 25 | **Additional information (optional)** 26 | Add any other information about the problem here. 27 | -------------------------------------------------------------------------------- /ChromeDevExtWarningPatcher/InstallationFinder/Defaults/Brave.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO; 3 | 4 | namespace ChromeDevExtWarningPatcher.InstallationFinder.Defaults { 5 | internal class Brave : Installation { 6 | public Brave() : base("Brave") { } 7 | 8 | public override List FindInstallationPaths() { 9 | List dllFiles = new List(); 10 | 11 | AddDllAndExeToList(dllFiles, this.GetLatestDllAndExe(new DirectoryInfo(@"C:\Program Files (x86)\BraveSoftware\Brave-Browser\Application"), "chrome.dll", "brave.exe")); 12 | AddDllAndExeToList(dllFiles, this.GetLatestDllAndExe(new DirectoryInfo(@"C:\Program Files\BraveSoftware\Brave-Browser\Application"), "chrome.dll", "brave.exe")); 13 | 14 | return dllFiles; 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /ChromeDevExtWarningPatcher/Patches/BytePatch.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace ChromeDevExtWarningPatcher.Patches { 4 | public class BytePatch { 5 | public byte OrigByte, PatchByte; 6 | public List Offsets; 7 | public int SigOffset; 8 | public bool IsSig; 9 | public BytePatchPattern Pattern; 10 | public byte[]? NewBytes; 11 | 12 | public int Group; 13 | 14 | public BytePatch(BytePatchPattern pattern, byte origByte, byte patchByte, List offsets, int group, byte[]? newBytes = null, bool isSig = false, int sigOffset = 0) { 15 | this.Pattern = pattern; 16 | this.OrigByte = origByte; 17 | this.PatchByte = patchByte; 18 | this.Offsets = offsets; 19 | this.IsSig = isSig; 20 | this.SigOffset = sigOffset; 21 | this.Group = group; 22 | this.NewBytes = newBytes; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /ChromeDevExtWarningPatcher/App.xaml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /ChromeDevExtWarningPatcher/CommandLineOptions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using CommandLine; 3 | 4 | namespace ChromeDevExtWarningPatcher { 5 | public class CommandLineOptions { 6 | [Option("groups", Required = false, HelpText = "Set what patch groups you want to use. See patterns.xml to get the group ids (comma-separated: 0,1,2,etc.)", Separator = ',')] 7 | public IEnumerable Groups { get; set; } = new List(); 8 | 9 | [Option('w', "noWait", Required = false, HelpText = "Disable the almost-pointless wait after finishing")] 10 | public bool NoWait { get; set; } 11 | 12 | [Option("customPath", Required = false, HelpText = "Instead of automatically detecting and patching all chrome.dll files, define a custom Application-folder path (see README) (string in quotes is recommended)")] 13 | public string? CustomPath { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /ChromePatcherDll/simplepatternsearcher.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "patches.hpp" 3 | #include "simplepatternsearcher.hpp" 4 | 5 | namespace ChromePatch { 6 | byte* SimplePatternSearcher::SearchBytePattern(Patch& patch, byte* startAddr, size_t length) { 7 | for(size_t i = 0; i < length; i++) { 8 | for (PatchPattern& pattern : patch.patterns) { 9 | const byte searchByte = pattern.pattern[pattern.searchOffset]; 10 | if (searchByte == startAddr[i] || searchByte == 0xFF) { 11 | pattern.searchOffset++; 12 | } else { 13 | pattern.searchOffset = 0; // Reset found offsets if the byte differs from the pattern 14 | } 15 | 16 | if (pattern.searchOffset == pattern.pattern.size()) { 17 | return startAddr + i - pattern.searchOffset + 1; // Pattern found 18 | } 19 | } 20 | 21 | } 22 | 23 | return nullptr; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /signall.bat: -------------------------------------------------------------------------------- 1 | @ECHO off 2 | SET CodeSignFile=codesign.pfx 3 | SET /A FindTries=0 4 | 5 | REM Recursively search for the pfx file 6 | :RetryFind 7 | IF EXIST %CodeSignFile% GOTO SignAll 8 | SET CodeSignFile=..\%CodeSignFile% 9 | 10 | SET /A FindTries=FindTries+1 11 | IF %FindTries% GEQ 10 GOTO Fail 12 | GOTO RetryFind 13 | 14 | :SignAll 15 | CALL :NormalizePath %CodeSignFile% 16 | SET CodeSignFile=%RETVAL% 17 | ECHO Found pfx at: %CodeSignFile% 18 | 19 | SET FileLoc=%cd% 20 | CALL :Sign 21 | FOR /D %%i IN (%cd%\*) DO ( 22 | SET FileLoc=%%i 23 | CALL :Sign 24 | ) 25 | 26 | ECHO Done 27 | REM Make sure that the batch has an error code of 0 28 | EXIT /b 0 29 | 30 | :Fail 31 | ECHO Failed to find pfx 32 | EXIT /b 0 33 | 34 | :Sign 35 | REM signtool required in PATH 36 | ECHO Signing in %FileLoc% 37 | START /wait cmd.exe /c %CodeSignFile%\..\sign.bat 38 | REM Another batch file is required to ignore errors somehow 39 | GOTO :EOF 40 | 41 | :NormalizePath 42 | SET RETVAL=%~f1 43 | EXIT /B 44 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature-request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature Request 3 | about: Suggest an idea for this project or a new patch 4 | title: 'Feature Request: ' 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex.: I'm always frustrated when [...] 12 | !!Please make sure that the patch you are requesting either improves the patcher generally or is a patch that removes an annoyance and would be used by many other users!! 13 | 14 | **Describe the solution you'd like** 15 | A clear and concise description of what you want to happen. 16 | 17 | **Describe alternatives you've considered (optional)** 18 | A clear and concise description of any alternative solutions or features you've considered. 19 | 20 | **Additional context (optional)** 21 | Add any other context or screenshots about the feature request here. 22 | 23 | **Define a name for your feature (optional)** 24 | Ex.: Remove annoying thing patch 25 | -------------------------------------------------------------------------------- /ChromeDevExtWarningPatcher/InstallationFinder/Defaults/Edge.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | 5 | namespace ChromeDevExtWarningPatcher.InstallationFinder.Defaults { 6 | internal class Edge : Installation { 7 | public Edge() : base("Edge") { } 8 | 9 | public override List FindInstallationPaths() { 10 | List dllFiles = new List(); 11 | 12 | AddDllAndExeToList(dllFiles, this.GetLatestDllAndExe(new DirectoryInfo(@"C:\Program Files (x86)\Microsoft\Edge\Application"), "msedge.dll", "msedge.exe")); 13 | AddDllAndExeToList(dllFiles, this.GetLatestDllAndExe(new DirectoryInfo(@"C:\Program Files\Microsoft\Edge\Application"), "msedge.dll", "msedge.exe")); 14 | AddDllAndExeToList(dllFiles, this.GetLatestDllAndExe(new DirectoryInfo(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), @"Microsoft\Edge\Application")), "msedge.dll", "msedge.exe")); // From the MS Store 15 | 16 | return dllFiles; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /ChromeDevExtWarningPatcher/InstallationFinder/InstallationPaths.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using System.IO; 3 | 4 | namespace ChromeDevExtWarningPatcher.InstallationFinder { 5 | public class InstallationPaths { 6 | [Required] 7 | public string Name; 8 | public string? ChromeDllPath, ChromeExePath; 9 | 10 | public InstallationPaths(string name, string chromeDllPath, string chromeExePath) { 11 | this.Name = name; 12 | this.ChromeDllPath = chromeDllPath; 13 | this.ChromeExePath = chromeExePath; 14 | } 15 | 16 | public InstallationPaths(string name, FileInfo chromeDll, FileInfo chromeExe) : this(name, chromeDll.FullName, chromeExe.FullName) { } 17 | 18 | public InstallationPaths(string name) { 19 | this.Name = name; 20 | } 21 | 22 | public bool Is64Bit() { 23 | if(this.ChromeDllPath == null || this.ChromeExePath == null) { 24 | return false; 25 | } 26 | 27 | return InstallationManager.IsImageX64(this.ChromeDllPath) && InstallationManager.IsImageX64(this.ChromeExePath); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /ChromeDevExtWarningPatcher/ComponentModels/SelectionListElement.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using System.ComponentModel.DataAnnotations; 3 | using System.Runtime.CompilerServices; 4 | using System.Windows.Media; 5 | 6 | namespace ChromeDevExtWarningPatcher.ComponentModels { 7 | public class SelectionListElement : INotifyPropertyChanged { 8 | [Required] 9 | public string Name { get; set; } 10 | public string? Tooltip { get; set; } 11 | public string? Description { get; set; } 12 | public ImageSource? IconImage { get; set; } 13 | 14 | private bool isSelected; 15 | public bool IsSelected { 16 | get => this.isSelected; 17 | set { 18 | this.isSelected = value; 19 | this.OnPropertyChanged(); 20 | } 21 | } 22 | 23 | public event PropertyChangedEventHandler? PropertyChanged; 24 | 25 | public SelectionListElement(string name) { 26 | this.Name = name; 27 | } 28 | 29 | protected internal void OnPropertyChanged([CallerMemberName] string propertyName = "") { 30 | this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /ChromeDevExtWarningPatcher/InstallationFinder/Defaults/Chrome.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO; 3 | 4 | namespace ChromeDevExtWarningPatcher.InstallationFinder.Defaults { 5 | internal class Chrome : Installation { 6 | public Chrome() : base("Chrome") { } 7 | 8 | public override List FindInstallationPaths() { 9 | List dllFiles = new List(); 10 | 11 | AddDllAndExeToList(dllFiles, this.GetLatestDllAndExe(new DirectoryInfo(@"C:\Program Files (x86)\Google\Chrome\Application"), "chrome.dll", "chrome.exe")); 12 | AddDllAndExeToList(dllFiles, this.GetLatestDllAndExe(new DirectoryInfo(@"C:\Program Files (x86)\Google\Chrome Beta\Application"), "chrome.dll", "chrome.exe")); 13 | 14 | AddDllAndExeToList(dllFiles, this.GetLatestDllAndExe(new DirectoryInfo(@"C:\Program Files\Google\Chrome\Application"), "chrome.dll", "chrome.exe")); 15 | AddDllAndExeToList(dllFiles, this.GetLatestDllAndExe(new DirectoryInfo(@"C:\Program Files\Google\Chrome Beta\Application"), "chrome.dll", "chrome.exe")); 16 | 17 | return dllFiles; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /ChromeDllInjectorBuildZipper/ChromeDllInjectorBuildZipper.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net6.0-windows10.0.17763.0 6 | enable 7 | 6.0.0.0 8 | 6.0.0.0 9 | Ceiridge 10 | 11 | Chromium Developer Extension Warning Patcher ChromeDllInjector Build Zipper 12 | Zip the build files for use in the Chrome Developer Extension Warning Patcher 13 | GNU General Public License 3, Ceiridge 14 | LICENSE 15 | https://github.com/Ceiridge/Chrome-Developer-Mode-Extension-Warning-Patcher 16 | https://github.com/Ceiridge/Chrome-Developer-Mode-Extension-Warning-Patcher 17 | 18 | ChromeDllInjectorBuildZipper.Program 19 | 20 | 7.0 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /ChromeDllInjectorBuildZipper/ZipArchiveExtension.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.IO.Compression; 3 | using System.Linq; 4 | 5 | // Taken from https://stackoverflow.com/questions/15133626/creating-directories-in-a-ziparchive-c-sharp-net-4-5 6 | namespace ChromeDllInjectorBuildZipper { 7 | public static class ZipArchiveExtension { 8 | public static void CreateEntryFromAny(this ZipArchive archive, string sourceName, string entryName = "") { 9 | var fileName = Path.GetFileName(sourceName); 10 | if (File.GetAttributes(sourceName).HasFlag(FileAttributes.Directory)) { 11 | archive.CreateEntryFromDirectory(sourceName, Path.Combine(entryName, fileName)); 12 | } else { 13 | archive.CreateEntryFromFile(sourceName, Path.Combine(entryName, fileName), CompressionLevel.Fastest); 14 | } 15 | } 16 | 17 | public static void CreateEntryFromDirectory(this ZipArchive archive, string sourceDirName, string entryName = "") { 18 | string[] files = Directory.GetFiles(sourceDirName).Concat(Directory.GetDirectories(sourceDirName)).ToArray(); 19 | archive.CreateEntry(Path.Combine(entryName, Path.GetFileName(sourceDirName))); 20 | foreach (var file in files) { 21 | archive.CreateEntryFromAny(file, entryName); 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /ChromePatcherDllUnitTests/ChromePatcherDllUnitTests.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Quelldateien 20 | 21 | 22 | Quelldateien 23 | 24 | 25 | 26 | 27 | Headerdateien 28 | 29 | 30 | -------------------------------------------------------------------------------- /ChromePatcherDll/patches.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace ChromePatch { 4 | class PatternSearcher; // Forward declaration for PatchThreadDelegate 5 | 6 | struct ReadPatchResult { // Make sure to null-initialize all fields 7 | bool UsingWrongVersion{}; 8 | }; 9 | 10 | struct PatchPattern { 11 | std::vector pattern{}; 12 | int searchOffset{}; 13 | }; 14 | 15 | struct Patch { 16 | std::vector patterns{}; 17 | byte origByte{}, patchByte{}; 18 | std::vector offsets{}; 19 | std::vector newBytes{}; 20 | bool isSig{}; 21 | int sigOffset{}; 22 | bool finishedPatch{}, successfulPatch{}; 23 | 24 | friend std::ostream& operator<<(std::ostream& os, const Patch& patch); 25 | }; 26 | 27 | class Patches { 28 | public: 29 | HMODULE chromeDll{}; 30 | std::wstring chromeDllPath{}; 31 | std::vector patches{}; 32 | 33 | ReadPatchResult ReadPatchFile(); 34 | int ApplyPatches(); 35 | private: 36 | static std::wstring MultibyteToWide(const std::string& str); 37 | static std::string ReadString(std::ifstream& file); 38 | static unsigned int ReadUInteger(std::ifstream& file); 39 | static void PatchThreadDelegate(Patch* patch, PatternSearcher* patternSearcher, MEMORY_BASIC_INFORMATION* mbi); 40 | }; 41 | inline Patches patches; 42 | 43 | class PatternSearcher { 44 | public: 45 | virtual byte* SearchBytePattern(Patch& patch, byte* startAddr, size_t length) = 0; 46 | }; 47 | } 48 | -------------------------------------------------------------------------------- /ChromeDllInjectorBuildZipper/ProjectFileFinders.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | 6 | namespace ChromeDllInjectorBuildZipper; 7 | 8 | public class ProjectFileFinders { 9 | public static string FindBuildFolder() { 10 | FileInfo builtInjector = FindAllInjectorExecutables(new DirectoryInfo(".")).OrderByDescending(file => { 11 | DateTimeOffset lastWriteOffset = file.LastWriteTimeUtc; 12 | return lastWriteOffset.ToUnixTimeSeconds(); 13 | }).First(); 14 | 15 | string buildFolder = Directory.GetParent(builtInjector.FullName)!.FullName; 16 | Console.WriteLine("Found build folder at: " + buildFolder); 17 | return buildFolder; 18 | } 19 | 20 | public static FileInfo? FindSignExecutor(DirectoryInfo dir) { 21 | foreach (FileInfo file in dir.EnumerateFiles()) { 22 | if (file.Name == "signall.bat") { 23 | return file; 24 | } 25 | } 26 | 27 | DirectoryInfo? parentDir = dir.Parent; 28 | return parentDir is not null ? FindSignExecutor(parentDir) : null; 29 | } 30 | 31 | private static IEnumerable FindAllInjectorExecutables(DirectoryInfo dir) { 32 | foreach (FileInfo file in dir.EnumerateFiles()) { 33 | if (file.Name == "ChromeDllInjector.exe") { 34 | yield return file; 35 | } 36 | } 37 | 38 | foreach (DirectoryInfo foundDir in dir.EnumerateDirectories()) { 39 | foreach (FileInfo file in FindAllInjectorExecutables(foundDir)) { 40 | yield return file; 41 | } 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /ChromePatcherDll/threads.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "threads.hpp" 3 | 4 | namespace ChromePatch { 5 | // Partially taken from https://stackoverflow.com/questions/16684245/can-i-suspend-a-process-except-one-thread 6 | void SuspendOtherThreads() { 7 | const DWORD pid = GetCurrentProcessId(); 8 | const HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); 9 | const DWORD mine = GetCurrentThreadId(); 10 | 11 | if (snap != INVALID_HANDLE_VALUE) { 12 | THREADENTRY32 te; 13 | te.dwSize = sizeof(te); 14 | 15 | if (Thread32First(snap, &te)) { 16 | do { 17 | if (te.dwSize >= FIELD_OFFSET(THREADENTRY32, th32OwnerProcessID) + sizeof(te.th32OwnerProcessID)) { 18 | if (te.th32ThreadID != mine && te.th32OwnerProcessID == pid) 19 | { 20 | const HANDLE thread = OpenThread(THREAD_ALL_ACCESS, FALSE, te.th32ThreadID); 21 | if (thread && thread != INVALID_HANDLE_VALUE) { 22 | SuspendThread(thread); 23 | CloseHandle(thread); 24 | suspendedThreads.push_back(te.th32ThreadID); 25 | } 26 | } 27 | } 28 | te.dwSize = sizeof(te); 29 | } while (Thread32Next(snap, &te)); 30 | } 31 | CloseHandle(snap); 32 | } 33 | } 34 | 35 | void ResumeOtherThreads() { 36 | for (DWORD tId : suspendedThreads) { 37 | const HANDLE thread = OpenThread(THREAD_ALL_ACCESS, FALSE, tId); 38 | if (thread && thread != INVALID_HANDLE_VALUE) { 39 | ResumeThread(thread); 40 | CloseHandle(thread); 41 | } 42 | } 43 | 44 | suspendedThreads.clear(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /ChromeDllInjector/ChromeDllInjector.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | WinExe 5 | net6.0-windows10.0.17763.0 6 | enable 7 | 6.0.0.0 8 | 6.0.0.0 9 | Ceiridge 10 | 11 | Chromium Developer Extension Warning Patcher Injector 12 | This waits for a Chromium process to start and injects the patcher dll into it 13 | GNU General Public License 3, Ceiridge 14 | LICENSE 15 | https://github.com/Ceiridge/Chrome-Developer-Mode-Extension-Warning-Patcher 16 | https://github.com/Ceiridge/Chrome-Developer-Mode-Extension-Warning-Patcher 17 | 18 | ChromeDllInjector.Program 19 | app.manifest 20 | 7.0 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /ChromeDevExtWarningPatcher/ComponentViews/SelectionListView.xaml: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /ChromeDllInjector/ProcessListeners/CompatibleListener.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Threading; 5 | 6 | namespace ChromeDllInjector.ProcessListeners { 7 | // The purpose of this listener is that it should also run on Windows 7, which has problems with the EtwListener. 8 | // One side effect is a much higher CPU usage. 9 | public class CompatibleListener : IProcessListener { 10 | private readonly HashSet checkedProcesses = new HashSet(); // PIDs can be reused and the start time makes sure that it is actually unique. 11 | 12 | public void StartListener(Action callback) { 13 | while (true) { 14 | Thread.Sleep(50); 15 | 16 | foreach (Process process in Process.GetProcesses()) { 17 | try { 18 | UniquePid proUniquePid = new UniquePid(process.Id, process.StartTime); 19 | 20 | if (!this.checkedProcesses.Contains(proUniquePid)) { 21 | this.checkedProcesses.Add(proUniquePid); 22 | callback(proUniquePid.Pid); // Only call once for each (newly) started process 23 | } 24 | } catch (Exception) {} // Ignore errors that might occur while trying to get the start time of system processes 25 | } 26 | } 27 | } 28 | 29 | private class UniquePid : IEquatable { 30 | public readonly int Pid; 31 | public readonly DateTime StartTime; 32 | 33 | public UniquePid(int pid, DateTime startTime) { 34 | this.Pid = pid; 35 | this.StartTime = startTime; 36 | } 37 | 38 | public override int GetHashCode() { 39 | return (this.Pid, this.StartTime).GetHashCode(); 40 | } 41 | 42 | public bool Equals(UniquePid other) { 43 | return other != null && (other.Pid, other.StartTime).Equals((this.Pid, this.StartTime)); 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /ChromeDllInjector/ProcessListeners/EtwListener.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Diagnostics.Tracing.Parsers; 2 | using Microsoft.Diagnostics.Tracing.Parsers.Kernel; 3 | using Microsoft.Diagnostics.Tracing.Session; 4 | using System; 5 | using System.Threading; 6 | using Vanara.PInvoke; 7 | 8 | namespace ChromeDllInjector.ProcessListeners { 9 | public class EtwListener : IProcessListener { 10 | private Action processCallback; 11 | 12 | public void StartListener(Action callback) { 13 | this.processCallback = callback; 14 | 15 | TraceEventSession kernelSession = new TraceEventSession("ChromePatcherETW"); 16 | kernelSession.EnableKernelProvider(KernelTraceEventParser.Keywords.Process); 17 | kernelSession.Source.Kernel.ProcessStart += this.Kernel_ProcessStart; 18 | 19 | new Thread(() => { // Required because of blocking Process() below 20 | Thread.Sleep(10); // Wait a bit to make sure the ETW started processing 21 | 22 | AdvApi32.EVENT_TRACE_PROPERTIES properties = new AdvApi32.EVENT_TRACE_PROPERTIES { 23 | Wnode = new AdvApi32.WNODE_HEADER { 24 | BufferSize = 1024 // Max buffer size 25 | } 26 | }; 27 | 28 | AdvApi32.QueryTrace(0 /* NULL Handle */, kernelSession.SessionName, ref properties); // Fill the struct with info 29 | Console.WriteLine("Flush thread started: " + properties.Wnode.Guid); 30 | 31 | while (true) { 32 | Thread.Sleep(50); // Flush the ETW buffer every 50ms to be faster than Chromium starting up; The default flush timer is set to 1s (=> too slow) 33 | try { 34 | AdvApi32.FlushTrace(0 /* NULL Handle */, kernelSession.SessionName, ref properties); 35 | } catch (Exception) { } 36 | } 37 | }).Start(); 38 | 39 | Console.WriteLine("Starting to process"); 40 | kernelSession.Source.Process(); // Blocking forever 41 | } 42 | 43 | private void Kernel_ProcessStart(ProcessTraceData obj) { 44 | this.processCallback(obj.ProcessID); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /ChromeDevExtWarningPatcher/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace ChromeDevExtWarningPatcher.Properties { 2 | using System; 3 | 4 | 5 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] 6 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 7 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 8 | internal class Resources { 9 | 10 | private static global::System.Resources.ResourceManager resourceMan; 11 | 12 | private static global::System.Globalization.CultureInfo resourceCulture; 13 | 14 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 15 | internal Resources() { 16 | } 17 | 18 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 19 | internal static global::System.Resources.ResourceManager ResourceManager { 20 | get { 21 | if (object.ReferenceEquals(resourceMan, null)) { 22 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ChromeDevExtWarningPatcher.Properties.Resources", typeof(Resources).Assembly); 23 | resourceMan = temp; 24 | } 25 | return resourceMan; 26 | } 27 | } 28 | 29 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 30 | internal static global::System.Globalization.CultureInfo Culture { 31 | get { 32 | return resourceCulture; 33 | } 34 | set { 35 | resourceCulture = value; 36 | } 37 | } 38 | 39 | internal static byte[] ChromeDllInjector { 40 | get { 41 | object obj = ResourceManager.GetObject("ChromeDllInjector", resourceCulture); 42 | return ((byte[])(obj)); 43 | } 44 | } 45 | 46 | internal static byte[] ChromePatcherDll { 47 | get { 48 | object obj = ResourceManager.GetObject("ChromePatcherDll", resourceCulture); 49 | return ((byte[])(obj)); 50 | } 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /ChromeDllInjector/Injector.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using System.Runtime.InteropServices; 4 | using Vanara.Extensions; 5 | using Vanara.PInvoke; 6 | 7 | namespace ChromeDllInjector { 8 | internal class Injector { 9 | private readonly string dllPath; 10 | 11 | public Injector(string dllPath) { 12 | this.dllPath = dllPath; 13 | } 14 | 15 | // Inject the dll with by creating a remote thread on LoadLibraryW 16 | public void Inject(Process p) { 17 | Kernel32.SafeHPROCESS proc = Kernel32.OpenProcess(new ACCESS_MASK(Kernel32.ProcessAccess.PROCESS_ALL_ACCESS), false, (uint)p.Id); 18 | 19 | if (!proc.IsNull && !proc.IsInvalid) { 20 | IntPtr loadLib = Kernel32.GetProcAddress(Kernel32.LoadLibrary("kernel32.dll"), "LoadLibraryW"); 21 | if (loadLib == IntPtr.Zero) { 22 | Console.WriteLine("LoadLibaryW not found"); 23 | return; 24 | } 25 | 26 | byte[] dllPathBytes = this.dllPath.GetBytes(true, CharSet.Unicode); // Unicode for wide chars 27 | IntPtr alloc = Kernel32.VirtualAllocEx(proc, IntPtr.Zero, dllPathBytes.Length, Kernel32.MEM_ALLOCATION_TYPE.MEM_COMMIT, Kernel32.MEM_PROTECTION.PAGE_EXECUTE_READWRITE); 28 | if (alloc == IntPtr.Zero) { 29 | Console.WriteLine("Couldn't allocate"); 30 | return; 31 | } 32 | if (!Kernel32.WriteProcessMemory(proc, alloc, dllPathBytes, dllPathBytes.Length, out _)) { 33 | Console.WriteLine("Couldn't write " + Kernel32.GetLastError()); 34 | return; 35 | } 36 | 37 | Kernel32.SafeHTHREAD thread = Kernel32.CreateRemoteThread(proc, null, 0, loadLib, alloc, 0, out _); 38 | if (!thread.IsNull && !thread.IsInvalid) { 39 | Console.WriteLine("Injected!"); 40 | 41 | Kernel32.WaitForSingleObject(thread, Kernel32.INFINITE); // Wait until the dll is injected, so the path can be freed later 42 | thread.Close(); 43 | } 44 | 45 | Kernel32.VirtualFreeEx(proc, alloc, 0, Kernel32.MEM_ALLOCATION_TYPE.MEM_RELEASE); // Free path from the target's memory (alloc's existence is ensured above) 46 | } 47 | 48 | proc.Close(); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /ChromeDevExtWarningPatcher/InstallationFinder/Installation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | 6 | namespace ChromeDevExtWarningPatcher.InstallationFinder { 7 | internal abstract class Installation { 8 | protected string Name; 9 | 10 | protected Installation(string name) { 11 | this.Name = name; 12 | } 13 | 14 | public abstract List FindInstallationPaths(); 15 | 16 | protected InstallationPaths GetLatestDllAndExe(DirectoryInfo versionsFolder, string dllName, string exeName) { 17 | if (!versionsFolder.Exists) { 18 | return new InstallationPaths(this.Name); 19 | } 20 | 21 | InstallationPaths paths = new InstallationPaths(this.Name); 22 | 23 | List chromeVersions = new List(versionsFolder.EnumerateDirectories()); 24 | chromeVersions = chromeVersions.OrderByDescending(dirInfo => GetUnixTime(dirInfo.LastWriteTime)).ToList(); 25 | 26 | foreach (DirectoryInfo chromeVersion in chromeVersions) { 27 | if (chromeVersion.Name.Contains(".")) { 28 | foreach (FileInfo file in chromeVersion.EnumerateFiles()) { 29 | if (file.Name.Equals(dllName)) { 30 | paths.ChromeDllPath = file.FullName; 31 | break; 32 | } 33 | } 34 | } 35 | } 36 | 37 | FileInfo chromeExe = new FileInfo(Path.Combine(versionsFolder.FullName, exeName)); 38 | if (chromeExe.Exists && paths.ChromeDllPath != null) { // Every installation path also has to have a chrome.exe, otherwise the entire patcher won't work 39 | paths.ChromeExePath = chromeExe.FullName; 40 | return paths; 41 | } 42 | 43 | return new InstallationPaths(this.Name); 44 | } 45 | 46 | protected static void AddDllAndExeToList(List pathList, InstallationPaths latestDllAndExe) { 47 | if (latestDllAndExe.ChromeDllPath != null && latestDllAndExe.ChromeExePath != null) { 48 | pathList.Add(latestDllAndExe); 49 | } 50 | } 51 | 52 | public static double GetUnixTime(DateTime date) { 53 | return (date.Subtract(new DateTime(1970, 1, 1))).TotalSeconds; 54 | } 55 | public static double GetUnixTime() { 56 | return GetUnixTime(DateTime.UtcNow); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /ChromeDevExtWarningPatcher/InstallationFinder/Defaults/CustomPath.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO; 3 | using Microsoft.Win32; 4 | 5 | namespace ChromeDevExtWarningPatcher.InstallationFinder.Defaults { 6 | internal class CustomPath : Installation { 7 | private readonly string path; 8 | 9 | public CustomPath(string path) : base("CustomPath") { 10 | this.path = path; 11 | } 12 | 13 | public override List FindInstallationPaths() { 14 | List dllFiles = new List(); 15 | 16 | AddDllAndExeToList(dllFiles, this.GetLatestDllAndExe(new DirectoryInfo(this.path), "chrome.dll", "chrome.exe")); 17 | AddDllAndExeToList(dllFiles, this.GetLatestDllAndExe(new DirectoryInfo(this.path), "msedge.dll", "msedge.exe")); 18 | AddDllAndExeToList(dllFiles, this.GetLatestDllAndExe(new DirectoryInfo(this.path), "chrome.dll", "brave.exe")); 19 | AddDllAndExeToList(dllFiles, this.GetLatestDllAndExe(new DirectoryInfo(this.path), "browser.dll", "browser.exe")); 20 | 21 | return dllFiles; 22 | } 23 | 24 | public static InstallationPaths? GuiAddCustomPath() { 25 | OpenFileDialog openFile = new OpenFileDialog { 26 | Title = "Select a chrome.dll", 27 | Filter = "chrome.dll/msedge.dll file (chrome.dll;msedge.dll)|chrome.dll;msedge.dll|Alternative chrome.dll file (*.dll)|*.dll|All files (*.*)|*.*", 28 | FilterIndex = 1 29 | }; 30 | openFile.CheckFileExists = openFile.CheckPathExists = openFile.AddExtension = true; 31 | 32 | if (!openFile.ShowDialog() ?? true) { 33 | return null; 34 | } 35 | 36 | string chromeDllPath = openFile.FileName; 37 | 38 | openFile = new OpenFileDialog { 39 | Title = "Select a chrome.exe", 40 | Filter = "Browser executable file (*.exe)|*.exe|All files (*.*)|*.*", 41 | FilterIndex = 1 42 | }; 43 | openFile.CheckFileExists = openFile.CheckPathExists = openFile.AddExtension = true; 44 | openFile.InitialDirectory = Directory.GetParent(Path.GetDirectoryName(chromeDllPath)!)!.FullName; 45 | 46 | if (!openFile.ShowDialog() ?? true) { 47 | return null; 48 | } 49 | 50 | string chromeExePath = openFile.FileName; 51 | return new InstallationPaths("Custom Browser", chromeDllPath, chromeExePath); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /ChromeDllInjectorBuildZipper/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using System.IO; 4 | using System.IO.Compression; 5 | 6 | // This tool is helps in the build process 7 | namespace ChromeDllInjectorBuildZipper { 8 | internal class Program { 9 | public static void Main(string[] _) { 10 | Console.WriteLine("\n\n=== CHR DLL INJECTOR BUILD ZIPPER HELPER START ===\n"); 11 | 12 | string buildFolder = ProjectFileFinders.FindBuildFolder(); 13 | SignFiles(buildFolder); 14 | 15 | // Place zip file in the root project folder 16 | string zipFilePath = Path.Combine(buildFolder, "..", "..", "..", "..", "ChromeDllInjector.zip"); 17 | ZipFiles(buildFolder, zipFilePath); 18 | 19 | Console.WriteLine("\n=== CHR DLL INJECTOR BUILD ZIPPER HELPER DONE ===\n\n"); 20 | } 21 | 22 | private static void SignFiles(string buildFolder) { 23 | FileInfo? signExe = ProjectFileFinders.FindSignExecutor(new DirectoryInfo(Path.Combine(buildFolder, ".."))); 24 | 25 | if (signExe is null) { 26 | Console.Error.WriteLine("No sign executor found! Not signing any files now."); 27 | return; 28 | } 29 | 30 | ProcessStartInfo psi = new ProcessStartInfo("cmd.exe") { 31 | ArgumentList = { "/c", signExe.FullName }, 32 | WorkingDirectory = buildFolder 33 | }; 34 | Process? p = Process.Start(psi); 35 | p?.WaitForExit(); 36 | 37 | Console.WriteLine("Possibly signed all files."); 38 | } 39 | 40 | private static void ZipFiles(string buildFolder, string zipFilePath) { 41 | Console.WriteLine("Writing zip file to: " + zipFilePath); 42 | 43 | FileInfo zipFile = new FileInfo(zipFilePath); 44 | if (zipFile.Exists) { 45 | zipFile.Delete(); 46 | } 47 | 48 | using ZipArchive zip = ZipFile.Open(zipFile.FullName, ZipArchiveMode.Create); 49 | DirectoryInfo current = new DirectoryInfo(buildFolder); 50 | 51 | foreach (FileInfo file in current.EnumerateFiles()) { 52 | zip.CreateEntryFromFile(file.FullName, file.Name); 53 | } 54 | 55 | // Include the native binaries 56 | foreach (DirectoryInfo folder in current.EnumerateDirectories()) { 57 | if (folder.Name is not ("amd64" or "arm64" or "fr" or "ref" or "x86")) { 58 | continue; 59 | } 60 | 61 | zip.CreateEntryFromDirectory(folder.FullName, folder.Name); 62 | } 63 | 64 | Console.WriteLine("Wrote zip file."); 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /ChromeDevExtWarningPatcher/InstallationFinder/InstallationManager.cs: -------------------------------------------------------------------------------- 1 | using ChromeDevExtWarningPatcher.InstallationFinder.Defaults; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | 6 | namespace ChromeDevExtWarningPatcher.InstallationFinder { 7 | public class InstallationManager { 8 | private readonly List installationFinders = new List(); 9 | 10 | public InstallationManager() { 11 | this.installationFinders.Clear(); 12 | this.installationFinders.Add(new Chrome()); 13 | this.installationFinders.Add(new Brave()); 14 | this.installationFinders.Add(new Edge()); 15 | this.installationFinders.Add(new Yandex()); 16 | } 17 | 18 | public List FindAllChromiumInstallations() { 19 | List installations = new List(); 20 | 21 | foreach (Installation installation in this.installationFinders) { 22 | foreach (InstallationPaths paths in installation.FindInstallationPaths()) { 23 | if (paths.Is64Bit()) { // Force x64 installations 24 | installations.Add(paths); 25 | } 26 | } 27 | } 28 | 29 | return installations; 30 | } 31 | 32 | // Taken from https://stackoverflow.com/questions/480696/how-to-find-if-a-native-dll-file-is-compiled-as-x64-or-x86 33 | public static bool IsImageX64(string peFilePath) { 34 | using FileStream stream = new FileStream(peFilePath, FileMode.Open, FileAccess.Read); 35 | using BinaryReader reader = new BinaryReader(stream); 36 | 37 | //check the MZ signature to ensure it's a valid Portable Executable image 38 | if (reader.ReadUInt16() != 23117) { 39 | throw new BadImageFormatException("Not a valid Portable Executable image", peFilePath); 40 | } 41 | 42 | // seek to, and read, e_lfanew then advance the stream to there (start of NT header) 43 | stream.Seek(0x3A, SeekOrigin.Current); 44 | stream.Seek(reader.ReadUInt32(), SeekOrigin.Begin); 45 | 46 | // Ensure the NT header is valid by checking the "PE\0\0" signature 47 | if (reader.ReadUInt32() != 17744) { 48 | throw new BadImageFormatException("Not a valid Portable Executable image", peFilePath); 49 | } 50 | 51 | // seek past the file header, then read the magic number from the optional header 52 | stream.Seek(20, SeekOrigin.Current); 53 | ushort magicByte = reader.ReadUInt16(); 54 | return magicByte == 0x20B; 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /ChromePatcherDll/ChromePatcherDll.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Quelldateien 20 | 21 | 22 | Quelldateien 23 | 24 | 25 | Quelldateien 26 | 27 | 28 | Quelldateien 29 | 30 | 31 | Quelldateien 32 | 33 | 34 | 35 | 36 | Headerdateien 37 | 38 | 39 | Headerdateien 40 | 41 | 42 | Headerdateien 43 | 44 | 45 | Headerdateien 46 | 47 | 48 | Headerdateien 49 | 50 | 51 | Headerdateien 52 | 53 | 54 | Headerdateien 55 | 56 | 57 | 58 | 59 | Ressourcendateien 60 | 61 | 62 | -------------------------------------------------------------------------------- /ChromeDevExtWarningPatcher/ChromeDevExtWarningPatcher.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net6.0-windows10.0.17763.0 6 | enable 7 | true 8 | 6.0.0.0 9 | Ceiridge 10 | 11 | Chromium Developer Extension Warning Patcher 12 | Patches Chromium and disables the developer extension warning among others 13 | GNU General Public License 3, Ceiridge 14 | LICENSE 15 | https://github.com/Ceiridge/Chrome-Developer-Mode-Extension-Warning-Patcher 16 | https://github.com/Ceiridge/Chrome-Developer-Mode-Extension-Warning-Patcher 17 | 18 | true 19 | false 20 | ChromeDevExtWarningPatcher.MainClass 21 | app.manifest 22 | 6.0.0.0 23 | 7.0 24 | 25 | 26 | 27 | 28 | True 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | True 43 | True 44 | Resources.resx 45 | 46 | 47 | 48 | 49 | 50 | ResXFileCodeGenerator 51 | Resources.Designer.cs 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /ChromePatcherDll/simdpatternsearcher.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "patches.hpp" 3 | #include "simdpatternsearcher.hpp" 4 | 5 | namespace ChromePatch { 6 | constexpr int SIMD_BYTE_COUNT = 32; // 256 bit 7 | 8 | // Inspired by http://0x80.pl/articles/simd-strfind.html 9 | byte* SimdPatternSearcher::SearchBytePattern(Patch& patch, byte* startAddr, const size_t length) { 10 | for (PatchPattern& pattern : patch.patterns) { 11 | const size_t patternSize = pattern.pattern.size(); 12 | const __m256i firstByte = _mm256_set1_epi8(pattern.pattern[0]); // Set first __m256i to the first byte 13 | const __m256i lastByte = _mm256_set1_epi8(pattern.pattern[patternSize - 1]); // Set first __m256i to the last byte of the pattern 14 | 15 | for (size_t i = 0; i < length; i += SIMD_BYTE_COUNT) { 16 | const size_t lastBytesAdd = i + patternSize - 1; 17 | if (lastBytesAdd + SIMD_BYTE_COUNT > length) { // Prevent access violations 18 | break; 19 | } 20 | 21 | const __m256i firstBytes = _mm256_loadu_si256(reinterpret_cast(startAddr + i)); 22 | const __m256i lastBytes = _mm256_loadu_si256(reinterpret_cast(startAddr + lastBytesAdd)); 23 | 24 | const __m256i equalFirst = _mm256_cmpeq_epi8(firstByte, firstBytes); 25 | const __m256i equalLast = _mm256_cmpeq_epi8(lastByte, lastBytes); 26 | 27 | int equalityMask = _mm256_movemask_epi8(_mm256_and_si256(equalFirst, equalLast)); // AND operation -> save FFs of the __mm256i into mask 28 | 29 | while(equalityMask) { // Manually compare if the first and last byte were equal 30 | DWORD bitPos; 31 | _BitScanForward(&bitPos, equalityMask); 32 | 33 | pattern.searchOffset = 1; // Skip first byte, because it has already been compared 34 | for(size_t x = i + bitPos + 1; x < i + bitPos + patternSize - 1; x++) { // Also subtract one byte; same reason 35 | const byte patternByte = pattern.pattern[pattern.searchOffset]; 36 | if(patternByte == 0xFF || startAddr[x] == patternByte) { 37 | pattern.searchOffset++; 38 | } else { 39 | pattern.searchOffset = 0; 40 | } 41 | 42 | if (pattern.searchOffset == patternSize - 1) { 43 | return startAddr + x - pattern.searchOffset + 1; 44 | } 45 | } 46 | 47 | equalityMask &= equalityMask - 1; // Sets left-most bit to 0 48 | } 49 | } 50 | } 51 | 52 | return nullptr; 53 | } 54 | 55 | bool SimdPatternSearcher::IsCpuSupported() { 56 | return IsProcessorFeaturePresent(PF_AVX_INSTRUCTIONS_AVAILABLE) && IsProcessorFeaturePresent(PF_AVX2_INSTRUCTIONS_AVAILABLE); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /ChromePatcherDll/ChromePatcherDll.rc: -------------------------------------------------------------------------------- 1 | // Microsoft Visual C++ generated resource script. 2 | // 3 | #include "resource.h" 4 | 5 | #define APSTUDIO_READONLY_SYMBOLS 6 | ///////////////////////////////////////////////////////////////////////////// 7 | // 8 | // Generated from the TEXTINCLUDE 2 resource. 9 | // 10 | #include "winres.h" 11 | 12 | ///////////////////////////////////////////////////////////////////////////// 13 | #undef APSTUDIO_READONLY_SYMBOLS 14 | 15 | ///////////////////////////////////////////////////////////////////////////// 16 | // Deutsch (Deutschland) resources 17 | 18 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU) 19 | LANGUAGE LANG_GERMAN, SUBLANG_GERMAN 20 | #pragma code_page(1252) 21 | 22 | #ifdef APSTUDIO_INVOKED 23 | ///////////////////////////////////////////////////////////////////////////// 24 | // 25 | // TEXTINCLUDE 26 | // 27 | 28 | 1 TEXTINCLUDE 29 | BEGIN 30 | "resource.h\0" 31 | END 32 | 33 | 2 TEXTINCLUDE 34 | BEGIN 35 | "#include ""winres.h""\r\n" 36 | "\0" 37 | END 38 | 39 | 3 TEXTINCLUDE 40 | BEGIN 41 | "\r\n" 42 | "\0" 43 | END 44 | 45 | #endif // APSTUDIO_INVOKED 46 | 47 | 48 | ///////////////////////////////////////////////////////////////////////////// 49 | // 50 | // Version 51 | // 52 | 53 | VS_VERSION_INFO VERSIONINFO 54 | FILEVERSION 7,0,0,0 55 | PRODUCTVERSION 6,0,0,0 56 | FILEFLAGSMASK 0x3fL 57 | #ifdef _DEBUG 58 | FILEFLAGS 0x1L 59 | #else 60 | FILEFLAGS 0x0L 61 | #endif 62 | FILEOS 0x40004L 63 | FILETYPE 0x2L 64 | FILESUBTYPE 0x0L 65 | BEGIN 66 | BLOCK "StringFileInfo" 67 | BEGIN 68 | BLOCK "040004b0" 69 | BEGIN 70 | VALUE "CompanyName", "Ceiridge" 71 | VALUE "FileDescription", "Patches Chromium and disables the developer extension warning among others (https://github.com/Ceiridge/Chrome-Developer-Mode-Extension-Warning-Patcher)" 72 | VALUE "FileVersion", "7.0.0.0" 73 | VALUE "InternalName", "ChromePatcherDll.dll" 74 | VALUE "LegalCopyright", "GNU General Public License 3, Ceiridge" 75 | VALUE "OriginalFilename", "ChromePatcherDll.dll" 76 | VALUE "ProductName", "Chromium Developer Extension Warning Patcher" 77 | VALUE "ProductVersion", "6.0.0.0" 78 | END 79 | END 80 | BLOCK "VarFileInfo" 81 | BEGIN 82 | VALUE "Translation", 0x400, 1200 83 | END 84 | END 85 | 86 | #endif // Deutsch (Deutschland) resources 87 | ///////////////////////////////////////////////////////////////////////////// 88 | 89 | 90 | 91 | #ifndef APSTUDIO_INVOKED 92 | ///////////////////////////////////////////////////////////////////////////// 93 | // 94 | // Generated from the TEXTINCLUDE 3 resource. 95 | // 96 | 97 | 98 | ///////////////////////////////////////////////////////////////////////////// 99 | #endif // not APSTUDIO_INVOKED 100 | 101 | -------------------------------------------------------------------------------- /ChromeDevExtWarningPatcher/MainView.xaml: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 |