From 385103a0bf1dc35e8eaad53e589fce952b12325c Mon Sep 17 00:00:00 2001 From: PhuocNTB Date: Wed, 1 Jul 2026 14:07:55 +0700 Subject: [PATCH] add bao mat --- client/app.go | 18 +++++++-- client/build.ps1 | 51 +++++++++++++++++++++++--- client/build.sh | 30 +++++++++++++-- client/frontend/src/main.js | 14 ++++++- client/frontend/wailsjs/go/main/App.js | 44 +++++++++++----------- 5 files changed, 123 insertions(+), 34 deletions(-) diff --git a/client/app.go b/client/app.go index 5aebbf4..4548b46 100644 --- a/client/app.go +++ b/client/app.go @@ -7,6 +7,7 @@ import ( "crypto/aes" "crypto/cipher" "crypto/rand" + "crypto/sha256" "encoding/json" "encoding/base64" "errors" @@ -59,10 +60,20 @@ func getWsUrl(apiBase string) string { var wifiReportLast sync.Map // ssidKey -> time.Time -var encryptionKey = []byte("simple-care-proctor-secretkey32!") // 32-byte key for AES-256 +func getDynamicEncryptionKey() []byte { + base := "simple-care-proctor-secretkey32!" + hostname, _ := os.Hostname() + home, _ := os.UserHomeDir() + combined := fmt.Sprintf("%s-%s-%s", base, hostname, home) + + hasher := sha256.New() + hasher.Write([]byte(combined)) + return hasher.Sum(nil) +} func encrypt(data []byte) ([]byte, error) { - block, err := aes.NewCipher(encryptionKey) + key := getDynamicEncryptionKey() + block, err := aes.NewCipher(key) if err != nil { return nil, err } @@ -79,7 +90,8 @@ func encrypt(data []byte) ([]byte, error) { } func decrypt(data []byte) ([]byte, error) { - block, err := aes.NewCipher(encryptionKey) + key := getDynamicEncryptionKey() + block, err := aes.NewCipher(key) if err != nil { return nil, err } diff --git a/client/build.ps1 b/client/build.ps1 index e2997e2..cf87a2f 100644 --- a/client/build.ps1 +++ b/client/build.ps1 @@ -2,16 +2,51 @@ $ErrorActionPreference = "Stop" Write-Host "=============================================" -ForegroundColor Cyan -Write-Host " BUILDING WAILS CLIENT " -ForegroundColor Cyan +Write-Host " BUILDING SECURE WAILS CLIENT " -ForegroundColor Cyan Write-Host "=============================================" -ForegroundColor Cyan +# Setup Go path for tools like garble +try { + $goPath = go env GOPATH + if ($goPath) { + $goBin = Join-Path $goPath "bin" + if (Test-Path $goBin) { + if ($env:PATH -notlike "*$goBin*") { + $env:PATH = "$goBin;$env:PATH" + Write-Host "[*] Added $goBin to PATH temporarily" -ForegroundColor Gray + } + } + } +} catch { + Write-Host "[!] Could not resolve GOPATH. Proceeding with default PATH..." -ForegroundColor Yellow +} + +# Ensure Garble is installed +$garbleInstalled = $null -ne (Get-Command garble -ErrorAction SilentlyContinue) +if (-not $garbleInstalled) { + Write-Host "[*] Garble is not installed. Installing mvdan.cc/garble@latest..." -ForegroundColor Cyan + try { + go install mvdan.cc/garble@latest + Write-Host "[+] Garble installed successfully!" -ForegroundColor Green + } catch { + Write-Host "[!] Failed to install Garble. Will fall back to standard Go compiler." -ForegroundColor Yellow + } +} + # Check if wails is installed $wailsInstalled = $null -ne (Get-Command wails -ErrorAction SilentlyContinue) if ($wailsInstalled) { - Write-Host "[*] Found Wails CLI. Building via Wails..." -ForegroundColor Green + Write-Host "[*] Found Wails CLI. Building via Wails with Obfuscation..." -ForegroundColor Green try { - wails build + $garbleInstalled = $null -ne (Get-Command garble -ErrorAction SilentlyContinue) + if ($garbleInstalled) { + Write-Host "[*] Compiling using Garble compiler..." -ForegroundColor Green + wails build -clean -compiler garble -obfuscated -trimpath -m -ldflags "-s -w" + } else { + Write-Host "[!] Garble not available. Compiling with default Go compiler..." -ForegroundColor Yellow + wails build -clean -ldflags "-s -w" + } Write-Host "[+] Build completed successfully using Wails CLI!" -ForegroundColor Green exit 0 } catch { @@ -53,8 +88,14 @@ try { Write-Host "[*] Building Go application..." -ForegroundColor Cyan try { - # -H windowsgui: prevents console window from flashing on startup - go build -ldflags="-s -w -H windowsgui" -o client.exe main.go app.go + $garbleInstalled = $null -ne (Get-Command garble -ErrorAction SilentlyContinue) + if ($garbleInstalled) { + Write-Host "[*] Compiling manual build with Garble..." -ForegroundColor Green + garble build -ldflags="-s -w -H windowsgui" -o client.exe main.go app.go + } else { + Write-Host "[!] Garble not available. Compiling manual build with standard Go..." -ForegroundColor Yellow + go build -ldflags="-s -w -H windowsgui" -o client.exe main.go app.go + } Write-Host "[+] Build completed successfully! Generated client.exe" -ForegroundColor Green } catch { Write-Host "[-] Go build failed." -ForegroundColor Red diff --git a/client/build.sh b/client/build.sh index 994cfb7..75b8baf 100755 --- a/client/build.sh +++ b/client/build.sh @@ -5,9 +5,24 @@ set -e cd "$(dirname "$0")" echo "=============================================" -echo " BUILDING WAILS CLIENT FOR MACOS " +echo " BUILDING SECURE WAILS CLIENT FOR MACOS " echo "=============================================" +# Setup Go path for tools like garble and wails +GOPATH=$(go env GOPATH) +if [ -n "$GOPATH" ] && [ -d "$GOPATH/bin" ]; then + export PATH="$GOPATH/bin:$PATH" +fi +if [ -d "$HOME/go/bin" ]; then + export PATH="$HOME/go/bin:$PATH" +fi + +# Ensure Garble is installed +if ! command -v garble &> /dev/null; then + echo "[*] Garble is not installed. Installing mvdan.cc/garble@latest..." + go install mvdan.cc/garble@latest || echo "[!] Failed to install Garble. Will use default Go compiler." +fi + # Check if wails is installed WAILS_CMD="wails" if ! command -v wails &> /dev/null; then @@ -21,10 +36,19 @@ if ! command -v wails &> /dev/null; then fi fi +# Set compiler and obfuscation flags if garble is available +BUILD_FLAGS="-clean -obfuscated -trimpath -m -ldflags -s -w" +if command -v garble &> /dev/null; then + echo "[*] Garble found. Compiling with Obfuscator..." + BUILD_FLAGS="-compiler garble $BUILD_FLAGS" +else + echo "[!] Garble not found. Compiling with default Go compiler..." +fi + echo "[*] Building macOS Apple Silicon (arm64)..." -"$WAILS_CMD" build -platform darwin/arm64 +"$WAILS_CMD" build -platform darwin/arm64 $BUILD_FLAGS echo "[*] Building macOS Intel (amd64)..." -"$WAILS_CMD" build -platform darwin/amd64 +"$WAILS_CMD" build -platform darwin/amd64 $BUILD_FLAGS echo "[+] macOS arm64 and amd64 builds completed successfully!" diff --git a/client/frontend/src/main.js b/client/frontend/src/main.js index 3f5c87d..948b937 100644 --- a/client/frontend/src/main.js +++ b/client/frontend/src/main.js @@ -8,6 +8,15 @@ import { renderSecurePdf, renderSecureText, } from './examViewer.js'; +import * as GoApp from '../wailsjs/go/main/App.js'; + +// Map Wails bindings to window.go.main.App for backward compatibility with obfuscated builds +window.go = window.go || {}; +window.go.main = window.go.main || {}; +if (typeof window.go.main.App === 'undefined') { + window.go.main.App = GoApp; + window.go.main._custom = true; +} const brandLogoHtml = `Simple Care`; @@ -54,7 +63,10 @@ webcamCanvas.style.display = 'none'; document.body.appendChild(webcamCanvas); function init() { - if (typeof window.go === 'undefined' || typeof window.go.main === 'undefined') { + const ready = (typeof window.ObfuscatedCall === 'function') || + (typeof window.go !== 'undefined' && typeof window.go.main !== 'undefined' && !window.go.main._custom); + + if (!ready || typeof window.runtime === 'undefined') { setTimeout(init, 200); return; } diff --git a/client/frontend/wailsjs/go/main/App.js b/client/frontend/wailsjs/go/main/App.js index 15890ec..408c3b2 100755 --- a/client/frontend/wailsjs/go/main/App.js +++ b/client/frontend/wailsjs/go/main/App.js @@ -3,89 +3,89 @@ // This file is automatically generated. DO NOT EDIT export function CheckLoginStatus() { - return window['go']['main']['App']['CheckLoginStatus'](); + return ObfuscatedCall(0, []); } export function ClearChatUnread() { - return window['go']['main']['App']['ClearChatUnread'](); + return ObfuscatedCall(1, []); } export function DownloadExamResource(arg1) { - return window['go']['main']['App']['DownloadExamResource'](arg1); + return ObfuscatedCall(2, [arg1]); } export function GetChatConversations() { - return window['go']['main']['App']['GetChatConversations'](); + return ObfuscatedCall(3, []); } export function GetChatMessages(arg1) { - return window['go']['main']['App']['GetChatMessages'](arg1); + return ObfuscatedCall(4, [arg1]); } export function GetChatUnread() { - return window['go']['main']['App']['GetChatUnread'](); + return ObfuscatedCall(5, []); } export function GetExamPaperFiles() { - return window['go']['main']['App']['GetExamPaperFiles'](); + return ObfuscatedCall(6, []); } export function GetExamPaperViewURL() { - return window['go']['main']['App']['GetExamPaperViewURL'](); + return ObfuscatedCall(7, []); } export function GetExamQuizViewURL() { - return window['go']['main']['App']['GetExamQuizViewURL'](); + return ObfuscatedCall(8, []); } export function GetStats() { - return window['go']['main']['App']['GetStats'](); + return ObfuscatedCall(9, []); } export function GetStudentInfo() { - return window['go']['main']['App']['GetStudentInfo'](); + return ObfuscatedCall(10, []); } export function LoadExamViewFile(arg1) { - return window['go']['main']['App']['LoadExamViewFile'](arg1); + return ObfuscatedCall(11, [arg1]); } export function Logout() { - return window['go']['main']['App']['Logout'](); + return ObfuscatedCall(12, []); } export function NavigateToLogin() { - return window['go']['main']['App']['NavigateToLogin'](); + return ObfuscatedCall(13, []); } export function OpenExamPaper() { - return window['go']['main']['App']['OpenExamPaper'](); + return ObfuscatedCall(14, []); } export function OpenExamQuiz() { - return window['go']['main']['App']['OpenExamQuiz'](); + return ObfuscatedCall(15, []); } export function OpenExamResource(arg1) { - return window['go']['main']['App']['OpenExamResource'](arg1); + return ObfuscatedCall(16, [arg1]); } export function ReturnToDashboard() { - return window['go']['main']['App']['ReturnToDashboard'](); + return ObfuscatedCall(17, []); } export function SendChatMessage(arg1) { - return window['go']['main']['App']['SendChatMessage'](arg1); + return ObfuscatedCall(18, [arg1]); } export function SendWebcamFrame(arg1) { - return window['go']['main']['App']['SendWebcamFrame'](arg1); + return ObfuscatedCall(19, [arg1]); } export function SubmitExamWork() { - return window['go']['main']['App']['SubmitExamWork'](); + return ObfuscatedCall(20, []); } export function UnlockChatAudio() { - return window['go']['main']['App']['UnlockChatAudio'](); + return ObfuscatedCall(21, []); }