commit 601773d487013280b3afff666e84967c16dbee25 Author: Huang-158 Date: Wed Jul 15 11:50:35 2026 +0800 v1.2: Clean release with rewritten README, Chinese/English UI, AI anti-false-positive, CE-MCP auto-start diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..449b31b --- /dev/null +++ b/.gitignore @@ -0,0 +1,31 @@ +# Build output +**/bin/ +**/obj/ +**/publish/ +**/data/ +**/logs/ +**/dumps/ +**/reports/ +*.exe +*.dll +*.pdb +*.cache + +# IDE +.vs/ +.vscode/ +*.user +*.suo + +# OS +Thumbs.db +Desktop.ini +.DS_Store + +# Python (legacy) +__pycache__/ +*.pyc +venv/ +dist/ +build/ +*.spec diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..0557a73 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 MemScan-EDR Contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..467679d --- /dev/null +++ b/README.md @@ -0,0 +1,201 @@ +# MemScan-EDR + +> **Open-Source, Lightweight, Memory-Focused Windows Endpoint Detection & Response (EDR) Tool** + +[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE) +[![.NET 8](https://img.shields.io/badge/.NET-8.0-purple.svg)](https://dotnet.microsoft.com/) +[![Platform: Windows](https://img.shields.io/badge/Platform-Windows%2010%2F11-lightgrey.svg)](https://www.microsoft.com/windows) +[![CS-WPF](https://img.shields.io/badge/UI-WPF-green.svg)](https://github.com/dotnet/wpf) + +MemScan-EDR scans all running processes, inspects memory for shellcode/injection/C2 patterns, and uses AI (OpenAI / Claude / local models) to classify threats in real time. Built with C# WPF for zero-dependency deployment as a single `.exe`. + +--- +## Screenshots + +| Dashboard | Scan Progress | Settings | +|-----------|--------------|----------| +| Real-time risk dashboard with live process statistics | Real-time scan log with per-process results | Multi-provider AI configuration panel | + +--- +## Features + +### Core Capabilities + +| Capability | Description | +|------------|-------------| +| **Process Enumeration** | Full process list with PID, name, path, parent tree, command line, digital signature, thread count, memory usage | +| **Memory Scanning** | `VirtualQueryEx` traversal of every committed region; detects RWX private memory, unbacked executable pages | +| **Signature Matching** | 12 built-in detection rules: NOP sled, CALL/POP EIP, ROR13 hash, CobaltStrike Beacon, Meterpreter, ReflectiveLoader, Mimikatz, etc. | +| **AI Threat Classification** | Multi-provider support (OpenAI-compatible / Claude / Ollama / LM Studio) + heuristic fallback engine | +| **CE-MCP Integration** | Auto-launch Cheat Engine MCP server for kernel-level memory operations | +| **Chinese / English UI** | One-click language toggle; all labels, buttons, and alerts switch instantly | +| **Single-File EXE** | `dotnet publish` produces a self-contained `MemScan-EDR.exe` — no .NET runtime needed on target | + +### AI Providers + +| Provider | Description | Base URL Example | +|----------|-------------|-----------------| +| **OpenAI-Compatible** | OpenAI / DeepSeek / Qwen / Zhipu / any OpenAI-format API | `https://api.openai.com/v1` | +| **Claude** | Anthropic Claude via Messages API | `https://api.anthropic.com` | +| **Local** | Ollama / LM Studio / vLLM / llama.cpp server | `http://127.0.0.1:11434` | +| **Heuristic** | Built-in rule engine (no API key needed) | N/A | + +### Built-in Signatures + +| Signature | Category | Severity | +|-----------|----------|----------| +| `SHELLCODE_NOP_SLED` | Shellcode | Medium | +| `SHELLCODE_GETEIP` | Shellcode | Medium | +| `SHELLCODE_ROR13` | Shellcode | Medium | +| `C2_COBALTSTRIKE` | C2 | High | +| `C2_METERPRETER` | C2 | Medium | +| `INJECTION_REFLECTIVE` | Injection | High | +| `INJECTION_CRT` | Injection | Medium | +| `INJECTION_VAE` | Injection | Medium | +| `MALWARE_MIMIKATZ` | Malware | High | +| `CRYPTO_MINER` | Crypto | High | +| `RANSOM_NOTE` | Malware | High | +| `PS_DOWNLOAD` | Malware | Medium | + +--- +## Architecture + +``` +TitleBar ── Window Chrome (Min/Max/Close, Language Toggle) +Sidebar ── Navigation (Dashboard / Processes / Scan / Settings) +Content ── 4 Views (WPF Grid Visibility switching) + +Services: + ProcessCollector ── CreateToolhelp32Snapshot + WMI → ProcessInfo[] + MemoryScanner ── VirtualQueryEx + signature walk → SignatureMatch[] + AIAnalyzer ── HTTP → OpenAI/Claude/Ollama API → ScanResult + CeMcpManager ── Process.Start → python server.py +``` + +Data flows: +``` +[Start Scan] → ProcessCollector.CollectAll() + → for each ProcessInfo: + → MemoryScanner.ScanProcess() → signature matches + → MemoryScanner.GetSuspiciousRegions() → RWX private regions + → QuickPreScore() — skip API if score < 0.05 + → AIAnalyzer.AnalyzeProcessAsync() → ScanResult + → API call with structured prompt + → ParseResponse() → RiskLevel + Score + Indicators + → Update DataGrid / Stats in real-time via IProgress<> +``` + +--- +## Quick Start + +### Prerequisites + +- Windows 10 / 11 (x64) +- [.NET 8 SDK](https://dotnet.microsoft.com/download/dotnet/8.0) (for building) +- Administrator privileges (for memory scanning) + +### Build + +```powershell +# Clone +git clone https://github.com/Huang-158/MemScan-EDR.git +cd MemScan-EDR\src-csharp + +# Build (Debug) +dotnet build MemScanEDR.sln + +# Publish single-file EXE (Release) +dotnet publish MemScanEDR\MemScanEDR.csproj -c Release -r win-x64 --self-contained true -p:PublishSingleFile=true -o publish + +# Run +.\publish\MemScan-EDR.exe +``` + +Or use the convenience script: + +```powershell +.\scripts\build_csharp.bat +``` + +### CE-MCP Setup (Optional) + +CE-MCP provides deeper memory scanning via Cheat Engine. The application auto-starts it at launch if `server.py` is found. + +1. Place [ce-mcp-server](https://github.com/Huang-158/ce-mcp-server) next to the project +2. Or configure the path in Settings → CE-MCP Server Path +3. Set to `disabled` to run without CE-MCP + +### AI Configuration + +Open Settings panel in the application: + +1. Select provider: Heuristic / OpenAI-Compatible / Claude / Local +2. Enter API Base URL (pre-filled defaults for each provider) +3. Enter API Key (stored locally in `data/settings.json`) +4. Enter Model name (e.g. `gpt-4o-mini`, `claude-3-5-sonnet`, `llama3`) +5. Click Save + +--- +## Project Structure + +``` +MemScan-EDR/ +├── src-csharp/ +│ ├── MemScanEDR.sln +│ └── MemScanEDR/ +│ ├── MemScanEDR.csproj # .NET 8 WPF project +│ ├── app.manifest # UAC asInvoker +│ ├── App.xaml / App.xaml.cs # Application entry + crash logging +│ ├── MainWindow.xaml # WPF UI (white theme, 4 views) +│ ├── MainWindow.xaml.cs # UI logic + scan orchestrator + Lang helper +│ ├── Models/ +│ │ ├── ProcessInfo.cs # Data models (ProcessInfo, ScanResult, Signature, etc.) +│ │ ├── AIConfig.cs # AI provider enum + config class +│ │ └── AppSettings.cs # JSON persistence (settings.json) +│ └── Services/ +│ ├── ProcessCollector.cs # P/Invoke process enumeration + WMI command lines +│ ├── MemoryScanner.cs # VirtualQueryEx scanning + 12 built-in signatures +│ ├── AIAnalyzer.cs # Multi-provider AI + heuristic fallback + pre-filter +│ └── CeMcpManager.cs # CE-MCP subprocess lifecycle +├── rules/ +│ ├── shellcode.yar # YARA shellcode rules +│ ├── injection.yar # YARA injection rules +│ └── malware_strings.yar # YARA malware string rules +├── scripts/ +│ └── build_csharp.bat # Build + publish shortcut +├── LICENSE +└── README.md +``` + +--- +## How AI Analysis Works + +The AI analyzer uses a carefully designed prompt to reduce false positives: + +1. **Pre-filter**: Processes with zero suspicious indicators (signed, system path, no RWX memory, no signature matches) are marked `Safe` without any API call — saving cost and time. + +2. **Structured Prompt**: Each process gets a formatted report including: + - Process metadata (PID, name, path, parent, command line, signer) + - Network connections (protocol, remote address, state) + - Memory signature matches (category, severity, description) + - Suspicious memory regions (RWX private, unbacked executable) + +3. **Safe-by-Default Policy**: The AI is instructed that >95% of processes are benign. It requires **multiple concurring indicators** to elevate risk level — a single RWX region or signature match alone is not enough. + +4. **Heuristic Fallback**: If the AI API is unavailable, a weighted heuristic engine takes over with conservative thresholds (≥0.50 for suspicious, ≥0.75 for high). + +--- +## Disclaimer + +> **Third-Party / Non-Affiliation Statement** +> +> This project is not affiliated with Cheat Engine, its original author Dark Byte, or any AI provider (OpenAI, Anthropic, etc.). +> +> **Legal Use Statement** +> +> This tool is intended for **legitimate security research, education, and authorized security assessments only**. Unauthorized use against systems you do not own or have permission to test is illegal. Users are responsible for complying with all applicable laws. + +--- +## License + +MIT License — see [LICENSE](LICENSE) for full text. diff --git a/rules/injection.yar b/rules/injection.yar new file mode 100644 index 0000000..211ce1d --- /dev/null +++ b/rules/injection.yar @@ -0,0 +1,89 @@ +/* + * MemScan-EDR 进程注入检测规则 + */ + +rule Remote_Thread_Creation { + meta: + description = "检测远程线程注入相关API字符串" + author = "MemScan-EDR" + severity = "medium" + category = "injection" + strings: + $createremotethread = "CreateRemoteThread" nocase + $rtlcreateuserthread = "RtlCreateUserThread" nocase + $ntcreatethreadex = "NtCreateThreadEx" nocase + condition: + any of them +} + +rule DLL_Injection_APC { + meta: + description = "检测 APC 注入 (QueueUserAPC) 特征" + author = "MemScan-EDR" + severity = "medium" + category = "injection" + strings: + $queueuserapc = "QueueUserAPC" nocase + $ntqueueapcthread = "NtQueueApcThread" nocase + $setthreadcontext = "SetThreadContext" nocase + condition: + any of them +} + +rule Process_DLL_Injection { + meta: + description = "检测 DLL 注入常用 API" + author = "MemScan-EDR" + severity = "medium" + category = "injection" + strings: + $virtualallocex = "VirtualAllocEx" nocase + $writeprocessmemory = "WriteProcessMemory" nocase + $loadlibrarya = "LoadLibraryA" nocase + $getprocaddress = "GetProcAddress" nocase + condition: + ($virtualallocex and $writeprocessmemory) or $loadlibrarya +} + +rule Process_Hollowing { + meta: + description = "检测 Process Hollowing 特征" + author = "MemScan-EDR" + severity = "high" + category = "injection" + strings: + $createprocess = "CreateProcess" nocase + $zwunmap = "ZwUnmapViewOfSection" nocase + $ntunmap = "NtUnmapViewOfSection" nocase + $rtluserprocess = "RtlUserProcessParameters" nocase + condition: + $createprocess and ($zwunmap or $ntunmap) +} + +rule Atom_Bombing { + meta: + description = "检测 Atom Bombing 注入技术" + author = "MemScan-EDR" + severity = "high" + category = "injection" + strings: + $globaladd = "GlobalAddAtom" nocase + $globalget = "GlobalGetAtomName" nocase + $ntqueueapc = "NtQueueApcThread" nocase + condition: + 2 of them +} + +rule Early_Bird_APC { + meta: + description = "检测 Early Bird APC 注入" + author = "MemScan-EDR" + severity = "high" + category = "injection" + strings: + $create_suspended = "CREATE_SUSPENDED" nocase + $queueuserapc = "QueueUserAPC" nocase + $resumethread = "ResumeThread" nocase + condition: + 2 of them +} diff --git a/rules/malware_strings.yar b/rules/malware_strings.yar new file mode 100644 index 0000000..7e360d9 --- /dev/null +++ b/rules/malware_strings.yar @@ -0,0 +1,119 @@ +/* + * MemScan-EDR 恶意字符串检测规则 + * 覆盖 C2 通信、勒索软件、挖矿等常见恶意字符串模式 + */ + +rule C2_Domain_Patterns { + meta: + description = "常见 C2 域名/URL 模式" + author = "MemScan-EDR" + severity = "high" + category = "c2" + strings: + $beacon_c2 = ".php?id=" ascii + $api_req = "/api/v1/beacon" nocase + $c2_uri = "/index.asp?id=" ascii + $heartbeat = "heartbeat" nocase + $check_in = "/checkin" nocase + $pulse = "/pulse" nocase + condition: + any of them +} + +rule Ransomware_Strings { + meta: + description = "勒索软件常见字符串模式" + author = "MemScan-EDR" + severity = "high" + category = "malware" + strings: + $ransom = "ransom" nocase + $decrypt = "decrypt" nocase + $bitcoin = "bitcoin" nocase + $monero = "monero" nocase + $payment = "payment" nocase + $encrypted = "YOUR_FILES_ARE_ENCRYPTED" nocase + condition: + any of them +} + +rule Crypto_Mining_Pool { + meta: + description = "加密货币挖矿池 URL 模式" + author = "MemScan-EDR" + severity = "high" + category = "crypto" + strings: + $stratum = "stratum+tcp://" ascii + $xmrig = "xmrig" nocase + $pool_url = "pool." nocase + $mining_proxy = "nicehash" nocase + $worker = "worker" nocase + condition: + any of them +} + +rule Keylogger_Strings { + meta: + description = "键盘记录器常见字符串" + author = "MemScan-EDR" + severity = "high" + category = "malware" + strings: + $hook = "SetWindowsHookEx" nocase + $getkeystate = "GetAsyncKeyState" nocase + $keylog = "keylog" nocase + $clipboard = "GetClipboardData" nocase + condition: + 2 of them +} + +rule Credential_Theft { + meta: + description = "凭证窃取工具特征字符串" + author = "MemScan-EDR" + severity = "high" + category = "malware" + strings: + $mimikatz = "mimikatz" nocase + $sekurlsa = "sekurlsa" nocase + $lsa_dump = "lsadump" nocase + $wdigest = "wdigest" nocase + $kerberos = "kerberos" nocase + $logonpasswords = "logonpasswords" nocase + condition: + any of them +} + +rule Reverse_Shell_Commands { + meta: + description = "反弹 Shell 常见命令" + author = "MemScan-EDR" + severity = "medium" + category = "c2" + strings: + $bash = "/bin/sh" ascii + $cmd = "cmd.exe" nocase + $powershell = "powershell.exe" nocase + $ncat = "nc " ascii + $pipe = "mkfifo" ascii + condition: + any of them +} + +rule Credential_Dump_Tools { + meta: + description = "常见凭证提取工具名称" + author = "MemScan-EDR" + severity = "high" + category = "malware" + strings: + $pwdump = "pwdump" nocase + $fgdump = "fgdump" nocase + $cachedump = "cachedump" nocase + $samdump = "samdump" nocase + $procdump = "procdump" nocase + $lsass = "lsass" nocase + condition: + any of them +} diff --git a/rules/shellcode.yar b/rules/shellcode.yar new file mode 100644 index 0000000..92dcae0 --- /dev/null +++ b/rules/shellcode.yar @@ -0,0 +1,121 @@ +/* + * MemScan-EDR Shellcode 检测规则 + * 覆盖常见 C2 框架、注入技术、恶意 Shellcode 特征 + */ + +rule Meterpreter_Reverse_TCP_Shellcode { + meta: + description = "检测 Metasploit Meterpreter reverse_tcp shellcode" + author = "MemScan-EDR" + severity = "high" + category = "shellcode" + reference = "https://github.com/rapid7/metasploit-framework" + strings: + $stager = "WS2_32.dll" nocase + $port_loop = { 66 B8 [4] 50 6A 02 6A } + $wsastartup = { B8 [4] 50 6A [1-2] 6A } + $connect_pattern = { 6A 00 6A 00 6A 00 6A 06 6A 01 6A 02 } + condition: + any of them +} + +rule CobaltStrike_Beacon_Config { + meta: + description = "检测 CobaltStrike Beacon 配置特征" + author = "MemScan-EDR" + severity = "high" + category = "c2" + strings: + $beacon_x86 = { 00 00 00 00 [16] 00 00 00 00 00 01 00 01 } + $beacon_x64 = { 00 00 00 00 00 00 00 00 [32] 00 01 00 01 00 } + $sleep_mask = { 00 00 00 00 [8] 00 00 00 00 } + $config_header = { 00 01 00 01 [16] } + condition: + any of them +} + +rule Reflective_DLL_Injection { + meta: + description = "检测 Reflective DLL Injection 特征" + author = "MemScan-EDR" + severity = "high" + category = "injection" + strings: + $reflectiveloader = "ReflectiveLoader" nocase + $reflective_dll = "reflective_dll" nocase + $pe_in_memory = "MZ" at 0 + $getprocaddress_hash = { 8B [1-2] E8 [4] 01 C1 [1-2] [1-2] 85 } + condition: + ($reflectiveloader or $reflective_dll) and $pe_in_memory +} + +rule Shellcode_NOP_Sled { + meta: + description = "检测 NOP sled (连续 0x90 指令)" + author = "MemScan-EDR" + severity = "medium" + category = "shellcode" + strings: + $nop_sled = { 90 90 90 90 90 90 90 90 90 90 90 90 } + $nop_int3_sled = { CC CC CC CC CC CC CC CC } + condition: + $nop_sled or $nop_int3_sled +} + +rule Shellcode_GetEIP_Technique { + meta: + description = "检测获取 EIP/EIP 的 Shellcode 技术" + author = "MemScan-EDR" + severity = "medium" + category = "shellcode" + strings: + $call_pop = { E8 00 00 00 00 58 } // call $+5; pop eax + $call_pop2 = { E8 00 00 00 00 59 } // call $+5; pop ecx + $fs_teb = { 64 A1 30 00 00 00 } // mov eax, fs:[0x30] (PEB x86) + $gs_teb = { 65 48 8B [1-2] 60 00 00 00 } // mov reg, gs:[0x60] (PEB x64) + condition: + any of them +} + +rule Shellcode_API_Hash_ROR13 { + meta: + description = "检测 ROR13 API 哈希解析模式" + author = "MemScan-EDR" + severity = "medium" + category = "shellcode" + strings: + $ror13_x86 = { C1 C8 0D } // ror eax, 0xD + $ror13_x64 = { 41 C1 C8 0D } // ror r8d, 0xD + $rol13_x86 = { C1 C0 0D } // rol eax, 0xD + condition: + any of them +} + +rule Sliver_Implant { + meta: + description = "检测 Sliver C2 框架 implant 特征" + author = "MemScan-EDR" + severity = "high" + category = "c2" + strings: + $sliver = "sliver" nocase + $mtls = "mtls" nocase + $wg = "wireguard" nocase + $grpc = "gRPC" nocase + condition: + any of them +} + +rule Process_Hollowing_Indicator { + meta: + description = "检测 Process Hollowing 特征" + author = "MemScan-EDR" + severity = "high" + category = "injection" + strings: + $ntunmap = "NtUnmapViewOfSection" nocase + $create_suspended = { 00 00 00 00 00 00 00 00 [8] 04 00 00 00 } + $pe_imagebase = { 00 00 40 00 00 00 00 00 } // IMAGE_BASE 0x400000 + condition: + any of them +} diff --git a/scripts/build_csharp.bat b/scripts/build_csharp.bat new file mode 100644 index 0000000..2833c9a --- /dev/null +++ b/scripts/build_csharp.bat @@ -0,0 +1,61 @@ +@echo off +setlocal + +cd /d "%~dp0.." + +echo ======================================================= +echo MemScan-EDR C# Build +echo ======================================================= +echo. + +where dotnet >nul 2>&1 +if %ERRORLEVEL% NEQ 0 ( + echo [ERROR] .NET SDK not found! + echo. + echo Install .NET 8 SDK from: + echo https://dotnet.microsoft.com/download/dotnet/8.0 + echo. + pause + exit /b 1 +) + +dotnet --version +echo. + +echo [1/3] Restoring NuGet packages... +dotnet restore src-csharp\MemScanEDR.sln +if %ERRORLEVEL% NEQ 0 ( + echo [FAIL] Restore failed + pause + exit /b 1 +) + +echo. +echo [2/3] Building Release (single-file exe)... +dotnet publish src-csharp\MemScanEDR\MemScanEDR.csproj -c Release -r win-x64 --self-contained true -p:PublishSingleFile=true -o dist-csharp +if %ERRORLEVEL% NEQ 0 ( + echo [FAIL] Build failed + pause + exit /b 1 +) + +echo. +echo [3/3] Copying resources... +if exist "rules" xcopy /E /I /Y "rules" "dist-csharp\rules" >nul +if exist "config" xcopy /E /I /Y "config" "dist-csharp\config" >nul +if exist "src\ce_mcp_server\server.py" copy /Y "src\ce_mcp_server\server.py" "dist-csharp\src\ce_mcp_server\server.py" >nul + +echo. +echo ======================================================= +echo BUILD SUCCESS! +echo. +if exist "dist-csharp\MemScan-EDR.exe" ( + echo Output: dist-csharp\MemScan-EDR.exe + dir "dist-csharp\MemScan-EDR.exe" 2>nul | findstr "MemScan" +) +echo. +echo Copy dist-csharp\ folder to target machine. +echo Requires .NET 8 runtime OR self-contained exe. +echo ======================================================= +echo. +pause diff --git a/src-csharp/MemScanEDR.sln b/src-csharp/MemScanEDR.sln new file mode 100644 index 0000000..92a884d --- /dev/null +++ b/src-csharp/MemScanEDR.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31903.59 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MemScanEDR", "MemScanEDR\MemScanEDR.csproj", "{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A1B2C3D4-E5F6-7890-ABCD-EF1234567890}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A1B2C3D4-E5F6-7890-ABCD-EF1234567890}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A1B2C3D4-E5F6-7890-ABCD-EF1234567890}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A1B2C3D4-E5F6-7890-ABCD-EF1234567890}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/src-csharp/MemScanEDR/App.xaml b/src-csharp/MemScanEDR/App.xaml new file mode 100644 index 0000000..abb2fe8 --- /dev/null +++ b/src-csharp/MemScanEDR/App.xaml @@ -0,0 +1,5 @@ + + diff --git a/src-csharp/MemScanEDR/App.xaml.cs b/src-csharp/MemScanEDR/App.xaml.cs new file mode 100644 index 0000000..1cfe922 --- /dev/null +++ b/src-csharp/MemScanEDR/App.xaml.cs @@ -0,0 +1,55 @@ +using System; +using System.IO; +using System.Windows; +using System.Windows.Threading; + +namespace MemScanEDR +{ + public partial class App : Application + { + private static readonly string LogPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "crash.log"); + + protected override void OnStartup(StartupEventArgs e) + { + DispatcherUnhandledException += OnDispatcherUnhandledException; + AppDomain.CurrentDomain.UnhandledException += OnDomainUnhandledException; + + base.OnStartup(e); + + try + { + Directory.CreateDirectory("data"); + Directory.CreateDirectory("logs"); + Directory.CreateDirectory("dumps"); + Directory.CreateDirectory("reports"); + } + catch (Exception ex) + { + LogError("Directory creation failed", ex); + } + } + + private void OnDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e) + { + LogError("UI Exception", e.Exception); + MessageBox.Show($"Error logged to crash.log:\n\n{e.Exception.Message}", "MemScan-EDR", + MessageBoxButton.OK, MessageBoxImage.Error); + e.Handled = true; + } + + private void OnDomainUnhandledException(object sender, UnhandledExceptionEventArgs e) + { + LogError("Fatal Exception", e.ExceptionObject as Exception); + } + + private static void LogError(string context, Exception? ex) + { + try + { + var msg = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] {context}\n{ex}\n\n"; + File.AppendAllText(LogPath, msg); + } + catch { } + } + } +} \ No newline at end of file diff --git a/src-csharp/MemScanEDR/MainWindow.xaml b/src-csharp/MemScanEDR/MainWindow.xaml new file mode 100644 index 0000000..2f3dc3f --- /dev/null +++ b/src-csharp/MemScanEDR/MainWindow.xaml @@ -0,0 +1,489 @@ + + + + #f0f2f5 + #1e293b + #ffffff + #ffffff + #f1f5f9 + #e2e8f0 + #1e293b + #64748b + #94a3b8 + #ef4444 + #3b82f6 + #22c55e + #f59e0b + #eff6ff + #cbd5e1 + #64748b + #334155 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +