├── img ├── flow.png ├── flow1.png ├── logo.png ├── proxy-rule.png ├── ProxyBridge.png ├── proxy-rule2.png ├── ProxyBridge-mac.png ├── ProxyBridge_CLI.png ├── proxy-rule-mac.png ├── proxy-rule2-mac.png ├── proxy-setting.png └── proxy-setting-mac.png ├── .github ├── FUNDING.yml └── workflows │ ├── build-mac.yml │ └── build.yml ├── Windows ├── gui │ ├── Assets │ │ └── logo.ico │ ├── Views │ │ ├── UpdateCheckWindow.axaml.cs │ │ ├── UpdateNotificationWindow.axaml.cs │ │ ├── AboutWindow.axaml.cs │ │ ├── ProxySettingsWindow.axaml.cs │ │ ├── MainWindow.axaml.cs │ │ ├── AboutWindow.axaml │ │ ├── UpdateNotificationWindow.axaml │ │ ├── ProxyRulesWindow.axaml.cs │ │ ├── UpdateCheckWindow.axaml │ │ └── ProxySettingsWindow.axaml │ ├── Program.cs │ ├── ViewModels │ │ ├── AboutViewModel.cs │ │ ├── ViewModelBase.cs │ │ ├── UpdateNotificationViewModel.cs │ │ ├── UpdateCheckViewModel.cs │ │ └── ProxySettingsViewModel.cs │ ├── app.manifest │ ├── App.axaml │ ├── App.axaml.cs │ ├── Services │ │ ├── SettingsService.cs │ │ ├── ConfigManager.cs │ │ ├── ProxyBridgeService.cs │ │ ├── Loc.cs │ │ └── UpdateService.cs │ ├── ProxyBridge.GUI.csproj │ ├── Interop │ │ └── ProxyBridgeNative.cs │ └── Resources │ │ ├── Resources.zh.resx │ │ └── Resources.resx ├── cli │ ├── ProxyBridge.CLI.csproj │ └── ProxyBridgeNative.cs ├── src │ └── ProxyBridge.h ├── installer │ └── ProxyBridge.nsi └── compile.ps1 ├── MacOS └── ProxyBridge │ ├── ProxyBridge │ ├── Assets.xcassets │ │ ├── Contents.json │ │ ├── AppIcon.appiconset │ │ │ ├── icon_16x16.png │ │ │ ├── icon_32x32.png │ │ │ ├── icon_128x128.png │ │ │ ├── icon_16x16@2x.png │ │ │ ├── icon_256x256.png │ │ │ ├── icon_32x32@2x.png │ │ │ ├── icon_512x512.png │ │ │ ├── icon_128x128@2x.png │ │ │ ├── icon_256x256@2x.png │ │ │ ├── icon_512x512@2x.png │ │ │ └── Contents.json │ │ └── AccentColor.colorset │ │ │ └── Contents.json │ ├── ProxyBridge.entitlements │ ├── ProxyBridgeRelease.entitlements │ ├── AboutView.swift │ ├── UpdateNotificationView.swift │ ├── ProxyBridgeGUI.swift │ ├── UpdateService.swift │ ├── UpdateCheckView.swift │ ├── ContentView.swift │ ├── ProxySettingsView.swift │ └── RuleManager.swift │ ├── extension │ ├── main.swift │ ├── extension.entitlements │ └── Info.plist │ ├── ExportOptions.plist │ └── build.sh ├── LICENSE ├── .gitignore └── README.md /img/flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/InterceptSuite/ProxyBridge/HEAD/img/flow.png -------------------------------------------------------------------------------- /img/flow1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/InterceptSuite/ProxyBridge/HEAD/img/flow1.png -------------------------------------------------------------------------------- /img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/InterceptSuite/ProxyBridge/HEAD/img/logo.png -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: Anof-Cyber 2 | custom: 3 | - https://www.buymeacoffee.com/AnoF -------------------------------------------------------------------------------- /img/proxy-rule.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/InterceptSuite/ProxyBridge/HEAD/img/proxy-rule.png -------------------------------------------------------------------------------- /img/ProxyBridge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/InterceptSuite/ProxyBridge/HEAD/img/ProxyBridge.png -------------------------------------------------------------------------------- /img/proxy-rule2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/InterceptSuite/ProxyBridge/HEAD/img/proxy-rule2.png -------------------------------------------------------------------------------- /img/ProxyBridge-mac.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/InterceptSuite/ProxyBridge/HEAD/img/ProxyBridge-mac.png -------------------------------------------------------------------------------- /img/ProxyBridge_CLI.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/InterceptSuite/ProxyBridge/HEAD/img/ProxyBridge_CLI.png -------------------------------------------------------------------------------- /img/proxy-rule-mac.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/InterceptSuite/ProxyBridge/HEAD/img/proxy-rule-mac.png -------------------------------------------------------------------------------- /img/proxy-rule2-mac.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/InterceptSuite/ProxyBridge/HEAD/img/proxy-rule2-mac.png -------------------------------------------------------------------------------- /img/proxy-setting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/InterceptSuite/ProxyBridge/HEAD/img/proxy-setting.png -------------------------------------------------------------------------------- /img/proxy-setting-mac.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/InterceptSuite/ProxyBridge/HEAD/img/proxy-setting-mac.png -------------------------------------------------------------------------------- /Windows/gui/Assets/logo.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/InterceptSuite/ProxyBridge/HEAD/Windows/gui/Assets/logo.ico -------------------------------------------------------------------------------- /MacOS/ProxyBridge/ProxyBridge/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /MacOS/ProxyBridge/ProxyBridge/Assets.xcassets/AppIcon.appiconset/icon_16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/InterceptSuite/ProxyBridge/HEAD/MacOS/ProxyBridge/ProxyBridge/Assets.xcassets/AppIcon.appiconset/icon_16x16.png -------------------------------------------------------------------------------- /MacOS/ProxyBridge/ProxyBridge/Assets.xcassets/AppIcon.appiconset/icon_32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/InterceptSuite/ProxyBridge/HEAD/MacOS/ProxyBridge/ProxyBridge/Assets.xcassets/AppIcon.appiconset/icon_32x32.png -------------------------------------------------------------------------------- /MacOS/ProxyBridge/ProxyBridge/Assets.xcassets/AppIcon.appiconset/icon_128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/InterceptSuite/ProxyBridge/HEAD/MacOS/ProxyBridge/ProxyBridge/Assets.xcassets/AppIcon.appiconset/icon_128x128.png -------------------------------------------------------------------------------- /MacOS/ProxyBridge/ProxyBridge/Assets.xcassets/AppIcon.appiconset/icon_16x16@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/InterceptSuite/ProxyBridge/HEAD/MacOS/ProxyBridge/ProxyBridge/Assets.xcassets/AppIcon.appiconset/icon_16x16@2x.png -------------------------------------------------------------------------------- /MacOS/ProxyBridge/ProxyBridge/Assets.xcassets/AppIcon.appiconset/icon_256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/InterceptSuite/ProxyBridge/HEAD/MacOS/ProxyBridge/ProxyBridge/Assets.xcassets/AppIcon.appiconset/icon_256x256.png -------------------------------------------------------------------------------- /MacOS/ProxyBridge/ProxyBridge/Assets.xcassets/AppIcon.appiconset/icon_32x32@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/InterceptSuite/ProxyBridge/HEAD/MacOS/ProxyBridge/ProxyBridge/Assets.xcassets/AppIcon.appiconset/icon_32x32@2x.png -------------------------------------------------------------------------------- /MacOS/ProxyBridge/ProxyBridge/Assets.xcassets/AppIcon.appiconset/icon_512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/InterceptSuite/ProxyBridge/HEAD/MacOS/ProxyBridge/ProxyBridge/Assets.xcassets/AppIcon.appiconset/icon_512x512.png -------------------------------------------------------------------------------- /MacOS/ProxyBridge/ProxyBridge/Assets.xcassets/AppIcon.appiconset/icon_128x128@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/InterceptSuite/ProxyBridge/HEAD/MacOS/ProxyBridge/ProxyBridge/Assets.xcassets/AppIcon.appiconset/icon_128x128@2x.png -------------------------------------------------------------------------------- /MacOS/ProxyBridge/ProxyBridge/Assets.xcassets/AppIcon.appiconset/icon_256x256@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/InterceptSuite/ProxyBridge/HEAD/MacOS/ProxyBridge/ProxyBridge/Assets.xcassets/AppIcon.appiconset/icon_256x256@2x.png -------------------------------------------------------------------------------- /MacOS/ProxyBridge/ProxyBridge/Assets.xcassets/AppIcon.appiconset/icon_512x512@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/InterceptSuite/ProxyBridge/HEAD/MacOS/ProxyBridge/ProxyBridge/Assets.xcassets/AppIcon.appiconset/icon_512x512@2x.png -------------------------------------------------------------------------------- /MacOS/ProxyBridge/ProxyBridge/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Windows/gui/Views/UpdateCheckWindow.axaml.cs: -------------------------------------------------------------------------------- 1 | using Avalonia.Controls; 2 | 3 | namespace ProxyBridge.GUI.Views; 4 | 5 | public partial class UpdateCheckWindow : Window 6 | { 7 | public UpdateCheckWindow() 8 | { 9 | InitializeComponent(); 10 | } 11 | } -------------------------------------------------------------------------------- /Windows/gui/Views/UpdateNotificationWindow.axaml.cs: -------------------------------------------------------------------------------- 1 | using Avalonia.Controls; 2 | 3 | namespace ProxyBridge.GUI.Views; 4 | 5 | public partial class UpdateNotificationWindow : Window 6 | { 7 | public UpdateNotificationWindow() 8 | { 9 | InitializeComponent(); 10 | } 11 | } -------------------------------------------------------------------------------- /MacOS/ProxyBridge/extension/main.swift: -------------------------------------------------------------------------------- 1 | // 2 | // main.swift 3 | // extension 4 | // 5 | // Created by sourav kalal on 13/11/25. 6 | // 7 | 8 | import Foundation 9 | import NetworkExtension 10 | 11 | autoreleasepool { 12 | NEProvider.startSystemExtensionMode() 13 | } 14 | 15 | dispatchMain() 16 | -------------------------------------------------------------------------------- /Windows/gui/Program.cs: -------------------------------------------------------------------------------- 1 | using Avalonia; 2 | using System; 3 | 4 | namespace ProxyBridge.GUI; 5 | 6 | class Program 7 | { 8 | [STAThread] 9 | public static void Main(string[] args) 10 | { 11 | BuildAvaloniaApp() 12 | .StartWithClassicDesktopLifetime(args); 13 | } 14 | 15 | public static AppBuilder BuildAvaloniaApp() 16 | => AppBuilder.Configure() 17 | .UsePlatformDetect() 18 | .WithInterFont() 19 | .LogToTrace(); 20 | } 21 | -------------------------------------------------------------------------------- /MacOS/ProxyBridge/ExportOptions.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | method 7 | mac-application 8 | signingStyle 9 | automatic 10 | stripSwiftSymbols 11 | 12 | thinning 13 | <none> 14 | uploadSymbols 15 | 16 | 17 | -------------------------------------------------------------------------------- /MacOS/ProxyBridge/extension/extension.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.developer.networking.networkextension 6 | 7 | app-proxy-provider 8 | 9 | com.apple.security.application-groups 10 | 11 | group.com.interceptsuite.ProxyBridge 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /MacOS/ProxyBridge/ProxyBridge/ProxyBridge.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.developer.system-extension.install 6 | 7 | com.apple.developer.networking.networkextension 8 | 9 | app-proxy-provider 10 | transparent-proxy 11 | 12 | com.apple.security.files.user-selected.read-write 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /MacOS/ProxyBridge/extension/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSSystemExtensionUsageDescription 6 | ProxyBridge needs to install a system extension to intercept network traffic 7 | NetworkExtension 8 | 9 | NEProviderClasses 10 | 11 | com.apple.networkextension.app-proxy 12 | $(PRODUCT_MODULE_NAME).AppProxyProvider 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /MacOS/ProxyBridge/ProxyBridge/ProxyBridgeRelease.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.developer.networking.networkextension 6 | 7 | app-proxy-provider 8 | 9 | com.apple.developer.system-extension.install 10 | 11 | com.apple.security.application-groups 12 | 13 | group.com.interceptsuite.ProxyBridge 14 | 15 | com.apple.security.files.user-selected.read-write 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /Windows/gui/ViewModels/AboutViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | using System.Windows.Input; 4 | 5 | namespace ProxyBridge.GUI.ViewModels; 6 | 7 | public class AboutViewModel 8 | { 9 | public string Version { get; } 10 | public ICommand CloseCommand { get; } 11 | 12 | public AboutViewModel() : this(() => { }) 13 | { 14 | } 15 | 16 | public AboutViewModel(Action onClose) 17 | { 18 | var version = Assembly.GetExecutingAssembly().GetName().Version; 19 | Version = version != null 20 | ? $"Version {version.Major}.{version.Minor}.{version.Build}" 21 | : "Version 1.0.0"; 22 | 23 | CloseCommand = new RelayCommand(onClose); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Windows/gui/ViewModels/ViewModelBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using System.Runtime.CompilerServices; 4 | 5 | namespace ProxyBridge.GUI.ViewModels; 6 | 7 | public class ViewModelBase : INotifyPropertyChanged 8 | { 9 | public event PropertyChangedEventHandler? PropertyChanged; 10 | 11 | protected void OnPropertyChanged([CallerMemberName] string? propertyName = null) 12 | { 13 | PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 14 | } 15 | 16 | protected bool SetProperty(ref T field, T value, [CallerMemberName] string? propertyName = null) 17 | { 18 | if (Equals(field, value)) return false; 19 | field = value; 20 | OnPropertyChanged(propertyName); 21 | return true; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Windows/gui/app.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | ProxyBridge - Network Traffic Proxy Control 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Windows/gui/App.axaml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /.github/workflows/build-mac.yml: -------------------------------------------------------------------------------- 1 | name: Build macOS 2 | permissions: 3 | contents: read 4 | 5 | on: 6 | push: 7 | branches: [ dev, main, master ] 8 | pull_request: 9 | branches: [ dev, main, master ] 10 | workflow_dispatch: 11 | 12 | jobs: 13 | build: 14 | runs-on: macos-latest 15 | 16 | steps: 17 | - name: Checkout code 18 | uses: actions/checkout@v4 19 | 20 | - name: Set up Xcode 21 | uses: maxim-lobanov/setup-xcode@v1 22 | with: 23 | xcode-version: latest-stable 24 | 25 | - name: Build ProxyBridge 26 | run: | 27 | cd MacOS/ProxyBridge 28 | chmod +x build.sh 29 | ./build.sh 30 | env: 31 | SIGN_APP: "" 32 | SIGN_PKG: "" 33 | NOTARIZE: "" 34 | 35 | - name: Upload PKG artifact 36 | uses: actions/upload-artifact@v4 37 | with: 38 | name: ProxyBridge-macOS 39 | path: MacOS/ProxyBridge/output/ProxyBridge-Installer.pkg 40 | retention-days: 30 41 | -------------------------------------------------------------------------------- /Windows/gui/Views/AboutWindow.axaml.cs: -------------------------------------------------------------------------------- 1 | using Avalonia.Controls; 2 | using System.Diagnostics; 3 | using Avalonia.Input; 4 | 5 | namespace ProxyBridge.GUI.Views; 6 | 7 | public partial class AboutWindow : Window 8 | { 9 | public AboutWindow() 10 | { 11 | InitializeComponent(); 12 | } 13 | 14 | private void OnWebsiteClick(object? sender, PointerPressedEventArgs e) 15 | { 16 | OpenUrl("https://interceptsuite.com"); 17 | } 18 | 19 | private void OnGitHubClick(object? sender, PointerPressedEventArgs e) 20 | { 21 | OpenUrl("https://github.com/InterceptSuite/ProxyBridge"); 22 | } 23 | 24 | private void OpenUrl(string url) 25 | { 26 | try 27 | { 28 | Process.Start(new ProcessStartInfo 29 | { 30 | FileName = url, 31 | UseShellExecute = true 32 | }); 33 | } 34 | catch 35 | { 36 | // Silently fail if browser can't be opened 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Anof-cyber/InterceptSuite 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Windows/cli/ProxyBridge.CLI.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net9.0-windows 6 | enable 7 | enable 8 | ProxyBridge_CLI 9 | 3.0.0 10 | true 11 | false 12 | true 13 | 14 | Size 15 | false 16 | true 17 | false 18 | true 19 | false 20 | false 21 | false 22 | false 23 | 24 | true 25 | link 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Windows 2 | 3 | *.exe 4 | *.dll 5 | *.sys 6 | *.zip 7 | *.py 8 | build/** 9 | *.pyc 10 | Windows/gui/bin/** 11 | Windows/gui/obj/** 12 | Windows/cli/bin/** 13 | Windows/cli/obj/** 14 | .vscode/** 15 | Windows/output/ProxyBridge_CLI.pdb 16 | 17 | ## macOS / Xcode / Swift 18 | 19 | # Build environment 20 | MacOS/ProxyBridge/.env 21 | MacOS/ProxyBridge/output/ 22 | MacOS/ProxyBridge/build/ 23 | 24 | # Xcode 25 | xcuserdata/ 26 | *.xcscmblueprint 27 | *.xccheckout 28 | *.moved-aside 29 | DerivedData/ 30 | *.hmap 31 | *.ipa 32 | *.dSYM.zip 33 | *.dSYM 34 | 35 | # CocoaPods 36 | Pods/ 37 | *.xcworkspace 38 | !default.xcworkspace 39 | 40 | # Carthage 41 | Carthage/Build/ 42 | 43 | # Swift Package Manager 44 | .build/ 45 | .swiftpm/ 46 | Package.resolved 47 | 48 | # Playgrounds 49 | timeline.xctimeline 50 | playground.xcworkspace 51 | 52 | # Swift 53 | *.swp 54 | *~.nib 55 | *.swiftdoc 56 | *.swiftmodule 57 | 58 | # macOS 59 | .DS_Store 60 | .AppleDouble 61 | .LSOverride 62 | 63 | # Thumbnails 64 | ._* 65 | 66 | # Files that might appear in the root of a volume 67 | .DocumentRevisions-V100 68 | .fseventsd 69 | .Spotlight-V100 70 | .TemporaryItems 71 | .Trashes 72 | .VolumeIcon.icns 73 | .com.apple.timemachine.donotpresent 74 | 75 | # Directories potentially created on remote AFP share 76 | .AppleDB 77 | .AppleDesktop 78 | Network Trash Folder 79 | Temporary Items 80 | .apdisk 81 | MacOS/ProxyBridge/build/ 82 | MacOS/ProxyBridge/output/ 83 | 84 | Linux/** 85 | -------------------------------------------------------------------------------- /Windows/gui/Views/ProxySettingsWindow.axaml.cs: -------------------------------------------------------------------------------- 1 | using Avalonia.Controls; 2 | using Avalonia.Interactivity; 3 | using ProxyBridge.GUI.ViewModels; 4 | 5 | namespace ProxyBridge.GUI.Views; 6 | 7 | public partial class ProxySettingsWindow : Window 8 | { 9 | public ProxySettingsWindow() 10 | { 11 | InitializeComponent(); 12 | 13 | this.Opened += (s, e) => 14 | { 15 | if (DataContext is ProxySettingsViewModel vm) 16 | { 17 | var comboBox = this.FindControl("ProxyTypeComboBox"); 18 | if (comboBox != null) 19 | { 20 | foreach (var obj in comboBox.Items) 21 | { 22 | if (obj is ComboBoxItem item && item.Tag is string tag && tag == vm.ProxyType) 23 | { 24 | comboBox.SelectedItem = item; 25 | break; 26 | } 27 | } 28 | 29 | comboBox.SelectionChanged += (sender, args) => 30 | { 31 | if (DataContext is ProxySettingsViewModel vm2) 32 | { 33 | if (comboBox.SelectedItem is ComboBoxItem sel && sel.Tag is string selTag) 34 | { 35 | vm2.ProxyType = selTag; 36 | } 37 | } 38 | }; 39 | } 40 | } 41 | }; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /MacOS/ProxyBridge/ProxyBridge/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "icon_16x16.png", 5 | "idiom" : "mac", 6 | "scale" : "1x", 7 | "size" : "16x16" 8 | }, 9 | { 10 | "filename" : "icon_16x16@2x.png", 11 | "idiom" : "mac", 12 | "scale" : "2x", 13 | "size" : "16x16" 14 | }, 15 | { 16 | "filename" : "icon_32x32.png", 17 | "idiom" : "mac", 18 | "scale" : "1x", 19 | "size" : "32x32" 20 | }, 21 | { 22 | "filename" : "icon_32x32@2x.png", 23 | "idiom" : "mac", 24 | "scale" : "2x", 25 | "size" : "32x32" 26 | }, 27 | { 28 | "filename" : "icon_128x128.png", 29 | "idiom" : "mac", 30 | "scale" : "1x", 31 | "size" : "128x128" 32 | }, 33 | { 34 | "filename" : "icon_128x128@2x.png", 35 | "idiom" : "mac", 36 | "scale" : "2x", 37 | "size" : "128x128" 38 | }, 39 | { 40 | "filename" : "icon_256x256.png", 41 | "idiom" : "mac", 42 | "scale" : "1x", 43 | "size" : "256x256" 44 | }, 45 | { 46 | "filename" : "icon_256x256@2x.png", 47 | "idiom" : "mac", 48 | "scale" : "2x", 49 | "size" : "256x256" 50 | }, 51 | { 52 | "filename" : "icon_512x512.png", 53 | "idiom" : "mac", 54 | "scale" : "1x", 55 | "size" : "512x512" 56 | }, 57 | { 58 | "filename" : "icon_512x512@2x.png", 59 | "idiom" : "mac", 60 | "scale" : "2x", 61 | "size" : "512x512" 62 | } 63 | ], 64 | "info" : { 65 | "author" : "xcode", 66 | "version" : 1 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /Windows/gui/App.axaml.cs: -------------------------------------------------------------------------------- 1 | using Avalonia; 2 | using Avalonia.Controls.ApplicationLifetimes; 3 | using Avalonia.Markup.Xaml; 4 | using Avalonia.Controls; 5 | using ProxyBridge.GUI.ViewModels; 6 | using ProxyBridge.GUI.Views; 7 | using System; 8 | 9 | namespace ProxyBridge.GUI; 10 | 11 | public class App : Application 12 | { 13 | public override void Initialize() 14 | { 15 | AvaloniaXamlLoader.Load(this); 16 | } 17 | 18 | public override void OnFrameworkInitializationCompleted() 19 | { 20 | if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) 21 | { 22 | desktop.MainWindow = new MainWindow 23 | { 24 | DataContext = new MainWindowViewModel() 25 | }; 26 | 27 | // save config during shutdown 28 | desktop.ShutdownRequested += (s, e) => 29 | { 30 | if (desktop.MainWindow?.DataContext is MainWindowViewModel vm) 31 | { 32 | vm.Cleanup(); 33 | } 34 | }; 35 | } 36 | 37 | base.OnFrameworkInitializationCompleted(); 38 | } 39 | // https://docs.avaloniaui.net/docs/reference/controls/tray-icon 40 | public void TrayIcon_Show(object? sender, EventArgs e) 41 | { 42 | if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) 43 | { 44 | var mainWindow = desktop.MainWindow; 45 | if (mainWindow != null) 46 | { 47 | mainWindow.Show(); 48 | mainWindow.WindowState = WindowState.Normal; 49 | mainWindow.Activate(); 50 | } 51 | } 52 | } 53 | 54 | public void TrayIcon_Exit(object? sender, EventArgs e) 55 | { 56 | if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) 57 | { 58 | desktop.Shutdown(); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /Windows/gui/Services/SettingsService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Text.Json; 4 | using System.Text.Json.Serialization; 5 | 6 | namespace ProxyBridge.GUI.Services; 7 | 8 | [JsonSourceGenerationOptions(WriteIndented = true)] 9 | [JsonSerializable(typeof(AppSettings))] 10 | internal partial class AppSettingsContext : JsonSerializerContext 11 | { 12 | } 13 | 14 | public class SettingsService 15 | { 16 | private static readonly string SettingsPath = Path.Combine( 17 | Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), 18 | "ProxyBridge", 19 | "settings.json"); 20 | 21 | public AppSettings LoadSettings() 22 | { 23 | try 24 | { 25 | if (File.Exists(SettingsPath)) 26 | { 27 | var json = File.ReadAllText(SettingsPath); 28 | var settings = JsonSerializer.Deserialize(json, AppSettingsContext.Default.AppSettings); 29 | return settings ?? new AppSettings(); 30 | } 31 | } 32 | catch 33 | { 34 | // If there's any error loading settings, return defaults 35 | } 36 | 37 | return new AppSettings(); 38 | } 39 | 40 | public void SaveSettings(AppSettings settings) 41 | { 42 | try 43 | { 44 | var directory = Path.GetDirectoryName(SettingsPath); 45 | if (directory != null && !Directory.Exists(directory)) 46 | { 47 | Directory.CreateDirectory(directory); 48 | } 49 | 50 | var json = JsonSerializer.Serialize(settings, AppSettingsContext.Default.AppSettings); 51 | File.WriteAllText(SettingsPath, json); 52 | } 53 | catch 54 | { 55 | // silently fail 56 | } 57 | } 58 | } 59 | 60 | public class AppSettings 61 | { 62 | public bool CheckForUpdatesOnStartup { get; set; } = true; 63 | public DateTime LastUpdateCheck { get; set; } = DateTime.MinValue; 64 | } -------------------------------------------------------------------------------- /Windows/gui/ProxyBridge.GUI.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | WinExe 4 | net9.0-windows 5 | enable 6 | true 7 | app.manifest 8 | ProxyBridge 9 | ProxyBridge.GUI 10 | 3.0.0 11 | Assets\logo.ico 12 | 13 | true 14 | false 15 | Speed 16 | false 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | ResXFileCodeGenerator 26 | Resources.Designer.cs 27 | 28 | 29 | Resources.resx 30 | 31 | 32 | 33 | 34 | 35 | True 36 | True 37 | Resources.resx 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /Windows/src/ProxyBridge.h: -------------------------------------------------------------------------------- 1 | #ifndef PROXYBRIDGE_H 2 | #define PROXYBRIDGE_H 3 | 4 | #include 5 | 6 | #ifdef PROXYBRIDGE_EXPORTS 7 | #define PROXYBRIDGE_API __declspec(dllexport) 8 | #else 9 | #define PROXYBRIDGE_API __declspec(dllimport) 10 | #endif 11 | 12 | #ifdef __cplusplus 13 | extern "C" { 14 | #endif 15 | 16 | typedef void (*LogCallback)(const char* message); 17 | typedef void (*ConnectionCallback)(const char* process_name, DWORD pid, const char* dest_ip, UINT16 dest_port, const char* proxy_info); 18 | 19 | typedef enum { 20 | PROXY_TYPE_HTTP = 0, 21 | PROXY_TYPE_SOCKS5 = 1 22 | } ProxyType; 23 | 24 | typedef enum { 25 | RULE_ACTION_PROXY = 0, 26 | RULE_ACTION_DIRECT = 1, 27 | RULE_ACTION_BLOCK = 2 28 | } RuleAction; 29 | 30 | typedef enum { 31 | RULE_PROTOCOL_TCP = 0, 32 | RULE_PROTOCOL_UDP = 1, 33 | RULE_PROTOCOL_BOTH = 2 34 | } RuleProtocol; 35 | 36 | PROXYBRIDGE_API UINT32 ProxyBridge_AddRule(const char* process_name, const char* target_hosts, const char* target_ports, RuleProtocol protocol, RuleAction action); 37 | PROXYBRIDGE_API BOOL ProxyBridge_EnableRule(UINT32 rule_id); 38 | PROXYBRIDGE_API BOOL ProxyBridge_DisableRule(UINT32 rule_id); 39 | PROXYBRIDGE_API BOOL ProxyBridge_DeleteRule(UINT32 rule_id); 40 | PROXYBRIDGE_API BOOL ProxyBridge_EditRule(UINT32 rule_id, const char* process_name, const char* target_hosts, const char* target_ports, RuleProtocol protocol, RuleAction action); 41 | PROXYBRIDGE_API BOOL ProxyBridge_SetProxyConfig(ProxyType type, const char* proxy_ip, UINT16 proxy_port, const char* username, const char* password); // proxy_ip can be IP address or hostname 42 | PROXYBRIDGE_API void ProxyBridge_SetDnsViaProxy(BOOL enable); 43 | PROXYBRIDGE_API void ProxyBridge_SetLogCallback(LogCallback callback); 44 | PROXYBRIDGE_API void ProxyBridge_SetConnectionCallback(ConnectionCallback callback); 45 | PROXYBRIDGE_API BOOL ProxyBridge_Start(void); 46 | PROXYBRIDGE_API BOOL ProxyBridge_Stop(void); 47 | PROXYBRIDGE_API int ProxyBridge_TestConnection(const char* target_host, UINT16 target_port, char* result_buffer, size_t buffer_size); 48 | 49 | #ifdef __cplusplus 50 | } 51 | #endif 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /Windows/gui/Views/MainWindow.axaml.cs: -------------------------------------------------------------------------------- 1 | using Avalonia.Controls; 2 | using ProxyBridge.GUI.ViewModels; 3 | using System; 4 | using System.ComponentModel; 5 | using Avalonia.Interactivity; 6 | 7 | namespace ProxyBridge.GUI.Views; 8 | 9 | public partial class MainWindow : Window 10 | { 11 | public MainWindow() 12 | { 13 | InitializeComponent(); 14 | 15 | // Set window reference in ViewModel 16 | this.Opened += (s, e) => 17 | { 18 | if (DataContext is MainWindowViewModel vm) 19 | { 20 | vm.SetMainWindow(this); 21 | } 22 | }; 23 | } 24 | 25 | private void OnChangeLanguageEnglish(object? sender, RoutedEventArgs e) 26 | { 27 | if (DataContext is MainWindowViewModel vm) 28 | { 29 | vm.ChangeLanguage("en"); 30 | } 31 | } 32 | 33 | private void OnChangeLanguageChinese(object? sender, RoutedEventArgs e) 34 | { 35 | if (DataContext is MainWindowViewModel vm) 36 | { 37 | vm.ChangeLanguage("zh"); 38 | } 39 | } 40 | 41 | protected override void OnClosing(WindowClosingEventArgs e) 42 | { 43 | if (e.CloseReason == WindowCloseReason.ApplicationShutdown) 44 | { 45 | if (DataContext is MainWindowViewModel vm) 46 | { 47 | vm.Cleanup(); 48 | } 49 | base.OnClosing(e); 50 | return; 51 | } 52 | 53 | // verify if user cclose app or minimize to tray 54 | if (DataContext is MainWindowViewModel viewModel) 55 | { 56 | if (viewModel.CloseToTray) 57 | { 58 | // minimize to tray 59 | e.Cancel = true; 60 | this.Hide(); 61 | } 62 | else 63 | { 64 | // exit the app if not tray 65 | viewModel.Cleanup(); 66 | base.OnClosing(e); 67 | } 68 | } 69 | else 70 | { 71 | // fallback to tray 72 | e.Cancel = true; 73 | this.Hide(); 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /MacOS/ProxyBridge/ProxyBridge/AboutView.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct AboutView: View { 4 | @Environment(\.dismiss) var dismiss 5 | 6 | var body: some View { 7 | VStack(spacing: 20) { 8 | Text("ProxyBridge") 9 | .font(.system(size: 28, weight: .bold)) 10 | .foregroundColor(.accentColor) 11 | 12 | Text("Version 3.0") 13 | .font(.system(size: 14)) 14 | .foregroundColor(.secondary) 15 | 16 | Text("Universal proxy client for macOS applications") 17 | .font(.system(size: 14)) 18 | .foregroundColor(.secondary) 19 | .multilineTextAlignment(.center) 20 | .padding(.bottom, 8) 21 | 22 | Text("Author: Sourav Kalal / InterceptSuite") 23 | .font(.system(size: 13)) 24 | .foregroundColor(.secondary) 25 | .padding(.top, 4) 26 | 27 | VStack(spacing: 12) { 28 | HStack { 29 | Text("Website:") 30 | .foregroundColor(.secondary) 31 | Link("interceptsuite.com", destination: URL(string: "https://interceptsuite.com")!) 32 | .foregroundColor(.accentColor) 33 | } 34 | 35 | HStack { 36 | Text("GitHub:") 37 | .foregroundColor(.secondary) 38 | Link("github.com/InterceptSuite/ProxyBridge", destination: URL(string: "https://github.com/InterceptSuite/ProxyBridge")!) 39 | .foregroundColor(.accentColor) 40 | } 41 | } 42 | .font(.system(size: 13)) 43 | 44 | Text("License: MIT") 45 | .font(.system(size: 13)) 46 | .foregroundColor(.secondary) 47 | .padding(.top, 8) 48 | 49 | Button("Close") { 50 | dismiss() 51 | } 52 | .keyboardShortcut(.defaultAction) 53 | .padding(.top, 12) 54 | } 55 | .padding(32) 56 | .frame(width: 400, height: 350) 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build ProxyBridge 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | pull_request: 7 | branches: [ main ] 8 | workflow_dispatch: 9 | 10 | jobs: 11 | build: 12 | runs-on: windows-latest 13 | 14 | steps: 15 | - name: Checkout code 16 | uses: actions/checkout@v4 17 | 18 | - name: Setup .NET 19 | uses: actions/setup-dotnet@v4 20 | with: 21 | dotnet-version: '9.0.x' 22 | 23 | - name: Setup MSYS2 (for GCC) 24 | uses: msys2/setup-msys2@v2 25 | with: 26 | msystem: MINGW64 27 | update: true 28 | install: >- 29 | mingw-w64-x86_64-gcc 30 | mingw-w64-x86_64-toolchain 31 | 32 | - name: Add MSYS2 to PATH 33 | run: echo "C:\msys64\mingw64\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append 34 | shell: pwsh 35 | 36 | - name: Install NSIS 37 | run: | 38 | choco install nsis -y 39 | shell: pwsh 40 | 41 | - name: Download WinDivert 42 | run: | 43 | $url = "https://github.com/basil00/Divert/releases/download/v2.2.2/WinDivert-2.2.2-A.zip" 44 | Invoke-WebRequest -Uri $url -OutFile "WinDivert.zip" 45 | Expand-Archive -Path "WinDivert.zip" -DestinationPath "C:\" 46 | shell: pwsh 47 | 48 | - name: Verify WinDivert installation 49 | run: | 50 | if (Test-Path "C:\WinDivert-2.2.2-A") { 51 | Write-Host "WinDivert installed successfully" 52 | Get-ChildItem "C:\WinDivert-2.2.2-A" -Recurse | Select-Object FullName 53 | } else { 54 | Write-Error "WinDivert installation failed" 55 | exit 1 56 | } 57 | shell: pwsh 58 | 59 | - name: Build project 60 | run: .\Windows\compile.ps1 -NoSign -Compiler gcc 61 | shell: pwsh 62 | 63 | - name: Upload artifacts 64 | uses: actions/upload-artifact@v4 65 | with: 66 | name: ProxyBridge-Build-${{ github.sha }} 67 | path: Windows/output/ 68 | retention-days: 30 69 | 70 | - name: List output files 71 | run: | 72 | Write-Host "`nBuild artifacts:" 73 | Get-ChildItem Windows/output -Recurse | ForEach-Object { 74 | $size = [math]::Round($_.Length/1MB, 2) 75 | Write-Host " $($_.Name) - $size MB" 76 | } 77 | shell: pwsh 78 | -------------------------------------------------------------------------------- /Windows/gui/Services/ConfigManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Text.Json; 5 | using System.Text.Json.Serialization; 6 | using ProxyBridge.GUI.ViewModels; 7 | 8 | namespace ProxyBridge.GUI.Services; 9 | 10 | public class AppConfig 11 | { 12 | public string ProxyType { get; set; } = "SOCKS5"; 13 | public string ProxyIp { get; set; } = ""; 14 | public string ProxyPort { get; set; } = ""; 15 | public string ProxyUsername { get; set; } = ""; 16 | public string ProxyPassword { get; set; } = ""; 17 | public bool DnsViaProxy { get; set; } = true; 18 | public string Language { get; set; } = "en"; 19 | public bool CloseToTray { get; set; } = true; 20 | public List ProxyRules { get; set; } = new(); 21 | } 22 | 23 | public class ProxyRuleConfig 24 | { 25 | public string ProcessName { get; set; } = ""; 26 | public string TargetHosts { get; set; } = "*"; 27 | public string TargetPorts { get; set; } = "*"; 28 | public string Protocol { get; set; } = "TCP"; 29 | public string Action { get; set; } = "PROXY"; 30 | public bool IsEnabled { get; set; } = true; 31 | } 32 | 33 | [JsonSerializable(typeof(AppConfig))] 34 | [JsonSerializable(typeof(ProxyRuleConfig))] 35 | [JsonSerializable(typeof(List))] 36 | internal partial class AppConfigJsonContext : JsonSerializerContext 37 | { 38 | } 39 | 40 | public static class ConfigManager 41 | { 42 | private static readonly string ConfigDirectory = Path.Combine( 43 | Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), 44 | "ProxyBridge" 45 | ); 46 | // C:\Users\\AppData\Roaming\ProxyBridge\config.json 47 | 48 | private static readonly string ConfigFilePath = Path.Combine(ConfigDirectory, "config.json"); 49 | 50 | public static bool SaveConfig(AppConfig config) 51 | { 52 | try 53 | { 54 | if (!Directory.Exists(ConfigDirectory)) 55 | { 56 | Directory.CreateDirectory(ConfigDirectory); 57 | } 58 | 59 | var json = JsonSerializer.Serialize(config, AppConfigJsonContext.Default.AppConfig); 60 | File.WriteAllText(ConfigFilePath, json); 61 | return true; 62 | } 63 | catch 64 | { 65 | return false; 66 | } 67 | } 68 | 69 | public static AppConfig LoadConfig() 70 | { 71 | try 72 | { 73 | if (!File.Exists(ConfigFilePath)) 74 | { 75 | return new AppConfig(); 76 | } 77 | 78 | var json = File.ReadAllText(ConfigFilePath); 79 | var config = JsonSerializer.Deserialize(json, AppConfigJsonContext.Default.AppConfig); 80 | return config ?? new AppConfig(); 81 | } 82 | catch 83 | { 84 | return new AppConfig(); 85 | } 86 | } 87 | 88 | public static bool ConfigExists() 89 | { 90 | return File.Exists(ConfigFilePath); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /Windows/cli/ProxyBridgeNative.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | 3 | namespace ProxyBridge.CLI; 4 | 5 | public static class ProxyBridgeNative 6 | { 7 | private const string DllName = "ProxyBridgeCore.dll"; 8 | 9 | static ProxyBridgeNative() 10 | { 11 | var assemblyPath = AppContext.BaseDirectory; 12 | if (!string.IsNullOrEmpty(assemblyPath)) 13 | { 14 | var dllPath = Path.Combine(assemblyPath, DllName); 15 | if (File.Exists(dllPath)) 16 | { 17 | NativeLibrary.Load(dllPath); 18 | } 19 | } 20 | } 21 | 22 | public enum ProxyType 23 | { 24 | HTTP = 0, 25 | SOCKS5 = 1 26 | } 27 | 28 | public enum RuleAction 29 | { 30 | PROXY = 0, 31 | DIRECT = 1, 32 | BLOCK = 2 33 | } 34 | 35 | public enum RuleProtocol 36 | { 37 | TCP = 0, 38 | UDP = 1, 39 | BOTH = 2 40 | } 41 | 42 | [UnmanagedFunctionPointer(CallingConvention.Cdecl)] 43 | public delegate void LogCallback([MarshalAs(UnmanagedType.LPStr)] string message); 44 | 45 | [UnmanagedFunctionPointer(CallingConvention.Cdecl)] 46 | public delegate void ConnectionCallback( 47 | [MarshalAs(UnmanagedType.LPStr)] string processName, 48 | uint pid, 49 | [MarshalAs(UnmanagedType.LPStr)] string destIp, 50 | ushort destPort, 51 | [MarshalAs(UnmanagedType.LPStr)] string proxyInfo); 52 | 53 | [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] 54 | public static extern uint ProxyBridge_AddRule( 55 | [MarshalAs(UnmanagedType.LPStr)] string processName, 56 | [MarshalAs(UnmanagedType.LPStr)] string targetHosts, 57 | [MarshalAs(UnmanagedType.LPStr)] string targetPorts, 58 | RuleProtocol protocol, 59 | RuleAction action); 60 | 61 | [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] 62 | [return: MarshalAs(UnmanagedType.Bool)] 63 | public static extern bool ProxyBridge_EnableRule(uint ruleId); 64 | 65 | [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] 66 | [return: MarshalAs(UnmanagedType.Bool)] 67 | public static extern bool ProxyBridge_DisableRule(uint ruleId); 68 | 69 | [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] 70 | [return: MarshalAs(UnmanagedType.Bool)] 71 | public static extern bool ProxyBridge_SetProxyConfig( 72 | ProxyType type, 73 | [MarshalAs(UnmanagedType.LPStr)] string proxyIp, 74 | ushort proxyPort, 75 | [MarshalAs(UnmanagedType.LPStr)] string username, 76 | [MarshalAs(UnmanagedType.LPStr)] string password); 77 | 78 | [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] 79 | public static extern void ProxyBridge_SetLogCallback(LogCallback callback); 80 | 81 | [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] 82 | public static extern void ProxyBridge_SetConnectionCallback(ConnectionCallback callback); 83 | 84 | [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] 85 | public static extern void ProxyBridge_SetDnsViaProxy([MarshalAs(UnmanagedType.Bool)] bool enable); 86 | 87 | [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] 88 | [return: MarshalAs(UnmanagedType.Bool)] 89 | public static extern bool ProxyBridge_Start(); 90 | 91 | [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] 92 | [return: MarshalAs(UnmanagedType.Bool)] 93 | public static extern bool ProxyBridge_Stop(); 94 | } 95 | -------------------------------------------------------------------------------- /Windows/installer/ProxyBridge.nsi: -------------------------------------------------------------------------------- 1 | !define PRODUCT_NAME "ProxyBridge" 2 | !define PRODUCT_VERSION "3.0.0" 3 | !define PRODUCT_PUBLISHER "InterceptSuite" 4 | !define PRODUCT_WEB_SITE "https://github.com/InterceptSuite/ProxyBridge" 5 | !define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" 6 | !define PRODUCT_UNINST_ROOT_KEY "HKLM" 7 | 8 | !include "MUI2.nsh" 9 | 10 | Name "${PRODUCT_NAME} ${PRODUCT_VERSION}" 11 | OutFile "ProxyBridge-Setup-${PRODUCT_VERSION}.exe" 12 | InstallDir "$PROGRAMFILES64\${PRODUCT_NAME}" 13 | InstallDirRegKey HKLM "${PRODUCT_UNINST_KEY}" "InstallLocation" 14 | RequestExecutionLevel admin 15 | 16 | !define MUI_ABORTWARNING 17 | !define MUI_ICON "..\gui\Assets\logo.ico" 18 | !define MUI_UNICON "..\gui\Assets\logo.ico" 19 | 20 | !insertmacro MUI_PAGE_WELCOME 21 | !insertmacro MUI_PAGE_LICENSE "..\..\\LICENSE" 22 | !insertmacro MUI_PAGE_DIRECTORY 23 | !insertmacro MUI_PAGE_INSTFILES 24 | !insertmacro MUI_PAGE_FINISH 25 | 26 | !insertmacro MUI_UNPAGE_CONFIRM 27 | !insertmacro MUI_UNPAGE_INSTFILES 28 | 29 | !insertmacro MUI_LANGUAGE "English" 30 | 31 | Section "MainSection" SEC01 32 | SetOutPath "$INSTDIR" 33 | SetOverwrite on 34 | 35 | File "..\output\ProxyBridge.exe" 36 | File "..\output\ProxyBridge_CLI.exe" 37 | File "..\output\ProxyBridgeCore.dll" 38 | File "..\output\WinDivert.dll" 39 | File "..\output\WinDivert64.sys" 40 | File "..\output\av_libglesv2.dll" 41 | File "..\output\libHarfBuzzSharp.dll" 42 | File "..\output\libSkiaSharp.dll" 43 | 44 | CreateDirectory "$SMPROGRAMS\${PRODUCT_NAME}" 45 | CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\${PRODUCT_NAME}.lnk" "$INSTDIR\ProxyBridge.exe" 46 | CreateShortCut "$DESKTOP\${PRODUCT_NAME}.lnk" "$INSTDIR\ProxyBridge.exe" 47 | 48 | ; Add to PATH using EnVar plugin 49 | EnVar::SetHKLM 50 | EnVar::AddValue "PATH" "$INSTDIR" 51 | Pop $0 52 | 53 | ; Broadcast environment change 54 | SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 55 | SectionEnd 56 | 57 | Section -Post 58 | WriteUninstaller "$INSTDIR\uninst.exe" 59 | WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)" 60 | WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\uninst.exe" 61 | WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\ProxyBridge.exe" 62 | WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}" 63 | WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "URLInfoAbout" "${PRODUCT_WEB_SITE}" 64 | WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "Publisher" "${PRODUCT_PUBLISHER}" 65 | WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "InstallLocation" "$INSTDIR" 66 | SectionEnd 67 | 68 | Section Uninstall 69 | Delete "$INSTDIR\ProxyBridge.exe" 70 | Delete "$INSTDIR\ProxyBridge_CLI.exe" 71 | Delete "$INSTDIR\ProxyBridgeCore.dll" 72 | Delete "$INSTDIR\WinDivert.dll" 73 | Delete "$INSTDIR\WinDivert64.sys" 74 | Delete "$INSTDIR\av_libglesv2.dll" 75 | Delete "$INSTDIR\libHarfBuzzSharp.dll" 76 | Delete "$INSTDIR\libSkiaSharp.dll" 77 | Delete "$INSTDIR\uninst.exe" 78 | 79 | Delete "$SMPROGRAMS\${PRODUCT_NAME}\${PRODUCT_NAME}.lnk" 80 | Delete "$DESKTOP\${PRODUCT_NAME}.lnk" 81 | RMDir "$SMPROGRAMS\${PRODUCT_NAME}" 82 | RMDir "$INSTDIR" 83 | 84 | ; Remove from PATH using EnVar plugin 85 | EnVar::SetHKLM 86 | EnVar::DeleteValue "PATH" "$INSTDIR" 87 | Pop $0 88 | 89 | ; Broadcast environment change 90 | SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 91 | 92 | DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" 93 | SetAutoClose true 94 | SectionEnd 95 | -------------------------------------------------------------------------------- /Windows/gui/Views/AboutWindow.axaml: -------------------------------------------------------------------------------- 1 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 27 | 28 | 29 | 30 | 31 | 32 | 37 | 38 | 42 | 43 | 49 | 50 | 51 | 56 | 57 | 58 | 59 | 60 | 61 | 66 | 67 | 68 | 69 | 70 | 75 | 76 | 77 | 78 | 83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /Windows/gui/Interop/ProxyBridgeNative.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | using System.IO; 4 | using System.Reflection; 5 | 6 | namespace ProxyBridge.GUI.Interop; 7 | 8 | public static class ProxyBridgeNative 9 | { 10 | private const string DllName = "ProxyBridgeCore.dll"; 11 | 12 | static ProxyBridgeNative() 13 | { 14 | var assemblyPath = AppContext.BaseDirectory; 15 | if (!string.IsNullOrEmpty(assemblyPath)) 16 | { 17 | var dllPath = Path.Combine(assemblyPath, DllName); 18 | if (File.Exists(dllPath)) 19 | { 20 | NativeLibrary.Load(dllPath); 21 | } 22 | } 23 | } 24 | 25 | public enum ProxyType 26 | { 27 | HTTP = 0, 28 | SOCKS5 = 1 29 | } 30 | 31 | public enum RuleAction 32 | { 33 | PROXY = 0, 34 | DIRECT = 1, 35 | BLOCK = 2 36 | } 37 | 38 | public enum RuleProtocol 39 | { 40 | TCP = 0, 41 | UDP = 1, 42 | BOTH = 2 43 | } 44 | 45 | [UnmanagedFunctionPointer(CallingConvention.Cdecl)] 46 | public delegate void LogCallback([MarshalAs(UnmanagedType.LPStr)] string message); 47 | 48 | [UnmanagedFunctionPointer(CallingConvention.Cdecl)] 49 | public delegate void ConnectionCallback( 50 | [MarshalAs(UnmanagedType.LPStr)] string processName, 51 | uint pid, 52 | [MarshalAs(UnmanagedType.LPStr)] string destIp, 53 | ushort destPort, 54 | [MarshalAs(UnmanagedType.LPStr)] string proxyInfo); 55 | 56 | [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] 57 | public static extern uint ProxyBridge_AddRule( 58 | [MarshalAs(UnmanagedType.LPStr)] string processName, 59 | [MarshalAs(UnmanagedType.LPStr)] string targetHosts, 60 | [MarshalAs(UnmanagedType.LPStr)] string targetPorts, 61 | RuleProtocol protocol, 62 | RuleAction action); 63 | 64 | [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] 65 | [return: MarshalAs(UnmanagedType.Bool)] 66 | public static extern bool ProxyBridge_EnableRule(uint ruleId); 67 | 68 | [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] 69 | [return: MarshalAs(UnmanagedType.Bool)] 70 | public static extern bool ProxyBridge_DisableRule(uint ruleId); 71 | 72 | [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] 73 | [return: MarshalAs(UnmanagedType.Bool)] 74 | public static extern bool ProxyBridge_DeleteRule(uint ruleId); 75 | 76 | [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] 77 | [return: MarshalAs(UnmanagedType.Bool)] 78 | public static extern bool ProxyBridge_EditRule( 79 | uint ruleId, 80 | [MarshalAs(UnmanagedType.LPStr)] string processName, 81 | [MarshalAs(UnmanagedType.LPStr)] string targetHosts, 82 | [MarshalAs(UnmanagedType.LPStr)] string targetPorts, 83 | RuleProtocol protocol, 84 | RuleAction action); 85 | 86 | [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] 87 | [return: MarshalAs(UnmanagedType.Bool)] 88 | public static extern bool ProxyBridge_SetProxyConfig( 89 | ProxyType type, 90 | [MarshalAs(UnmanagedType.LPStr)] string proxyIp, 91 | ushort proxyPort, 92 | [MarshalAs(UnmanagedType.LPStr)] string username, 93 | [MarshalAs(UnmanagedType.LPStr)] string password); 94 | 95 | [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] 96 | public static extern void ProxyBridge_SetLogCallback(LogCallback callback); 97 | 98 | [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] 99 | public static extern void ProxyBridge_SetConnectionCallback(ConnectionCallback callback); 100 | 101 | [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] 102 | public static extern void ProxyBridge_SetDnsViaProxy([MarshalAs(UnmanagedType.Bool)] bool enable); 103 | 104 | [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] 105 | [return: MarshalAs(UnmanagedType.Bool)] 106 | public static extern bool ProxyBridge_Start(); 107 | 108 | [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] 109 | [return: MarshalAs(UnmanagedType.Bool)] 110 | public static extern bool ProxyBridge_Stop(); 111 | 112 | [DllImport(DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] 113 | public static extern int ProxyBridge_TestConnection( 114 | [MarshalAs(UnmanagedType.LPStr)] string targetHost, 115 | ushort targetPort, 116 | [MarshalAs(UnmanagedType.LPStr)] System.Text.StringBuilder resultBuffer, 117 | UIntPtr bufferSize); 118 | } 119 | -------------------------------------------------------------------------------- /Windows/gui/Views/UpdateNotificationWindow.axaml: -------------------------------------------------------------------------------- 1 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 38 | 40 | 41 | 42 | 43 | 47 | 49 | 50 | 51 | 52 | 53 | 58 | 59 | 60 | 61 | 64 | 69 | 70 | 71 | 72 | 77 | 78 | 79 | 80 | 81 | 82 |