Написал на полу гпт полу гайды Состоит из двух частей Первая Просто меню настроек где ты можешь выбрать пароль, экстренный пароль(для обхода двухфакторной защиты если тг не работает. После идет кнопка с окошком ввода данных телеграм бота Token/ChatID куда будет идти вся отправка информации о использование пк пока вас нету 2 галочки использовать или 2FA через телеграм , и отправлять ли снимок вебки или нет. После идет путь для сохранение ***** локально если нужно в .log файл, Кнопка добавления в автозапуск пк(она чет не особо работает) И просто просмотр лога из меню настроек чтобы не искать файл И кнопка запуска защиты про это ниже Вторая часть(сам блокировщик) Блокирует ваш пк Вот чо юзает модули import pygame import sys import math import keyboard import ctypes import win32gui import win32con import psutil import time import threading import random import cv2 import requests import json import os from datetime import datetime Просто открывается на весь экран окно что пк заблокан и есть поле ввода пароля или же экстренный пароль(если тг двухфакторка включена и нету доступа к инету) Блокирует открытие диспетчера через ctrl alt delete просто следит что при запуске опять развернется на весь экран и толком без перезагрузки ничо не воркает, Win, fn, f4, и тп заблочено. При вводе пароля который вы указали происходит снимок вебки и идет отправка в телеграм бота с кодом OTP ну для двух факторки который рандомно генерируется каждый раз и в соо вы видите что то типо Ну и сверху фотка с вебки В итоге это происходит 2 раза хз зачем просто для крутости. Вроде хуйня а вроде можно улучшать и норм прога для офиса чтобы долбоебы пк не трогали пока ты листаешь тик ток в толчке и видишь ебало дибила который пытается твой пк открыть САМ ТОП КОД настройки import sys import os import json from PyQt5 import QtCore, QtGui, QtWidgets CONFIG_FILE = "config.json" def load_config(): if os.path.exists(CONFIG_FILE): with open(CONFIG_FILE, "r", encoding="utf-8") as f: return json.load(f) return {} def save_config(config): with open(CONFIG_FILE, "w", encoding="utf-8") as f: json.dump(config, f, indent=4, ensure_ascii=False) class HoverButton(QtWidgets.QPushButton): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.setStyleSheet(self.default_style()) self.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor)) def enterEvent(self, event): self.setStyleSheet(self.hover_style()) super().enterEvent(event) def leaveEvent(self, event): self.setStyleSheet(self.default_style()) super().leaveEvent(event) def mousePressEvent(self, event): self.setStyleSheet(self.pressed_style()) super().mousePressEvent(event) def mouseReleaseEvent(self, event): self.setStyleSheet(self.hover_style()) super().mouseReleaseEvent(event) def default_style(self): return """ QPushButton { background-color: #1c1c1c; color: #f44336; border: 2px solid #f44336; border-radius: 6px; font-weight: bold; padding: 8px 16px; } """ def hover_style(self): return """ QPushButton { background-color: #f44336; color: #1c1c1c; border: 2px solid #f44336; border-radius: 6px; font-weight: bold; padding: 8px 16px; } """ def pressed_style(self): return """ QPushButton { background-color: #b71c1c; color: #fff; border: 2px solid #b71c1c; border-radius: 6px; font-weight: bold; padding: 8px 16px; } """ def create_label(text): label = QtWidgets.QLabel(text) label.setStyleSheet(""" color: #f44336; font-size: 14pt; font-weight: 600; """) return label class PasswordInput(QtWidgets.QWidget): def __init__(self, initial_text="", placeholder="", parent=None): super().__init__(parent) layout = QtWidgets.QHBoxLayout(self) layout.setContentsMargins(0,0,0,0) layout.setSpacing(5) self.line_edit = QtWidgets.QLineEdit() self.line_edit.setEchoMode(QtWidgets.QLineEdit.Password) self.line_edit.setText(initial_text) self.line_edit.setPlaceholderText(placeholder) self.line_edit.setStyleSheet(""" QLineEdit { background-color: #1c1c1c; border: 1px solid #f44336; border-radius: 6px; padding: 6px; color: #eee; font-size: 14px; } QLineEdit:focus { border: 2px solid #f44336; background-color: #2a2a2a; } """) self.toggle_btn = QtWidgets.QPushButton() self.toggle_btn.setCheckable(True) self.toggle_btn.setFixedSize(28, 28) self.toggle_btn.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor)) self.toggle_btn.setToolTip("Показать/скрыть пароль") icon_show = self.style().standardIcon(QtWidgets.QStyle.SP_DialogYesButton) icon_hide = self.style().standardIcon(QtWidgets.QStyle.SP_DialogNoButton) self.toggle_btn.setIcon(icon_show) self.icon_show = icon_show self.icon_hide = icon_hide self.toggle_btn.clicked.connect(self.toggle_password) layout.addWidget(self.line_edit) layout.addWidget(self.toggle_btn) def toggle_password(self): if self.toggle_btn.isChecked(): self.line_edit.setEchoMode(QtWidgets.QLineEdit.Normal) self.toggle_btn.setIcon(self.icon_hide) else: self.line_edit.setEchoMode(QtWidgets.QLineEdit.Password) self.toggle_btn.setIcon(self.icon_show) def text(self): return self.line_edit.text() def setText(self, text): self.line_edit.setText(text) class TelegramDetailsDialog(QtWidgets.QDialog): def __init__(self, token="", chat_id="", parent=None): super().__init__(parent) self.setWindowTitle("Telegram Details") self.setMinimumSize(500, 220) # Увеличил размеры окна self.resize(520, 240) self.setStyleSheet("background-color: #1c1c1c;") layout = QtWidgets.QVBoxLayout(self) layout.setContentsMargins(20, 20, 20, 20) layout.setSpacing(10) # Больше отступов label_token = create_label("Telegram Bot Token:") self.token_input = QtWidgets.QLineEdit(token) self.token_input.setMinimumWidth(440) self.token_input.setStyleSheet(""" QLineEdit { background-color: #2a2a2a; border: 1px solid #f44336; border-radius: 6px; padding: 10px; color: #eee; font-size: 14px; } QLineEdit:focus { border: 2px solid #f44336; } """) label_chat = create_label("Telegram Chat ID:") self.chat_input = QtWidgets.QLineEdit(chat_id) self.chat_input.setMinimumWidth(440) self.chat_input.setStyleSheet(self.token_input.styleSheet()) layout.addWidget(label_token) layout.addWidget(self.token_input) layout.addWidget(label_chat) layout.addWidget(self.chat_input) btn_save = HoverButton("Сохранить") btn_save.setFixedWidth(120) btn_save.clicked.connect(self.accept) btn_layout = QtWidgets.QHBoxLayout() btn_layout.addStretch() btn_layout.addWidget(btn_save) layout.addLayout(btn_layout) def get_data(self): return self.token_input.text().strip(), self.chat_input.text().strip() class SettingsApp(QtWidgets.QWidget): def __init__(self): super().__init__() self.setWindowTitle("Secure Life - Настройки защиты") self.setGeometry(100, 100, 600, 700) self.setStyleSheet("background-color: #121212;") self.config_data = load_config() main_layout = QtWidgets.QVBoxLayout(self) main_layout.setContentsMargins(30, 20, 30, 20) main_layout.setSpacing(10) main_layout.addWidget(create_label("Основной пароль:")) self.password_input = PasswordInput(initial_text=self.config_data.get("password", "")) main_layout.addWidget(self.password_input) main_layout.addWidget(create_label("Экстренный пароль (без 2FA):")) self.emergency_input = PasswordInput(initial_text=self.config_data.get("emergency_password", "")) main_layout.addWidget(self.emergency_input) self.token = self.config_data.get("telegram_token", "") self.chat_id = self.config_data.get("telegram_chat_id", "") self.btn_telegram = HoverButton("Telegram Details") self.btn_telegram.clicked.connect(self.open_telegram_dialog) main_layout.addWidget(self.btn_telegram) self.use_2fa_checkbox = QtWidgets.QCheckBox("Использовать 2FA через Telegram") self.use_2fa_checkbox.setChecked(self.config_data.get("use_2fa", True)) self.use_2fa_checkbox.setStyleSheet("color: #f44336; font-weight: bold;") main_layout.addWidget(self.use_2fa_checkbox) self.send_photo_checkbox = QtWidgets.QCheckBox("Отправлять снимок с камеры") self.send_photo_checkbox.setChecked(self.config_data.get("send_photo", True)) self.send_photo_checkbox.setStyleSheet("color: #f44336; font-weight: bold;") main_layout.addWidget(self.send_photo_checkbox) main_layout.addWidget(create_label("Папка для *****:")) h_log = QtWidgets.QHBoxLayout() self.log_path_input = QtWidgets.QLineEdit(self.config_data.get("log_path", os.getcwd())) self.log_path_input.setStyleSheet(""" QLineEdit { background-color: #2a2a2a; border: 1px solid #f44336; border-radius: 6px; padding: 6px; color: #eee; font-size: 14px; } QLineEdit:focus { border: 2px solid #f44336; } """) h_log.addWidget(self.log_path_input) btn_choose_folder = HoverButton("Выбрать") btn_choose_folder.clicked.connect(self.select_log_folder) h_log.addWidget(btn_choose_folder) main_layout.addLayout(h_log) self.btn_autorun = HoverButton("Добавить в автозапуск") self.btn_autorun.clicked.connect(self.add_to_autorun) main_layout.addWidget(self.btn_autorun) self.btn_start = HoverButton("Запустить защиту") self.btn_start.clicked.connect(self.start_protection) main_layout.addWidget(self.btn_start) main_layout.addWidget(create_label("Просмотр лога:")) self.log_view = QtWidgets.QPlainTextEdit() self.log_view.setReadOnly(True) self.log_view.setStyleSheet(""" QPlainTextEdit { background-color: #1c1c1c; border: 1px solid #f44336; border-radius: 6px; color: #eee; font-family: Consolas, monospace; font-size: 12px; padding: 6px; } """) self.log_view.setMinimumHeight(200) main_layout.addWidget(self.log_view) btn_refresh_log = HoverButton("Обновить лог") btn_refresh_log.clicked.connect(self.load_log) main_layout.addWidget(btn_refresh_log) self.load_log() def select_log_folder(self): folder = QtWidgets.QFileDialog.getExistingDirectory(self, "Выберите папку для *****", self.log_path_input.text()) if folder: self.log_path_input.setText(folder) def add_to_autorun(self): try: import winreg exe_path = os.path.abspath(__file__) locker_path = os.path.abspath("securelife.py") python_exe = sys.executable cmd = f'"{python_exe}" "{locker_path}"' key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, r"Software\Microsoft\Windows\CurrentVersion\Run", 0, winreg.KEY_SET_VALUE) winreg.SetValueEx(key, "SecureLife", 0, winreg.REG_SZ, cmd) winreg.CloseKey(key) msg_box = QtWidgets.QMessageBox(self) msg_box.setWindowTitle("Автозапуск") msg_box.setText("Программа добавлена в автозапуск.") msg_box.setIcon(QtWidgets.QMessageBox.Information) # Стилизация текста и кнопок msg_box.setStyleSheet(""" QMessageBox { background-color: #1c1c1c; } QMessageBox QLabel { color: white; /* <-- Вот сюда добавлен белый цвет текста */ font-weight: bold; font-size: 14px; } QPushButton { background-color: #f44336; color: #1c1c1c; border-radius: 6px; padding: 6px 12px; font-weight: bold; } QPushButton:hover { background-color: #b71c1c; } """) msg_box.exec_() except Exception as e: QtWidgets.QMessageBox.critical(self, "Ошибка", f"Не удалось добавить в автозапуск:\n{e}") def open_telegram_dialog(self): dlg = TelegramDetailsDialog(self.token, self.chat_id, self) if dlg.exec_() == QtWidgets.QDialog.Accepted: self.token, self.chat_id = dlg.get_data() def start_protection(self): password = self.password_input.text().strip() if not password: QtWidgets.QMessageBox.critical(self, "Ошибка", "Основной пароль не может быть пустым!") return token = self.token.strip() chat_id = self.chat_id.strip() if not token or not chat_id: if self.use_2fa_checkbox.isChecked(): res = QtWidgets.QMessageBox.question( self, "Подтверждение", "Telegram данные пусты или не введены.\nПродолжить без 2FA?", QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No, QtWidgets.QMessageBox.No) if res == QtWidgets.QMessageBox.No: return self.config_data.update({ "password": password, "emergency_password": self.emergency_input.text().strip(), "telegram_token": token, "telegram_chat_id": chat_id, "use_2fa": self.use_2fa_checkbox.isChecked(), "send_photo": self.send_photo_checkbox.isChecked(), "log_path": self.log_path_input.text(), }) save_config(self.config_data) os.system(f'"{sys.executable}" locker.py') self.close() def load_log(self): log_folder = self.log_path_input.text() log_file = os.path.join(log_folder, "login_attempts.log") if os.path.exists(log_file): try: with open(log_file, "r", encoding="utf-8") as f: content = f.read() self.log_view.setPlainText(content) except Exception as e: self.log_view.setPlainText(f"Ошибка при чтении лога:\n{e}") else: self.log_view.setPlainText("Лог-файл не найден.") if __name__ == "__main__": app = QtWidgets.QApplication(sys.argv) window = SettingsApp() window.show() sys.exit(app.exec_()) Python import sys import os import json from PyQt5 import QtCore, QtGui, QtWidgets CONFIG_FILE = "config.json" def load_config(): if os.path.exists(CONFIG_FILE): with open(CONFIG_FILE, "r", encoding="utf-8") as f: return json.load(f) return {} def save_config(config): with open(CONFIG_FILE, "w", encoding="utf-8") as f: json.dump(config, f, indent=4, ensure_ascii=False) class HoverButton(QtWidgets.QPushButton): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.setStyleSheet(self.default_style()) self.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor)) def enterEvent(self, event): self.setStyleSheet(self.hover_style()) super().enterEvent(event) def leaveEvent(self, event): self.setStyleSheet(self.default_style()) super().leaveEvent(event) def mousePressEvent(self, event): self.setStyleSheet(self.pressed_style()) super().mousePressEvent(event) def mouseReleaseEvent(self, event): self.setStyleSheet(self.hover_style()) super().mouseReleaseEvent(event) def default_style(self): return """ QPushButton { background-color: #1c1c1c; color: #f44336; border: 2px solid #f44336; border-radius: 6px; font-weight: bold; padding: 8px 16px; } """ def hover_style(self): return """ QPushButton { background-color: #f44336; color: #1c1c1c; border: 2px solid #f44336; border-radius: 6px; font-weight: bold; padding: 8px 16px; } """ def pressed_style(self): return """ QPushButton { background-color: #b71c1c; color: #fff; border: 2px solid #b71c1c; border-radius: 6px; font-weight: bold; padding: 8px 16px; } """ def create_label(text): label = QtWidgets.QLabel(text) label.setStyleSheet(""" color: #f44336; font-size: 14pt; font-weight: 600; """) return label class PasswordInput(QtWidgets.QWidget): def __init__(self, initial_text="", placeholder="", parent=None): super().__init__(parent) layout = QtWidgets.QHBoxLayout(self) layout.setContentsMargins(0,0,0,0) layout.setSpacing(5) self.line_edit = QtWidgets.QLineEdit() self.line_edit.setEchoMode(QtWidgets.QLineEdit.Password) self.line_edit.setText(initial_text) self.line_edit.setPlaceholderText(placeholder) self.line_edit.setStyleSheet(""" QLineEdit { background-color: #1c1c1c; border: 1px solid #f44336; border-radius: 6px; padding: 6px; color: #eee; font-size: 14px; } QLineEdit:focus { border: 2px solid #f44336; background-color: #2a2a2a; } """) self.toggle_btn = QtWidgets.QPushButton() self.toggle_btn.setCheckable(True) self.toggle_btn.setFixedSize(28, 28) self.toggle_btn.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor)) self.toggle_btn.setToolTip("Показать/скрыть пароль") icon_show = self.style().standardIcon(QtWidgets.QStyle.SP_DialogYesButton) icon_hide = self.style().standardIcon(QtWidgets.QStyle.SP_DialogNoButton) self.toggle_btn.setIcon(icon_show) self.icon_show = icon_show self.icon_hide = icon_hide self.toggle_btn.clicked.connect(self.toggle_password) layout.addWidget(self.line_edit) layout.addWidget(self.toggle_btn) def toggle_password(self): if self.toggle_btn.isChecked(): self.line_edit.setEchoMode(QtWidgets.QLineEdit.Normal) self.toggle_btn.setIcon(self.icon_hide) else: self.line_edit.setEchoMode(QtWidgets.QLineEdit.Password) self.toggle_btn.setIcon(self.icon_show) def text(self): return self.line_edit.text() def setText(self, text): self.line_edit.setText(text) class TelegramDetailsDialog(QtWidgets.QDialog): def __init__(self, token="", chat_id="", parent=None): super().__init__(parent) self.setWindowTitle("Telegram Details") self.setMinimumSize(500, 220) # Увеличил размеры окна self.resize(520, 240) self.setStyleSheet("background-color: #1c1c1c;") layout = QtWidgets.QVBoxLayout(self) layout.setContentsMargins(20, 20, 20, 20) layout.setSpacing(10) # Больше отступов label_token = create_label("Telegram Bot Token:") self.token_input = QtWidgets.QLineEdit(token) self.token_input.setMinimumWidth(440) self.token_input.setStyleSheet(""" QLineEdit { background-color: #2a2a2a; border: 1px solid #f44336; border-radius: 6px; padding: 10px; color: #eee; font-size: 14px; } QLineEdit:focus { border: 2px solid #f44336; } """) label_chat = create_label("Telegram Chat ID:") self.chat_input = QtWidgets.QLineEdit(chat_id) self.chat_input.setMinimumWidth(440) self.chat_input.setStyleSheet(self.token_input.styleSheet()) layout.addWidget(label_token) layout.addWidget(self.token_input) layout.addWidget(label_chat) layout.addWidget(self.chat_input) btn_save = HoverButton("Сохранить") btn_save.setFixedWidth(120) btn_save.clicked.connect(self.accept) btn_layout = QtWidgets.QHBoxLayout() btn_layout.addStretch() btn_layout.addWidget(btn_save) layout.addLayout(btn_layout) def get_data(self): return self.token_input.text().strip(), self.chat_input.text().strip() class SettingsApp(QtWidgets.QWidget): def __init__(self): super().__init__() self.setWindowTitle("Secure Life - Настройки защиты") self.setGeometry(100, 100, 600, 700) self.setStyleSheet("background-color: #121212;") self.config_data = load_config() main_layout = QtWidgets.QVBoxLayout(self) main_layout.setContentsMargins(30, 20, 30, 20) main_layout.setSpacing(10) main_layout.addWidget(create_label("Основной пароль:")) self.password_input = PasswordInput(initial_text=self.config_data.get("password", "")) main_layout.addWidget(self.password_input) main_layout.addWidget(create_label("Экстренный пароль (без 2FA):")) self.emergency_input = PasswordInput(initial_text=self.config_data.get("emergency_password", "")) main_layout.addWidget(self.emergency_input) self.token = self.config_data.get("telegram_token", "") self.chat_id = self.config_data.get("telegram_chat_id", "") self.btn_telegram = HoverButton("Telegram Details") self.btn_telegram.clicked.connect(self.open_telegram_dialog) main_layout.addWidget(self.btn_telegram) self.use_2fa_checkbox = QtWidgets.QCheckBox("Использовать 2FA через Telegram") self.use_2fa_checkbox.setChecked(self.config_data.get("use_2fa", True)) self.use_2fa_checkbox.setStyleSheet("color: #f44336; font-weight: bold;") main_layout.addWidget(self.use_2fa_checkbox) self.send_photo_checkbox = QtWidgets.QCheckBox("Отправлять снимок с камеры") self.send_photo_checkbox.setChecked(self.config_data.get("send_photo", True)) self.send_photo_checkbox.setStyleSheet("color: #f44336; font-weight: bold;") main_layout.addWidget(self.send_photo_checkbox) main_layout.addWidget(create_label("Папка для *****:")) h_log = QtWidgets.QHBoxLayout() self.log_path_input = QtWidgets.QLineEdit(self.config_data.get("log_path", os.getcwd())) self.log_path_input.setStyleSheet(""" QLineEdit { background-color: #2a2a2a; border: 1px solid #f44336; border-radius: 6px; padding: 6px; color: #eee; font-size: 14px; } QLineEdit:focus { border: 2px solid #f44336; } """) h_log.addWidget(self.log_path_input) btn_choose_folder = HoverButton("Выбрать") btn_choose_folder.clicked.connect(self.select_log_folder) h_log.addWidget(btn_choose_folder) main_layout.addLayout(h_log) self.btn_autorun = HoverButton("Добавить в автозапуск") self.btn_autorun.clicked.connect(self.add_to_autorun) main_layout.addWidget(self.btn_autorun) self.btn_start = HoverButton("Запустить защиту") self.btn_start.clicked.connect(self.start_protection) main_layout.addWidget(self.btn_start) main_layout.addWidget(create_label("Просмотр лога:")) self.log_view = QtWidgets.QPlainTextEdit() self.log_view.setReadOnly(True) self.log_view.setStyleSheet(""" QPlainTextEdit { background-color: #1c1c1c; border: 1px solid #f44336; border-radius: 6px; color: #eee; font-family: Consolas, monospace; font-size: 12px; padding: 6px; } """) self.log_view.setMinimumHeight(200) main_layout.addWidget(self.log_view) btn_refresh_log = HoverButton("Обновить лог") btn_refresh_log.clicked.connect(self.load_log) main_layout.addWidget(btn_refresh_log) self.load_log() def select_log_folder(self): folder = QtWidgets.QFileDialog.getExistingDirectory(self, "Выберите папку для *****", self.log_path_input.text()) if folder: self.log_path_input.setText(folder) def add_to_autorun(self): try: import winreg exe_path = os.path.abspath(__file__) locker_path = os.path.abspath("securelife.py") python_exe = sys.executable cmd = f'"{python_exe}" "{locker_path}"' key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, r"Software\Microsoft\Windows\CurrentVersion\Run", 0, winreg.KEY_SET_VALUE) winreg.SetValueEx(key, "SecureLife", 0, winreg.REG_SZ, cmd) winreg.CloseKey(key) msg_box = QtWidgets.QMessageBox(self) msg_box.setWindowTitle("Автозапуск") msg_box.setText("Программа добавлена в автозапуск.") msg_box.setIcon(QtWidgets.QMessageBox.Information) # Стилизация текста и кнопок msg_box.setStyleSheet(""" QMessageBox { background-color: #1c1c1c; } QMessageBox QLabel { color: white; /* <-- Вот сюда добавлен белый цвет текста */ font-weight: bold; font-size: 14px; } QPushButton { background-color: #f44336; color: #1c1c1c; border-radius: 6px; padding: 6px 12px; font-weight: bold; } QPushButton:hover { background-color: #b71c1c; } """) msg_box.exec_() except Exception as e: QtWidgets.QMessageBox.critical(self, "Ошибка", f"Не удалось добавить в автозапуск:\n{e}") def open_telegram_dialog(self): dlg = TelegramDetailsDialog(self.token, self.chat_id, self) if dlg.exec_() == QtWidgets.QDialog.Accepted: self.token, self.chat_id = dlg.get_data() def start_protection(self): password = self.password_input.text().strip() if not password: QtWidgets.QMessageBox.critical(self, "Ошибка", "Основной пароль не может быть пустым!") return token = self.token.strip() chat_id = self.chat_id.strip() if not token or not chat_id: if self.use_2fa_checkbox.isChecked(): res = QtWidgets.QMessageBox.question( self, "Подтверждение", "Telegram данные пусты или не введены.\nПродолжить без 2FA?", QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No, QtWidgets.QMessageBox.No) if res == QtWidgets.QMessageBox.No: return self.config_data.update({ "password": password, "emergency_password": self.emergency_input.text().strip(), "telegram_token": token, "telegram_chat_id": chat_id, "use_2fa": self.use_2fa_checkbox.isChecked(), "send_photo": self.send_photo_checkbox.isChecked(), "log_path": self.log_path_input.text(), }) save_config(self.config_data) os.system(f'"{sys.executable}" locker.py') self.close() def load_log(self): log_folder = self.log_path_input.text() log_file = os.path.join(log_folder, "login_attempts.log") if os.path.exists(log_file): try: with open(log_file, "r", encoding="utf-8") as f: content = f.read() self.log_view.setPlainText(content) except Exception as e: self.log_view.setPlainText(f"Ошибка при чтении лога:\n{e}") else: self.log_view.setPlainText("Лог-файл не найден.") if __name__ == "__main__": app = QtWidgets.QApplication(sys.argv) window = SettingsApp() window.show() sys.exit(app.exec_()) основная import pygame import sys import math import keyboard import ctypes import win32gui import win32con import psutil import time import threading import random import cv2 import requests import json import os from datetime import datetime # === ПАРАМЕТРЫ === WIDTH, HEIGHT = 1920, 1080 input_text = "" error_shake = 0 error_flash = 0 error_count = 0 otp = None awaiting_otp = False otp_attempts = 0 MAX_OTP_ATTEMPTS = 3 current_mode = "password" # "password", "otp", "emergency" # Загрузка конфигурации CONFIG_FILE = "config.json" if not os.path.exists(CONFIG_FILE): print("Конфигурационный файл не найден. Запустите securelife.py для настройки.") sys.exit() with open(CONFIG_FILE, "r", encoding="utf-8") as f: config = json.load(f) PASSWORD = config.get("password", "admin") EMERGENCY_PASSWORD = config.get("emergency_password", "") TELEGRAM_TOKEN = config.get("telegram_token", "") TELEGRAM_CHAT_ID = config.get("telegram_chat_id", "") USE_2FA = config.get("use_2fa", True) SEND_PHOTO = config.get("send_photo", True) LOG_PATH = config.get("log_path", os.getcwd()) LOG_FILE = os.path.join(LOG_PATH, "login_attempts.log") PC_NAME = os.getenv("COMPUTERNAME") or "UnknownPC" ru_to_en = { 'ф': 'a', 'и': 'b', 'с': 'c', 'в': 'd', 'у': 'e', 'а': 'f', 'п': 'g', 'р': 'h', 'ш': 'i', 'о': 'j', 'л': 'k', 'д': 'l', 'ь': 'm', 'т': 'n', 'щ': 'o', 'з': 'p', 'й': 'q', 'к': 'r', 'ы': 's', 'е': 't', 'г': 'u', 'м': 'v', 'ц': 'w', 'ч': 'x', 'н': 'y', 'я': 'z', 'Ф': 'A', 'И': 'B', 'С': 'C', 'В': 'D', 'У': 'E', 'А': 'F', 'П': 'G', 'Р': 'H', 'Ш': 'I', 'О': 'J', 'Л': 'K', 'Д': 'L', 'Ь': 'M', 'Т': 'N', 'Щ': 'O', 'З': 'P', 'Й': 'Q', 'К': 'R', 'Ы': 'S', 'Е': 'T', 'Г': 'U', 'М': 'V', 'Ц': 'W', 'Ч': 'X', 'Н': 'Y', 'Я': 'Z' } # === ФУНКЦИИ === def log_attempt(password_attempt, success): global error_count now = datetime.now().strftime("%Y-%m-%d %H:%M:%S") status = "SUCCESS" if success else "FAIL" if not success: error_count += 1 log_line = f"{now} | PC: {PC_NAME} | Attempt: '{password_attempt}' | Result: {status} | Errors: {error_count}\n" with open(LOG_FILE, "a", encoding="utf-8") as f: f.write(log_line) def take_photo(): if not SEND_PHOTO: return None cap = cv2.VideoCapture(0) if not cap.isOpened(): return None ret, frame = cap.read() cap.release() if ret: photo_path = os.path.join(LOG_PATH, "attempt_photo.jpg") cv2.imwrite(photo_path, frame) return photo_path return None def send_telegram_message(message, success=True): if not TELEGRAM_TOKEN or not TELEGRAM_CHAT_ID or not USE_2FA: return photo_path = take_photo() now = datetime.now().strftime("%Y-%m-%d %H:%M:%S") status = "SUCCESS" if success else "FAIL" text = f" Secure Life\nPC: {PC_NAME}\nTime: {now}\n{message}\nResult: {status}" if photo_path: files = {'photo': open(photo_path, 'rb')} data = {'chat_id': TELEGRAM_CHAT_ID, 'caption': text} url = f"https://api.telegram.org/bot{TELEGRAM_TOKEN}/sendPhoto" try: requests.post(url, files=files, data=data, timeout=5) except: pass else: url = f"https://api.telegram.org/bot{TELEGRAM_TOKEN}/sendMessage" try: requests.post(url, data={'chat_id': TELEGRAM_CHAT_ID, 'text': text}, timeout=5) except: pass def switch_to_english_layout(): user32 = ctypes.WinDLL('user32', use_last_error=True) layout = 0x04090409 user32.LoadKeyboardLayoutW(hex(layout), 1) user32.ActivateKeyboardLayout(layout, 0) def generate_otp(): return str(random.randint(100000, 999999)) class FireParticle: def __init__(self): self.x = random.uniform(0, WIDTH) self.y = random.uniform(0, HEIGHT) self.size = random.uniform(2, 6) self.speed_y = random.uniform(-0.3, -1.0) self.alpha = random.randint(50, 150) self.surface = pygame.Surface((int(self.size*2), int(self.size*2)), pygame.SRCALPHA) def update(self): self.y += self.speed_y self.alpha -= 1.2 if self.alpha <= 0 or self.y < 0: self.__init__() def draw(self, screen): self.surface.fill((0, 0, 0, 0)) pygame.draw.circle(self.surface, (255, 40, 40, int(self.alpha)), (int(self.size), int(self.size)), int(self.size)) screen.blit(self.surface, (self.x, self.y)) # === ИНИЦИАЛИЗАЦИЯ === keys_to_block = ["alt", "ctrl", "esc", "f4", "win", "tab"] for key in keys_to_block: try: keyboard.block_key(key) except: pass pygame.init() switch_to_english_layout() screen = pygame.display.set_mode((WIDTH, HEIGHT), pygame.FULLSCREEN | pygame.NOFRAME) pygame.display.set_caption("Secure Life") clock = pygame.time.Clock() font_input = pygame.font.SysFont("consolas", 48, bold=True) font_footer = pygame.font.SysFont("Segoe Script", 32, bold=True) font_mode = pygame.font.SysFont("consolas", 24, bold=True) BLACK = (10, 10, 10) RED = (255, 0, 0) WHITE = (255, 255, 255) YELLOW = (255, 255, 0) try: skull_img = pygame.image.load("skull.png").convert_alpha() skull_img = pygame.transform.smoothscale(skull_img, (300, 300)) except: skull_img = pygame.Surface((300, 300), pygame.SRCALPHA) pygame.draw.circle(skull_img, RED, (150, 150), 150, 10) hwnd = pygame.display.get_wm_info()["window"] def keep_window_on_top(): try: win32gui.ShowWindow(hwnd, win32con.SW_RESTORE) win32gui.SetWindowPos(hwnd, win32con.HWND_TOPMOST, 0, 0, WIDTH, HEIGHT, win32con.SWP_SHOWWINDOW) win32gui.SetForegroundWindow(hwnd) except: pass def trigger_error_animation(): global error_shake, error_flash error_shake = 15 error_flash = 30 particles = [FireParticle() for _ in range(60)] def draw(tick): global error_flash screen.fill((30 + (error_flash * 2 if error_flash > 0 else 0), 10, 10)) if error_flash > 0: error_flash -= 1 for p in particles: p.update() p.draw(screen) scale = 1 + 0.05 * math.sin(tick * 0.1) skull_scaled = pygame.transform.rotozoom(skull_img, 0, scale) skull_rect = skull_scaled.get_rect(center=(WIDTH//2, HEIGHT//2 - 100)) screen.blit(skull_scaled, skull_rect) global error_shake offset = int(math.sin(tick * 0.6) * 10) if error_shake > 0 else 0 if error_shake > 0: error_shake -= 1 # Отображение текущего режима mode_text = "" if current_mode == "password": mode_text = "ENTER MAIN PASSWORD:" elif current_mode == "otp": mode_text = "ENTER OTP FROM TELEGRAM:" elif current_mode == "emergency": mode_text = "ENTER EMERGENCY PASSWORD:" mode_label = font_mode.render("(No 2FA required)", True, YELLOW) screen.blit(mode_label, (WIDTH//2 - mode_label.get_width()//2 + offset, HEIGHT//2 + 160)) label = font_input.render(mode_text, True, WHITE) screen.blit(label, (WIDTH//2 - label.get_width()//2 + offset, HEIGHT//2 + 120)) stars = "*" * len(input_text) text_surf = font_input.render(stars, True, RED) box_rect = pygame.Rect(WIDTH//2 - 200 + offset, HEIGHT//2 + 180, 400, 60) pygame.draw.rect(screen, RED, box_rect, 2) screen.blit(text_surf, (WIDTH//2 - text_surf.get_width()//2 + offset, HEIGHT//2 + 190)) # Кнопка переключения в режим экстренного пароля if current_mode != "emergency" and EMERGENCY_PASSWORD: emergency_btn = font_mode.render("Use emergency password", True, YELLOW) emergency_rect = pygame.Rect(WIDTH//2 - 150, HEIGHT//2 + 260, 300, 40) pygame.draw.rect(screen, RED, emergency_rect, 2) screen.blit(emergency_btn, (WIDTH//2 - emergency_btn.get_width()//2, HEIGHT//2 + 265)) footer = font_footer.render("by Secure Life", True, RED) screen.blit(footer, (WIDTH - footer.get_width() - 40, HEIGHT - 60)) # === ЗАЩИТА ПРОЦЕССОВ === dangerous = ["taskmgr.exe", "processhacker.exe", "procmon.exe", "processmonitor.exe", "procexp.exe"] def monitor_dangerous_processes(): while True: for proc in psutil.process_iter(['name']): try: if proc.info['name'].lower() in dangerous: keep_window_on_top() except: pass time.sleep(1) threading.Thread(target=monitor_dangerous_processes, daemon=True).start() # === ГЛАВНЫЙ ЦИКЛ === tick = 0 running = True while running: draw(tick) keep_window_on_top() for event in pygame.event.get(): if event.type == pygame.QUIT: running = False elif event.type == pygame.MOUSEBUTTONDOWN: # Проверка нажатия на кнопку экстренного пароля if current_mode != "emergency" and EMERGENCY_PASSWORD: mouse_pos = pygame.mouse.get_pos() emergency_rect = pygame.Rect(WIDTH//2 - 150, HEIGHT//2 + 260, 300, 40) if emergency_rect.collidepoint(mouse_pos): current_mode = "emergency" input_text = "" elif event.type == pygame.KEYDOWN: if event.key == pygame.K_RETURN: attempt = input_text if current_mode == "password": if attempt == PASSWORD: if USE_2FA and TELEGRAM_TOKEN and TELEGRAM_CHAT_ID: otp = generate_otp() send_telegram_message(f"OTP для разблокировки: {otp}", True) current_mode = "otp" otp_attempts = 0 input_text = "" else: log_attempt(attempt, True) send_telegram_message("Вход успешен (без 2FA)", True) pygame.quit() sys.exit() else: log_attempt(attempt, False) send_telegram_message(f"Неудачная попытка ввода пароля: {attempt}", False) input_text = "" trigger_error_animation() elif current_mode == "otp": if attempt == otp: log_attempt("OTP " + attempt, True) send_telegram_message("OTP введён верно, разблокировка", True) pygame.quit() sys.exit() else: otp_attempts += 1 log_attempt("OTP " + attempt, False) send_telegram_message(f"Неверный OTP: {attempt}", False) input_text = "" trigger_error_animation() if otp_attempts >= MAX_OTP_ATTEMPTS: send_telegram_message("Превышено количество попыток OTP!", False) # Блокировка на 15 минут lock_until = time.time() + 900 while time.time() < lock_until: pygame.time.wait(100) otp_attempts = 0 elif current_mode == "emergency": if attempt == EMERGENCY_PASSWORD: log_attempt("EMERGENCY " + attempt, True) send_telegram_message("Вход с экстренным паролем!", True) pygame.quit() sys.exit() else: log_attempt("EMERGENCY " + attempt, False) send_telegram_message(f"Неудачная попытка экстренного пароля: {attempt}", False) input_text = "" trigger_error_animation() elif event.key == pygame.K_BACKSPACE: input_text = input_text[:-1] elif event.key == pygame.K_ESCAPE: # Возврат к вводу пароля if current_mode != "password": current_mode = "password" input_text = "" else: ch = event.unicode if ch.isprintable() and len(input_text) < 20: input_text += ru_to_en.get(ch, ch) tick += 1 pygame.display.flip() clock.tick(60) pygame.quit() sys.exit() Python import pygame import sys import math import keyboard import ctypes import win32gui import win32con import psutil import time import threading import random import cv2 import requests import json import os from datetime import datetime # === ПАРАМЕТРЫ === WIDTH, HEIGHT = 1920, 1080 input_text = "" error_shake = 0 error_flash = 0 error_count = 0 otp = None awaiting_otp = False otp_attempts = 0 MAX_OTP_ATTEMPTS = 3 current_mode = "password" # "password", "otp", "emergency" # Загрузка конфигурации CONFIG_FILE = "config.json" if not os.path.exists(CONFIG_FILE): print("Конфигурационный файл не найден. Запустите securelife.py для настройки.") sys.exit() with open(CONFIG_FILE, "r", encoding="utf-8") as f: config = json.load(f) PASSWORD = config.get("password", "admin") EMERGENCY_PASSWORD = config.get("emergency_password", "") TELEGRAM_TOKEN = config.get("telegram_token", "") TELEGRAM_CHAT_ID = config.get("telegram_chat_id", "") USE_2FA = config.get("use_2fa", True) SEND_PHOTO = config.get("send_photo", True) LOG_PATH = config.get("log_path", os.getcwd()) LOG_FILE = os.path.join(LOG_PATH, "login_attempts.log") PC_NAME = os.getenv("COMPUTERNAME") or "UnknownPC" ru_to_en = { 'ф': 'a', 'и': 'b', 'с': 'c', 'в': 'd', 'у': 'e', 'а': 'f', 'п': 'g', 'р': 'h', 'ш': 'i', 'о': 'j', 'л': 'k', 'д': 'l', 'ь': 'm', 'т': 'n', 'щ': 'o', 'з': 'p', 'й': 'q', 'к': 'r', 'ы': 's', 'е': 't', 'г': 'u', 'м': 'v', 'ц': 'w', 'ч': 'x', 'н': 'y', 'я': 'z', 'Ф': 'A', 'И': 'B', 'С': 'C', 'В': 'D', 'У': 'E', 'А': 'F', 'П': 'G', 'Р': 'H', 'Ш': 'I', 'О': 'J', 'Л': 'K', 'Д': 'L', 'Ь': 'M', 'Т': 'N', 'Щ': 'O', 'З': 'P', 'Й': 'Q', 'К': 'R', 'Ы': 'S', 'Е': 'T', 'Г': 'U', 'М': 'V', 'Ц': 'W', 'Ч': 'X', 'Н': 'Y', 'Я': 'Z' } # === ФУНКЦИИ === def log_attempt(password_attempt, success): global error_count now = datetime.now().strftime("%Y-%m-%d %H:%M:%S") status = "SUCCESS" if success else "FAIL" if not success: error_count += 1 log_line = f"{now} | PC: {PC_NAME} | Attempt: '{password_attempt}' | Result: {status} | Errors: {error_count}\n" with open(LOG_FILE, "a", encoding="utf-8") as f: f.write(log_line) def take_photo(): if not SEND_PHOTO: return None cap = cv2.VideoCapture(0) if not cap.isOpened(): return None ret, frame = cap.read() cap.release() if ret: photo_path = os.path.join(LOG_PATH, "attempt_photo.jpg") cv2.imwrite(photo_path, frame) return photo_path return None def send_telegram_message(message, success=True): if not TELEGRAM_TOKEN or not TELEGRAM_CHAT_ID or not USE_2FA: return photo_path = take_photo() now = datetime.now().strftime("%Y-%m-%d %H:%M:%S") status = "SUCCESS" if success else "FAIL" text = f" Secure Life\nPC: {PC_NAME}\nTime: {now}\n{message}\nResult: {status}" if photo_path: files = {'photo': open(photo_path, 'rb')} data = {'chat_id': TELEGRAM_CHAT_ID, 'caption': text} url = f"https://api.telegram.org/bot{TELEGRAM_TOKEN}/sendPhoto" try: requests.post(url, files=files, data=data, timeout=5) except: pass else: url = f"https://api.telegram.org/bot{TELEGRAM_TOKEN}/sendMessage" try: requests.post(url, data={'chat_id': TELEGRAM_CHAT_ID, 'text': text}, timeout=5) except: pass def switch_to_english_layout(): user32 = ctypes.WinDLL('user32', use_last_error=True) layout = 0x04090409 user32.LoadKeyboardLayoutW(hex(layout), 1) user32.ActivateKeyboardLayout(layout, 0) def generate_otp(): return str(random.randint(100000, 999999)) class FireParticle: def __init__(self): self.x = random.uniform(0, WIDTH) self.y = random.uniform(0, HEIGHT) self.size = random.uniform(2, 6) self.speed_y = random.uniform(-0.3, -1.0) self.alpha = random.randint(50, 150) self.surface = pygame.Surface((int(self.size*2), int(self.size*2)), pygame.SRCALPHA) def update(self): self.y += self.speed_y self.alpha -= 1.2 if self.alpha <= 0 or self.y < 0: self.__init__() def draw(self, screen): self.surface.fill((0, 0, 0, 0)) pygame.draw.circle(self.surface, (255, 40, 40, int(self.alpha)), (int(self.size), int(self.size)), int(self.size)) screen.blit(self.surface, (self.x, self.y)) # === ИНИЦИАЛИЗАЦИЯ === keys_to_block = ["alt", "ctrl", "esc", "f4", "win", "tab"] for key in keys_to_block: try: keyboard.block_key(key) except: pass pygame.init() switch_to_english_layout() screen = pygame.display.set_mode((WIDTH, HEIGHT), pygame.FULLSCREEN | pygame.NOFRAME) pygame.display.set_caption("Secure Life") clock = pygame.time.Clock() font_input = pygame.font.SysFont("consolas", 48, bold=True) font_footer = pygame.font.SysFont("Segoe Script", 32, bold=True) font_mode = pygame.font.SysFont("consolas", 24, bold=True) BLACK = (10, 10, 10) RED = (255, 0, 0) WHITE = (255, 255, 255) YELLOW = (255, 255, 0) try: skull_img = pygame.image.load("skull.png").convert_alpha() skull_img = pygame.transform.smoothscale(skull_img, (300, 300)) except: skull_img = pygame.Surface((300, 300), pygame.SRCALPHA) pygame.draw.circle(skull_img, RED, (150, 150), 150, 10) hwnd = pygame.display.get_wm_info()["window"] def keep_window_on_top(): try: win32gui.ShowWindow(hwnd, win32con.SW_RESTORE) win32gui.SetWindowPos(hwnd, win32con.HWND_TOPMOST, 0, 0, WIDTH, HEIGHT, win32con.SWP_SHOWWINDOW) win32gui.SetForegroundWindow(hwnd) except: pass def trigger_error_animation(): global error_shake, error_flash error_shake = 15 error_flash = 30 particles = [FireParticle() for _ in range(60)] def draw(tick): global error_flash screen.fill((30 + (error_flash * 2 if error_flash > 0 else 0), 10, 10)) if error_flash > 0: error_flash -= 1 for p in particles: p.update() p.draw(screen) scale = 1 + 0.05 * math.sin(tick * 0.1) skull_scaled = pygame.transform.rotozoom(skull_img, 0, scale) skull_rect = skull_scaled.get_rect(center=(WIDTH//2, HEIGHT//2 - 100)) screen.blit(skull_scaled, skull_rect) global error_shake offset = int(math.sin(tick * 0.6) * 10) if error_shake > 0 else 0 if error_shake > 0: error_shake -= 1 # Отображение текущего режима mode_text = "" if current_mode == "password": mode_text = "ENTER MAIN PASSWORD:" elif current_mode == "otp": mode_text = "ENTER OTP FROM TELEGRAM:" elif current_mode == "emergency": mode_text = "ENTER EMERGENCY PASSWORD:" mode_label = font_mode.render("(No 2FA required)", True, YELLOW) screen.blit(mode_label, (WIDTH//2 - mode_label.get_width()//2 + offset, HEIGHT//2 + 160)) label = font_input.render(mode_text, True, WHITE) screen.blit(label, (WIDTH//2 - label.get_width()//2 + offset, HEIGHT//2 + 120)) stars = "*" * len(input_text) text_surf = font_input.render(stars, True, RED) box_rect = pygame.Rect(WIDTH//2 - 200 + offset, HEIGHT//2 + 180, 400, 60) pygame.draw.rect(screen, RED, box_rect, 2) screen.blit(text_surf, (WIDTH//2 - text_surf.get_width()//2 + offset, HEIGHT//2 + 190)) # Кнопка переключения в режим экстренного пароля if current_mode != "emergency" and EMERGENCY_PASSWORD: emergency_btn = font_mode.render("Use emergency password", True, YELLOW) emergency_rect = pygame.Rect(WIDTH//2 - 150, HEIGHT//2 + 260, 300, 40) pygame.draw.rect(screen, RED, emergency_rect, 2) screen.blit(emergency_btn, (WIDTH//2 - emergency_btn.get_width()//2, HEIGHT//2 + 265)) footer = font_footer.render("by Secure Life", True, RED) screen.blit(footer, (WIDTH - footer.get_width() - 40, HEIGHT - 60)) # === ЗАЩИТА ПРОЦЕССОВ === dangerous = ["taskmgr.exe", "processhacker.exe", "procmon.exe", "processmonitor.exe", "procexp.exe"] def monitor_dangerous_processes(): while True: for proc in psutil.process_iter(['name']): try: if proc.info['name'].lower() in dangerous: keep_window_on_top() except: pass time.sleep(1) threading.Thread(target=monitor_dangerous_processes, daemon=True).start() # === ГЛАВНЫЙ ЦИКЛ === tick = 0 running = True while running: draw(tick) keep_window_on_top() for event in pygame.event.get(): if event.type == pygame.QUIT: running = False elif event.type == pygame.MOUSEBUTTONDOWN: # Проверка нажатия на кнопку экстренного пароля if current_mode != "emergency" and EMERGENCY_PASSWORD: mouse_pos = pygame.mouse.get_pos() emergency_rect = pygame.Rect(WIDTH//2 - 150, HEIGHT//2 + 260, 300, 40) if emergency_rect.collidepoint(mouse_pos): current_mode = "emergency" input_text = "" elif event.type == pygame.KEYDOWN: if event.key == pygame.K_RETURN: attempt = input_text if current_mode == "password": if attempt == PASSWORD: if USE_2FA and TELEGRAM_TOKEN and TELEGRAM_CHAT_ID: otp = generate_otp() send_telegram_message(f"OTP для разблокировки: {otp}", True) current_mode = "otp" otp_attempts = 0 input_text = "" else: log_attempt(attempt, True) send_telegram_message("Вход успешен (без 2FA)", True) pygame.quit() sys.exit() else: log_attempt(attempt, False) send_telegram_message(f"Неудачная попытка ввода пароля: {attempt}", False) input_text = "" trigger_error_animation() elif current_mode == "otp": if attempt == otp: log_attempt("OTP " + attempt, True) send_telegram_message("OTP введён верно, разблокировка", True) pygame.quit() sys.exit() else: otp_attempts += 1 log_attempt("OTP " + attempt, False) send_telegram_message(f"Неверный OTP: {attempt}", False) input_text = "" trigger_error_animation() if otp_attempts >= MAX_OTP_ATTEMPTS: send_telegram_message("Превышено количество попыток OTP!", False) # Блокировка на 15 минут lock_until = time.time() + 900 while time.time() < lock_until: pygame.time.wait(100) otp_attempts = 0 elif current_mode == "emergency": if attempt == EMERGENCY_PASSWORD: log_attempt("EMERGENCY " + attempt, True) send_telegram_message("Вход с экстренным паролем!", True) pygame.quit() sys.exit() else: log_attempt("EMERGENCY " + attempt, False) send_telegram_message(f"Неудачная попытка экстренного пароля: {attempt}", False) input_text = "" trigger_error_animation() elif event.key == pygame.K_BACKSPACE: input_text = input_text[:-1] elif event.key == pygame.K_ESCAPE: # Возврат к вводу пароля if current_mode != "password": current_mode = "password" input_text = "" else: ch = event.unicode if ch.isprintable() and len(input_text) < 20: input_text += ru_to_en.get(ch, ch) tick += 1 pygame.display.flip() clock.tick(60) pygame.quit() sys.exit() названия locker.py and securelife.py также скачайте картинку и назовите skull.png или сами меняйте как надо это для красоты(я после фикса лолза добавлю свою) И скрины софта кому нада
Код объективно бесполезный. Для просмотра действий на пк есть event viewer. И там видно что кто делал и какой юзер.
здравствуйте а вы не пробовали использовать защифрованный ssd диск с win to go на борту, в связке с хуникс, дабл ***ами и ****** на конечном устройстве?
>от незваных гостей да пошли они нахуй, не открываю дверь тем, кого не жду. но за старания респект. хоть и вряд ли кому-то понадобится
вот сделал бы, если бы кто то пытался попользоваться пк и ему в ебало боксерская перчатка прилетает со скорость 2м/с