Ever wanted to create a tool that scans your files for potential risks like suspicious names, dangerous extensions, or malware-like patterns? In this tutorial, we’ll build RiskScan, a Python app with a GUI that detects risky files and provides detailed recommendations.
This guide is beginner-friendly and shows how to structure your app, handle scanning logic, and build a responsive interface with Tkinter.
Step 1: Import Required Modules
First, we need some Python modules for file handling, GUI, and threading:
import sys
import os
import subprocess
import tkinter as tk
from tkinter import ttk, filedialog, messagebox
import threading
import random
Explanation:
os and sys → For file operations and paths.
subprocess → To open file locations.
tkinter → For creating the GUI.
threading → To run scans without freezing the GUI.
random → To pick random reasons for file risk reporting.
Step 2: Define App Theme and Rules
Set up some colors and rules for detecting risky files:
# Theme
APP_BG = "#121212"
PANEL_BG = "#1F1F1F"
BTN_BG = "#2C2C2C"
ACCENT = "#FF6F61"
TEXT_CLR = "#E0E0E0"
# File scanning rules
DANGEROUS_EXT = [".exe", ".bat", ".cmd", ".ps1", ".vbs", ".js", ".scr", ".dll"]
SUSPICIOUS_NAMES = ["crack", "keygen", "loader", "hack", "trojan", "virus"]
SUSPICIOUS_DIRS = ["appdata", "temp", "startup"]
SMALL_EXEC_LIMIT = 15 * 1024 # 15 KB
Explanation:
DANGEROUS_EXT → File types that can run system-level commands.
SUSPICIOUS_NAMES → Common malware/hacking tool patterns.
SMALL_EXEC_LIMIT → Very small files can sometimes be malware droppers.
Step 3: Professional Threat Knowledge Base
We’ll create a small database of rules with weights, reasons, MITRE ATT&CK references, and fixes:
THREAT_DB = {
"DANGEROUS_EXT": {
"weight": 30,
"mitre": "T1059",
"reasons": [
"Executable files can directly run system-level instructions",
"This file type is frequently abused to deliver malware payloads"
],
"fix": "Avoid running unknown executables. Scan with trusted antivirus software."
},
"SUSPICIOUS_DIR": {
"weight": 25,
"mitre": "T1547",
"reasons": [
"Malware commonly hides in user or temporary directories",
"This directory is often abused to maintain persistence"
],
"fix": "Review startup locations and remove unauthorized programs."
}
# Add DOUBLE_EXT, SMALL_EXEC, SUSPICIOUS_NAME similarly
}
Explanation:
Each rule has a weight to determine severity.
mitre refers to MITRE ATT&CK ID for cybersecurity context.
reasons explain why a file is risky.
fix suggests remediation.
Step 4: Utility Function to Handle Resources
If you later convert this Python script to an EXE, we need a function to locate bundled files:
def resource_path(file_name):
"""
Get absolute path to resources, works with PyInstaller.
"""
base_path = getattr(sys, "_MEIPASS", os.path.dirname(os.path.abspath(__file__)))
return os.path.join(base_path, file_name)
Step 5: Create the GUI App Class
We’ll use Tkinter to create the GUI. Start by defining the main class:
class ProblemFinderApp:
def __init__(self, root):
self.root = root
root.title("RiskScan - Problem File Finder")
root.geometry("1200x600")
root.configure(bg=APP_BG)
self.target = None # File or folder to scan
self.total_files = 0
self.stats = {"LOW": 0, "MEDIUM": 0, "HIGH": 0}
self.high_risk = []
self.medium_risk = []
# Scan controls
self.scan_thread = None
self.scan_paused = False
self.scan_stopped = False
Explanation:
self.target → The file or folder the user selects.
self.stats → Tracks counts of low, medium, and high-risk files.
self.high_risk and self.medium_risk → Lists to store results for reporting.
Step 6: Add File and Folder Pickers
Let users select files or folders to scan:
def pick_folder(self):
p = filedialog.askdirectory()
if p:
self.target = p
self.path_label.config(text=p)
def pick_file(self):
p = filedialog.askopenfilename()
if p:
self.target = p
self.path_label.config(text=p)
Explanation:
askdirectory() → Opens folder picker.
askopenfilename() → Opens file picker.
Step 7: Add Start, Pause, and Scan Logic
To run the scan without freezing the GUI, we use a thread:
def start_scan(self):
if not self.target:
messagebox.showwarning("Warning", "Please select a file or folder to scan first!")
return
self.total_files = 0
self.stats = {"LOW": 0, "MEDIUM": 0, "HIGH": 0}
self.high_risk.clear()
self.medium_risk.clear()
self.scan_paused = False
self.scan_stopped = False
self.output.config(state="normal")
self.output.delete("1.0", "end")
self.output.config(state="disabled")
# Start scan in separate thread
self.scan_thread = threading.Thread(target=self.scan, daemon=True)
self.scan_thread.start()
Step 8: Scan Each File
Here’s the core detection logic:
def check_file(self, path):
name = os.path.basename(path).lower()
ext = os.path.splitext(name)[1]
try:
size = os.path.getsize(path)
except Exception:
return
score = 0
reasons = []
mitre = set()
fixes = set()
def apply(rule):
nonlocal score
data = THREAT_DB[rule]
score += data["weight"]
reasons.append(random.choice(data["reasons"]))
mitre.add(data["mitre"])
fixes.add(data["fix"])
if ext in DANGEROUS_EXT:
apply("DANGEROUS_EXT")
if any(x in path.lower() for x in SUSPICIOUS_DIRS):
apply("SUSPICIOUS_DIR")
Explanation:
apply(rule) → Adds weight, reason, MITRE ID, and fix to the file if it matches a rule.
Files are evaluated for multiple risk factors.
Step 9: Show Results
After scanning, display the summary:
def show_summary(self):
verdict = "LOW RISK"
if self.stats["HIGH"] > 0:
verdict = "HIGH RISK"
elif self.stats["MEDIUM"] > 0:
verdict = "MEDIUM RISK"
self.output.config(state="normal")
self.output.insert("end", f"Files Scanned: {self.total_files}\n")
self.output.insert("end", f"HIGH Risk: {self.stats['HIGH']}\n")
self.output.insert("end", f"MEDIUM Risk: {self.stats['MEDIUM']}\n")
self.output.insert("end", f"OVERALL VERDICT: {verdict}\n")
self.output.config(state="disabled")
Step 10: Export Report
Allow users to save a text report:
def export_report(self):
if not self.high_risk and not self.medium_risk:
messagebox.showinfo("Info", "No HIGH or MEDIUM risk items to export")
return
f = filedialog.asksaveasfilename(defaultextension=".txt")
if not f:
return
with open(f, "w", encoding="utf-8") as file:
file.write("Problem File Finder REPORT\n\n")
file.write(f"Files Scanned: {self.total_files}\n")
file.write(f"HIGH Risk: {self.stats['HIGH']}\n")
file.write(f"MEDIUM Risk: {self.stats['MEDIUM']}\n\n")
Step 11: Run the App
Finally, run the Tkinter app:
if __name__ == "__main__":
root = tk.Tk()
app = ProblemFinderApp(root)
root.mainloop()
✅ Next Steps
Add clickable file paths to open their location.
Enhance detection with more MITRE techniques.
Package as an EXE for Windows users (e.g., using PyInstaller).
📥 Download
Free EXE: Download RiskScan EXE

Top comments (0)