mirror of
https://github.com/BenjiTrapp/MostShittyAV
synced 2026-06-06 15:24:25 +00:00
DLL wrapper added for AMSI Provider
This commit is contained in:
@@ -0,0 +1,348 @@
|
||||
name: Build and Release MostShittyAV
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*' # Trigger on version tags like v1.0.0
|
||||
workflow_dispatch: # Allow manual trigger
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build on ${{ matrix.os }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [windows-latest]
|
||||
include:
|
||||
- os: windows-latest
|
||||
nim_arch: amd64
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Nim
|
||||
uses: jiro4989/setup-nim-action@v1
|
||||
with:
|
||||
nim-version: '2.0.4'
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
nimble install -y winim
|
||||
|
||||
- name: Build AMSI Provider DLL (New Wrapper)
|
||||
run: |
|
||||
nim c --app:lib --cpu:${{ matrix.nim_arch }} -d:release --out:MostShittyAVWrapper.dll nim_amsi_wrapper_dll.nim
|
||||
|
||||
- name: Build Scanner Executable (Standalone - Original)
|
||||
run: |
|
||||
nim c --cpu:${{ matrix.nim_arch }} -d:release --out:MostShittyAVScanner.exe nim_antimalware_sim.nim
|
||||
|
||||
- name: Verify builds
|
||||
run: |
|
||||
$success = $true
|
||||
|
||||
if (Test-Path "MostShittyAVWrapper.dll") {
|
||||
Write-Host "✓ DLL built successfully (AMSI Provider Wrapper)" -ForegroundColor Green
|
||||
$dll = Get-Item "MostShittyAVWrapper.dll"
|
||||
Write-Host " Size: $([math]::Round($dll.Length / 1KB, 2)) KB"
|
||||
} else {
|
||||
Write-Error "DLL build failed"
|
||||
$success = $false
|
||||
}
|
||||
|
||||
if (Test-Path "MostShittyAVScanner.exe") {
|
||||
Write-Host "✓ EXE built successfully (Standalone Scanner)" -ForegroundColor Green
|
||||
$exe = Get-Item "MostShittyAVScanner.exe"
|
||||
Write-Host " Size: $([math]::Round($exe.Length / 1KB, 2)) KB"
|
||||
} else {
|
||||
Write-Error "EXE build failed"
|
||||
$success = $false
|
||||
}
|
||||
|
||||
if (-not $success) {
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Host "`nBuild Summary:" -ForegroundColor Cyan
|
||||
Write-Host " DLL: AMSI Provider (system-wide, requires registration)" -ForegroundColor Gray
|
||||
Write-Host " EXE: Standalone Scanner (no installation needed)" -ForegroundColor Gray
|
||||
shell: pwsh
|
||||
|
||||
- name: Create build info
|
||||
run: |
|
||||
$info = @"
|
||||
MostShittyAV Build Information
|
||||
==============================
|
||||
Build Date: $(Get-Date -Format "yyyy-MM-dd HH:mm:ss UTC")
|
||||
Nim Version: 2.0.4
|
||||
Architecture: ${{ matrix.nim_arch }}
|
||||
OS: ${{ matrix.os }}
|
||||
|
||||
Components:
|
||||
|
||||
1. AMSI Provider DLL (New - System Integration)
|
||||
- MostShittyAVWrapper.dll - AMSI Provider DLL
|
||||
- Integrates with Windows AMSI system-wide
|
||||
- Requires Administrator registration
|
||||
- Provider GUID: {2E5D8A62-77F9-4F7B-A90B-1C8F6E9D4C3A}
|
||||
|
||||
2. Standalone Scanner EXE (Original - No Installation)
|
||||
- MostShittyAVScanner.exe - Standalone file scanner
|
||||
- Works independently without registration
|
||||
- Can scan files directly from command line
|
||||
- No admin privileges required
|
||||
|
||||
Scripts & Tools:
|
||||
- build_and_register.ps1 - DLL registration automation
|
||||
- quick_build.ps1 - Quick rebuild script
|
||||
|
||||
Documentation:
|
||||
- BUILD_GUIDE.md - Build instructions
|
||||
- TEST_REGISTERED_PROVIDER.md - Testing with Process Monitor
|
||||
- WORKING_SOLUTION.md - Technical details
|
||||
|
||||
Installation Options:
|
||||
|
||||
Option A - AMSI Provider (System-wide):
|
||||
1. Extract all files
|
||||
2. Run PowerShell as Administrator
|
||||
3. Execute: .\build_and_register.ps1 -BuildAndRegister
|
||||
4. Verify: .\build_and_register.ps1 -Status
|
||||
5. Test: Start new PowerShell window
|
||||
|
||||
Option B - Standalone Scanner (No Installation):
|
||||
1. Extract MostShittyAVScanner.exe
|
||||
2. Run: .\MostShittyAVScanner.exe <file1> [file2] ...
|
||||
3. Example: .\MostShittyAVScanner.exe malware.exe
|
||||
|
||||
For detailed instructions, see BUILD_GUIDE.md
|
||||
"@
|
||||
$info | Out-File -FilePath BUILD_INFO.txt -Encoding UTF8
|
||||
shell: pwsh
|
||||
|
||||
- name: Package release artifacts
|
||||
run: |
|
||||
$version = "${{ github.ref_name }}"
|
||||
if (-not $version.StartsWith("v")) {
|
||||
$version = "latest"
|
||||
}
|
||||
|
||||
# Create release directory
|
||||
New-Item -ItemType Directory -Force -Path "release"
|
||||
|
||||
# Copy binaries
|
||||
Copy-Item "MostShittyAVWrapper.dll" "release/"
|
||||
Copy-Item "MostShittyAVScanner.exe" "release/"
|
||||
|
||||
# Copy scripts
|
||||
Copy-Item "build_and_register.ps1" "release/"
|
||||
Copy-Item "quick_build.ps1" "release/"
|
||||
Copy-Item "check_provider_is_running.ps1" "release/" -ErrorAction SilentlyContinue
|
||||
|
||||
# Copy documentation
|
||||
Copy-Item "BUILD_GUIDE.md" "release/"
|
||||
Copy-Item "TEST_REGISTERED_PROVIDER.md" "release/"
|
||||
Copy-Item "WORKING_SOLUTION.md" "release/"
|
||||
Copy-Item "USAGE_COMPARISON.md" "release/"
|
||||
Copy-Item "README.md" "release/"
|
||||
Copy-Item "BUILD_INFO.txt" "release/"
|
||||
|
||||
# Create archive
|
||||
$archiveName = "MostShittyAV-$version-windows-${{ matrix.nim_arch }}.zip"
|
||||
Compress-Archive -Path "release/*" -DestinationPath $archiveName
|
||||
|
||||
Write-Host "Created release archive: $archiveName"
|
||||
Get-Item $archiveName | Select-Object Name, Length
|
||||
shell: pwsh
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: MostShittyAV-${{ matrix.os }}-${{ matrix.nim_arch }}
|
||||
path: |
|
||||
MostShittyAV-*.zip
|
||||
BUILD_INFO.txt
|
||||
|
||||
release:
|
||||
name: Create GitHub Release
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Download all artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
path: artifacts
|
||||
|
||||
- name: Display structure
|
||||
run: ls -R artifacts
|
||||
|
||||
- name: Create Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
files: |
|
||||
artifacts/**/*.zip
|
||||
artifacts/**/BUILD_INFO.txt
|
||||
body: |
|
||||
## MostShittyAV Release ${{ github.ref_name }}
|
||||
|
||||
### 🎯 Two Ways to Use MostShittyAV
|
||||
|
||||
#### 1️⃣ AMSI Provider (System-Wide Integration) - NEW!
|
||||
- **MostShittyAVWrapper.dll** - Integrates with Windows AMSI
|
||||
- Automatically scans content in PowerShell, Windows Defender, etc.
|
||||
- Requires Administrator privileges for registration
|
||||
- System-wide protection
|
||||
|
||||
#### 2️⃣ Standalone Scanner (No Installation) - ORIGINAL
|
||||
- **MostShittyAVScanner.exe** - Command-line file scanner
|
||||
- Works immediately without registration
|
||||
- Scan files on-demand
|
||||
- No admin privileges required
|
||||
|
||||
### 📦 What's Included
|
||||
|
||||
- **MostShittyAVWrapper.dll** - AMSI Provider DLL (new wrapper)
|
||||
- **MostShittyAVScanner.exe** - Standalone Scanner (original)
|
||||
- **Scripts** - Build and registration automation
|
||||
- **Documentation** - Complete setup and testing guides
|
||||
|
||||
### 🚀 Quick Start
|
||||
|
||||
#### Option A: Use Standalone Scanner (Easiest)
|
||||
|
||||
1. Download and extract the ZIP
|
||||
2. Open PowerShell/CMD in the extracted folder
|
||||
3. Run: `.\MostShittyAVScanner.exe <file-to-scan>`
|
||||
4. Example: `.\MostShittyAVScanner.exe malware.exe`
|
||||
|
||||
✅ No installation, no admin rights needed!
|
||||
|
||||
#### Option B: Install AMSI Provider (System Integration)
|
||||
|
||||
1. Download and extract the ZIP file
|
||||
2. **Run PowerShell as Administrator**
|
||||
3. Execute: `.\build_and_register.ps1 -BuildAndRegister`
|
||||
4. Verify: `.\build_and_register.ps1 -Status`
|
||||
5. Test: Start a new PowerShell window
|
||||
|
||||
✅ Integrates with Windows AMSI system-wide!
|
||||
|
||||
### Provider Information
|
||||
|
||||
- **GUID:** `{2E5D8A62-77F9-4F7B-A90B-1C8F6E9D4C3A}`
|
||||
- **Name:** MostShittyAVProvider
|
||||
- **Architecture:** x64 (amd64)
|
||||
|
||||
### Documentation
|
||||
|
||||
- See `BUILD_GUIDE.md` for complete build instructions
|
||||
- See `TEST_REGISTERED_PROVIDER.md` for testing with Process Monitor
|
||||
- See `WORKING_SOLUTION.md` for technical details
|
||||
|
||||
### Requirements
|
||||
|
||||
- Windows 10/11 (x64)
|
||||
- PowerShell 5.1 or later
|
||||
- Administrator privileges (for registration)
|
||||
|
||||
### Security Notice
|
||||
|
||||
⚠️ This is an educational project demonstrating AMSI provider development.
|
||||
The provider registers system-wide and will be loaded by AMSI-aware applications.
|
||||
Use in test environments only.
|
||||
|
||||
### 🧪 Testing
|
||||
|
||||
#### Testing Standalone Scanner:
|
||||
```powershell
|
||||
# Scan a single file
|
||||
.\MostShittyAVScanner.exe test_file.exe
|
||||
|
||||
# Scan multiple files
|
||||
.\MostShittyAVScanner.exe file1.txt file2.ps1 file3.exe
|
||||
```
|
||||
|
||||
#### Testing AMSI Provider:
|
||||
After registration, start a new PowerShell window to load the provider:
|
||||
```powershell
|
||||
# In a NEW PowerShell window
|
||||
.\build_and_register.ps1 -Status
|
||||
|
||||
# The provider will now scan PowerShell commands automatically
|
||||
Write-Host "MALWARE" # Should trigger if "malware" signature is detected
|
||||
```
|
||||
|
||||
For detailed testing with Process Monitor, see `TEST_REGISTERED_PROVIDER.md`.
|
||||
|
||||
### 🗑️ Uninstall
|
||||
|
||||
**Standalone Scanner:** Just delete the EXE - no uninstall needed!
|
||||
|
||||
**AMSI Provider:**
|
||||
```powershell
|
||||
# As Administrator
|
||||
.\build_and_register.ps1 -Unregister
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Built with Nim 2.0.4 | Architecture: amd64 | Platform: Windows
|
||||
draft: false
|
||||
prerelease: false
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
build-on-manual:
|
||||
name: Manual Build (No Release)
|
||||
runs-on: windows-latest
|
||||
if: github.event_name == 'workflow_dispatch' && !startsWith(github.ref, 'refs/tags/')
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Nim
|
||||
uses: jiro4989/setup-nim-action@v1
|
||||
with:
|
||||
nim-version: '2.0.4'
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: nimble install -y winim
|
||||
|
||||
- name: Build AMSI Provider DLL (New Wrapper)
|
||||
run: nim c --app:lib --cpu:amd64 -d:release --out:MostShittyAVWrapper.dll nim_amsi_wrapper_dll.nim
|
||||
|
||||
- name: Build Scanner Executable (Standalone - Original)
|
||||
run: nim c --cpu:amd64 -d:release --out:MostShittyAVScanner.exe nim_antimalware_sim.nim
|
||||
|
||||
- name: Verify manual builds
|
||||
run: |
|
||||
Write-Host "`n=== Build Summary ===" -ForegroundColor Cyan
|
||||
if (Test-Path "MostShittyAVWrapper.dll") {
|
||||
$dll = Get-Item "MostShittyAVWrapper.dll"
|
||||
Write-Host "✓ DLL: $([math]::Round($dll.Length / 1KB, 2)) KB (AMSI Provider)" -ForegroundColor Green
|
||||
}
|
||||
if (Test-Path "MostShittyAVScanner.exe") {
|
||||
$exe = Get-Item "MostShittyAVScanner.exe"
|
||||
Write-Host "✓ EXE: $([math]::Round($exe.Length / 1KB, 2)) KB (Standalone Scanner)" -ForegroundColor Green
|
||||
}
|
||||
shell: pwsh
|
||||
|
||||
- name: Upload build artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: manual-build-artifacts
|
||||
path: |
|
||||
MostShittyAVWrapper.dll
|
||||
MostShittyAVScanner.exe
|
||||
@@ -1,8 +1,33 @@
|
||||
.PHONY: build test_extension_bypass test_signature_detection
|
||||
.PHONY: build dll clean test_extension_bypass test_signature_detection register unregister status
|
||||
|
||||
build:
|
||||
nim c --app:lib --cpu:amd64 --os:windows amsi_raccoon_lab.nim
|
||||
# Build the AMSI Provider DLL
|
||||
dll:
|
||||
@powershell -ExecutionPolicy Bypass -File quick_build.ps1
|
||||
|
||||
# Alias for dll
|
||||
build: dll
|
||||
|
||||
# Build and register (requires Admin)
|
||||
install: dll
|
||||
@echo "Note: Registration requires Administrator privileges"
|
||||
@powershell -ExecutionPolicy Bypass -File build_and_register.ps1 -BuildAndRegister
|
||||
|
||||
# Unregister the provider (requires Admin)
|
||||
unregister:
|
||||
@powershell -ExecutionPolicy Bypass -File build_and_register.ps1 -Unregister
|
||||
|
||||
# Check registration status
|
||||
status:
|
||||
@powershell -ExecutionPolicy Bypass -File build_and_register.ps1 -Status
|
||||
|
||||
# Clean build artifacts
|
||||
clean:
|
||||
@if exist MostShittyAVWrapper.dll del /F /Q MostShittyAVWrapper.dll
|
||||
@if exist MostShittyAVWrapper.dll.old del /F /Q MostShittyAVWrapper.dll.old
|
||||
@if exist test_register.exe del /F /Q test_register.exe
|
||||
@echo Cleaned build artifacts
|
||||
|
||||
# Legacy test targets
|
||||
test_extension_bypass:
|
||||
nim c -r nim_antimalware_sim.nim test\document.pdf.exe test\help.hta test\05\legacy.com test\05\malware test\05\suspicious_file
|
||||
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,389 @@
|
||||
# Testing the Registered AMSI Provider
|
||||
|
||||
This guide shows how to register and verify that your AMSI provider is actually being loaded by Windows processes.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Administrator privileges
|
||||
- [Process Monitor](https://learn.microsoft.com/en-us/sysinternals/downloads/procmon) from Sysinternals
|
||||
- MostShittyAVWrapper.dll built and ready
|
||||
|
||||
## Step 1: Build the DLL
|
||||
|
||||
```powershell
|
||||
.\quick_build.ps1
|
||||
```
|
||||
|
||||
Expected output:
|
||||
```
|
||||
Build successful!
|
||||
DLL: MostShittyAVWrapper.dll
|
||||
Size: 425.12 KB
|
||||
```
|
||||
|
||||
## Step 2: Register the AMSI Provider
|
||||
|
||||
**Important: Run PowerShell as Administrator**
|
||||
|
||||
```powershell
|
||||
.\build_and_register.ps1 -BuildAndRegister
|
||||
```
|
||||
|
||||
Or manually:
|
||||
```powershell
|
||||
regsvr32 "X:\MostShittyAV\MostShittyAVWrapper.dll"
|
||||
```
|
||||
|
||||
## Step 3: Verify Registration
|
||||
|
||||
```powershell
|
||||
.\build_and_register.ps1 -Status
|
||||
```
|
||||
|
||||
Or use the check script:
|
||||
```powershell
|
||||
.\check_provider_is_running.ps1
|
||||
```
|
||||
|
||||
You should see:
|
||||
```
|
||||
AMSI Registration: REGISTERED ✓
|
||||
COM CLSID: REGISTERED ✓
|
||||
```
|
||||
|
||||
Verify registry keys manually:
|
||||
```powershell
|
||||
# Check AMSI Provider
|
||||
Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\AMSI\Providers\{2E5D8A62-77F9-4F7B-A90B-1C8F6E9D4C3A}"
|
||||
|
||||
# Check COM CLSID
|
||||
Get-ItemProperty "HKLM:\SOFTWARE\Classes\CLSID\{2E5D8A62-77F9-4F7B-A90B-1C8F6E9D4C3A}\InprocServer32"
|
||||
```
|
||||
|
||||
## Step 4: Setup Process Monitor
|
||||
|
||||
### 4.1 Download and Launch Process Monitor
|
||||
|
||||
1. Download from: https://learn.microsoft.com/en-us/sysinternals/downloads/procmon
|
||||
2. Extract and run `Procmon.exe` **as Administrator**
|
||||
3. Accept the license agreement
|
||||
|
||||
### 4.2 Configure Filters
|
||||
|
||||
Process Monitor shows ALL system activity by default. We need to filter for our DLL.
|
||||
|
||||
**Click Filter → Filter... (or press Ctrl+L)**
|
||||
|
||||
Add the following filters:
|
||||
|
||||
**Filter 1: DLL Path**
|
||||
```
|
||||
Path contains MostShittyAVWrapper.dll
|
||||
Include
|
||||
Add
|
||||
```
|
||||
|
||||
**Filter 2: DLL Name**
|
||||
```
|
||||
Path contains MostShittyAVWrapper
|
||||
Include
|
||||
Add
|
||||
```
|
||||
|
||||
**Filter 3: Our CLSID (optional)**
|
||||
```
|
||||
Path contains 2E5D8A62-77F9-4F7B-A90B-1C8F6E9D4C3A
|
||||
Include
|
||||
Add
|
||||
```
|
||||
|
||||
Click **OK** to apply filters.
|
||||
|
||||
### 4.3 Configure Columns (Optional)
|
||||
|
||||
To see more useful information:
|
||||
|
||||
1. Right-click on column headers
|
||||
2. Select **Select Columns...**
|
||||
3. Enable these columns:
|
||||
- Process Name
|
||||
- PID
|
||||
- Operation
|
||||
- Path
|
||||
- Result
|
||||
- Detail
|
||||
|
||||
### 4.4 Clear Existing Events
|
||||
|
||||
Click **Edit → Clear Display** (or press Ctrl+X)
|
||||
|
||||
## Step 5: Test Provider Loading
|
||||
|
||||
### Test 1: Launch PowerShell
|
||||
|
||||
With Process Monitor running and filtered:
|
||||
|
||||
```powershell
|
||||
# Start a new PowerShell process
|
||||
Start-Process powershell
|
||||
```
|
||||
|
||||
**What to look for in Process Monitor:**
|
||||
|
||||
You should see events like:
|
||||
```
|
||||
powershell.exe CreateFile X:\MostShittyAV\MostShittyAVWrapper.dll SUCCESS
|
||||
powershell.exe Load Image MostShittyAVWrapper.dll SUCCESS
|
||||
powershell.exe QueryNameInformationFile MostShittyAVWrapper.dll SUCCESS
|
||||
```
|
||||
|
||||
**If you see these events:** ✅ Your AMSI provider is being loaded!
|
||||
|
||||
**If you see nothing:** ❌ Provider is not loading (see Troubleshooting section)
|
||||
|
||||
### Test 2: Launch Multiple Processes
|
||||
|
||||
Try other AMSI-aware applications:
|
||||
|
||||
```powershell
|
||||
# PowerShell
|
||||
Start-Process powershell
|
||||
|
||||
# Windows Script Host
|
||||
Start-Process wscript
|
||||
|
||||
# Command Prompt (if AMSI is enabled)
|
||||
Start-Process cmd
|
||||
```
|
||||
|
||||
Watch Process Monitor for `MostShittyAVWrapper.dll` load events.
|
||||
|
||||
### Test 3: Registry Access
|
||||
|
||||
Look for registry access to your provider's keys:
|
||||
|
||||
**Filter for:**
|
||||
```
|
||||
Path contains AMSI\Providers
|
||||
Include
|
||||
```
|
||||
|
||||
You should see:
|
||||
```
|
||||
powershell.exe RegOpenKey HKLM\SOFTWARE\Microsoft\AMSI\Providers\{2E5D8A62-77F9-4F7B-A90B-1C8F6E9D4C3A} SUCCESS
|
||||
powershell.exe RegQueryValue ... SUCCESS
|
||||
```
|
||||
|
||||
## Step 6: Verify DLL Functions Are Called
|
||||
|
||||
To see if your DLL's functions are actually being invoked, you can:
|
||||
|
||||
### Option A: Add Debug Output to Your Code
|
||||
|
||||
In `nim_amsi_wrapper_dll.nim`, the functions already have echo statements:
|
||||
|
||||
```nim
|
||||
proc DllGetClassObject(...): HRESULT {.exportc, stdcall, dynlib.} =
|
||||
...
|
||||
echo "DllGetClassObject (wrapper) aufgerufen" # This will output when called
|
||||
...
|
||||
```
|
||||
|
||||
### Option B: Use DebugView
|
||||
|
||||
1. Download [DebugView](https://learn.microsoft.com/en-us/sysinternals/downloads/debugview)
|
||||
2. Run as Administrator
|
||||
3. Enable: Capture → Capture Global Win32
|
||||
4. Launch a new PowerShell window
|
||||
5. Look for debug output from your DLL
|
||||
|
||||
### Option C: Attach a Debugger
|
||||
|
||||
For advanced debugging:
|
||||
|
||||
```powershell
|
||||
# Build with debug symbols
|
||||
nim c --app:lib --cpu:amd64 --debugger:native --out:MostShittyAVWrapper.dll nim_amsi_wrapper_dll.nim
|
||||
|
||||
# Use Visual Studio or WinDbg to attach to powershell.exe
|
||||
```
|
||||
|
||||
## Expected Process Monitor Output
|
||||
|
||||
When everything works correctly, you should see:
|
||||
|
||||
```
|
||||
Time Process Operation Path Result
|
||||
---------- -------------- -------------- -------------------------------------- -------
|
||||
12:34:56 powershell.exe CreateFile X:\...\MostShittyAVWrapper.dll SUCCESS
|
||||
12:34:56 powershell.exe QueryAttributes X:\...\MostShittyAVWrapper.dll SUCCESS
|
||||
12:34:56 powershell.exe CreateFileMap X:\...\MostShittyAVWrapper.dll SUCCESS
|
||||
12:34:56 powershell.exe Load Image MostShittyAVWrapper.dll SUCCESS
|
||||
12:34:56 powershell.exe QueryBasicInfo X:\...\MostShittyAVWrapper.dll SUCCESS
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Provider Not Loading
|
||||
|
||||
**Problem:** No events in Process Monitor
|
||||
|
||||
**Solutions:**
|
||||
|
||||
1. **Verify Registration:**
|
||||
```powershell
|
||||
.\build_and_register.ps1 -Status
|
||||
```
|
||||
|
||||
2. **Check DLL Path in Registry:**
|
||||
```powershell
|
||||
$path = (Get-ItemProperty "HKLM:\SOFTWARE\Classes\CLSID\{2E5D8A62-77F9-4F7B-A90B-1C8F6E9D4C3A}\InprocServer32").'(default)'
|
||||
Write-Host "DLL Path: $path"
|
||||
Test-Path $path # Should return True
|
||||
```
|
||||
|
||||
3. **Verify DLL is Accessible:**
|
||||
```powershell
|
||||
$path = "X:\MostShittyAV\MostShittyAVWrapper.dll"
|
||||
icacls $path
|
||||
# Should show Read & Execute permissions for Everyone or Users
|
||||
```
|
||||
|
||||
4. **Check for COM/AMSI Errors in Event Viewer:**
|
||||
```powershell
|
||||
# Open Event Viewer
|
||||
eventvwr.msc
|
||||
|
||||
# Navigate to: Windows Logs → Application
|
||||
# Filter for Source: AMSI, COM+, etc.
|
||||
```
|
||||
|
||||
### DLL Loads But Functions Not Called
|
||||
|
||||
**Problem:** DLL loads in Process Monitor but no function calls
|
||||
|
||||
**Possible Causes:**
|
||||
|
||||
1. **DllGetClassObject failing** - Check return codes
|
||||
2. **COM registration incomplete** - Verify all registry keys
|
||||
3. **Wrong threading model** - Should be "Both"
|
||||
4. **AMSI choosing different provider** - Windows may prioritize other providers
|
||||
|
||||
**Debug Steps:**
|
||||
|
||||
```powershell
|
||||
# Check Windows Defender AMSI logs
|
||||
Get-WinEvent -LogName "Microsoft-Windows-Windows Defender/Operational" -MaxEvents 20
|
||||
|
||||
# Check COM initialization
|
||||
Get-WinEvent -LogName "System" -MaxEvents 50 | Where-Object {$_.Message -like "*COM*"}
|
||||
```
|
||||
|
||||
### Access Denied
|
||||
|
||||
**Problem:** Registration fails with "Access Denied"
|
||||
|
||||
**Solution:**
|
||||
- Run PowerShell as Administrator
|
||||
- Check User Account Control (UAC) settings
|
||||
- Verify you have write access to HKLM
|
||||
|
||||
### DLL In Use
|
||||
|
||||
**Problem:** Cannot rebuild DLL (file locked)
|
||||
|
||||
**Solution:**
|
||||
```powershell
|
||||
# Find processes using the DLL
|
||||
Get-Process | Where-Object {
|
||||
try {
|
||||
$_.Modules.FileName -like "*MostShittyAVWrapper*"
|
||||
} catch {
|
||||
$false
|
||||
}
|
||||
} | Select-Object ProcessName, Id
|
||||
|
||||
# Close those processes or restart computer
|
||||
```
|
||||
|
||||
## Verification Checklist
|
||||
|
||||
Before testing, verify:
|
||||
|
||||
- [ ] DLL exists: `X:\MostShittyAV\MostShittyAVWrapper.dll`
|
||||
- [ ] AMSI Provider key exists in registry
|
||||
- [ ] COM CLSID key exists in registry
|
||||
- [ ] InprocServer32 path points to correct DLL location
|
||||
- [ ] ThreadingModel is set to "Both"
|
||||
- [ ] DLL is not locked/in-use
|
||||
- [ ] Process Monitor is running as Administrator
|
||||
- [ ] Filters are configured correctly
|
||||
- [ ] Testing with a NEW PowerShell window (not existing one)
|
||||
|
||||
## Advanced Testing
|
||||
|
||||
### Test with AMSI Scanner
|
||||
|
||||
Create a test PowerShell script that AMSI should scan:
|
||||
|
||||
```powershell
|
||||
# test_amsi_scan.ps1
|
||||
$code = @"
|
||||
Write-Host "This is a test"
|
||||
# AMSI scans this content
|
||||
"@
|
||||
|
||||
Invoke-Expression $code
|
||||
```
|
||||
|
||||
Run it in a new PowerShell window:
|
||||
```powershell
|
||||
.\test_amsi_scan.ps1
|
||||
```
|
||||
|
||||
Watch Process Monitor for your DLL being loaded and accessed.
|
||||
|
||||
### Test with Malicious String
|
||||
|
||||
```powershell
|
||||
# In a new PowerShell window
|
||||
$test = "AMSI Test " + "X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*"
|
||||
Write-Host $test
|
||||
```
|
||||
|
||||
AMSI should scan this content and your provider may be invoked.
|
||||
|
||||
## Uninstalling the Provider
|
||||
|
||||
To remove the provider after testing:
|
||||
|
||||
```powershell
|
||||
# As Administrator
|
||||
.\build_and_register.ps1 -Unregister
|
||||
|
||||
# Verify
|
||||
.\build_and_register.ps1 -Status
|
||||
```
|
||||
|
||||
Or manually:
|
||||
```powershell
|
||||
regsvr32 /u "X:\MostShittyAV\MostShittyAVWrapper.dll"
|
||||
```
|
||||
|
||||
## Summary
|
||||
|
||||
A successfully registered and loaded AMSI provider will show:
|
||||
|
||||
1. ✅ Registry keys present in HKLM
|
||||
2. ✅ DLL load events in Process Monitor when starting AMSI-aware apps
|
||||
3. ✅ DLL functions being called (visible via debug output)
|
||||
4. ✅ No errors in Event Viewer related to COM or AMSI
|
||||
|
||||
If all checks pass, your AMSI provider is working correctly! 🎉
|
||||
|
||||
## References
|
||||
|
||||
- [Process Monitor](https://learn.microsoft.com/en-us/sysinternals/downloads/procmon)
|
||||
- [DebugView](https://learn.microsoft.com/en-us/sysinternals/downloads/debugview)
|
||||
- [AMSI Documentation](https://docs.microsoft.com/en-us/windows/win32/amsi/)
|
||||
- [COM Registration](https://docs.microsoft.com/en-us/windows/win32/com/registering-com-applications)
|
||||
@@ -0,0 +1,205 @@
|
||||
# MostShittyAV - Usage Comparison
|
||||
|
||||
## Two Ways to Use MostShittyAV
|
||||
|
||||
MostShittyAV offers **two different components** that can be used independently:
|
||||
|
||||
### 🆕 AMSI Provider DLL (New - System Integration)
|
||||
|
||||
**File:** `MostShittyAVWrapper.dll`
|
||||
|
||||
**What it does:**
|
||||
- Integrates with Windows AMSI (Anti-Malware Scan Interface)
|
||||
- Automatically scans content in AMSI-aware applications
|
||||
- Works system-wide once registered
|
||||
|
||||
**Use Cases:**
|
||||
- ✅ Automatic scanning in PowerShell
|
||||
- ✅ Integration with Windows Defender
|
||||
- ✅ System-wide malware detection
|
||||
- ✅ Real-time protection
|
||||
|
||||
**Requirements:**
|
||||
- ⚠️ Administrator privileges for registration
|
||||
- ⚠️ Must be registered via `regsvr32` or scripts
|
||||
- ⚠️ Affects system-wide behavior
|
||||
|
||||
**Installation:**
|
||||
```powershell
|
||||
# As Administrator
|
||||
.\build_and_register.ps1 -BuildAndRegister
|
||||
```
|
||||
|
||||
**Testing:**
|
||||
```powershell
|
||||
# Start a new PowerShell window - provider auto-loads
|
||||
Write-Host "MALWARE" # Will be scanned by AMSI
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 📦 Standalone Scanner EXE (Original - No Installation)
|
||||
|
||||
**File:** `MostShittyAVScanner.exe`
|
||||
|
||||
**What it does:**
|
||||
- Command-line file scanner
|
||||
- Scans files on-demand
|
||||
- Works completely independently
|
||||
|
||||
**Use Cases:**
|
||||
- ✅ Quick file scanning
|
||||
- ✅ Batch file scanning
|
||||
- ✅ Testing/research
|
||||
- ✅ Portable scanning tool
|
||||
|
||||
**Requirements:**
|
||||
- ✅ No installation needed
|
||||
- ✅ No admin privileges required
|
||||
- ✅ Works immediately
|
||||
|
||||
**Usage:**
|
||||
```powershell
|
||||
# Scan a single file
|
||||
.\MostShittyAVScanner.exe malware.exe
|
||||
|
||||
# Scan multiple files
|
||||
.\MostShittyAVScanner.exe file1.ps1 file2.bat file3.dll
|
||||
|
||||
# Scan test files
|
||||
.\MostShittyAVScanner.exe test\02_malware.ps1 test\trojan_sample.txt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Feature Comparison
|
||||
|
||||
| Feature | AMSI Provider DLL | Standalone Scanner EXE |
|
||||
|---------|-------------------|------------------------|
|
||||
| **Installation Required** | Yes (registration) | No |
|
||||
| **Admin Privileges** | Required | Not required |
|
||||
| **System Integration** | Yes (AMSI) | No |
|
||||
| **Automatic Scanning** | Yes | No |
|
||||
| **On-Demand Scanning** | No | Yes |
|
||||
| **Portable** | No | Yes |
|
||||
| **Affects PowerShell** | Yes | No |
|
||||
| **Works Without Restart** | No (needs new process) | Yes (immediate) |
|
||||
| **Can Scan Multiple Files** | N/A (automatic) | Yes |
|
||||
| **Learning/Testing** | ✅ See AMSI internals | ✅ Simple scanner logic |
|
||||
|
||||
---
|
||||
|
||||
## Which One Should You Use?
|
||||
|
||||
### Use the **AMSI Provider DLL** if you want to:
|
||||
- ✅ Learn how AMSI providers work
|
||||
- ✅ Test system-wide integration
|
||||
- ✅ Automatically scan PowerShell commands
|
||||
- ✅ Integrate with Windows security
|
||||
- ✅ Study AMSI internals with Process Monitor
|
||||
|
||||
**Best for:** Security researchers, AMSI learning, system integration testing
|
||||
|
||||
### Use the **Standalone Scanner EXE** if you want to:
|
||||
- ✅ Quickly scan files
|
||||
- ✅ Test the scanner logic without system changes
|
||||
- ✅ Avoid requiring admin privileges
|
||||
- ✅ Portable scanning tool
|
||||
- ✅ Batch process files
|
||||
|
||||
**Best for:** Quick file scanning, testing scanner logic, casual use
|
||||
|
||||
---
|
||||
|
||||
## Can I Use Both?
|
||||
|
||||
**Yes!** They work completely independently:
|
||||
|
||||
1. **Standalone Scanner** can be used anytime without affecting the system
|
||||
2. **AMSI Provider** runs automatically when registered, affecting AMSI-aware apps
|
||||
3. Both use the same scanner logic from `nim_antimalware_sim.nim`
|
||||
|
||||
---
|
||||
|
||||
## Examples
|
||||
|
||||
### Example 1: Testing Scanner Logic (Use Standalone EXE)
|
||||
|
||||
```powershell
|
||||
# No installation needed
|
||||
.\MostShittyAVScanner.exe test\02_malware.ps1
|
||||
```
|
||||
|
||||
Output:
|
||||
```
|
||||
[2025-11-09 01:30:00] AMSI: Starting scan for file: test\02_malware.ps1
|
||||
[2025-11-09 01:30:00] AMSI: Threat detected - Signature found
|
||||
Result: MALICIOUS
|
||||
```
|
||||
|
||||
### Example 2: Testing AMSI Integration (Use DLL)
|
||||
|
||||
```powershell
|
||||
# Register (as Admin)
|
||||
.\build_and_register.ps1 -BuildAndRegister
|
||||
|
||||
# Open NEW PowerShell window
|
||||
# Type commands - they're automatically scanned
|
||||
Write-Host "This is safe" # ✅ No detection
|
||||
$malware = "MALWARE" # ⚠️ May trigger detection
|
||||
```
|
||||
|
||||
### Example 3: Scanning Multiple Files (Use Standalone EXE)
|
||||
|
||||
```powershell
|
||||
# Scan entire test directory
|
||||
Get-ChildItem test -Recurse -File | ForEach-Object {
|
||||
.\MostShittyAVScanner.exe $_.FullName
|
||||
}
|
||||
```
|
||||
|
||||
### Example 4: Research AMSI Provider Loading (Use DLL + Process Monitor)
|
||||
|
||||
```powershell
|
||||
# Register provider
|
||||
.\build_and_register.ps1 -BuildAndRegister
|
||||
|
||||
# Start Process Monitor with filters
|
||||
# Launch new PowerShell
|
||||
# Watch DLL load events in Process Monitor
|
||||
|
||||
# See TEST_REGISTERED_PROVIDER.md for detailed steps
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Technical Details
|
||||
|
||||
### Both Components Share:
|
||||
- Same scanner engine (`nim_antimalware_sim.nim`)
|
||||
- Same signature detection
|
||||
- Same heuristics
|
||||
- Same threat analysis logic
|
||||
|
||||
### Differences:
|
||||
| Aspect | AMSI Provider DLL | Standalone Scanner |
|
||||
|--------|-------------------|-------------------|
|
||||
| **Entry Point** | `DllRegisterServer`, `DllGetClassObject` | `main()` |
|
||||
| **Invocation** | Called by AMSI automatically | Called by user manually |
|
||||
| **Context** | Runs in host process (PowerShell, etc.) | Runs in own process |
|
||||
| **Input** | AMSI scan requests | Command-line file paths |
|
||||
| **Output** | HRESULT codes | Console logs + exit code |
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
**TLDR:**
|
||||
|
||||
- 🆕 **Want system integration?** → Use `MostShittyAVWrapper.dll` (AMSI Provider)
|
||||
- 📦 **Want quick file scanning?** → Use `MostShittyAVScanner.exe` (Standalone)
|
||||
- 🎓 **Learning AMSI?** → Use the DLL + Process Monitor
|
||||
- 🧪 **Testing scanner logic?** → Use the EXE (faster iteration)
|
||||
- 🚀 **Not sure?** → Start with the EXE (no installation)
|
||||
|
||||
Both are included in the release package - choose what fits your needs!
|
||||
@@ -0,0 +1,286 @@
|
||||
# build_and_register.ps1
|
||||
# Complete workflow to build and register the AMSI provider
|
||||
#
|
||||
# Usage:
|
||||
# .\build_and_register.ps1 -Build # Just build the DLL
|
||||
# .\build_and_register.ps1 -BuildAndRegister # Build and register (requires Admin)
|
||||
# .\build_and_register.ps1 -Status # Show current status
|
||||
# .\build_and_register.ps1 -Unregister # Unregister the provider
|
||||
|
||||
param(
|
||||
[switch]$Build,
|
||||
[switch]$BuildAndRegister,
|
||||
[switch]$Status,
|
||||
[switch]$Unregister
|
||||
)
|
||||
|
||||
$PROVIDER_GUID = "{2E5D8A62-77F9-4F7B-A90B-1C8F6E9D4C3A}"
|
||||
$PROVIDER_NAME = "MostShittyAVProvider"
|
||||
$DLL_NAME = "MostShittyAVWrapper.dll"
|
||||
$SOURCE_FILE = "nim_amsi_wrapper_dll.nim"
|
||||
|
||||
function Test-IsAdmin {
|
||||
$currentUser = [Security.Principal.WindowsIdentity]::GetCurrent()
|
||||
$principal = New-Object Security.Principal.WindowsPrincipal($currentUser)
|
||||
return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
|
||||
}
|
||||
|
||||
function Build-DLL {
|
||||
Write-Host "`n=== Building AMSI Provider DLL ===" -ForegroundColor Cyan
|
||||
|
||||
# Remove old DLL if it exists
|
||||
if (Test-Path $DLL_NAME) {
|
||||
Write-Host "Removing old DLL..." -ForegroundColor Yellow
|
||||
try {
|
||||
Remove-Item $DLL_NAME -Force -ErrorAction Stop
|
||||
} catch {
|
||||
Write-Host "Warning: Could not remove old DLL (may be in use)" -ForegroundColor Yellow
|
||||
$oldName = "$DLL_NAME.old"
|
||||
Move-Item $DLL_NAME $oldName -Force
|
||||
Write-Host "Renamed to $oldName" -ForegroundColor Yellow
|
||||
}
|
||||
}
|
||||
|
||||
# Build with Nim
|
||||
Write-Host "Compiling $SOURCE_FILE..." -ForegroundColor Cyan
|
||||
$buildCmd = "nim c --app:lib --cpu:amd64 --out:$DLL_NAME $SOURCE_FILE"
|
||||
|
||||
Write-Host "Command: $buildCmd" -ForegroundColor Gray
|
||||
Invoke-Expression $buildCmd
|
||||
|
||||
if ($LASTEXITCODE -eq 0 -and (Test-Path $DLL_NAME)) {
|
||||
Write-Host "`n✓ Build successful!" -ForegroundColor Green
|
||||
Write-Host " DLL: $((Get-Item $DLL_NAME).FullName)" -ForegroundColor Gray
|
||||
Write-Host " Size: $([math]::Round((Get-Item $DLL_NAME).Length / 1KB, 2)) KB" -ForegroundColor Gray
|
||||
return $true
|
||||
} else {
|
||||
Write-Host "`n✗ Build failed!" -ForegroundColor Red
|
||||
return $false
|
||||
}
|
||||
}
|
||||
|
||||
function Register-Provider {
|
||||
if (-not (Test-IsAdmin)) {
|
||||
Write-Host "`n✗ ERROR: Administrator privileges required!" -ForegroundColor Red
|
||||
Write-Host "Please run PowerShell as Administrator." -ForegroundColor Yellow
|
||||
return $false
|
||||
}
|
||||
|
||||
if (-not (Test-Path $DLL_NAME)) {
|
||||
Write-Host "`n✗ ERROR: DLL not found: $DLL_NAME" -ForegroundColor Red
|
||||
Write-Host "Build the DLL first with: .\build_and_register.ps1 -Build" -ForegroundColor Yellow
|
||||
return $false
|
||||
}
|
||||
|
||||
Write-Host "`n=== Registering AMSI Provider ===" -ForegroundColor Cyan
|
||||
Write-Host "DLL: $((Get-Item $DLL_NAME).FullName)" -ForegroundColor Gray
|
||||
|
||||
# Use regsvr32 to register
|
||||
$dllPath = (Get-Item $DLL_NAME).FullName
|
||||
Write-Host "Running: regsvr32 /s `"$dllPath`"" -ForegroundColor Gray
|
||||
|
||||
$result = Start-Process -FilePath "regsvr32.exe" -ArgumentList "/s `"$dllPath`"" -Wait -PassThru -NoNewWindow
|
||||
|
||||
if ($result.ExitCode -eq 0) {
|
||||
Write-Host "✓ regsvr32 completed successfully!" -ForegroundColor Green
|
||||
|
||||
# Verify registration
|
||||
Start-Sleep -Milliseconds 500
|
||||
$amsiKey = "HKLM:\SOFTWARE\Microsoft\AMSI\Providers\$PROVIDER_GUID"
|
||||
if (Test-Path $amsiKey) {
|
||||
Write-Host "✓ AMSI Provider registered successfully!" -ForegroundColor Green
|
||||
return $true
|
||||
} else {
|
||||
Write-Host "⚠ Warning: regsvr32 succeeded but registry keys not found" -ForegroundColor Yellow
|
||||
Write-Host " The DllRegisterServer function may have returned an error" -ForegroundColor Gray
|
||||
return $false
|
||||
}
|
||||
} else {
|
||||
Write-Host "✗ Registration failed with exit code: $($result.ExitCode)" -ForegroundColor Red
|
||||
switch ($result.ExitCode) {
|
||||
3 { Write-Host " DllRegisterServer entry point not found" -ForegroundColor Yellow }
|
||||
4 { Write-Host " DllRegisterServer failed (check permissions)" -ForegroundColor Yellow }
|
||||
5 { Write-Host " Access denied (run as Administrator)" -ForegroundColor Yellow }
|
||||
default { Write-Host " Unknown error code" -ForegroundColor Yellow }
|
||||
}
|
||||
return $false
|
||||
}
|
||||
}
|
||||
|
||||
function Unregister-Provider {
|
||||
if (-not (Test-IsAdmin)) {
|
||||
Write-Host "`n✗ ERROR: Administrator privileges required!" -ForegroundColor Red
|
||||
Write-Host "Please run PowerShell as Administrator." -ForegroundColor Yellow
|
||||
return $false
|
||||
}
|
||||
|
||||
Write-Host "`n=== Unregistering AMSI Provider ===" -ForegroundColor Cyan
|
||||
|
||||
if (Test-Path $DLL_NAME) {
|
||||
$dllPath = (Get-Item $DLL_NAME).FullName
|
||||
Write-Host "Running: regsvr32 /u /s `"$dllPath`"" -ForegroundColor Gray
|
||||
$result = Start-Process -FilePath "regsvr32.exe" -ArgumentList "/u /s `"$dllPath`"" -Wait -PassThru -NoNewWindow
|
||||
|
||||
if ($result.ExitCode -eq 0) {
|
||||
Write-Host "✓ regsvr32 unregister completed" -ForegroundColor Green
|
||||
}
|
||||
} else {
|
||||
Write-Host "Warning: DLL not found, will clean registry manually" -ForegroundColor Yellow
|
||||
}
|
||||
|
||||
# Manual cleanup
|
||||
Write-Host "Cleaning up registry keys..." -ForegroundColor Cyan
|
||||
|
||||
$amsiKey = "HKLM:\SOFTWARE\Microsoft\AMSI\Providers\$PROVIDER_GUID"
|
||||
if (Test-Path $amsiKey) {
|
||||
Remove-Item -Path $amsiKey -Force -ErrorAction SilentlyContinue
|
||||
Write-Host " ✓ Removed AMSI Provider key" -ForegroundColor Green
|
||||
}
|
||||
|
||||
$inprocKey = "HKLM:\SOFTWARE\Classes\CLSID\$PROVIDER_GUID\InprocServer32"
|
||||
if (Test-Path $inprocKey) {
|
||||
Remove-Item -Path $inprocKey -Force -ErrorAction SilentlyContinue
|
||||
Write-Host " ✓ Removed InprocServer32 key" -ForegroundColor Green
|
||||
}
|
||||
|
||||
$clsidKey = "HKLM:\SOFTWARE\Classes\CLSID\$PROVIDER_GUID"
|
||||
if (Test-Path $clsidKey) {
|
||||
Remove-Item -Path $clsidKey -Force -ErrorAction SilentlyContinue
|
||||
Write-Host " ✓ Removed CLSID key" -ForegroundColor Green
|
||||
}
|
||||
|
||||
Write-Host "`n✓ Unregistration complete!" -ForegroundColor Green
|
||||
return $true
|
||||
}
|
||||
|
||||
function Show-Status {
|
||||
Write-Host "`n=== AMSI Provider Status ===" -ForegroundColor Cyan
|
||||
Write-Host "Provider GUID: $PROVIDER_GUID" -ForegroundColor Gray
|
||||
Write-Host "Provider Name: $PROVIDER_NAME" -ForegroundColor Gray
|
||||
Write-Host "DLL Path: $PSScriptRoot\$DLL_NAME" -ForegroundColor Gray
|
||||
|
||||
if (Test-Path $DLL_NAME) {
|
||||
$dll = Get-Item $DLL_NAME
|
||||
Write-Host "DLL Exists: YES ($([math]::Round($dll.Length / 1KB, 2)) KB)" -ForegroundColor Green
|
||||
Write-Host "Last Modified: $($dll.LastWriteTime)" -ForegroundColor Gray
|
||||
} else {
|
||||
Write-Host "DLL Exists: NO" -ForegroundColor Red
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
|
||||
# Check AMSI registration
|
||||
$amsiKey = "HKLM:\SOFTWARE\Microsoft\AMSI\Providers\$PROVIDER_GUID"
|
||||
$amsiExists = Test-Path $amsiKey
|
||||
Write-Host "AMSI Registration: " -NoNewline
|
||||
if ($amsiExists) {
|
||||
Write-Host "REGISTERED ✓" -ForegroundColor Green
|
||||
try {
|
||||
$value = Get-ItemProperty -Path $amsiKey -Name "(default)" -ErrorAction SilentlyContinue
|
||||
if ($value) {
|
||||
Write-Host " Provider Name: $($value.'(default)')" -ForegroundColor Gray
|
||||
}
|
||||
} catch {}
|
||||
} else {
|
||||
Write-Host "NOT REGISTERED" -ForegroundColor Yellow
|
||||
}
|
||||
|
||||
# Check COM registration
|
||||
$clsidKey = "HKLM:\SOFTWARE\Classes\CLSID\$PROVIDER_GUID"
|
||||
$clsidExists = Test-Path $clsidKey
|
||||
Write-Host "COM CLSID: " -NoNewline
|
||||
if ($clsidExists) {
|
||||
Write-Host "REGISTERED ✓" -ForegroundColor Green
|
||||
$inprocKey = "$clsidKey\InprocServer32"
|
||||
if (Test-Path $inprocKey) {
|
||||
try {
|
||||
$dllPath = Get-ItemProperty -Path $inprocKey -Name "(default)" -ErrorAction SilentlyContinue
|
||||
if ($dllPath) {
|
||||
Write-Host " DLL Path: $($dllPath.'(default)')" -ForegroundColor Gray
|
||||
}
|
||||
$threading = Get-ItemProperty -Path $inprocKey -Name "ThreadingModel" -ErrorAction SilentlyContinue
|
||||
if ($threading) {
|
||||
Write-Host " Threading: $($threading.ThreadingModel)" -ForegroundColor Gray
|
||||
}
|
||||
} catch {}
|
||||
}
|
||||
} else {
|
||||
Write-Host "NOT REGISTERED" -ForegroundColor Yellow
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
|
||||
if ($amsiExists -and $clsidExists) {
|
||||
Write-Host "Status: ACTIVE - AMSI will load this provider ✓" -ForegroundColor Green
|
||||
} elseif ($amsiExists -or $clsidExists) {
|
||||
Write-Host "Status: PARTIAL - Some keys registered" -ForegroundColor Yellow
|
||||
} else {
|
||||
Write-Host "Status: NOT ACTIVE - Provider not registered" -ForegroundColor Gray
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
}
|
||||
|
||||
# Main script logic
|
||||
if ($BuildAndRegister) {
|
||||
Write-Host "=== Build and Register Workflow ===" -ForegroundColor Magenta
|
||||
|
||||
if (Build-DLL) {
|
||||
if (Register-Provider) {
|
||||
Write-Host "`n=== SUCCESS ===" -ForegroundColor Green
|
||||
Write-Host "AMSI Provider is built and registered!" -ForegroundColor Green
|
||||
Show-Status
|
||||
Write-Host "`nIMPORTANT: Restart applications for them to load the provider." -ForegroundColor Yellow
|
||||
Write-Host "Example: Start a new PowerShell window" -ForegroundColor Gray
|
||||
} else {
|
||||
Write-Host "`n=== PARTIAL SUCCESS ===" -ForegroundColor Yellow
|
||||
Write-Host "Build succeeded but registration failed." -ForegroundColor Yellow
|
||||
Write-Host "Make sure you're running as Administrator." -ForegroundColor Gray
|
||||
}
|
||||
} else {
|
||||
Write-Host "`n=== FAILED ===" -ForegroundColor Red
|
||||
Write-Host "Build failed. Fix compilation errors and try again." -ForegroundColor Red
|
||||
}
|
||||
} elseif ($Build) {
|
||||
Build-DLL | Out-Null
|
||||
if (Test-Path $DLL_NAME) {
|
||||
Show-Status
|
||||
}
|
||||
} elseif ($Unregister) {
|
||||
Unregister-Provider | Out-Null
|
||||
Show-Status
|
||||
} elseif ($Status) {
|
||||
Show-Status
|
||||
} else {
|
||||
Write-Host @"
|
||||
|
||||
===============================================================
|
||||
MostShittyAV - AMSI Provider Build Tool
|
||||
===============================================================
|
||||
|
||||
Usage:
|
||||
.\build_and_register.ps1 -Build
|
||||
Build the AMSI provider DLL
|
||||
|
||||
.\build_and_register.ps1 -BuildAndRegister
|
||||
Build and register the AMSI provider (requires Admin)
|
||||
|
||||
.\build_and_register.ps1 -Status
|
||||
Show current build and registration status
|
||||
|
||||
.\build_and_register.ps1 -Unregister
|
||||
Unregister the AMSI provider (requires Admin)
|
||||
|
||||
Quick Start:
|
||||
1. Build: .\build_and_register.ps1 -Build
|
||||
2. Check: .\build_and_register.ps1 -Status
|
||||
3. Register (as Admin): .\build_and_register.ps1 -BuildAndRegister
|
||||
|
||||
Provider Details:
|
||||
GUID: $PROVIDER_GUID
|
||||
Name: $PROVIDER_NAME
|
||||
DLL: $DLL_NAME
|
||||
|
||||
"@
|
||||
Show-Status
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
# check_provider_is_running.ps1
|
||||
|
||||
# AMSI Provider GUID
|
||||
$providerGuid = "{2E5D8A62-77F9-4F7B-A90B-1C8F6E9D4C3A}"
|
||||
|
||||
# Registry paths
|
||||
$amsiProviderPath = "HKLM:\SOFTWARE\Microsoft\AMSI\Providers\$providerGuid"
|
||||
$clsidPath = "HKLM:\SOFTWARE\Classes\CLSID\$providerGuid"
|
||||
|
||||
# Check AMSI Provider registration
|
||||
Write-Host "Checking AMSI Provider registration..."
|
||||
if (Test-Path $amsiProviderPath) {
|
||||
Write-Host "AMSI Provider is registered."
|
||||
Get-ItemProperty $amsiProviderPath | Format-List
|
||||
} else {
|
||||
Write-Host "AMSI Provider is NOT registered."
|
||||
}
|
||||
|
||||
# Check COM CLSID registration
|
||||
Write-Host "`nChecking COM CLSID registration..."
|
||||
if (Test-Path $clsidPath) {
|
||||
Write-Host "COM CLSID is registered."
|
||||
Get-ItemProperty $clsidPath | Format-List
|
||||
} else {
|
||||
Write-Host "COM CLSID is NOT registered."
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
when defined(windows):
|
||||
import winim/lean
|
||||
import winim/com
|
||||
|
||||
import nim_antimalware_sim
|
||||
|
||||
const PROVIDER_GUID = "{2E5D8A62-77F9-4F7B-A90B-1C8F6E9D4C3A}"
|
||||
const PROVIDER_NAME = "MostShittyAVProvider"
|
||||
|
||||
var g_hModule: HMODULE = 0
|
||||
|
||||
type
|
||||
TPQueryInterface = proc(this: pointer, riid: pointer, ppv: ptr pointer): HRESULT {.stdcall.}
|
||||
TPAddRef = proc(this: pointer): ULONG {.stdcall.}
|
||||
TPRelease = proc(this: pointer): ULONG {.stdcall.}
|
||||
TPScan = proc(this: pointer, session: pointer, request: pointer, result: ptr UINT): HRESULT {.stdcall.}
|
||||
TPCloseSession = proc(this: pointer, session: pointer): HRESULT {.stdcall.}
|
||||
TPDisplayName = proc(this: pointer, name: ptr BSTR): HRESULT {.stdcall.}
|
||||
|
||||
TAmsiProviderVtbl* = object
|
||||
QueryInterface*: TPQueryInterface
|
||||
AddRef*: TPAddRef
|
||||
Release*: TPRelease
|
||||
Scan*: TPScan
|
||||
CloseSession*: TPCloseSession
|
||||
DisplayName*: TPDisplayName
|
||||
|
||||
TAmsiProvider* = object
|
||||
lpVtbl*: ptr TAmsiProviderVtbl
|
||||
|
||||
proc QueryInterfaceImpl(this: pointer, riid: pointer, ppv: ptr pointer): HRESULT {.stdcall.} =
|
||||
if ppv != nil:
|
||||
ppv[] = this
|
||||
return S_OK
|
||||
|
||||
proc AddRefImpl(this: pointer): ULONG {.stdcall.} = 1
|
||||
proc ReleaseImpl(this: pointer): ULONG {.stdcall.} = 1
|
||||
|
||||
proc ScanImpl(this: pointer, session: pointer, request: pointer, pResult: ptr UINT): HRESULT {.stdcall.} =
|
||||
try:
|
||||
if request == nil:
|
||||
if pResult != nil: pResult[] = 0
|
||||
return E_INVALIDARG
|
||||
|
||||
let cpath = cast[cstring](request)
|
||||
if cpath == nil:
|
||||
if pResult != nil: pResult[] = 0
|
||||
return E_INVALIDARG
|
||||
|
||||
let path = $cpath
|
||||
var demoProv = LoggingAntimalwareProvider(name: "MostShittyAVScanner (from DLL)")
|
||||
let ok = demoProv.scan(path)
|
||||
if pResult != nil:
|
||||
if ok: pResult[] = 0 else: pResult[] = 1
|
||||
return S_OK
|
||||
except OSError:
|
||||
if pResult != nil: pResult[] = 0
|
||||
return HRESULT(ERROR_INVALID_DATA)
|
||||
except:
|
||||
if pResult != nil: pResult[] = 0
|
||||
return E_FAIL
|
||||
|
||||
proc CloseSessionImpl(this: pointer, session: pointer): HRESULT {.stdcall.} =
|
||||
return S_OK
|
||||
|
||||
proc DisplayNameImpl(this: pointer, name: ptr BSTR): HRESULT {.stdcall.} =
|
||||
if name != nil:
|
||||
name[] = SysAllocString("MostShittyAV Nim Demo Provider (Wrapper)")
|
||||
return S_OK
|
||||
|
||||
var DemoVtbl*: TAmsiProviderVtbl
|
||||
var DemoProvider*: TAmsiProvider
|
||||
|
||||
DemoVtbl = TAmsiProviderVtbl(
|
||||
QueryInterface: QueryInterfaceImpl,
|
||||
AddRef: AddRefImpl,
|
||||
Release: ReleaseImpl,
|
||||
Scan: ScanImpl,
|
||||
CloseSession: CloseSessionImpl,
|
||||
DisplayName: DisplayNameImpl
|
||||
)
|
||||
|
||||
DemoProvider = TAmsiProvider(lpVtbl: addr DemoVtbl)
|
||||
|
||||
proc getOurModuleHandle(): HMODULE =
|
||||
var hm: HMODULE
|
||||
let funcAddr = cast[LPCSTR](getOurModuleHandle)
|
||||
if GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS or
|
||||
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
|
||||
funcAddr, addr hm) != 0:
|
||||
return hm
|
||||
return 0
|
||||
|
||||
proc DllGetClassObject(rclsid: pointer, riid: pointer, ppv: ptr pointer): HRESULT {.exportc, stdcall, dynlib.} =
|
||||
if ppv == nil:
|
||||
return E_POINTER
|
||||
ppv[] = cast[pointer](addr DemoProvider)
|
||||
echo "DllGetClassObject (wrapper) called"
|
||||
return S_OK
|
||||
|
||||
proc DllCanUnloadNow(): HRESULT {.exportc, stdcall, dynlib.} =
|
||||
return S_FALSE
|
||||
|
||||
proc DllRegisterServer(): HRESULT {.exportc, stdcall, dynlib.} =
|
||||
try:
|
||||
var hKey: HKEY
|
||||
var disposition: DWORD
|
||||
|
||||
let clsidPath = "SOFTWARE\\Classes\\CLSID\\" & PROVIDER_GUID
|
||||
var regResult = RegCreateKeyExA(HKEY_LOCAL_MACHINE, clsidPath, 0, nil,
|
||||
REG_OPTION_NON_VOLATILE, KEY_WRITE, nil,
|
||||
addr hKey, addr disposition)
|
||||
if regResult != ERROR_SUCCESS:
|
||||
echo "DllRegisterServer: Failed to create CLSID key: ", regResult
|
||||
return HRESULT(ERROR_ACCESS_DENIED)
|
||||
|
||||
let providerNameStr = "MostShittyAV AMSI Provider"
|
||||
discard RegSetValueExA(hKey, nil, 0, REG_SZ,
|
||||
cast[LPBYTE](unsafeAddr providerNameStr[0]),
|
||||
DWORD(providerNameStr.len + 1))
|
||||
discard RegCloseKey(hKey)
|
||||
|
||||
let inprocPath = clsidPath & "\\InprocServer32"
|
||||
regResult = RegCreateKeyExA(HKEY_LOCAL_MACHINE, inprocPath, 0, nil,
|
||||
REG_OPTION_NON_VOLATILE, KEY_WRITE, nil,
|
||||
addr hKey, addr disposition)
|
||||
if regResult != ERROR_SUCCESS:
|
||||
echo "DllRegisterServer: Failed to create InprocServer32 key: ", regResult
|
||||
return HRESULT(ERROR_ACCESS_DENIED)
|
||||
|
||||
if g_hModule == 0:
|
||||
g_hModule = getOurModuleHandle()
|
||||
|
||||
var dllPath: array[MAX_PATH, char]
|
||||
let pathLen = GetModuleFileNameA(g_hModule, cast[LPSTR](addr dllPath[0]), MAX_PATH)
|
||||
if pathLen == 0 or pathLen >= MAX_PATH:
|
||||
echo "DllRegisterServer: Failed to get DLL path: ", GetLastError()
|
||||
discard RegCloseKey(hKey)
|
||||
return HRESULT(ERROR_BAD_PATHNAME)
|
||||
|
||||
discard RegSetValueExA(hKey, nil, 0, REG_SZ,
|
||||
cast[LPBYTE](addr dllPath[0]),
|
||||
DWORD(pathLen + 1))
|
||||
echo "DllRegisterServer: DLL Path = ", cast[cstring](addr dllPath[0])
|
||||
|
||||
let threadingModel = "Both"
|
||||
discard RegSetValueExA(hKey, "ThreadingModel", 0, REG_SZ,
|
||||
cast[LPBYTE](unsafeAddr threadingModel[0]),
|
||||
DWORD(threadingModel.len + 1))
|
||||
discard RegCloseKey(hKey)
|
||||
|
||||
let amsiPath = "SOFTWARE\\Microsoft\\AMSI\\Providers\\" & PROVIDER_GUID
|
||||
regResult = RegCreateKeyExA(HKEY_LOCAL_MACHINE, amsiPath, 0, nil,
|
||||
REG_OPTION_NON_VOLATILE, KEY_WRITE, nil,
|
||||
addr hKey, addr disposition)
|
||||
if regResult != ERROR_SUCCESS:
|
||||
echo "DllRegisterServer: Failed to create AMSI Provider key: ", regResult
|
||||
return HRESULT(ERROR_ACCESS_DENIED)
|
||||
|
||||
let providerNameCopy = PROVIDER_NAME
|
||||
discard RegSetValueExA(hKey, nil, 0, REG_SZ,
|
||||
cast[LPBYTE](unsafeAddr providerNameCopy[0]),
|
||||
DWORD(providerNameCopy.len + 1))
|
||||
discard RegCloseKey(hKey)
|
||||
|
||||
echo "DllRegisterServer: Successfully registered as AMSI Provider"
|
||||
echo " CLSID: ", PROVIDER_GUID
|
||||
echo " Provider: ", PROVIDER_NAME
|
||||
return S_OK
|
||||
|
||||
except OSError as e:
|
||||
echo "DllRegisterServer OSError: ", e.msg
|
||||
return HRESULT(ERROR_ACCESS_DENIED)
|
||||
except:
|
||||
echo "DllRegisterServer: Unexpected error"
|
||||
return E_FAIL
|
||||
|
||||
proc DllUnregisterServer(): HRESULT {.exportc, stdcall, dynlib.} =
|
||||
try:
|
||||
let amsiPath = "SOFTWARE\\Microsoft\\AMSI\\Providers\\" & PROVIDER_GUID
|
||||
discard RegDeleteKeyA(HKEY_LOCAL_MACHINE, amsiPath)
|
||||
echo "DllUnregisterServer: Removed AMSI Provider key"
|
||||
|
||||
let inprocPath = "SOFTWARE\\Classes\\CLSID\\" & PROVIDER_GUID & "\\InprocServer32"
|
||||
discard RegDeleteKeyA(HKEY_LOCAL_MACHINE, inprocPath)
|
||||
|
||||
let clsidPath = "SOFTWARE\\Classes\\CLSID\\" & PROVIDER_GUID
|
||||
discard RegDeleteKeyA(HKEY_LOCAL_MACHINE, clsidPath)
|
||||
echo "DllUnregisterServer: Removed CLSID registration"
|
||||
|
||||
return S_OK
|
||||
except OSError as e:
|
||||
echo "DllUnregisterServer OSError: ", e.msg
|
||||
return HRESULT(ERROR_ACCESS_DENIED)
|
||||
except:
|
||||
echo "DllUnregisterServer: Unexpected error"
|
||||
return E_FAIL
|
||||
|
||||
proc GetDemoProviderPtr(): pointer {.exportc.} =
|
||||
return addr DemoProvider
|
||||
|
||||
else:
|
||||
echo "This DLL wrapper file is intended for Windows."
|
||||
Binary file not shown.
@@ -0,0 +1,27 @@
|
||||
# quick_build.ps1
|
||||
# Quick build script for MostShittyAV AMSI Provider
|
||||
|
||||
Write-Host "Building MostShittyAV AMSI Provider..." -ForegroundColor Cyan
|
||||
|
||||
# Remove old DLL
|
||||
if (Test-Path "MostShittyAVWrapper.dll") {
|
||||
Remove-Item "MostShittyAVWrapper.dll" -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
# Build
|
||||
nim c --app:lib --cpu:amd64 --out:MostShittyAVWrapper.dll nim_amsi_wrapper_dll.nim
|
||||
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
Write-Host "`nBuild successful!" -ForegroundColor Green
|
||||
Write-Host "DLL: MostShittyAVWrapper.dll" -ForegroundColor Gray
|
||||
|
||||
# Get file size
|
||||
$dll = Get-Item "MostShittyAVWrapper.dll"
|
||||
Write-Host "Size: $([math]::Round($dll.Length / 1KB, 2)) KB" -ForegroundColor Gray
|
||||
|
||||
Write-Host "`nTo register (requires Admin):" -ForegroundColor Yellow
|
||||
Write-Host " regsvr32 `"$($dll.FullName)`"" -ForegroundColor White
|
||||
} else {
|
||||
Write-Host "`nBuild failed!" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
Reference in New Issue
Block a user