From 570323bc0367364632384a72fd2df4bc096d62ea Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 21 Sep 2023 20:39:55 +0000 Subject: [PATCH 1/7] Bump cryptography from 41.0.0 to 41.0.4 Bumps [cryptography](https://github.com/pyca/cryptography) from 41.0.0 to 41.0.4. - [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pyca/cryptography/compare/41.0.0...41.0.4) --- updated-dependencies: - dependency-name: cryptography dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 9bf4720..149497f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ command_runner==1.5.0 -cryptography==41.0.0 +cryptography==41.0.4 discord_webhook==1.1.0 httpx==0.23.3 humanize==4.6.0 From fcb0a3307b40cd738c17697917ec318ab2ba9c18 Mon Sep 17 00:00:00 2001 From: xFGhoul Date: Tue, 17 Dec 2024 22:12:30 -0400 Subject: [PATCH 2/7] =?UTF-8?q?=F0=9F=9A=A8=20Update=20Remote?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pyprotector/keyauth/keyauth.py | 13 ++--- pyprotector/keyauth/utils.py | 7 ++- pyprotector/modules/analysis.py | 14 +----- pyprotector/modules/dll.py | 12 ++--- pyprotector/modules/miscellaneous.py | 11 ++++- pyprotector/modules/process.py | 69 ++++++++++++-------------- pyprotector/modules/vm.py | 37 ++++---------- pyprotector/protector.py | 73 +++++++++++++++------------- pyprotector/utils/events.py | 16 ++---- pyprotector/utils/http.py | 3 +- pyprotector/utils/webhook.py | 2 +- 11 files changed, 108 insertions(+), 149 deletions(-) diff --git a/pyprotector/keyauth/keyauth.py b/pyprotector/keyauth/keyauth.py index 2d576be..5e3946d 100644 --- a/pyprotector/keyauth/keyauth.py +++ b/pyprotector/keyauth/keyauth.py @@ -50,10 +50,8 @@ def _post_data(self, type: str, data: Optional[Dict] = None) -> Dict: "ownerid": self.ownerid, } - if data is None: - pass - else: - _post_data.update(data) + if data is not None: + _post_data |= data return _post_data @@ -62,8 +60,8 @@ def __request(self, data: Dict) -> Response: response = httpx.post(API.BASE_URL, params=data, timeout=30) response.raise_for_status() return response.json() - except (httpx.TimeoutException, httpx.ConnectError, httpx.HTTPError): - raise RequestError("Internal Request Failed!") + except (httpx.TimeoutException, httpx.ConnectError, httpx.HTTPError) as e: + raise RequestError("Internal Request Failed!") from e def initialize(self) -> Union[bool, KeyauthAppData]: """Initializes your Keyauth Application @@ -388,8 +386,7 @@ def download(self, file_id: str) -> bytes: if not response["success"]: raise RequestError(response["message"]) - file = bytes.fromhex(response["contents"]) - return file + return bytes.fromhex(response["contents"]) def checkSession(self) -> bool: """Check Session diff --git a/pyprotector/keyauth/utils.py b/pyprotector/keyauth/utils.py index fb22002..9cae49e 100644 --- a/pyprotector/keyauth/utils.py +++ b/pyprotector/keyauth/utils.py @@ -20,7 +20,6 @@ def getchecksum() -> str: str: File Hash """ md5_hash = hashlib.md5() - file = open("".join(sys.argv), "rb") - md5_hash.update(file.read()) - digest: str = md5_hash.hexdigest() - return digest + with open("".join(sys.argv), "rb") as file: + md5_hash.update(file.read()) + return md5_hash.hexdigest() diff --git a/pyprotector/modules/analysis.py b/pyprotector/modules/analysis.py index 97919e1..ca77e77 100644 --- a/pyprotector/modules/analysis.py +++ b/pyprotector/modules/analysis.py @@ -72,14 +72,10 @@ def CheckDebugPrivilege(self) -> None: for priv in debug_privilege: if priv.s_luid.LowPart == 21 and priv.s_attributes & 0x00000002: self.ntdll.NtClose(hToken) - self.logger.info("Debug Privilege Found Enabled") if self.report: self.webhook.send("Debug Privilege Enabled", self.name) self.event.dispatch( - "debug_privilege_found", "Debug Privilege Enabled", self.name - ) - self.event.dispatch( - "pyprotector_detect", "Debug Privilege Enabled", self.name + ["debug_privilege_found", "pyprotector_detect"], "Debug Privilege Enabled", self.name ) if self.exit: os._exit(1) @@ -126,16 +122,10 @@ def CheckDebugObject(self) -> None: ) if HasDebugObject: self.kernel32.CloseHandle(hProcess) - self.logger.info("Debug Object Handle Found") if self.report: self.webhook.send("Debug Object Handle Detected", self.name) self.event.dispatch( - "debug_object_handle_found", - "Debug Object Handle Detected", - self.name, - ) - self.event.dispatch( - "pyprotector_detect", + ["debug_object_handle_found", "pyprotector_detect"], "Debug Object Handle Detected", self.name, ) diff --git a/pyprotector/modules/dll.py b/pyprotector/modules/dll.py index bd6a615..a93c451 100644 --- a/pyprotector/modules/dll.py +++ b/pyprotector/modules/dll.py @@ -59,13 +59,13 @@ def BlockDLLs(self) -> None: win32process.GetModuleFileNameEx(hProcess, dll) ).lower() for sandboxDLL in Lists.BLACKLISTED_DLLS: - if sandboxDLL in dllName: - if dllName not in EvidenceOfSandbox: - EvidenceOfSandbox.append(dllName) - finally: + if sandboxDLL in dllName and dllName not in EvidenceOfSandbox: # noqa: E501 + EvidenceOfSandbox.append(dllName) win32api.CloseHandle(hProcess) - except BaseException: - pass + except BaseException: + pass + except Exception as e: + raise e if EvidenceOfSandbox: self.logger.info( f"The Following DLL's: {EvidenceOfSandbox} Were Found Loaded" diff --git a/pyprotector/modules/miscellaneous.py b/pyprotector/modules/miscellaneous.py index cc43990..bfcc959 100644 --- a/pyprotector/modules/miscellaneous.py +++ b/pyprotector/modules/miscellaneous.py @@ -21,6 +21,7 @@ import psutil import win32api +from functools import lru_cache from typing import Literal from ..types import Event, Logger @@ -48,6 +49,7 @@ def name(self) -> str: def version(self) -> int: return 1.0 + @lru_cache def CheckInternet(self) -> None: """ Checks If There Is A Valid Connection To The Internet @@ -62,6 +64,7 @@ def CheckInternet(self) -> None: else: pass + @lru_cache def CheckRAM(self) -> None: """Checks RAM Size For Being Less Than 4 GB""" memory: int = psutil.virtual_memory().total @@ -129,6 +132,7 @@ def CheckIsDebuggerPresent(self) -> None: if self.exit: os._exit(1) + @lru_cache def CheckDiskSize(self) -> None: """Check Disk Size""" minDiskSizeGB: Literal[50] = 50 @@ -184,6 +188,7 @@ def KillTasks(self) -> None: 'cmd.exe /c @RD /S /Q "C:\\Users\\%username%\\AppData\\Local\\Microsoft\\Windows\\INetCache\\IE" >nul 2>&1' ) + @lru_cache def CheckPaths(self) -> None: """Checks Paths on Computer Against Blacklisted Paths""" for path in Lists.BLACKLISTED_PATHS: @@ -257,6 +262,7 @@ def CheckOutPutDebugString(self) -> None: if self.exit: os._exit(1) + @lru_cache def CheckIPs(self) -> None: """Checks User IP Against Blacklisted List""" if UserInfo.IP in Lists.BLACKLISTED_IPS: @@ -281,7 +287,8 @@ def CheckIPs(self) -> None: os._exit(1) else: pass - + + @lru_cache def CheckCPUCores(self) -> None: """Checks CPU Core Count For Being Less Than 1""" if int(psutil.cpu_count()) <= 1: @@ -299,7 +306,7 @@ def CheckCPUCores(self) -> None: ) if self.exit: os._exit(1) - + def IsUsingProxy(self) -> None: """Checks If Proxies Are In Use""" headers: dict[str, str] = {"User-Agent": "Mozilla/5.0"} diff --git a/pyprotector/modules/process.py b/pyprotector/modules/process.py index f7a9cae..a5eebd8 100644 --- a/pyprotector/modules/process.py +++ b/pyprotector/modules/process.py @@ -21,6 +21,7 @@ from ..abc import Module from ..constants import Lists from ..utils.webhook import Webhook +import contextlib class AntiProcess(Module): @@ -61,13 +62,7 @@ def CheckProcessList(self) -> None: self.name, ) self.event.dispatch( - "process_running", - f"{process.name()} was detected running on the system.", - self.name, - process=process, - ) - self.event.dispatch( - "pyprotector_detect", + ["process_running", "pyprotector_detect"], f"{process.name()} was detected running on the system.", self.name, process=process, @@ -84,38 +79,34 @@ def CheckWindowNames(self) -> None: """Checks Window Names Against Blacklisted List""" def winEnumHandler(hwnd, ctx) -> None: - if win32gui.GetWindowText(hwnd).lower() in Lists.BLACKLISTED_WINDOW_NAMES: - pid: tuple[int, int] = GetWindowThreadProcessId(hwnd) - if isinstance(pid, int): - try: - psutil.Process(pid).terminate() - except BaseException: - pass - else: - for process in pid: - try: - psutil.Process(process).terminate() - except BaseException: - pass - self.logger.info(f"{win32gui.GetWindowText(hwnd)} Found") - if self.report: - self.webhook.send( - f"Debugger {win32gui.GetWindowText(hwnd)}", self.name - ) - self.event.dispatch( - "window_name_detected", - f"Debugger {win32gui.GetWindowText(hwnd)} Found Open", - self.name, - window_name=win32gui.GetWindowText(hwnd), - ) - self.event.dispatch( - "pyprotector_detect", - f"Debugger {win32gui.GetWindowText(hwnd)} Found Open", - self.name, - window_name=win32gui.GetWindowText(hwnd), - ) - if self.exit: - os._exit(1) + if ( + win32gui.GetWindowText(hwnd).lower() + not in Lists.BLACKLISTED_WINDOW_NAMES + ): + return + pid: tuple[int, int] = GetWindowThreadProcessId(hwnd) + if isinstance(pid, int): + with contextlib.suppress(BaseException): + psutil.Process(pid).terminate() + + else: + for process in pid: + with contextlib.suppress(BaseException): + psutil.Process(process).terminate() + + self.logger.info(f"{win32gui.GetWindowText(hwnd)} Found") + if self.report: + self.webhook.send( + f"Debugger {win32gui.GetWindowText(hwnd)}", self.name + ) + self.event.dispatch( + ["window_name_detected", "pyprotector_detect"], + f"Debugger {win32gui.GetWindowText(hwnd)} Found Open", + self.name, + window_name=win32gui.GetWindowText(hwnd), + ) + if self.exit: + os._exit(1) while True: win32gui.EnumWindows(winEnumHandler, None) diff --git a/pyprotector/modules/vm.py b/pyprotector/modules/vm.py index 62b870c..e7f5a2f 100644 --- a/pyprotector/modules/vm.py +++ b/pyprotector/modules/vm.py @@ -15,6 +15,7 @@ import httpx +from functools import lru_cache from typing import List from ..types import Event, Logger @@ -72,6 +73,7 @@ def _get_base_prefix_compat(self) -> None: or sys.prefix ) + @lru_cache def CheckLists(self) -> None: """ Checks if the user's HWID, PC username, PC name, IP, MAC address, or GPU is in the blacklists. @@ -83,13 +85,7 @@ def CheckLists(self) -> None: f"Blacklisted HWID Detected: `{UserInfo.HWID}`", self.name ) self.event.dispatch( - "blacklisted_hwid", - "Blacklisted HWID Detected", - self.name, - hwid=UserInfo.HWID, - ) - self.event.dispatch( - "pyprotector_detect", + ["blacklisted_hwid", "pyprotector_detect"], "Blacklisted HWID Detected", self.name, hwid=UserInfo.HWID, @@ -104,13 +100,7 @@ def CheckLists(self) -> None: f"Blacklisted PC User: `{UserInfo.USERNAME}`", self.name ) self.event.dispatch( - "blacklisted_pc_username", - "Blacklisted PC User Detected", - self.name, - pc_username=UserInfo.USERNAME, - ) - self.event.dispatch( - "pyprotector_detect", + ["blacklisted_pc_username", "pyprotector_detect"], "Blacklisted PC User Detected", self.name, pc_username=UserInfo.USERNAME, @@ -125,13 +115,7 @@ def CheckLists(self) -> None: f"Blacklisted PC Name: `{UserInfo.PC_NAME}`", self.name ) self.event.dispatch( - "blacklisted_pc_name", - "Blacklisted PC Name Detected", - self.name, - pc_name=UserInfo.PC_NAME, - ) - self.event.dispatch( - "pyprotector_detect", + ["blacklisted_pc_name", "pyprotector_detect"], "Blacklisted PC Name Detected", self.name, pc_name=UserInfo.PC_NAME, @@ -144,13 +128,7 @@ def CheckLists(self) -> None: if self.report: self.webhook.send(f"Blacklisted IP: `{UserInfo.IP}`", self.name) self.event.dispatch( - "blacklisted_ip", - "Blacklisted IP Detected", - self.name, - ip=UserInfo.IP, - ) - self.event.dispatch( - "blacklisted_ip", + ["blacklisted_ip", "pyprotector_detect"], "Blacklisted IP Detected", self.name, ip=UserInfo.IP, @@ -196,6 +174,7 @@ def CheckLists(self) -> None: if self.exit: os._exit(1) + @lru_cache def CheckVirtualEnv(self) -> None: """ Checks sys.prefix @@ -203,6 +182,7 @@ def CheckVirtualEnv(self) -> None: if self._get_base_prefix_compat() != sys.prefix and self.exit: os._exit(1) + @lru_cache def CheckRegistry(self) -> None: """ Checks VMWare Registry Keys @@ -258,6 +238,7 @@ def CheckMacAddress(self) -> None: if self.exit: os._exit(1) + @lru_cache def CheckScreenSize(self) -> None: """ Checks the screen size for being less than 200x200 diff --git a/pyprotector/protector.py b/pyprotector/protector.py index 70de4d4..5ebd336 100644 --- a/pyprotector/protector.py +++ b/pyprotector/protector.py @@ -104,9 +104,9 @@ def __init__( self.logger.configure(**LOGGING_CONFIG) # -- Initialize Constants - self.screenshot: bool = bool("Screenshot" in self.detections) - self.exit: bool = bool("Exit" in self.detections) - self.report: bool = bool("Report" in self.detections) + self.screenshot: bool = "Screenshot" in self.detections + self.exit: bool = "Exit" in self.detections + self.report: bool = "Report" in self.detections # -- Initialize Events self.event: ProtectorObservable = ProtectorObservable() @@ -251,6 +251,40 @@ def _run_module_threads(self, debug: bool) -> None: Thread( name=self.AntiDump.name, target=self.AntiDump.StartChecks ).start() + + def _run_debug_module_threads(self): + self.logger.info("PythonProtector Starting") + + self.logger.info(f"Version: {ProtectorInfo.VERSION}") + self.logger.info(f"Current Path: {ProtectorInfo.ROOT_PATH}") + self.logger.info( + f"Operating System: {platform.uname().system} {platform.uname().release} {platform.win32_edition()} ({platform.architecture(sys.executable)[0]})" + ) + bt = datetime.datetime.fromtimestamp(psutil.boot_time()) + self.logger.info( + f"Boot Time: {bt.year}/{bt.month}/{bt.day} {bt.hour}:{bt.minute}:{bt.second}" + ) + self.logger.info(f"Python: {platform.python_version()}") + self.logger.info(f"Is Administrator: {is_admin()}") + + cpu_info = cpuinfo.get_cpu_info() + cpu_type = cpu_info["arch"] + cpu_cores = cpu_info["count"] + + self.logger.info(f"Processor Type: {cpu_type}") + self.logger.info(f"Processor Cores: {cpu_cores}") + + vmem = psutil.virtual_memory() + + self.logger.info(f"Total Memory: {humanize.naturalsize(vmem.total)}") + self.logger.info( + f"Memory Availability: {humanize.naturalsize(vmem.available)}" + ) + self.logger.info(f"Memory Percentage: {vmem.percent}%") + + self.logger.info("Starting PythonProtector Services") + + self._run_module_threads(debug=True) def start(self) -> None: """Main Function Of PythonProtector @@ -267,37 +301,6 @@ def start(self) -> None: # -- Start Main Program if self.debug: - self.logger.info("PythonProtector Starting") - - self.logger.info(f"Version: {ProtectorInfo.VERSION}") - self.logger.info(f"Current Path: {ProtectorInfo.ROOT_PATH}") - self.logger.info( - f"Operating System: {platform.uname().system} {platform.uname().release} {platform.win32_edition()} ({platform.architecture(sys.executable)[0]})" - ) - bt = datetime.datetime.fromtimestamp(psutil.boot_time()) - self.logger.info( - f"Boot Time: {bt.year}/{bt.month}/{bt.day} {bt.hour}:{bt.minute}:{bt.second}" - ) - self.logger.info(f"Python: {platform.python_version()}") - self.logger.info(f"Is Administrator: {is_admin()}") - - cpu_info = cpuinfo.get_cpu_info() - cpu_type = cpu_info["arch"] - cpu_cores = cpu_info["count"] - - self.logger.info(f"Processor Type: {cpu_type}") - self.logger.info(f"Processor Cores: {cpu_cores}") - - vmem = psutil.virtual_memory() - - self.logger.info(f"Total Memory: {humanize.naturalsize(vmem.total)}") - self.logger.info( - f"Memory Availability: {humanize.naturalsize(vmem.available)}" - ) - self.logger.info(f"Memory Percentage: {vmem.percent}%") - - self.logger.info("Starting PythonProtector Services") - - self._run_module_threads(debug=True) + self._run_debug_module_threads() else: self._run_module_threads(debug=False) diff --git a/pyprotector/utils/events.py b/pyprotector/utils/events.py index 7d314f3..c28bf9b 100644 --- a/pyprotector/utils/events.py +++ b/pyprotector/utils/events.py @@ -10,21 +10,13 @@ """ from observable import Observable - - -class ProtectorEvent: - def __init__(self, event: str, text: str, module: str, **kwargs) -> None: - self.event: str = event - self.text: str = text - self.module: str = module - self.extra: dict = kwargs - +from typing import List class ProtectorObservable: def __init__(self) -> None: self.obs: Observable = Observable() - def dispatch(self, event: str, text: str, module: str, **kwargs) -> ProtectorEvent: + def dispatch(self, events: List[str], text: str, module: str, **kwargs) -> None: """ It triggers an event. @@ -36,5 +28,5 @@ def dispatch(self, event: str, text: str, module: str, **kwargs) -> ProtectorEve Returns: ProtectorEvent """ - self.obs.trigger(event, text, module, **kwargs) - return ProtectorEvent(event, text, module, **kwargs) + for event in events: + self.obs.trigger(event, text, module, **kwargs) diff --git a/pyprotector/utils/http.py b/pyprotector/utils/http.py index 1334498..de34174 100644 --- a/pyprotector/utils/http.py +++ b/pyprotector/utils/http.py @@ -31,8 +31,7 @@ def getIPAddress() -> str: return "No IP Address" response = response.json() - ip = response.get("ip") - return ip + return response.get("ip") def hasInternet() -> bool: diff --git a/pyprotector/utils/webhook.py b/pyprotector/utils/webhook.py index e56d252..32852ff 100644 --- a/pyprotector/utils/webhook.py +++ b/pyprotector/utils/webhook.py @@ -63,7 +63,7 @@ def DecryptLogs(self) -> bytes: decrypted_message: str = LoggingInfo.CIPHER.decrypt( encoded_message ).decode("utf-8") - line: str = line.replace(str(encrypted_message), str(decrypted_message)) + line: str = line.replace(encrypted_message, decrypted_message) decrypted_logs_file.write(f"{line}\n") return decrypted_logs_file.getvalue() From 986c23b1829fb00e83b4ebf623b7175e70041718 Mon Sep 17 00:00:00 2001 From: xFGhoul Date: Wed, 18 Dec 2024 00:31:51 -0400 Subject: [PATCH 3/7] =?UTF-8?q?=F0=9F=9A=91=20Fix=20`event.dispatch`=20not?= =?UTF-8?q?=20providing=20`List[str]`=20argument?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/ext/mixed.py | 2 +- examples/protector.py | 2 +- pyprotector/modules/analysis.py | 33 +++------- pyprotector/modules/dll.py | 9 +-- pyprotector/modules/miscellaneous.py | 92 +++++++--------------------- pyprotector/modules/vm.py | 59 +++--------------- pyprotector/utils/events.py | 2 +- requirements.txt | 12 ++-- 8 files changed, 49 insertions(+), 162 deletions(-) diff --git a/examples/ext/mixed.py b/examples/ext/mixed.py index c74bd0a..f9fb5a9 100644 --- a/examples/ext/mixed.py +++ b/examples/ext/mixed.py @@ -48,7 +48,7 @@ @security.event.obs.on("process_running") -def on_process_running(text: str, module: str, process): +def on_process_running(text: str, module: str, process) -> None: print(f"{module} - {text}\nProcess Name: {process.name()}") print(security.user) auth.ban() diff --git a/examples/protector.py b/examples/protector.py index 0cedf6e..68fbf5b 100644 --- a/examples/protector.py +++ b/examples/protector.py @@ -39,7 +39,7 @@ @security.event.obs.on("process_running") -def on_process_running(text: str, module: str, process): +def on_process_running(text: str, module: str, process) -> None: print(f"{module} - {text}\nProcess Name: {process.name()}") print(security.user) # Free To Do Whatever You Want Here... diff --git a/pyprotector/modules/analysis.py b/pyprotector/modules/analysis.py index ca77e77..3b97f36 100644 --- a/pyprotector/modules/analysis.py +++ b/pyprotector/modules/analysis.py @@ -156,10 +156,7 @@ def CheckSEDebugName(self) -> None: if self.report: self.webhook.send("Debug Object Handle Detected", self.name) self.event.dispatch( - "se_debug_name", "Debug Object Handle Detected", self.name - ) - self.event.dispatch( - "pyprotector_detect", "Debug Object Handle Detected", self.name + ["se_debug_name", "pyprotector_detect"], "Debug Object Handle Detected", self.name ) if self.exit: os._exit((1)) @@ -191,12 +188,7 @@ def CheckNtGlobalFlag(self) -> None: self.name, ) self.event.dispatch( - "nt_global_flag_debugged", - "NT_GLOBAL_FLAG_DEBUGGED Found in the Process Environment Block", - self.name, - ) - self.event.dispatch( - "pyprotector_detect", + ["nt_global_flag_debugged", "pyprotector_detect"], "NT_GLOBAL_FLAG_DEBUGGED Found in the Process Environment Block", self.name, ) @@ -226,12 +218,7 @@ def CheckHardwareBreakpoints(self) -> None: if self.report: self.webhook.send("Hardware Breakpoints Found Set", self.name) self.event.dispatch( - "hardware_breakpoint_set", - "Hardware Breakpoints Found Set", - self.name, - ) - self.event.dispatch( - "pyprotector_detect", + ["hardware_breakpoint_set", "pyprotector_detect"], "Hardware Breakpoints Found Set", self.name, ) @@ -254,10 +241,9 @@ def CheckDebugFilterState(self) -> None: "Debug Filter State `!= 0`, debugging detected", self.name ) self.event.dispatch( - "debug_filter_state", "Debug Filter State is not 0", self.name - ) - self.event.dispatch( - "pyprotector_detect", "Debug Filter State is not 0", self.name + ["debug_filter_state", "pyprotector_detect"], + "Debug Filter State is not 0", + self.name, ) if self.exit: os._exit(1) @@ -280,10 +266,9 @@ class PEB(ctypes.Structure): if self.report: self.webhook.send("Process Found Being Debugged", self.name) self.event.dispatch( - "peb_being_debugged", "Process Found Being Debugged", self.name - ) - self.event.dispatch( - "pyprotector_detect", "Process Found Being Debugged", self.name + ["peb_being_debugged", "pyprotector_detect"], + "Process Found Being Debugged", + self.name, ) if self.exit: os._exit(1) diff --git a/pyprotector/modules/dll.py b/pyprotector/modules/dll.py index a93c451..1f5e9e6 100644 --- a/pyprotector/modules/dll.py +++ b/pyprotector/modules/dll.py @@ -76,14 +76,7 @@ def BlockDLLs(self) -> None: self.name, ) self.event.dispatch( - "dll_attach", - f"The following DLLs were discovered loaded in processes running on the system. DLLS: {EvidenceOfSandbox}", - self.name, - {EvidenceOfSandbox}, - dlls=EvidenceOfSandbox, - ) - self.event.dispatch( - "pyprotector_detect", + ["dll_attach", "pyprotector_detect"], f"The following DLLs were discovered loaded in processes running on the system. DLLS: {EvidenceOfSandbox}", self.name, {EvidenceOfSandbox}, diff --git a/pyprotector/modules/miscellaneous.py b/pyprotector/modules/miscellaneous.py index bfcc959..9f96074 100644 --- a/pyprotector/modules/miscellaneous.py +++ b/pyprotector/modules/miscellaneous.py @@ -76,13 +76,7 @@ def CheckRAM(self) -> None: self.name, ) self.event.dispatch( - "ram_check", - "Less than 4 GB of RAM exists on this system", - self.name, - ram=memory, - ) - self.event.dispatch( - "pyprotector_detect", + ["ram_check", "pyprotector_detect"], "Less than 4 GB of RAM exists on this system", self.name, ram=memory, @@ -99,10 +93,9 @@ def CheckIsDebuggerPresent(self) -> None: if self.report: self.webhook.send("IsDebuggerPresent Returned True", self.name) self.event.dispatch( - "is_debugger_present", "IsDebuggerPresent Returned True", self.name - ) - self.event.dispatch( - "pyprotector_detect", "IsDebuggerPresent Returned True", self.name + ["is_debugger_present", "pyprotector_detect"], + "IsDebuggerPresent Returned True", + self.name, ) if self.exit: os._exit(1) @@ -120,12 +113,7 @@ def CheckIsDebuggerPresent(self) -> None: self.name, ) self.event.dispatch( - "check_remote_debugger_present", - "CheckRemoteDebuggerPresent Returned True", - self.name, - ) - self.event.dispatch( - "pyprotector_detect", + ["check_remote_debugger_present", "pyprotector_detect"], "CheckRemoteDebuggerPresent Returned True", self.name, ) @@ -148,13 +136,7 @@ def CheckDiskSize(self) -> None: f"The Current Disk Size Is {diskSizeGB}GB, Which Is Less Than The Minimum" ) self.event.dispatch( - "disk_size_check", - f"The Current Disk Size Is {diskSizeGB}GB, Which Is Less Than The Minimum", - self.name, - disk_size=diskSizeGB, - ) - self.event.dispatch( - "pyprotector_detect", + ["disk_size_check", "pyprotector_detect"], f"The Current Disk Size Is {diskSizeGB}GB, Which Is Less Than The Minimum", self.name, disk_size=diskSizeGB, @@ -197,13 +179,7 @@ def CheckPaths(self) -> None: if self.report: self.webhook.send("Blacklisted Path Found", self.name) self.event.dispatch( - "blacklisted_path", - "Blacklisted Path Found", - self.name, - path=path, - ) - self.event.dispatch( - "pyprotector_detect", + ["blacklisted_path", "pyprotector_detect"], "Blacklisted Path Found", self.name, path=path, @@ -226,18 +202,12 @@ def CheckImports(self) -> None: self.name, ) self.event.dispatch( - "blacklisted_import", + ["blacklisted_import", "pyprotector_detect"], f"{package} Was Found Installed", self.name, package=package, dist=dist, ) - self.event.dispatch( - "pyprotector_detect", - f"{package} Was Found Installed", - package=package, - dist=dist, - ) if self.exit: os._exit(1) else: @@ -254,10 +224,9 @@ def CheckOutPutDebugString(self) -> None: if self.report: self.webhook.send("OutputDebugString Not Equal To 0", self.name) self.event.dispatch( - "output_debug_string", "OutputDebugString Not Equal To 0", self.name - ) - self.event.dispatch( - "pyprotector_detect", "OutputDebugString Not Equal To 0", self.name + ["output_debug_string", "pyprotector_detect"], + "OutputDebugString Not Equal To 0", + self.name, ) if self.exit: os._exit(1) @@ -272,13 +241,7 @@ def CheckIPs(self) -> None: f"`{UserInfo.IP}` Is A Blacklisted IP Address", self.name ) self.event.dispatch( - "ip_check", - f"{UserInfo.IP} Is A Blacklisted IP Address", - self.name, - ip=UserInfo.IP, - ) - self.event.dispatch( - "pyprotector_detect", + ["ip_check", "pyprotector_detect"], f"{UserInfo.IP} Is A Blacklisted IP Address", self.name, ip=UserInfo.IP, @@ -298,10 +261,8 @@ def CheckCPUCores(self) -> None: "CPU Core Count Is Less Than Or Equal To `1`", self.name ) self.event.dispatch( - "cpu_count" "CPU Core Count Is Less Than Or Equal To 1", self.name - ) - self.event.dispatch( - "pyprotector_detect" "CPU Core Count Is Less Than Or Equal To 1", + ["cpu_count", "pyprotector_detect"], + "CPU Core Count Is Less Than Or Equal To 1", self.name, ) if self.exit: @@ -317,13 +278,7 @@ def IsUsingProxy(self) -> None: if self.report: self.webhook.send("Proxy Headers Being Used", self.name) self.event.dispatch( - "proxy_headers", - "Proxy Headers Being Used", - self.name, - header=header, - ) - self.event.dispatch( - "pyprotector_detect", + ["proxy_headers", "pyprotector_detect"], "Proxy Headers Being Used", self.name, header=header, @@ -336,10 +291,7 @@ def IsUsingProxy(self) -> None: if self.report: self.webhook.send("Proxy IP Being Used", self.name) self.event.dispatch( - "proxy_ip", "Proxy IP Being Used", self.name, ip=UserInfo.IP - ) - self.event.dispatch( - "pyprotector_detect", + ["proxy_ip", "pyprotector_detect"], "Proxy IP Being Used", self.name, ip=UserInfo.IP, @@ -357,9 +309,10 @@ def IsUsingProxy(self) -> None: self.logger.info("Tor Network Detected") if self.report: self.webhook.send("Tor Network In Use", self.name) - self.event.dispatch("tor_network", "Tor Network In Use", self.name) self.event.dispatch( - "pyprotector_detect", "Tor Network In Use", self.name + ["tor_network", "pyprotector_detect"], + "Tor Network In Use", + self.name, ) if self.exit: os._exit(1) @@ -373,10 +326,9 @@ def IsUsingProxy(self) -> None: if self.report: self.webhook.send("Transparent Proxies Detected", self.name) self.event.dispatch( - "transparent_proxies", "Transparent Proxies Detected", self.name - ) - self.event.dispatch( - "pyprotector_detect", "Transparent Proxies Detected", self.name + ["transparent_proxies", "pyprotector_detect"], + "Transparent Proxies Detected", + self.name, ) if self.exit: os._exit(1) diff --git a/pyprotector/modules/vm.py b/pyprotector/modules/vm.py index e7f5a2f..00a5be0 100644 --- a/pyprotector/modules/vm.py +++ b/pyprotector/modules/vm.py @@ -141,13 +141,7 @@ def CheckLists(self) -> None: if self.report: self.webhook.send(f"Blacklisted MAC: `{UserInfo.MAC}`", self.name) self.event.dispatch( - "blacklisted_mac_address", - "Blacklisted MAC Detected", - self.name, - mac_addr=UserInfo.MAC, - ) - self.event.dispatch( - "pyprotector_detect", + ["blacklisted_mac_address", "pyprotector_detect"], "Blacklisted MAC Detected", self.name, mac_addr=UserInfo.MAC, @@ -160,13 +154,7 @@ def CheckLists(self) -> None: if self.report: self.webhook.send(f"Blacklisted GPU: `{UserInfo.GPU}`", self.name) self.event.dispatch( - "blacklisted_gpu", - "Blacklisted GPU Detected", - self.name, - gpu=UserInfo.GPU, - ) - self.event.dispatch( - "pyprotector_detect", + ["blacklisted_gpu", "pyprotector_detect"], "Blacklisted GPU Detected", self.name, gpu=UserInfo.GPU, @@ -199,14 +187,7 @@ def CheckRegistry(self) -> None: if self.report: self.webhook.send("VMWare Registry Detected", self.name) self.event.dispatch( - "vmware_registry", - "VMWare Registry Detected", - self.name, - reg1=reg1, - reg2=reg2, - ) - self.event.dispatch( - "pyprotector_detect", + ["vmware_registry", "pyprotector_detect"], "VMWare Registry Detected", self.name, reg1=reg1, @@ -224,13 +205,7 @@ def CheckMacAddress(self) -> None: if self.report: self.webhook.send("VMWare MAC Address Detected", self.name) self.event.dispatch( - "vmware_mac", - "VMWare MAC Address Detected", - self.name, - mac_addr=UserInfo.MAC, - ) - self.event.dispatch( - "pyprotector_detect", + ["vmware_mac", "pyprotector_detect"], "VMWare MAC Address Detected", self.name, mac_addr=UserInfo.MAC, @@ -250,10 +225,7 @@ def CheckScreenSize(self) -> None: if self.report: self.webhook.send(f"Screen Size Is: **x**: {x} | **y**: {y}", self.name) self.event.dispatch( - "screen_size", f"Screen Size X: {x} | Y: {y}", self.name, x=x, y=y - ) - self.event.dispatch( - "pyprotector_detect", + ["screen_size", "pyprotector_detect"], f"Screen Size X: {x} | Y: {y}", self.name, x=x, @@ -287,13 +259,7 @@ def CheckProcessesAndFiles(self) -> None: "Blacklisted Virtual Machine Process Running", self.name ) self.event.dispatch( - "vm_process_running", - "Blacklisted Virtual Machine Process Running", - self.name, - processes=processList, - ) - self.event.dispatch( - "pyprotector_detect", + ["vm_process_running", "pyprotector_detect"], "Blacklisted Virtual Machine Process Running", self.name, processes=processList, @@ -306,10 +272,7 @@ def CheckProcessesAndFiles(self) -> None: if self.report: self.webhook.send("VMWare DLL Detected", self.name) self.event.dispatch( - "vmware_dll", "VMWare DLL Detected", self.name, dll=vmware_dll - ) - self.event.dispatch( - "pyprotector_detect", + ["vmware_dll", "pyprotector_detect"], "VMWare DLL Detected", self.name, dll=vmware_dll, @@ -322,13 +285,7 @@ def CheckProcessesAndFiles(self) -> None: if self.report: self.webhook.send("VirtualBox DLL Detected", self.name) self.event.dispatch( - "virtualbox_dll", - "VirtualBox DLL Detected", - self.name, - dll=virtualbox_dll, - ) - self.event.dispatch( - "pyprotector_detect", + ["virtualbox_dll", "pyprotector_detect"], "VirtualBox DLL Detected", self.name, dll=virtualbox_dll, diff --git a/pyprotector/utils/events.py b/pyprotector/utils/events.py index c28bf9b..5a2700e 100644 --- a/pyprotector/utils/events.py +++ b/pyprotector/utils/events.py @@ -26,7 +26,7 @@ def dispatch(self, events: List[str], text: str, module: str, **kwargs) -> None: module (str): The name of the module that triggered the event. Returns: - ProtectorEvent + None """ for event in events: self.obs.trigger(event, text, module, **kwargs) diff --git a/requirements.txt b/requirements.txt index 149497f..ec6af20 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,13 +1,13 @@ command_runner==1.5.0 -cryptography==41.0.4 +cryptography==44.0.0 discord_webhook==1.1.0 -httpx==0.23.3 +httpx==0.28.1 humanize==4.6.0 -loguru==0.6.0 +loguru==0.7.3 observable==1.0.3 -psutil==5.9.4 +psutil==6.1.0 py_cpuinfo==9.0.0 -pywin32==305 +pywin32==308 requests==2.31.0 -setuptools==67.6.0 +setuptools==75.6.0 WMI==1.5.1 From c1c09c97df28dddfbb166093cfd1ab7eb620d599 Mon Sep 17 00:00:00 2001 From: xFGhoul Date: Mon, 20 Jan 2025 20:59:10 -0400 Subject: [PATCH 4/7] =?UTF-8?q?=F0=9F=9A=80=20(code):=202.0.0!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/keyauth.py | 14 +- pyproject.toml | 35 +- pyprotector/abc.py | 1 - pyprotector/constants.py | 18 +- pyprotector/keyauth/__init__.py | 2 +- pyprotector/keyauth/keyauth.py | 54 ++- pyprotector/keyauth/models.py | 17 +- pyprotector/modules/analysis.py | 34 +- pyprotector/modules/dll.py | 25 +- pyprotector/modules/dump.py | 14 +- pyprotector/modules/miscellaneous.py | 30 +- pyprotector/modules/process.py | 16 +- pyprotector/modules/vm.py | 40 +- pyprotector/protector.py | 83 ++-- pyprotector/types.py | 1 + pyprotector/utils/events.py | 10 +- pyprotector/utils/webhook.py | 34 +- scripts/format.bat | 8 + scripts/{format.sh => format_linux.sh} | 0 setup.py | 78 ---- uv.lock | 505 +++++++++++++++++++++++++ 21 files changed, 794 insertions(+), 225 deletions(-) create mode 100644 scripts/format.bat rename scripts/{format.sh => format_linux.sh} (100%) delete mode 100644 setup.py create mode 100644 uv.lock diff --git a/examples/keyauth.py b/examples/keyauth.py index 94fa95a..163d2e4 100644 --- a/examples/keyauth.py +++ b/examples/keyauth.py @@ -12,16 +12,20 @@ from pyprotector.keyauth import Keyauth from pyprotector.keyauth.utils import getchecksum -auth = Keyauth(name="", ownerid="", secret="", version="", file_hash=getchecksum()) +auth = Keyauth( + name="", + ownerid="", + secret="", + version="", + file_hash=getchecksum()) app = auth.initialize() -print( - app -) # "Keyauth App ({self.version}) with {self.users} users, {self.keys} keys and {self.onlineUsers} online users" +# "Keyauth App ({self.version}) with {self.users} users, {self.keys} keys and {self.onlineUsers} online users" +print(app) license = auth.license("LICENSE") print(license.current_subscription) print(license.last_login) print(license.expiry) -### All Other Functions are documented. +# All Other Functions are documented. diff --git a/pyproject.toml b/pyproject.toml index 49a69aa..aa2c1b8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,3 +1,32 @@ -[tool.ruff] -extend-select = ["C4", "SIM"] -ignore = [] \ No newline at end of file +[project] +name = "pythonprotector" +version = "2.0" +description = "Add your description here" +readme = "README.md" +requires-python = ">=3.13" +dependencies = [ + "command_runner>=1.5.0", + "cryptography>=44.0.0", + "discord_webhook>=1.1.0", + "httpx>=0.28.1", + "humanize>=4.6.0", + "loguru>=0.7.3", + "observable>=1.0.3", + "psutil>=6.1.0", + "py_cpuinfo>=9.0.0", + "pywin32>=308", + "requests>=2.31.0", + "setuptools>=75.6.0", + "WMI>=1.5.1", + "Pillow>=11.0.0", +] + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[tool.hatch.build.targets.wheel] +packages = ["pythonprotector"] + +[dependency-groups] +dev = ["black", "autopep8", "autoflake"] \ No newline at end of file diff --git a/pyprotector/abc.py b/pyprotector/abc.py index fc7815b..d3d900e 100644 --- a/pyprotector/abc.py +++ b/pyprotector/abc.py @@ -9,7 +9,6 @@ Made With ❤️ By Ghoul & Marci """ - from abc import ABCMeta, abstractmethod diff --git a/pyprotector/constants.py b/pyprotector/constants.py index 5c527a4..888b441 100644 --- a/pyprotector/constants.py +++ b/pyprotector/constants.py @@ -28,13 +28,8 @@ class UserInfo: USERNAME: Final[str] = os.getlogin() PC_NAME: Final[str] = os.getenv("COMPUTERNAME") IP: Final[str] = getIPAddress() - HWID: Final[str] = ( - subprocess.check_output("wmic csproduct get uuid") - .decode() - .split("\n")[1] - .strip() - ) COMPUTER: Any = wmi.WMI() + HWID: Final[str] = COMPUTER.Win32_ComputerSystemProduct()[0].UUID MAC: Final[str] = ":".join(re.findall("..", "%012x" % uuid.getnode())) GPU: Final[str] = COMPUTER.Win32_VideoController()[0].Name @@ -45,14 +40,15 @@ class LoggingInfo: CIPHER: Fernet = Fernet(KEY) def encrypted_formatter(record) -> str: - encrypted: bytes = LoggingInfo.CIPHER.encrypt(record["message"].encode("utf8")) + encrypted: bytes = LoggingInfo.CIPHER.encrypt( + record["message"].encode("utf8")) record["extra"]["encrypted"] = b64encode(encrypted).decode("latin1") return "[{time:YYYY-MM-DD HH:mm:ss}] {module}::{function}({line}) - {extra[encrypted]}\n{exception}" @final class ProtectorInfo: - VERSION: Final[str] = "1.8" + VERSION: Final[str] = "2.0" ROOT_PATH: str = os.path.abspath(os.curdir) @@ -61,9 +57,9 @@ class EmbedConfig: COLOR: Final[str] = "5865F2" TITLE: Final[str] = f"PythonProtector - {ProtectorInfo.VERSION}" VERSION: Final[str] = ProtectorInfo.VERSION - ICON: Final[ - str - ] = "https://thereisabotforthat-storage.s3.amazonaws.com/1548526271231_security%20bot%20logo.png" + ICON: Final[str] = ( + "https://thereisabotforthat-storage.s3.amazonaws.com/1548526271231_security%20bot%20logo.png" + ) @final diff --git a/pyprotector/keyauth/__init__.py b/pyprotector/keyauth/__init__.py index 0293140..afcbfb3 100644 --- a/pyprotector/keyauth/__init__.py +++ b/pyprotector/keyauth/__init__.py @@ -10,4 +10,4 @@ """ from .utils import * -from .keyauth import Keyauth \ No newline at end of file +from .keyauth import Keyauth diff --git a/pyprotector/keyauth/keyauth.py b/pyprotector/keyauth/keyauth.py index 5e3946d..ed1d79e 100644 --- a/pyprotector/keyauth/keyauth.py +++ b/pyprotector/keyauth/keyauth.py @@ -24,7 +24,12 @@ class Keyauth: def __init__( - self, name: str, ownerid: str, secret: str, version: str, file_hash: Optional[str] = "" + self, + name: str, + ownerid: str, + secret: str, + version: str, + file_hash: Optional[str] = "", ) -> None: self.name: str = name self.ownerid: str = ownerid @@ -78,7 +83,8 @@ def initialize(self) -> Union[bool, KeyauthAppData]: if self.__session_id is not None: raise RuntimeError("This session has already been initialized!") - self._enc_key: str = SHA256.new(str(uuid.uuid4())[:8].encode()).hexdigest() + self._enc_key: str = SHA256.new( + str(uuid.uuid4())[:8].encode()).hexdigest() response: Response = self.__request( self._post_data( @@ -105,8 +111,11 @@ def initialize(self) -> Union[bool, KeyauthAppData]: return (self.initialized, KeyauthAppData(response["appinfo"])) def register( - self, username: str, password: str, license: str, hwid: Optional[str] = None - ) -> KeyauthUser: + self, + username: str, + password: str, + license: str, + hwid: Optional[str] = None) -> KeyauthUser: """Creates user with license key Args: username (str): user's input for username @@ -154,8 +163,11 @@ def upgrade(self, username: str, key: str) -> KeyauthUser: KeyauthUser: Upgraded User """ response: Response = self.__request( - self._post_data(type="upgrade", data={"username": username, "key": key}) - ) + self._post_data( + type="upgrade", + data={ + "username": username, + "key": key})) if not response["success"]: raise RequestError(response["message"]) @@ -184,9 +196,11 @@ def login( response: Response = self.__request( self._post_data( type="login", - data={"username": username, "password": password, "hwid": hwid}, - ) - ) + data={ + "username": username, + "password": password, + "hwid": hwid}, + )) if not response["success"]: raise RequestError(response["message"]) @@ -227,7 +241,8 @@ def getOnlineUsers(self) -> Dict: Returns: Dict: Dictionary of Online Users """ - response: Response = self.__request(self._post_data(type="fetchOnline")) + response: Response = self.__request( + self._post_data(type="fetchOnline")) if not response["success"]: raise RequestError(response["message"]) @@ -248,8 +263,11 @@ def setvar(self, variable: str, data: str) -> None: None """ response: Response = self.__request( - self._post_data(type="setvar", data={"var": variable, "data": data}) - ) + self._post_data( + type="setvar", + data={ + "var": variable, + "data": data})) if not response["success"]: raise RequestError(response["message"]) @@ -417,8 +435,9 @@ def changeUsername(self, username: str) -> bool: bool: If the username has changed or not """ response: Response = self.__request( - self._post_data(type="changeUsername", data={"newUsername": username}) - ) + self._post_data( + type="changeUsername", data={ + "newUsername": username})) if not response["success"]: raise RequestError(response["message"]) @@ -433,8 +452,11 @@ def log(self, user: str, message: str) -> None: message (str): Message """ self.__request( - self._post_data(type="log", data={"user": user, "message": message}) - ) + self._post_data( + type="log", + data={ + "user": user, + "message": message})) def webhook(self, webhook_id: str, params: str) -> None: """Send Webhook diff --git a/pyprotector/keyauth/models.py b/pyprotector/keyauth/models.py index 21bb816..8248267 100644 --- a/pyprotector/keyauth/models.py +++ b/pyprotector/keyauth/models.py @@ -8,6 +8,7 @@ Made With ❤️ By Ghoul & Marci """ + from dataclasses import dataclass from datetime import datetime @@ -27,7 +28,11 @@ def __init__(self, data: dict) -> None: self.onlineUsers: int = data["numOnlineUsers"] def __repr__(self) -> str: - return f"Keyauth App ({self.version}) with {self.users} users, {self.keys} keys and {self.onlineUsers} online users" + return f"Keyauth App ({ + self.version}) with { + self.users} users, { + self.keys} keys and { + self.onlineUsers} online users" class KeyauthUser: @@ -52,9 +57,8 @@ def __init__(self, data: dict) -> None: self.current_subscription: Subscription = Subscription( **data["subscriptions"][0] ) - self.subscriptions: list[Subscription] = [ - Subscription(**subscription) for subscription in data["subscriptions"] - ] + self.subscriptions: list[Subscription] = [Subscription( + **subscription) for subscription in data["subscriptions"]] def __repr__(self) -> str: return self.username @@ -67,9 +71,8 @@ class KeyauthChat: timestamp: str def __post_init__(self) -> None: - self.timestamp = datetime.utcfromtimestamp(int(self.timestamp)).strftime( - "%Y-%m-%d %H:%M:%S" - ) + self.timestamp = datetime.utcfromtimestamp( + int(self.timestamp)).strftime("%Y-%m-%d %H:%M:%S") @dataclass diff --git a/pyprotector/modules/analysis.py b/pyprotector/modules/analysis.py index 3b97f36..3519d53 100644 --- a/pyprotector/modules/analysis.py +++ b/pyprotector/modules/analysis.py @@ -21,8 +21,12 @@ class AntiAnalysis(Module): def __init__( - self, webhook: Webhook, logger: Logger, exit: bool, report: bool, event: Event - ) -> None: + self, + webhook: Webhook, + logger: Logger, + exit: bool, + report: bool, + event: Event) -> None: self.webhook: Webhook = webhook self.logger: Logger = logger self.exit: bool = exit @@ -66,16 +70,18 @@ def CheckDebugPrivilege(self) -> None: self.ntdll.NtClose(hToken) return - debug_privilege = (ctypes.c_int * (return_length.value // 8)).from_buffer( - privileges - ) + debug_privilege = (ctypes.c_int * + (return_length.value // + 8)).from_buffer(privileges) for priv in debug_privilege: if priv.s_luid.LowPart == 21 and priv.s_attributes & 0x00000002: self.ntdll.NtClose(hToken) if self.report: self.webhook.send("Debug Privilege Enabled", self.name) self.event.dispatch( - ["debug_privilege_found", "pyprotector_detect"], "Debug Privilege Enabled", self.name + ["debug_privilege_found", "pyprotector_detect"], + "Debug Privilege Enabled", + self.name, ) if self.exit: os._exit(1) @@ -96,8 +102,9 @@ def HideThreads(self) -> None: return self.ntdll.NtSetInformationThread( - hThread, 0x11, ctypes.byref((ctypes.c_int(1)), ctypes.sizeof(ctypes.c_int)) - ) + hThread, 0x11, ctypes.byref( + (ctypes.c_int(1)), ctypes.sizeof( + ctypes.c_int))) self.kernel32.CloseHandle(hThread) self.kernel32.CloseHandle(hProcess) @@ -156,7 +163,9 @@ def CheckSEDebugName(self) -> None: if self.report: self.webhook.send("Debug Object Handle Detected", self.name) self.event.dispatch( - ["se_debug_name", "pyprotector_detect"], "Debug Object Handle Detected", self.name + ["se_debug_name", "pyprotector_detect"], + "Debug Object Handle Detected", + self.name, ) if self.exit: os._exit((1)) @@ -184,9 +193,7 @@ def CheckNtGlobalFlag(self) -> None: ) if self.report: self.webhook.send( - "NT_GLOBAL_FLAG_DEBUGGED Found in the Process Environment Block", - self.name, - ) + "NT_GLOBAL_FLAG_DEBUGGED Found in the Process Environment Block", self.name, ) self.event.dispatch( ["nt_global_flag_debugged", "pyprotector_detect"], "NT_GLOBAL_FLAG_DEBUGGED Found in the Process Environment Block", @@ -203,7 +210,8 @@ def CheckHardwareBreakpoints(self) -> None: if hThread is None: return - if not self.kernel32.GetThreadContext(hThread, ctypes.byref(ThreadContext)): + if not self.kernel32.GetThreadContext( + hThread, ctypes.byref(ThreadContext)): self.kernel32.CloseHandle(hThread) return diff --git a/pyprotector/modules/dll.py b/pyprotector/modules/dll.py index 1f5e9e6..dedd6fd 100644 --- a/pyprotector/modules/dll.py +++ b/pyprotector/modules/dll.py @@ -24,8 +24,12 @@ class AntiDLL(Module): def __init__( - self, webhook: Webhook, logger: Logger, exit: bool, report: bool, event: Event - ) -> None: + self, + webhook: Webhook, + logger: Logger, + exit: bool, + report: bool, + event: Event) -> None: self.webhook: Webhook = webhook self.logger: Logger = logger self.exit: bool = exit @@ -52,24 +56,25 @@ def BlockDLLs(self) -> None: hProcess: int = win32api.OpenProcess(0x0410, 0, pid) try: curProcessDLLs: tuple = win32process.EnumProcessModules( - hProcess - ) + hProcess) for dll in curProcessDLLs: dllName: str = str( - win32process.GetModuleFileNameEx(hProcess, dll) - ).lower() + win32process.GetModuleFileNameEx( + hProcess, dll)).lower() for sandboxDLL in Lists.BLACKLISTED_DLLS: - if sandboxDLL in dllName and dllName not in EvidenceOfSandbox: # noqa: E501 + if ( + sandboxDLL in dllName + and dllName not in EvidenceOfSandbox + ): # noqa: E501 EvidenceOfSandbox.append(dllName) win32api.CloseHandle(hProcess) - except BaseException: + except BaseException: pass except Exception as e: raise e if EvidenceOfSandbox: self.logger.info( - f"The Following DLL's: {EvidenceOfSandbox} Were Found Loaded" - ) + f"The Following DLL's: {EvidenceOfSandbox} Were Found Loaded") if self.report: self.webhook.send( f"The following DLLs were discovered loaded in processes running on the system. DLLS: {EvidenceOfSandbox}", diff --git a/pyprotector/modules/dump.py b/pyprotector/modules/dump.py index 9b28fbe..74a0e01 100644 --- a/pyprotector/modules/dump.py +++ b/pyprotector/modules/dump.py @@ -8,6 +8,7 @@ Made With ❤️ By Ghoul & Marci """ + import ctypes import win32api @@ -22,8 +23,12 @@ class AntiDump(Module): def __init__( - self, webhook: Webhook, logger: Logger, exit: bool, report: bool, event: Event - ) -> None: + self, + webhook: Webhook, + logger: Logger, + exit: bool, + report: bool, + event: Event) -> None: self.webhook: Webhook = webhook self.logger: Logger = logger self.exit: bool = exit @@ -52,7 +57,10 @@ def ErasePEHeaderFromMemory(self) -> None: self.kernel32.VirtualProtect( ctypes.pointer(baseAddress), 4096, 0x04, ctypes.pointer(oldProtect) ) - ctypes.memset(ctypes.pointer(baseAddress), 4096, ctypes.sizeof(baseAddress)) + ctypes.memset( + ctypes.pointer(baseAddress), + 4096, + ctypes.sizeof(baseAddress)) self.event.dispatch( "pe_header_erased", "PE Header Erased From Memory", self.name ) diff --git a/pyprotector/modules/miscellaneous.py b/pyprotector/modules/miscellaneous.py index 9f96074..c1ec1f1 100644 --- a/pyprotector/modules/miscellaneous.py +++ b/pyprotector/modules/miscellaneous.py @@ -33,8 +33,12 @@ class Miscellaneous(Module): def __init__( - self, webhook: Webhook, logger: Logger, exit: bool, report: bool, event: Event - ) -> None: + self, + webhook: Webhook, + logger: Logger, + exit: bool, + report: bool, + event: Event) -> None: self.webhook: Webhook = webhook self.logger: Logger = logger self.exit: bool = exit @@ -133,8 +137,7 @@ def CheckDiskSize(self) -> None: self.logger.info("Disk Check Failed") if self.report: self.webhook.send( - f"The Current Disk Size Is {diskSizeGB}GB, Which Is Less Than The Minimum" - ) + f"The Current Disk Size Is {diskSizeGB}GB, Which Is Less Than The Minimum") self.event.dispatch( ["disk_size_check", "pyprotector_detect"], f"The Current Disk Size Is {diskSizeGB}GB, Which Is Less Than The Minimum", @@ -150,7 +153,8 @@ def KillTasks(self) -> None: os.system("taskkill /f /im HTTPDebuggerSvc.exe >nul 2>&1") os.system('taskkill /FI "IMAGENAME eq cheatengine*" /IM * /F /T >nul 2>&1') os.system('taskkill /FI "IMAGENAME eq httpdebugger*" /IM * /F /T >nul 2>&1') - os.system('taskkill /FI "IMAGENAME eq processhacker*" /IM * /F /T >nul 2>&1') + os.system( + 'taskkill /FI "IMAGENAME eq processhacker*" /IM * /F /T >nul 2>&1') os.system('taskkill /FI "IMAGENAME eq fiddler*" /IM * /F /T >nul 2>&1') os.system('taskkill /FI "IMAGENAME eq wireshark*" /IM * /F /T >nul 2>&1') os.system('taskkill /FI "IMAGENAME eq rawshark*" /IM * /F /T >nul 2>&1') @@ -158,7 +162,8 @@ def KillTasks(self) -> None: os.system('taskkill /FI "IMAGENAME eq cheatengine*" /IM * /F /T >nul 2>&1') os.system('taskkill /FI "IMAGENAME eq ida*" /IM * /F /T >nul 2>&1') os.system('taskkill /FI "IMAGENAME eq httpdebugger*" /IM * /F /T >nul 2>&1') - os.system('taskkill /FI "IMAGENAME eq processhacker*" /IM * /F /T >nul 2>&1') + os.system( + 'taskkill /FI "IMAGENAME eq processhacker*" /IM * /F /T >nul 2>&1') os.system("sc stop HTTPDebuggerPro >nul 2>&1") os.system("sc stop KProcessHacker3 >nul 2>&1") os.system("sc stop KProcessHacker2 >nul 2>&1") @@ -222,7 +227,8 @@ def CheckOutPutDebugString(self) -> None: if win32api.GetLastError() != 0: self.logger.info("OutputDebugString Is Not 0") if self.report: - self.webhook.send("OutputDebugString Not Equal To 0", self.name) + self.webhook.send( + "OutputDebugString Not Equal To 0", self.name) self.event.dispatch( ["output_debug_string", "pyprotector_detect"], "OutputDebugString Not Equal To 0", @@ -250,7 +256,7 @@ def CheckIPs(self) -> None: os._exit(1) else: pass - + @lru_cache def CheckCPUCores(self) -> None: """Checks CPU Core Count For Being Less Than 1""" @@ -267,7 +273,7 @@ def CheckCPUCores(self) -> None: ) if self.exit: os._exit(1) - + def IsUsingProxy(self) -> None: """Checks If Proxies Are In Use""" headers: dict[str, str] = {"User-Agent": "Mozilla/5.0"} @@ -303,7 +309,8 @@ def IsUsingProxy(self) -> None: _socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) _socket.settimeout(5) _socket.connect(("check.torproject.org", 9050)) - _socket.send(b"GET / HTTP/1.1\r\nHost: check.torproject.org\r\n\r\n") + _socket.send( + b"GET / HTTP/1.1\r\nHost: check.torproject.org\r\n\r\n") data: bytes = _socket.recv(1024) if "Congratulations" in data.decode(): self.logger.info("Tor Network Detected") @@ -324,7 +331,8 @@ def IsUsingProxy(self) -> None: if IP >> 24 in [0, 10, 100, 127, 169, 172, 192]: self.logger.info("Transparent Proxies Detected") if self.report: - self.webhook.send("Transparent Proxies Detected", self.name) + self.webhook.send( + "Transparent Proxies Detected", self.name) self.event.dispatch( ["transparent_proxies", "pyprotector_detect"], "Transparent Proxies Detected", diff --git a/pyprotector/modules/process.py b/pyprotector/modules/process.py index a5eebd8..0d7a806 100644 --- a/pyprotector/modules/process.py +++ b/pyprotector/modules/process.py @@ -26,8 +26,12 @@ class AntiProcess(Module): def __init__( - self, webhook: Webhook, logger: Logger, exit: bool, report: bool, event: Event - ) -> None: + self, + webhook: Webhook, + logger: Logger, + exit: bool, + report: bool, + event: Event) -> None: self.webhook: Webhook = webhook self.logger: Logger = logger self.exit: bool = exit @@ -56,7 +60,8 @@ def CheckProcessList(self) -> None: ): try: if self.report: - self.logger.info(f"{process.name} Process Was Running") + self.logger.info( + f"{process.name} Process Was Running") self.webhook.send( f"`{process.name()}` was detected running on the system.", self.name, @@ -97,8 +102,9 @@ def winEnumHandler(hwnd, ctx) -> None: self.logger.info(f"{win32gui.GetWindowText(hwnd)} Found") if self.report: self.webhook.send( - f"Debugger {win32gui.GetWindowText(hwnd)}", self.name - ) + f"Debugger { + win32gui.GetWindowText(hwnd)}", + self.name) self.event.dispatch( ["window_name_detected", "pyprotector_detect"], f"Debugger {win32gui.GetWindowText(hwnd)} Found Open", diff --git a/pyprotector/modules/vm.py b/pyprotector/modules/vm.py index 00a5be0..09dc0c9 100644 --- a/pyprotector/modules/vm.py +++ b/pyprotector/modules/vm.py @@ -26,15 +26,20 @@ class AntiVM(Module): def __init__( - self, webhook: Webhook, logger: Logger, exit: bool, report: bool, event: Event - ) -> None: + self, + webhook: Webhook, + logger: Logger, + exit: bool, + report: bool, + event: Event) -> None: self.webhook: Webhook = webhook self.logger: Logger = logger self.exit: bool = exit self.report: bool = report self.event: Event = event - self.VMWARE_MACS: List[str] = ["00:05:69", "00:0c:29", "00:1c:14", "00:50:56"] + self.VMWARE_MACS: List[str] = [ + "00:05:69", "00:0c:29", "00:1c:14", "00:50:56"] self.HWIDS: List[str] = httpx.get( "https://raw.githubusercontent.com/xFGhoul/PythonProtector/dev/data/hwid_list.txt" @@ -79,7 +84,9 @@ def CheckLists(self) -> None: Checks if the user's HWID, PC username, PC name, IP, MAC address, or GPU is in the blacklists. """ if UserInfo.HWID in self.HWIDS: - self.logger.info(f"Blacklisted HWID Detected. HWID: {UserInfo.HWID}") + self.logger.info( + f"Blacklisted HWID Detected. HWID: { + UserInfo.HWID}") if self.report: self.webhook.send( f"Blacklisted HWID Detected: `{UserInfo.HWID}`", self.name @@ -126,7 +133,9 @@ def CheckLists(self) -> None: if UserInfo.IP in self.IPS: self.logger.info(f"Blacklisted IP: {UserInfo.IP}") if self.report: - self.webhook.send(f"Blacklisted IP: `{UserInfo.IP}`", self.name) + self.webhook.send( + f"Blacklisted IP: `{ + UserInfo.IP}`", self.name) self.event.dispatch( ["blacklisted_ip", "pyprotector_detect"], "Blacklisted IP Detected", @@ -139,7 +148,9 @@ def CheckLists(self) -> None: if UserInfo.MAC in self.MACS: self.logger.info(f"Blacklisted MAC: {UserInfo.MAC}") if self.report: - self.webhook.send(f"Blacklisted MAC: `{UserInfo.MAC}`", self.name) + self.webhook.send( + f"Blacklisted MAC: `{ + UserInfo.MAC}`", self.name) self.event.dispatch( ["blacklisted_mac_address", "pyprotector_detect"], "Blacklisted MAC Detected", @@ -152,7 +163,9 @@ def CheckLists(self) -> None: if UserInfo.GPU in self.GPUS: self.logger.info(f"Blacklisted GPU: {UserInfo.GPU}") if self.report: - self.webhook.send(f"Blacklisted GPU: `{UserInfo.GPU}`", self.name) + self.webhook.send( + f"Blacklisted GPU: `{ + UserInfo.GPU}`", self.name) self.event.dispatch( ["blacklisted_gpu", "pyprotector_detect"], "Blacklisted GPU Detected", @@ -223,7 +236,8 @@ def CheckScreenSize(self) -> None: if x <= 200 or y <= 200: self.logger.info(f"Screen Size X: {x} | Y: {y}") if self.report: - self.webhook.send(f"Screen Size Is: **x**: {x} | **y**: {y}", self.name) + self.webhook.send( + f"Screen Size Is: **x**: {x} | **y**: {y}", self.name) self.event.dispatch( ["screen_size", "pyprotector_detect"], f"Screen Size X: {x} | Y: {y}", @@ -241,7 +255,8 @@ def CheckProcessesAndFiles(self) -> None: vmware_dll: str = os.path.join( os.environ["SystemRoot"], "System32\\vmGuestLib.dll" ) - virtualbox_dll: str = os.path.join(os.environ["SystemRoot"], "vboxmrxnp.dll") + virtualbox_dll: str = os.path.join( + os.environ["SystemRoot"], "vboxmrxnp.dll") process: str = os.popen( 'TASKLIST /FI "STATUS eq RUNNING" | find /V "Image Name" | find /V "="' @@ -250,7 +265,12 @@ def CheckProcessesAndFiles(self) -> None: for processNames in process.split(" "): if ".exe" in processNames: - processList.append(processNames.replace("K\n", "").replace("\n", "")) + processList.append( + processNames.replace( + "K\n", + "").replace( + "\n", + "")) if any(Lists.VIRTUAL_MACHINE_PROCESSES) in processList: self.logger.info("Blacklisted Virtual Machine Process Running") diff --git a/pyprotector/protector.py b/pyprotector/protector.py index 5ebd336..83475b9 100644 --- a/pyprotector/protector.py +++ b/pyprotector/protector.py @@ -83,7 +83,8 @@ def __init__( raise LogsPathEmpty("Debug Enabled But No Log Path Was Provided.") if self.logs_path and not self.debug: - raise RuntimeWarning("Logs Path Was Provided But Debug Was Disabled.") + raise RuntimeWarning( + "Logs Path Was Provided But Debug Was Disabled.") if self.debug and self.logs_path: LOGGING_CONFIG: Dict = { @@ -115,7 +116,8 @@ def __init__( self.webhook_url: str = webhook_url if self.report and self.webhook_url is None: - raise RuntimeWarning("Reporting Was Set But No Webhook URL Was Provided.") + raise RuntimeWarning( + "Reporting Was Set But No Webhook URL Was Provided.") self.webhook: Webhook = Webhook( self.webhook_url, self.logs_path, self.screenshot @@ -194,32 +196,32 @@ def _run_module_threads(self, debug: bool) -> None: if debug: if "Miscellaneous" in self.modules: self.logger.info("Starting Miscellaneous Thread") - Thread( - name=self.Miscellaneous.name, target=self.Miscellaneous.StartChecks - ).start() + Thread(name=self.Miscellaneous.name, + target=self.Miscellaneous.StartChecks).start() self.logger.info("Miscellaneous Thread Started") if "AntiProcess" in self.modules: self.logger.info("Starting Anti Process Thread") - Thread( - name="Anti Process List", target=self.AntiProcess.CheckProcessList - ).start() - Thread( - name="Anti Window Names", target=self.AntiProcess.CheckWindowNames - ).start() + Thread(name="Anti Process List", + target=self.AntiProcess.CheckProcessList).start() + Thread(name="Anti Window Names", + target=self.AntiProcess.CheckWindowNames).start() self.logger.info("Anti Process Thread Started") if "AntiDLL" in self.modules: self.logger.info("Starting Anti DLL Thread") - Thread(name=self.AntiDLL.name, target=self.AntiDLL.BlockDLLs).start() + Thread( + name=self.AntiDLL.name, + target=self.AntiDLL.BlockDLLs).start() self.logger.info("Anti DLL Thread Started") if "AntiVM" in self.modules: self.logger.info("Starting Anti VM Thread") - Thread(name=self.AntiVM.name, target=self.AntiVM.StartChecks).start() + Thread( + name=self.AntiVM.name, + target=self.AntiVM.StartChecks).start() self.logger.info("Anti VM Thread Started") if "AntiAnalysis" in self.modules: self.logger.info("Starting Anti Analysis Thread") - Thread( - name=self.AntiAnalysis.name, target=self.AntiAnalysis.StartAnalyzing - ).start() + Thread(name=self.AntiAnalysis.name, + target=self.AntiAnalysis.StartAnalyzing).start() self.logger.info("Anti Analysis Thread Started") if "AntiDump" in self.modules: self.logger.info("Starting Anti Dump Thread") @@ -229,37 +231,41 @@ def _run_module_threads(self, debug: bool) -> None: self.logger.info("Started Anti Dump Thread") else: if "Miscellaneous" in self.modules: - Thread( - name=self.Miscellaneous.name, target=self.Miscellaneous.StartChecks - ).start() + Thread(name=self.Miscellaneous.name, + target=self.Miscellaneous.StartChecks).start() if "AntiProcess" in self.modules: - Thread( - name="Anti Process List", target=self.AntiProcess.CheckProcessList - ).start() - Thread( - name="Anti Window Names", target=self.AntiProcess.CheckWindowNames - ).start() + Thread(name="Anti Process List", + target=self.AntiProcess.CheckProcessList).start() + Thread(name="Anti Window Names", + target=self.AntiProcess.CheckWindowNames).start() if "AntiDLL" in self.modules: - Thread(name=self.AntiDLL.name, target=self.AntiDLL.BlockDLLs).start() + Thread( + name=self.AntiDLL.name, + target=self.AntiDLL.BlockDLLs).start() if "AntiVM" in self.modules: - Thread(name=self.AntiVM.name, target=self.AntiVM.StartChecks).start() - if "AntiAnalysis" in self.modules: Thread( - name=self.AntiAnalysis.name, target=self.AntiAnalysis.StartAnalyzing - ).start() + name=self.AntiVM.name, + target=self.AntiVM.StartChecks).start() + if "AntiAnalysis" in self.modules: + Thread(name=self.AntiAnalysis.name, + target=self.AntiAnalysis.StartAnalyzing).start() if "AntiDump" in self.modules: Thread( name=self.AntiDump.name, target=self.AntiDump.StartChecks ).start() - + def _run_debug_module_threads(self): self.logger.info("PythonProtector Starting") self.logger.info(f"Version: {ProtectorInfo.VERSION}") self.logger.info(f"Current Path: {ProtectorInfo.ROOT_PATH}") self.logger.info( - f"Operating System: {platform.uname().system} {platform.uname().release} {platform.win32_edition()} ({platform.architecture(sys.executable)[0]})" - ) + f"Operating System: { + platform.uname().system} { + platform.uname().release} { + platform.win32_edition()} ({ + platform.architecture( + sys.executable)[0]})") bt = datetime.datetime.fromtimestamp(psutil.boot_time()) self.logger.info( f"Boot Time: {bt.year}/{bt.month}/{bt.day} {bt.hour}:{bt.minute}:{bt.second}" @@ -278,8 +284,9 @@ def _run_debug_module_threads(self): self.logger.info(f"Total Memory: {humanize.naturalsize(vmem.total)}") self.logger.info( - f"Memory Availability: {humanize.naturalsize(vmem.available)}" - ) + f"Memory Availability: { + humanize.naturalsize( + vmem.available)}") self.logger.info(f"Memory Percentage: {vmem.percent}%") self.logger.info("Starting PythonProtector Services") @@ -290,14 +297,14 @@ def start(self) -> None: """Main Function Of PythonProtector Raises: - DeprecationWarning: If Python Version < 3.11 + DeprecationWarning: If Python Version < 3.12 """ # -- Check If Windows Platform if sys.platform != "win32": os._exit(1) - if platform.python_version_tuple()[1] < "11": - raise DeprecationWarning("Python Is Not 3.11+") + if platform.python_version_tuple()[1] < "12": + raise DeprecationWarning("Python Is Not 3.12+") # -- Start Main Program if self.debug: diff --git a/pyprotector/types.py b/pyprotector/types.py index 2e2f907..f1331cf 100644 --- a/pyprotector/types.py +++ b/pyprotector/types.py @@ -8,6 +8,7 @@ Made With ❤️ By Ghoul & Marci """ + from typing import Type from pyprotector.utils.events import ProtectorObservable diff --git a/pyprotector/utils/events.py b/pyprotector/utils/events.py index 5a2700e..9327b31 100644 --- a/pyprotector/utils/events.py +++ b/pyprotector/utils/events.py @@ -12,11 +12,17 @@ from observable import Observable from typing import List + class ProtectorObservable: def __init__(self) -> None: self.obs: Observable = Observable() - def dispatch(self, events: List[str], text: str, module: str, **kwargs) -> None: + def dispatch( + self, + events: List[str], + text: str, + module: str, + **kwargs) -> None: """ It triggers an event. @@ -29,4 +35,4 @@ def dispatch(self, events: List[str], text: str, module: str, **kwargs) -> None: None """ for event in events: - self.obs.trigger(event, text, module, **kwargs) + self.obs.trigger(event, text, module, **kwargs) diff --git a/pyprotector/utils/webhook.py b/pyprotector/utils/webhook.py index 32852ff..3240c2b 100644 --- a/pyprotector/utils/webhook.py +++ b/pyprotector/utils/webhook.py @@ -8,6 +8,7 @@ Made With ❤️ By Ghoul & Marci """ + import io from io import BytesIO @@ -23,8 +24,10 @@ class Webhook: def __init__( - self, webhook_url: str, logs_path: Optional[str], screenshot: Optional[bool] - ) -> None: + self, + webhook_url: str, + logs_path: Optional[str], + screenshot: Optional[bool]) -> None: self.webhook_url: str = webhook_url self.logs_path: str = logs_path self.screenshot: bool = screenshot @@ -37,8 +40,10 @@ def TakeScreenshot(self) -> bytes: A byte array of the screenshot. """ screenshot: Image = ImageGrab.grab( - bbox=None, include_layered_windows=False, all_screens=True, xdisplay=None - ) + bbox=None, + include_layered_windows=False, + all_screens=True, + xdisplay=None) screenshot_bytes_array: BytesIO = io.BytesIO() screenshot.save(screenshot_bytes_array, format="PNG") @@ -59,7 +64,8 @@ def DecryptLogs(self) -> bytes: if not line.strip(): continue encrypted_message: str = line.split(" ")[4] - encoded_message: bytes = b64decode(encrypted_message.encode("latin1")) + encoded_message: bytes = b64decode( + encrypted_message.encode("latin1")) decrypted_message: str = LoggingInfo.CIPHER.decrypt( encoded_message ).decode("utf-8") @@ -81,18 +87,23 @@ def send(self, content: str, module: str) -> None: ) webhook.add_file( - file=self.DecryptLogs(), filename=f"{UserInfo.USERNAME}-[Security].log" - ) + file=self.DecryptLogs(), filename=f"{ + UserInfo.USERNAME}-[Security].log") embed: DiscordEmbed = DiscordEmbed( title=EmbedConfig.TITLE, color=EmbedConfig.COLOR ) if self.screenshot: - webhook.add_file(file=self.TakeScreenshot(), filename="screenshot.jpg") + webhook.add_file( + file=self.TakeScreenshot(), + filename="screenshot.jpg") embed.set_image(url="attachment://screenshot.jpg") - embed.add_embed_field(name="User", value=UserInfo.USERNAME, inline=True) + embed.add_embed_field( + name="User", + value=UserInfo.USERNAME, + inline=True) embed.add_embed_field(name="IP", value=UserInfo.IP, inline=True) embed.add_embed_field(name="Module", value=module, inline=True) @@ -101,8 +112,9 @@ def send(self, content: str, module: str) -> None: embed.set_thumbnail(url=EmbedConfig.ICON) embed.set_footer( - text=f"PythonProtector | {EmbedConfig.VERSION}", icon_url=EmbedConfig.ICON - ) + text=f"PythonProtector | { + EmbedConfig.VERSION}", + icon_url=EmbedConfig.ICON) webhook.add_embed(embed) diff --git a/scripts/format.bat b/scripts/format.bat new file mode 100644 index 0000000..5994bce --- /dev/null +++ b/scripts/format.bat @@ -0,0 +1,8 @@ +cd .. + +black -v . + +autopep8 --in-place --aggressive --aggressive --recursive -v . + + +autoflake --in-place --remove-unused-variables . diff --git a/scripts/format.sh b/scripts/format_linux.sh similarity index 100% rename from scripts/format.sh rename to scripts/format_linux.sh diff --git a/setup.py b/setup.py deleted file mode 100644 index fc9cc4f..0000000 --- a/setup.py +++ /dev/null @@ -1,78 +0,0 @@ -""" - ____ ____ __ __ - / __ \\ __ __ / __ \\ _____ ____ / /_ ___ _____ / /_ - / /_/ // / / // /_/ // ___// __ \\ / __// _ \\ / ___// __/ - / ____// /_/ // ____// / / /_/ // /_ / __// /__ / /_ -/_/ \\__, //_/ /_/ \\____/ \\__/ \\___/ \\___/ \\__/ - /____/ - -Made With ❤️ By Ghoul & Marci -""" - -from setuptools import setup - -with open("README.md", encoding="utf8") as readme_file: - README = readme_file.read() - -with open("HISTORY.md") as history_file: - HISTORY = history_file.read() - -setup( - name="PythonProtector", - packages=[ - "pyprotector", - "pyprotector.utils", - "pyprotector.modules", - "pyprotector.keyauth", - ], - version="1.8", - license="MIT", - description="Library for protecting your python files", - author="Ghoul & Marci", - url="https://github.com/xFGhoul/PythonProtecttor", - long_description_content_type="text/markdown", - long_description=README + "\n\n" + HISTORY, - python_requires=">=3.11", - project_urls={ - "Homepage": "http://ghouldev.me/PythonProtector/", - "Source": "https://github.com/xFGhoul/PythonProtector", - }, - keywords=[ - "keyauth", - "protection", - "protect", - "obfuscate", - "obfuscation", - "WMI", - "windows", - ], - install_requires=[ - "humanize", - "loguru", - "discord-webhook", - "py-cpuinfo", - "command_runner", - "psutil", - "httpx", - "WMI", - "pywin32", - "Pillow", - "observable", - "cryptography", - ], - extras_require={"Keyauth": ["pycryptodome"]}, - classifiers=[ - "Development Status :: 3 - Alpha", - "Intended Audience :: Developers", - "Operating System :: Microsoft :: Windows :: Windows 10", - "Operating System :: Microsoft :: Windows :: Windows 11", - "Natural Language :: English", - "Topic :: Internet", - "Topic :: Software Development :: Libraries", - "Topic :: Software Development :: Libraries :: Python Modules", - "Topic :: Utilities", - "License :: OSI Approved :: MIT License", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.11", - ], -) diff --git a/uv.lock b/uv.lock new file mode 100644 index 0000000..35e9700 --- /dev/null +++ b/uv.lock @@ -0,0 +1,505 @@ +version = 1 +requires-python = ">=3.13" + +[[package]] +name = "anyio" +version = "4.8.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "idna" }, + { name = "sniffio" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a3/73/199a98fc2dae33535d6b8e8e6ec01f8c1d76c9adb096c6b7d64823038cde/anyio-4.8.0.tar.gz", hash = "sha256:1d9fe889df5212298c0c0723fa20479d1b94883a2df44bd3897aa91083316f7a", size = 181126 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/46/eb/e7f063ad1fec6b3178a3cd82d1a3c4de82cccf283fc42746168188e1cdd5/anyio-4.8.0-py3-none-any.whl", hash = "sha256:b5011f270ab5eb0abf13385f851315585cc37ef330dd88e27ec3d34d651fd47a", size = 96041 }, +] + +[[package]] +name = "autoflake" +version = "2.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pyflakes" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2a/cb/486f912d6171bc5748c311a2984a301f4e2d054833a1da78485866c71522/autoflake-2.3.1.tar.gz", hash = "sha256:c98b75dc5b0a86459c4f01a1d32ac7eb4338ec4317a4469515ff1e687ecd909e", size = 27642 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a2/ee/3fd29bf416eb4f1c5579cf12bf393ae954099258abd7bde03c4f9716ef6b/autoflake-2.3.1-py3-none-any.whl", hash = "sha256:3ae7495db9084b7b32818b4140e6dc4fc280b712fb414f5b8fe57b0a8e85a840", size = 32483 }, +] + +[[package]] +name = "autopep8" +version = "2.3.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pycodestyle" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/50/d8/30873d2b7b57dee9263e53d142da044c4600a46f2d28374b3e38b023df16/autopep8-2.3.2.tar.gz", hash = "sha256:89440a4f969197b69a995e4ce0661b031f455a9f776d2c5ba3dbd83466931758", size = 92210 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/43/53afb8ba17218f19b77c7834128566c5bbb100a0ad9ba2e8e89d089d7079/autopep8-2.3.2-py2.py3-none-any.whl", hash = "sha256:ce8ad498672c845a0c3de2629c15b635ec2b05ef8177a6e7c91c74f3e9b51128", size = 45807 }, +] + +[[package]] +name = "black" +version = "24.10.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "mypy-extensions" }, + { name = "packaging" }, + { name = "pathspec" }, + { name = "platformdirs" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d8/0d/cc2fb42b8c50d80143221515dd7e4766995bd07c56c9a3ed30baf080b6dc/black-24.10.0.tar.gz", hash = "sha256:846ea64c97afe3bc677b761787993be4991810ecc7a4a937816dd6bddedc4875", size = 645813 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d0/a0/a993f58d4ecfba035e61fca4e9f64a2ecae838fc9f33ab798c62173ed75c/black-24.10.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1cbacacb19e922a1d75ef2b6ccaefcd6e93a2c05ede32f06a21386a04cedb981", size = 1643986 }, + { url = "https://files.pythonhosted.org/packages/37/d5/602d0ef5dfcace3fb4f79c436762f130abd9ee8d950fa2abdbf8bbc555e0/black-24.10.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1f93102e0c5bb3907451063e08b9876dbeac810e7da5a8bfb7aeb5a9ef89066b", size = 1448085 }, + { url = "https://files.pythonhosted.org/packages/47/6d/a3a239e938960df1a662b93d6230d4f3e9b4a22982d060fc38c42f45a56b/black-24.10.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ddacb691cdcdf77b96f549cf9591701d8db36b2f19519373d60d31746068dbf2", size = 1760928 }, + { url = "https://files.pythonhosted.org/packages/dd/cf/af018e13b0eddfb434df4d9cd1b2b7892bab119f7a20123e93f6910982e8/black-24.10.0-cp313-cp313-win_amd64.whl", hash = "sha256:680359d932801c76d2e9c9068d05c6b107f2584b2a5b88831c83962eb9984c1b", size = 1436875 }, + { url = "https://files.pythonhosted.org/packages/8d/a7/4b27c50537ebca8bec139b872861f9d2bf501c5ec51fcf897cb924d9e264/black-24.10.0-py3-none-any.whl", hash = "sha256:3bb2b7a1f7b685f85b11fed1ef10f8a9148bceb49853e47a294a3dd963c1dd7d", size = 206898 }, +] + +[[package]] +name = "certifi" +version = "2024.12.14" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0f/bd/1d41ee578ce09523c81a15426705dd20969f5abf006d1afe8aeff0dd776a/certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db", size = 166010 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a5/32/8f6669fc4798494966bf446c8c4a162e0b5d893dff088afddf76414f70e1/certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56", size = 164927 }, +] + +[[package]] +name = "cffi" +version = "1.17.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pycparser" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fc/97/c783634659c2920c3fc70419e3af40972dbaf758daa229a7d6ea6135c90d/cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824", size = 516621 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8d/f8/dd6c246b148639254dad4d6803eb6a54e8c85c6e11ec9df2cffa87571dbe/cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e", size = 182989 }, + { url = "https://files.pythonhosted.org/packages/8b/f1/672d303ddf17c24fc83afd712316fda78dc6fce1cd53011b839483e1ecc8/cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2", size = 178802 }, + { url = "https://files.pythonhosted.org/packages/0e/2d/eab2e858a91fdff70533cab61dcff4a1f55ec60425832ddfdc9cd36bc8af/cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3", size = 454792 }, + { url = "https://files.pythonhosted.org/packages/75/b2/fbaec7c4455c604e29388d55599b99ebcc250a60050610fadde58932b7ee/cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683", size = 478893 }, + { url = "https://files.pythonhosted.org/packages/4f/b7/6e4a2162178bf1935c336d4da8a9352cccab4d3a5d7914065490f08c0690/cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5", size = 485810 }, + { url = "https://files.pythonhosted.org/packages/c7/8a/1d0e4a9c26e54746dc08c2c6c037889124d4f59dffd853a659fa545f1b40/cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4", size = 471200 }, + { url = "https://files.pythonhosted.org/packages/26/9f/1aab65a6c0db35f43c4d1b4f580e8df53914310afc10ae0397d29d697af4/cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd", size = 479447 }, + { url = "https://files.pythonhosted.org/packages/5f/e4/fb8b3dd8dc0e98edf1135ff067ae070bb32ef9d509d6cb0f538cd6f7483f/cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed", size = 484358 }, + { url = "https://files.pythonhosted.org/packages/f1/47/d7145bf2dc04684935d57d67dff9d6d795b2ba2796806bb109864be3a151/cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9", size = 488469 }, + { url = "https://files.pythonhosted.org/packages/bf/ee/f94057fa6426481d663b88637a9a10e859e492c73d0384514a17d78ee205/cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d", size = 172475 }, + { url = "https://files.pythonhosted.org/packages/7c/fc/6a8cb64e5f0324877d503c854da15d76c1e50eb722e320b15345c4d0c6de/cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a", size = 182009 }, +] + +[[package]] +name = "charset-normalizer" +version = "3.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/16/b0/572805e227f01586461c80e0fd25d65a2115599cc9dad142fee4b747c357/charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3", size = 123188 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/38/94/ce8e6f63d18049672c76d07d119304e1e2d7c6098f0841b51c666e9f44a0/charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda", size = 195698 }, + { url = "https://files.pythonhosted.org/packages/24/2e/dfdd9770664aae179a96561cc6952ff08f9a8cd09a908f259a9dfa063568/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313", size = 140162 }, + { url = "https://files.pythonhosted.org/packages/24/4e/f646b9093cff8fc86f2d60af2de4dc17c759de9d554f130b140ea4738ca6/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9", size = 150263 }, + { url = "https://files.pythonhosted.org/packages/5e/67/2937f8d548c3ef6e2f9aab0f6e21001056f692d43282b165e7c56023e6dd/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b", size = 142966 }, + { url = "https://files.pythonhosted.org/packages/52/ed/b7f4f07de100bdb95c1756d3a4d17b90c1a3c53715c1a476f8738058e0fa/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11", size = 144992 }, + { url = "https://files.pythonhosted.org/packages/96/2c/d49710a6dbcd3776265f4c923bb73ebe83933dfbaa841c5da850fe0fd20b/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f", size = 147162 }, + { url = "https://files.pythonhosted.org/packages/b4/41/35ff1f9a6bd380303dea55e44c4933b4cc3c4850988927d4082ada230273/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd", size = 140972 }, + { url = "https://files.pythonhosted.org/packages/fb/43/c6a0b685fe6910d08ba971f62cd9c3e862a85770395ba5d9cad4fede33ab/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2", size = 149095 }, + { url = "https://files.pythonhosted.org/packages/4c/ff/a9a504662452e2d2878512115638966e75633519ec11f25fca3d2049a94a/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886", size = 152668 }, + { url = "https://files.pythonhosted.org/packages/6c/71/189996b6d9a4b932564701628af5cee6716733e9165af1d5e1b285c530ed/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601", size = 150073 }, + { url = "https://files.pythonhosted.org/packages/e4/93/946a86ce20790e11312c87c75ba68d5f6ad2208cfb52b2d6a2c32840d922/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd", size = 145732 }, + { url = "https://files.pythonhosted.org/packages/cd/e5/131d2fb1b0dddafc37be4f3a2fa79aa4c037368be9423061dccadfd90091/charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407", size = 95391 }, + { url = "https://files.pythonhosted.org/packages/27/f2/4f9a69cc7712b9b5ad8fdb87039fd89abba997ad5cbe690d1835d40405b0/charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971", size = 102702 }, + { url = "https://files.pythonhosted.org/packages/0e/f6/65ecc6878a89bb1c23a086ea335ad4bf21a588990c3f535a227b9eea9108/charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85", size = 49767 }, +] + +[[package]] +name = "click" +version = "8.1.8" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b9/2e/0090cbf739cee7d23781ad4b89a9894a41538e4fcf4c31dcdd705b78eb8b/click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a", size = 226593 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/d4/7ebdbd03970677812aac39c869717059dbb71a4cfc033ca6e5221787892c/click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2", size = 98188 }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 }, +] + +[[package]] +name = "command-runner" +version = "1.7.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "psutil" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ab/87/5588affc95b158ef639428122c990163fa5201cc0d473af788dd82af38f6/command_runner-1.7.0.tar.gz", hash = "sha256:0e37ab943ea577ac7fb55c5b1528bdb8339cc8b4ade71d48aac209da3b7d1f48", size = 39372 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/11/65/3f68702725baf23e03a39f881444caee854979cfb8e63461486892d58db1/command_runner-1.7.0-py3-none-any.whl", hash = "sha256:cd48c701273fa4871abd368da01f458b54923a951896d4da112d046767633570", size = 25356 }, +] + +[[package]] +name = "cryptography" +version = "44.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cffi", marker = "platform_python_implementation != 'PyPy'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/91/4c/45dfa6829acffa344e3967d6006ee4ae8be57af746ae2eba1c431949b32c/cryptography-44.0.0.tar.gz", hash = "sha256:cd4e834f340b4293430701e772ec543b0fbe6c2dea510a5286fe0acabe153a02", size = 710657 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/55/09/8cc67f9b84730ad330b3b72cf867150744bf07ff113cda21a15a1c6d2c7c/cryptography-44.0.0-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:84111ad4ff3f6253820e6d3e58be2cc2a00adb29335d4cacb5ab4d4d34f2a123", size = 6541833 }, + { url = "https://files.pythonhosted.org/packages/7e/5b/3759e30a103144e29632e7cb72aec28cedc79e514b2ea8896bb17163c19b/cryptography-44.0.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b15492a11f9e1b62ba9d73c210e2416724633167de94607ec6069ef724fad092", size = 3922710 }, + { url = "https://files.pythonhosted.org/packages/5f/58/3b14bf39f1a0cfd679e753e8647ada56cddbf5acebffe7db90e184c76168/cryptography-44.0.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:831c3c4d0774e488fdc83a1923b49b9957d33287de923d58ebd3cec47a0ae43f", size = 4137546 }, + { url = "https://files.pythonhosted.org/packages/98/65/13d9e76ca19b0ba5603d71ac8424b5694415b348e719db277b5edc985ff5/cryptography-44.0.0-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:761817a3377ef15ac23cd7834715081791d4ec77f9297ee694ca1ee9c2c7e5eb", size = 3915420 }, + { url = "https://files.pythonhosted.org/packages/b1/07/40fe09ce96b91fc9276a9ad272832ead0fddedcba87f1190372af8e3039c/cryptography-44.0.0-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:3c672a53c0fb4725a29c303be906d3c1fa99c32f58abe008a82705f9ee96f40b", size = 4154498 }, + { url = "https://files.pythonhosted.org/packages/75/ea/af65619c800ec0a7e4034207aec543acdf248d9bffba0533342d1bd435e1/cryptography-44.0.0-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:4ac4c9f37eba52cb6fbeaf5b59c152ea976726b865bd4cf87883a7e7006cc543", size = 3932569 }, + { url = "https://files.pythonhosted.org/packages/c7/af/d1deb0c04d59612e3d5e54203159e284d3e7a6921e565bb0eeb6269bdd8a/cryptography-44.0.0-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ed3534eb1090483c96178fcb0f8893719d96d5274dfde98aa6add34614e97c8e", size = 4016721 }, + { url = "https://files.pythonhosted.org/packages/bd/69/7ca326c55698d0688db867795134bdfac87136b80ef373aaa42b225d6dd5/cryptography-44.0.0-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:f3f6fdfa89ee2d9d496e2c087cebef9d4fcbb0ad63c40e821b39f74bf48d9c5e", size = 4240915 }, + { url = "https://files.pythonhosted.org/packages/ef/d4/cae11bf68c0f981e0413906c6dd03ae7fa864347ed5fac40021df1ef467c/cryptography-44.0.0-cp37-abi3-win32.whl", hash = "sha256:eb33480f1bad5b78233b0ad3e1b0be21e8ef1da745d8d2aecbb20671658b9053", size = 2757925 }, + { url = "https://files.pythonhosted.org/packages/64/b1/50d7739254d2002acae64eed4fc43b24ac0cc44bf0a0d388d1ca06ec5bb1/cryptography-44.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:abc998e0c0eee3c8a1904221d3f67dcfa76422b23620173e28c11d3e626c21bd", size = 3202055 }, + { url = "https://files.pythonhosted.org/packages/11/18/61e52a3d28fc1514a43b0ac291177acd1b4de00e9301aaf7ef867076ff8a/cryptography-44.0.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:660cb7312a08bc38be15b696462fa7cc7cd85c3ed9c576e81f4dc4d8b2b31591", size = 6542801 }, + { url = "https://files.pythonhosted.org/packages/1a/07/5f165b6c65696ef75601b781a280fc3b33f1e0cd6aa5a92d9fb96c410e97/cryptography-44.0.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1923cb251c04be85eec9fda837661c67c1049063305d6be5721643c22dd4e2b7", size = 3922613 }, + { url = "https://files.pythonhosted.org/packages/28/34/6b3ac1d80fc174812486561cf25194338151780f27e438526f9c64e16869/cryptography-44.0.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:404fdc66ee5f83a1388be54300ae978b2efd538018de18556dde92575e05defc", size = 4137925 }, + { url = "https://files.pythonhosted.org/packages/d0/c7/c656eb08fd22255d21bc3129625ed9cd5ee305f33752ef2278711b3fa98b/cryptography-44.0.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:c5eb858beed7835e5ad1faba59e865109f3e52b3783b9ac21e7e47dc5554e289", size = 3915417 }, + { url = "https://files.pythonhosted.org/packages/ef/82/72403624f197af0db6bac4e58153bc9ac0e6020e57234115db9596eee85d/cryptography-44.0.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:f53c2c87e0fb4b0c00fa9571082a057e37690a8f12233306161c8f4b819960b7", size = 4155160 }, + { url = "https://files.pythonhosted.org/packages/a2/cd/2f3c440913d4329ade49b146d74f2e9766422e1732613f57097fea61f344/cryptography-44.0.0-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:9e6fc8a08e116fb7c7dd1f040074c9d7b51d74a8ea40d4df2fc7aa08b76b9e6c", size = 3932331 }, + { url = "https://files.pythonhosted.org/packages/7f/df/8be88797f0a1cca6e255189a57bb49237402b1880d6e8721690c5603ac23/cryptography-44.0.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:d2436114e46b36d00f8b72ff57e598978b37399d2786fd39793c36c6d5cb1c64", size = 4017372 }, + { url = "https://files.pythonhosted.org/packages/af/36/5ccc376f025a834e72b8e52e18746b927f34e4520487098e283a719c205e/cryptography-44.0.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a01956ddfa0a6790d594f5b34fc1bfa6098aca434696a03cfdbe469b8ed79285", size = 4239657 }, + { url = "https://files.pythonhosted.org/packages/46/b0/f4f7d0d0bcfbc8dd6296c1449be326d04217c57afb8b2594f017eed95533/cryptography-44.0.0-cp39-abi3-win32.whl", hash = "sha256:eca27345e1214d1b9f9490d200f9db5a874479be914199194e746c893788d417", size = 2758672 }, + { url = "https://files.pythonhosted.org/packages/97/9b/443270b9210f13f6ef240eff73fd32e02d381e7103969dc66ce8e89ee901/cryptography-44.0.0-cp39-abi3-win_amd64.whl", hash = "sha256:708ee5f1bafe76d041b53a4f95eb28cdeb8d18da17e597d46d7833ee59b97ede", size = 3202071 }, +] + +[[package]] +name = "discord-webhook" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "requests" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e8/e6/660b07356a15d98787d893f879efc404eb15176312d457f2f6f7090acd32/discord_webhook-1.3.1.tar.gz", hash = "sha256:ee3e0f3ea4f3dc8dc42be91f75b894a01624c6c13fea28e23ebcf9a6c9a304f7", size = 11715 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/92/e2/eed83ebc8d88da0930143a6dd1d0ba0b6deba1fd91b956f21c23a2608510/discord_webhook-1.3.1-py3-none-any.whl", hash = "sha256:ede07028316de76d24eb811836e2b818b2017510da786777adcb0d5970e7af79", size = 13206 }, +] + +[[package]] +name = "h11" +version = "0.14.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f5/38/3af3d3633a34a3316095b39c8e8fb4853a28a536e55d347bd8d8e9a14b03/h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d", size = 100418 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/95/04/ff642e65ad6b90db43e668d70ffb6736436c7ce41fcc549f4e9472234127/h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761", size = 58259 }, +] + +[[package]] +name = "httpcore" +version = "1.0.7" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "h11" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/6a/41/d7d0a89eb493922c37d343b607bc1b5da7f5be7e383740b4753ad8943e90/httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c", size = 85196 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/87/f5/72347bc88306acb359581ac4d52f23c0ef445b57157adedb9aee0cd689d2/httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd", size = 78551 }, +] + +[[package]] +name = "httpx" +version = "0.28.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "certifi" }, + { name = "httpcore" }, + { name = "idna" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517 }, +] + +[[package]] +name = "humanize" +version = "4.11.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6a/40/64a912b9330786df25e58127194d4a5a7441f818b400b155e748a270f924/humanize-4.11.0.tar.gz", hash = "sha256:e66f36020a2d5a974c504bd2555cf770621dbdbb6d82f94a6857c0b1ea2608be", size = 80374 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/92/75/4bc3e242ad13f2e6c12e0b0401ab2c5e5c6f0d7da37ec69bc808e24e0ccb/humanize-4.11.0-py3-none-any.whl", hash = "sha256:b53caaec8532bcb2fff70c8826f904c35943f8cecaca29d272d9df38092736c0", size = 128055 }, +] + +[[package]] +name = "idna" +version = "3.10" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442 }, +] + +[[package]] +name = "loguru" +version = "0.7.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "win32-setctime", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3a/05/a1dae3dffd1116099471c643b8924f5aa6524411dc6c63fdae648c4f1aca/loguru-0.7.3.tar.gz", hash = "sha256:19480589e77d47b8d85b2c827ad95d49bf31b0dcde16593892eb51dd18706eb6", size = 63559 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0c/29/0348de65b8cc732daa3e33e67806420b2ae89bdce2b04af740289c5c6c8c/loguru-0.7.3-py3-none-any.whl", hash = "sha256:31a33c10c8e1e10422bfd431aeb5d351c7cf7fa671e3c4df004162264b28220c", size = 61595 }, +] + +[[package]] +name = "mypy-extensions" +version = "1.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/98/a4/1ab47638b92648243faf97a5aeb6ea83059cc3624972ab6b8d2316078d3f/mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782", size = 4433 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/e2/5d3f6ada4297caebe1a2add3b126fe800c96f56dbe5d1988a2cbe0b267aa/mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d", size = 4695 }, +] + +[[package]] +name = "observable" +version = "1.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/24/57/013c2610cf93f9ae87e522be17d679bcba0e7cee2cd8da4dc8efddef1138/observable-1.0.3.tar.gz", hash = "sha256:97fe8e9d8c2a6185cee3661fa5fba9ce38c7ba388894132940cd6a81633626d9", size = 5793 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/45/7c/b4b63f447378e8a0ebcd338d90f9389f57fb23253127425beacf0129edcb/observable-1.0.3-py2.py3-none-any.whl", hash = "sha256:955a721a225fe3a1df28b58c0d7add38e08cd49afd88d14669b2884410f47d10", size = 8056 }, +] + +[[package]] +name = "packaging" +version = "24.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d0/63/68dbb6eb2de9cb10ee4c9c14a0148804425e13c4fb20d61cce69f53106da/packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f", size = 163950 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", size = 65451 }, +] + +[[package]] +name = "pathspec" +version = "0.12.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712", size = 51043 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191 }, +] + +[[package]] +name = "pillow" +version = "11.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f3/af/c097e544e7bd278333db77933e535098c259609c4eb3b85381109602fb5b/pillow-11.1.0.tar.gz", hash = "sha256:368da70808b36d73b4b390a8ffac11069f8a5c85f29eff1f1b01bcf3ef5b2a20", size = 46742715 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/31/9ca79cafdce364fd5c980cd3416c20ce1bebd235b470d262f9d24d810184/pillow-11.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ae98e14432d458fc3de11a77ccb3ae65ddce70f730e7c76140653048c71bfcbc", size = 3226640 }, + { url = "https://files.pythonhosted.org/packages/ac/0f/ff07ad45a1f172a497aa393b13a9d81a32e1477ef0e869d030e3c1532521/pillow-11.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cc1331b6d5a6e144aeb5e626f4375f5b7ae9934ba620c0ac6b3e43d5e683a0f0", size = 3101437 }, + { url = "https://files.pythonhosted.org/packages/08/2f/9906fca87a68d29ec4530be1f893149e0cb64a86d1f9f70a7cfcdfe8ae44/pillow-11.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:758e9d4ef15d3560214cddbc97b8ef3ef86ce04d62ddac17ad39ba87e89bd3b1", size = 4326605 }, + { url = "https://files.pythonhosted.org/packages/b0/0f/f3547ee15b145bc5c8b336401b2d4c9d9da67da9dcb572d7c0d4103d2c69/pillow-11.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b523466b1a31d0dcef7c5be1f20b942919b62fd6e9a9be199d035509cbefc0ec", size = 4411173 }, + { url = "https://files.pythonhosted.org/packages/b1/df/bf8176aa5db515c5de584c5e00df9bab0713548fd780c82a86cba2c2fedb/pillow-11.1.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:9044b5e4f7083f209c4e35aa5dd54b1dd5b112b108648f5c902ad586d4f945c5", size = 4369145 }, + { url = "https://files.pythonhosted.org/packages/de/7c/7433122d1cfadc740f577cb55526fdc39129a648ac65ce64db2eb7209277/pillow-11.1.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:3764d53e09cdedd91bee65c2527815d315c6b90d7b8b79759cc48d7bf5d4f114", size = 4496340 }, + { url = "https://files.pythonhosted.org/packages/25/46/dd94b93ca6bd555588835f2504bd90c00d5438fe131cf01cfa0c5131a19d/pillow-11.1.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:31eba6bbdd27dde97b0174ddf0297d7a9c3a507a8a1480e1e60ef914fe23d352", size = 4296906 }, + { url = "https://files.pythonhosted.org/packages/a8/28/2f9d32014dfc7753e586db9add35b8a41b7a3b46540e965cb6d6bc607bd2/pillow-11.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b5d658fbd9f0d6eea113aea286b21d3cd4d3fd978157cbf2447a6035916506d3", size = 4431759 }, + { url = "https://files.pythonhosted.org/packages/33/48/19c2cbe7403870fbe8b7737d19eb013f46299cdfe4501573367f6396c775/pillow-11.1.0-cp313-cp313-win32.whl", hash = "sha256:f86d3a7a9af5d826744fabf4afd15b9dfef44fe69a98541f666f66fbb8d3fef9", size = 2291657 }, + { url = "https://files.pythonhosted.org/packages/3b/ad/285c556747d34c399f332ba7c1a595ba245796ef3e22eae190f5364bb62b/pillow-11.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:593c5fd6be85da83656b93ffcccc2312d2d149d251e98588b14fbc288fd8909c", size = 2626304 }, + { url = "https://files.pythonhosted.org/packages/e5/7b/ef35a71163bf36db06e9c8729608f78dedf032fc8313d19bd4be5c2588f3/pillow-11.1.0-cp313-cp313-win_arm64.whl", hash = "sha256:11633d58b6ee5733bde153a8dafd25e505ea3d32e261accd388827ee987baf65", size = 2375117 }, + { url = "https://files.pythonhosted.org/packages/79/30/77f54228401e84d6791354888549b45824ab0ffde659bafa67956303a09f/pillow-11.1.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:70ca5ef3b3b1c4a0812b5c63c57c23b63e53bc38e758b37a951e5bc466449861", size = 3230060 }, + { url = "https://files.pythonhosted.org/packages/ce/b1/56723b74b07dd64c1010fee011951ea9c35a43d8020acd03111f14298225/pillow-11.1.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:8000376f139d4d38d6851eb149b321a52bb8893a88dae8ee7d95840431977081", size = 3106192 }, + { url = "https://files.pythonhosted.org/packages/e1/cd/7bf7180e08f80a4dcc6b4c3a0aa9e0b0ae57168562726a05dc8aa8fa66b0/pillow-11.1.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ee85f0696a17dd28fbcfceb59f9510aa71934b483d1f5601d1030c3c8304f3c", size = 4446805 }, + { url = "https://files.pythonhosted.org/packages/97/42/87c856ea30c8ed97e8efbe672b58c8304dee0573f8c7cab62ae9e31db6ae/pillow-11.1.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:dd0e081319328928531df7a0e63621caf67652c8464303fd102141b785ef9547", size = 4530623 }, + { url = "https://files.pythonhosted.org/packages/ff/41/026879e90c84a88e33fb00cc6bd915ac2743c67e87a18f80270dfe3c2041/pillow-11.1.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:e63e4e5081de46517099dc30abe418122f54531a6ae2ebc8680bcd7096860eab", size = 4465191 }, + { url = "https://files.pythonhosted.org/packages/e5/fb/a7960e838bc5df57a2ce23183bfd2290d97c33028b96bde332a9057834d3/pillow-11.1.0-cp313-cp313t-win32.whl", hash = "sha256:dda60aa465b861324e65a78c9f5cf0f4bc713e4309f83bc387be158b077963d9", size = 2295494 }, + { url = "https://files.pythonhosted.org/packages/d7/6c/6ec83ee2f6f0fda8d4cf89045c6be4b0373ebfc363ba8538f8c999f63fcd/pillow-11.1.0-cp313-cp313t-win_amd64.whl", hash = "sha256:ad5db5781c774ab9a9b2c4302bbf0c1014960a0a7be63278d13ae6fdf88126fe", size = 2631595 }, + { url = "https://files.pythonhosted.org/packages/cf/6c/41c21c6c8af92b9fea313aa47c75de49e2f9a467964ee33eb0135d47eb64/pillow-11.1.0-cp313-cp313t-win_arm64.whl", hash = "sha256:67cd427c68926108778a9005f2a04adbd5e67c442ed21d95389fe1d595458756", size = 2377651 }, +] + +[[package]] +name = "platformdirs" +version = "4.3.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/13/fc/128cc9cb8f03208bdbf93d3aa862e16d376844a14f9a0ce5cf4507372de4/platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907", size = 21302 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3c/a6/bc1012356d8ece4d66dd75c4b9fc6c1f6650ddd5991e421177d9f8f671be/platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb", size = 18439 }, +] + +[[package]] +name = "psutil" +version = "6.1.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1f/5a/07871137bb752428aa4b659f910b399ba6f291156bdea939be3e96cae7cb/psutil-6.1.1.tar.gz", hash = "sha256:cf8496728c18f2d0b45198f06895be52f36611711746b7f30c464b422b50e2f5", size = 508502 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/61/99/ca79d302be46f7bdd8321089762dd4476ee725fce16fc2b2e1dbba8cac17/psutil-6.1.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:fc0ed7fe2231a444fc219b9c42d0376e0a9a1a72f16c5cfa0f68d19f1a0663e8", size = 247511 }, + { url = "https://files.pythonhosted.org/packages/0b/6b/73dbde0dd38f3782905d4587049b9be64d76671042fdcaf60e2430c6796d/psutil-6.1.1-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:0bdd4eab935276290ad3cb718e9809412895ca6b5b334f5a9111ee6d9aff9377", size = 248985 }, + { url = "https://files.pythonhosted.org/packages/17/38/c319d31a1d3f88c5b79c68b3116c129e5133f1822157dd6da34043e32ed6/psutil-6.1.1-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b6e06c20c05fe95a3d7302d74e7097756d4ba1247975ad6905441ae1b5b66003", size = 284488 }, + { url = "https://files.pythonhosted.org/packages/9c/39/0f88a830a1c8a3aba27fededc642da37613c57cbff143412e3536f89784f/psutil-6.1.1-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:97f7cb9921fbec4904f522d972f0c0e1f4fabbdd4e0287813b21215074a0f160", size = 287477 }, + { url = "https://files.pythonhosted.org/packages/47/da/99f4345d4ddf2845cb5b5bd0d93d554e84542d116934fde07a0c50bd4e9f/psutil-6.1.1-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:33431e84fee02bc84ea36d9e2c4a6d395d479c9dd9bba2376c1f6ee8f3a4e0b3", size = 289017 }, + { url = "https://files.pythonhosted.org/packages/38/53/bd755c2896f4461fd4f36fa6a6dcb66a88a9e4b9fd4e5b66a77cf9d4a584/psutil-6.1.1-cp37-abi3-win32.whl", hash = "sha256:eaa912e0b11848c4d9279a93d7e2783df352b082f40111e078388701fd479e53", size = 250602 }, + { url = "https://files.pythonhosted.org/packages/7b/d7/7831438e6c3ebbfa6e01a927127a6cb42ad3ab844247f3c5b96bea25d73d/psutil-6.1.1-cp37-abi3-win_amd64.whl", hash = "sha256:f35cfccb065fff93529d2afb4a2e89e363fe63ca1e4a5da22b603a85833c2649", size = 254444 }, +] + +[[package]] +name = "py-cpuinfo" +version = "9.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/37/a8/d832f7293ebb21690860d2e01d8115e5ff6f2ae8bbdc953f0eb0fa4bd2c7/py-cpuinfo-9.0.0.tar.gz", hash = "sha256:3cdbbf3fac90dc6f118bfd64384f309edeadd902d7c8fb17f02ffa1fc3f49690", size = 104716 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e0/a9/023730ba63db1e494a271cb018dcd361bd2c917ba7004c3e49d5daf795a2/py_cpuinfo-9.0.0-py3-none-any.whl", hash = "sha256:859625bc251f64e21f077d099d4162689c762b5d6a4c3c97553d56241c9674d5", size = 22335 }, +] + +[[package]] +name = "pycodestyle" +version = "2.12.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/aa/210b2c9aedd8c1cbeea31a50e42050ad56187754b34eb214c46709445801/pycodestyle-2.12.1.tar.gz", hash = "sha256:6838eae08bbce4f6accd5d5572075c63626a15ee3e6f842df996bf62f6d73521", size = 39232 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3a/d8/a211b3f85e99a0daa2ddec96c949cac6824bd305b040571b82a03dd62636/pycodestyle-2.12.1-py2.py3-none-any.whl", hash = "sha256:46f0fb92069a7c28ab7bb558f05bfc0110dac69a0cd23c61ea0040283a9d78b3", size = 31284 }, +] + +[[package]] +name = "pycparser" +version = "2.22" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1d/b2/31537cf4b1ca988837256c910a668b553fceb8f069bedc4b1c826024b52c/pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6", size = 172736 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/13/a3/a812df4e2dd5696d1f351d58b8fe16a405b234ad2886a0dab9183fb78109/pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc", size = 117552 }, +] + +[[package]] +name = "pyflakes" +version = "3.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/57/f9/669d8c9c86613c9d568757c7f5824bd3197d7b1c6c27553bc5618a27cce2/pyflakes-3.2.0.tar.gz", hash = "sha256:1c61603ff154621fb2a9172037d84dca3500def8c8b630657d1701f026f8af3f", size = 63788 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d4/d7/f1b7db88d8e4417c5d47adad627a93547f44bdc9028372dbd2313f34a855/pyflakes-3.2.0-py2.py3-none-any.whl", hash = "sha256:84b5be138a2dfbb40689ca07e2152deb896a65c3a3e24c251c5c62489568074a", size = 62725 }, +] + +[[package]] +name = "pythonprotector" +version = "2.0" +source = { editable = "." } +dependencies = [ + { name = "command-runner" }, + { name = "cryptography" }, + { name = "discord-webhook" }, + { name = "httpx" }, + { name = "humanize" }, + { name = "loguru" }, + { name = "observable" }, + { name = "pillow" }, + { name = "psutil" }, + { name = "py-cpuinfo" }, + { name = "pywin32" }, + { name = "requests" }, + { name = "setuptools" }, + { name = "wmi" }, +] + +[package.dev-dependencies] +dev = [ + { name = "autoflake" }, + { name = "autopep8" }, + { name = "black" }, +] + +[package.metadata] +requires-dist = [ + { name = "command-runner", specifier = ">=1.5.0" }, + { name = "cryptography", specifier = ">=44.0.0" }, + { name = "discord-webhook", specifier = ">=1.1.0" }, + { name = "httpx", specifier = ">=0.28.1" }, + { name = "humanize", specifier = ">=4.6.0" }, + { name = "loguru", specifier = ">=0.7.3" }, + { name = "observable", specifier = ">=1.0.3" }, + { name = "pillow", specifier = ">=11.0.0" }, + { name = "psutil", specifier = ">=6.1.0" }, + { name = "py-cpuinfo", specifier = ">=9.0.0" }, + { name = "pywin32", specifier = ">=308" }, + { name = "requests", specifier = ">=2.31.0" }, + { name = "setuptools", specifier = ">=75.6.0" }, + { name = "wmi", specifier = ">=1.5.1" }, +] + +[package.metadata.requires-dev] +dev = [ + { name = "autoflake" }, + { name = "autopep8" }, + { name = "black" }, +] + +[[package]] +name = "pywin32" +version = "308" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a9/a4/aa562d8935e3df5e49c161b427a3a2efad2ed4e9cf81c3de636f1fdddfd0/pywin32-308-cp313-cp313-win32.whl", hash = "sha256:1c44539a37a5b7b21d02ab34e6a4d314e0788f1690d65b48e9b0b89f31abbbed", size = 5938579 }, + { url = "https://files.pythonhosted.org/packages/c7/50/b0efb8bb66210da67a53ab95fd7a98826a97ee21f1d22949863e6d588b22/pywin32-308-cp313-cp313-win_amd64.whl", hash = "sha256:fd380990e792eaf6827fcb7e187b2b4b1cede0585e3d0c9e84201ec27b9905e4", size = 6542056 }, + { url = "https://files.pythonhosted.org/packages/26/df/2b63e3e4f2df0224f8aaf6d131f54fe4e8c96400eb9df563e2aae2e1a1f9/pywin32-308-cp313-cp313-win_arm64.whl", hash = "sha256:ef313c46d4c18dfb82a2431e3051ac8f112ccee1a34f29c263c583c568db63cd", size = 7974986 }, +] + +[[package]] +name = "requests" +version = "2.32.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "charset-normalizer" }, + { name = "idna" }, + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", size = 131218 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928 }, +] + +[[package]] +name = "setuptools" +version = "75.8.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/92/ec/089608b791d210aec4e7f97488e67ab0d33add3efccb83a056cbafe3a2a6/setuptools-75.8.0.tar.gz", hash = "sha256:c5afc8f407c626b8313a86e10311dd3f661c6cd9c09d4bf8c15c0e11f9f2b0e6", size = 1343222 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/69/8a/b9dc7678803429e4a3bc9ba462fa3dd9066824d3c607490235c6a796be5a/setuptools-75.8.0-py3-none-any.whl", hash = "sha256:e3982f444617239225d675215d51f6ba05f845d4eec313da4418fdbb56fb27e3", size = 1228782 }, +] + +[[package]] +name = "sniffio" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 }, +] + +[[package]] +name = "urllib3" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/aa/63/e53da845320b757bf29ef6a9062f5c669fe997973f966045cb019c3f4b66/urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d", size = 307268 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c8/19/4ec628951a74043532ca2cf5d97b7b14863931476d117c471e8e2b1eb39f/urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df", size = 128369 }, +] + +[[package]] +name = "win32-setctime" +version = "1.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b3/8f/705086c9d734d3b663af0e9bb3d4de6578d08f46b1b101c2442fd9aecaa2/win32_setctime-1.2.0.tar.gz", hash = "sha256:ae1fdf948f5640aae05c511ade119313fb6a30d7eabe25fef9764dca5873c4c0", size = 4867 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e1/07/c6fe3ad3e685340704d314d765b7912993bcb8dc198f0e7a89382d37974b/win32_setctime-1.2.0-py3-none-any.whl", hash = "sha256:95d644c4e708aba81dc3704a116d8cbc974d70b3bdb8be1d150e36be6e9d1390", size = 4083 }, +] + +[[package]] +name = "wmi" +version = "1.5.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pywin32" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d4/66/6364deb0a03415f96c66803d8c4379f808f2401da3bdb183348487b10510/WMI-1.5.1.tar.gz", hash = "sha256:b6a6be5711b1b6c8d55bda7a8befd75c48c12b770b9d227d31c1737dbf0d40a6", size = 26254 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ee/b9/a80d1ed4d115dac8e2ac08d16af046a77ab58e3d186e22395bf2add24090/WMI-1.5.1-py2.py3-none-any.whl", hash = "sha256:1d6b085e5c445141c475476000b661f60fff1aaa19f76bf82b7abb92e0ff4942", size = 28912 }, +] From 6b8c3b71954dbdf0d244abb0adfb3e94fb04fb0d Mon Sep 17 00:00:00 2001 From: xFGhoul Date: Mon, 20 Jan 2025 21:16:43 -0400 Subject: [PATCH 5/7] =?UTF-8?q?=F0=9F=93=9D=20(pip):=20Remove=20`requireme?= =?UTF-8?q?nts.txt`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- requirements.txt | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 requirements.txt diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index ec6af20..0000000 --- a/requirements.txt +++ /dev/null @@ -1,13 +0,0 @@ -command_runner==1.5.0 -cryptography==44.0.0 -discord_webhook==1.1.0 -httpx==0.28.1 -humanize==4.6.0 -loguru==0.7.3 -observable==1.0.3 -psutil==6.1.0 -py_cpuinfo==9.0.0 -pywin32==308 -requests==2.31.0 -setuptools==75.6.0 -WMI==1.5.1 From 5fdb1b38cf7266970c8234e601fb1760c3fc228f Mon Sep 17 00:00:00 2001 From: xFGhoul Date: Wed, 4 Jun 2025 22:06:43 -0400 Subject: [PATCH 6/7] =?UTF-8?q?=E2=99=BB=EF=B8=8F(core):=20Refactor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/configuration/Ext/Keyauth/index.md | 5 - docs/configuration/Modules/Anti VM/index.md | 4 - .../Modules/Miscellaneous/events.md | 12 - examples/ext/mixed.py | 65 --- examples/keyauth.py | 31 -- examples/protector.py | 4 +- pyproject.toml | 16 +- pyprotector/__init__.py | 2 +- pyprotector/constants.py | 24 +- pyprotector/keyauth/__init__.py | 13 - pyprotector/keyauth/_constants.py | 17 - pyprotector/keyauth/exceptions.py | 36 -- pyprotector/keyauth/keyauth.py | 476 ------------------ pyprotector/keyauth/models.py | 91 ---- pyprotector/keyauth/seller.py | 12 - pyprotector/keyauth/utils.py | 25 - pyprotector/modules/__init__.py | 2 +- pyprotector/modules/analysis.py | 106 ++-- pyprotector/modules/dll.py | 26 +- pyprotector/modules/dump.py | 21 +- pyprotector/modules/miscellaneous.py | 118 ++--- pyprotector/modules/process.py | 29 +- pyprotector/modules/vm.py | 152 +++--- pyprotector/protector.py | 105 ++-- pyprotector/types.py | 10 +- pyprotector/utils/__init__.py | 2 +- pyprotector/utils/events.py | 7 +- pyprotector/utils/exceptions.py | 4 +- pyprotector/utils/http.py | 8 +- pyprotector/utils/webhook.py | 49 +- pyprotector/utils/windows.py | 4 +- scripts/format.bat | 9 +- scripts/format_linux.sh | 16 +- uv.lock | 106 ++-- 34 files changed, 372 insertions(+), 1235 deletions(-) delete mode 100644 docs/configuration/Ext/Keyauth/index.md delete mode 100644 examples/ext/mixed.py delete mode 100644 examples/keyauth.py delete mode 100644 pyprotector/keyauth/__init__.py delete mode 100644 pyprotector/keyauth/_constants.py delete mode 100644 pyprotector/keyauth/exceptions.py delete mode 100644 pyprotector/keyauth/keyauth.py delete mode 100644 pyprotector/keyauth/models.py delete mode 100644 pyprotector/keyauth/seller.py delete mode 100644 pyprotector/keyauth/utils.py diff --git a/docs/configuration/Ext/Keyauth/index.md b/docs/configuration/Ext/Keyauth/index.md deleted file mode 100644 index 7e75485..0000000 --- a/docs/configuration/Ext/Keyauth/index.md +++ /dev/null @@ -1,5 +0,0 @@ -# Keyauth - -TBD. - -full implementation of api https://docs.keyauth.cc except seller api. \ No newline at end of file diff --git a/docs/configuration/Modules/Anti VM/index.md b/docs/configuration/Modules/Anti VM/index.md index bb2ac5f..3ec3e77 100644 --- a/docs/configuration/Modules/Anti VM/index.md +++ b/docs/configuration/Modules/Anti VM/index.md @@ -6,10 +6,6 @@ Check Blacklisted Lists To Compare Data like `HWID`, `IP`, `PC_NAME`, etc. -### `CheckVirtualEnv` - -Checks if `self._get_base_prefix_compat() != sys.prefix` - ### `CheckRegistry` Checks Registry For VMWare Software diff --git a/docs/configuration/Modules/Miscellaneous/events.md b/docs/configuration/Modules/Miscellaneous/events.md index b777884..75d3319 100644 --- a/docs/configuration/Modules/Miscellaneous/events.md +++ b/docs/configuration/Modules/Miscellaneous/events.md @@ -12,12 +12,6 @@ check_remote_debugger_present() Called When CheckRemoteDebuggerPresent Returns True -```py -output_debug_string() -``` - -Called When `OutputDebugString` != 0 - ```py ram_check(ram: int) ``` @@ -53,12 +47,6 @@ Called When Blacklisted Path Found - `path` ([`str`](https://docs.python.org/3/library/stdtypes.html#str)) - Blacklisted Path -```py -blacklisted_import(package: str, dist: Distribution) -``` - -Called When Blacklisted Import Found - ##### Parameters - `package` ([`str`](https://docs.python.org/3/library/stdtypes.html#str)) - Name Of Package diff --git a/examples/ext/mixed.py b/examples/ext/mixed.py deleted file mode 100644 index f9fb5a9..0000000 --- a/examples/ext/mixed.py +++ /dev/null @@ -1,65 +0,0 @@ -""" - ____ ____ __ __ - / __ \\ __ __ / __ \\ _____ ____ / /_ ___ _____ / /_ - / /_/ // / / // /_/ // ___// __ \\ / __// _ \\ / ___// __/ - / ____// /_/ // ____// / / /_/ // /_ / __// /__ / /_ -/_/ \\__, //_/ /_/ \\____/ \\__/ \\___/ \\___/ \\__/ - /____/ - -Made With ❤️ By Ghoul & Marci -""" - -from pathlib import Path -from threading import Thread - -from pyprotector import PythonProtector -from pyprotector.keyauth import Keyauth -from pyprotector.keyauth.utils import getchecksum - -# -- Define Constants -LOGGING_PATH = ( - Path.home() / "AppData/Roaming/PythonProtector/logs/[Security].log" -) # -- This can be any path - -# -- Construct Class -security = PythonProtector( - debug=True, - modules=[ - "AntiProcess", - "AntiVM", - "Miscellaneous", - "AntiDLL", - "AntiAnalysis", - "AntiDump", - ], - logs_path=LOGGING_PATH, - webhook_url="", - on_detect=["Report", "Exit", "Screenshot"], -) - -auth = Keyauth( - name="", - ownerid="", - secret="", - version="", - file_hash=getchecksum()) - -# -- Example Event - - -@security.event.obs.on("process_running") -def on_process_running(text: str, module: str, process) -> None: - print(f"{module} - {text}\nProcess Name: {process.name()}") - print(security.user) - auth.ban() - # Free To Do Whatever You Want Here... - - -# -- Main Code -if __name__ == "__main__": - SecurityThread = Thread( - name="Python Protector", target=security.start - ) # -- Start Before Any Other Code Is Run - SecurityThread.start() - auth.initialize() - # Other Code diff --git a/examples/keyauth.py b/examples/keyauth.py deleted file mode 100644 index 163d2e4..0000000 --- a/examples/keyauth.py +++ /dev/null @@ -1,31 +0,0 @@ -""" - ____ ____ __ __ - / __ \\ __ __ / __ \\ _____ ____ / /_ ___ _____ / /_ - / /_/ // / / // /_/ // ___// __ \\ / __// _ \\ / ___// __/ - / ____// /_/ // ____// / / /_/ // /_ / __// /__ / /_ -/_/ \\__, //_/ /_/ \\____/ \\__/ \\___/ \\___/ \\__/ - /____/ - -Made With ❤️ By Ghoul & Marci -""" - -from pyprotector.keyauth import Keyauth -from pyprotector.keyauth.utils import getchecksum - -auth = Keyauth( - name="", - ownerid="", - secret="", - version="", - file_hash=getchecksum()) - -app = auth.initialize() -# "Keyauth App ({self.version}) with {self.users} users, {self.keys} keys and {self.onlineUsers} online users" -print(app) - -license = auth.license("LICENSE") -print(license.current_subscription) -print(license.last_login) -print(license.expiry) - -# All Other Functions are documented. diff --git a/examples/protector.py b/examples/protector.py index 68fbf5b..75961d0 100644 --- a/examples/protector.py +++ b/examples/protector.py @@ -1,10 +1,10 @@ """ - ____ ____ __ __ + ____ ____ __ __ / __ \\ __ __ / __ \\ _____ ____ / /_ ___ _____ / /_ / /_/ // / / // /_/ // ___// __ \\ / __// _ \\ / ___// __/ / ____// /_/ // ____// / / /_/ // /_ / __// /__ / /_ /_/ \\__, //_/ /_/ \\____/ \\__/ \\___/ \\___/ \\__/ - /____/ + /____/ Made With ❤️ By Ghoul & Marci """ diff --git a/pyproject.toml b/pyproject.toml index aa2c1b8..07dd76e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,18 +5,18 @@ description = "Add your description here" readme = "README.md" requires-python = ">=3.13" dependencies = [ - "command_runner>=1.5.0", - "cryptography>=44.0.0", + "command-runner>=1.7.4", + "cryptography>=45.0.3", "discord_webhook>=1.1.0", "httpx>=0.28.1", - "humanize>=4.6.0", + "humanize>=4.12.3", "loguru>=0.7.3", "observable>=1.0.3", - "psutil>=6.1.0", - "py_cpuinfo>=9.0.0", - "pywin32>=308", + "psutil>=7.0.0", + "py-cpuinfo>=9.0.0", + "pywin32>=310", "requests>=2.31.0", - "setuptools>=75.6.0", + "setuptools>=80.9.0", "WMI>=1.5.1", "Pillow>=11.0.0", ] @@ -29,4 +29,4 @@ build-backend = "hatchling.build" packages = ["pythonprotector"] [dependency-groups] -dev = ["black", "autopep8", "autoflake"] \ No newline at end of file +dev = ["black", "autopep8", "autoflake"] diff --git a/pyprotector/__init__.py b/pyprotector/__init__.py index 4cf8b5b..056b588 100644 --- a/pyprotector/__init__.py +++ b/pyprotector/__init__.py @@ -4,7 +4,7 @@ / /_/ // / / // /_/ // ___// __ \\ / __// _ \\ / ___// __/ / ____// /_/ // ____// / / /_/ // /_ / __// /__ / /_ /_/ \\__, //_/ /_/ \\____/ \\__/ \\___/ \\___/ \\__/ - /____/ + /____/ Made With ❤️ By Ghoul & Marci """ diff --git a/pyprotector/constants.py b/pyprotector/constants.py index 888b441..1b12b7d 100644 --- a/pyprotector/constants.py +++ b/pyprotector/constants.py @@ -12,7 +12,6 @@ import os import re import wmi -import subprocess import uuid @@ -26,7 +25,7 @@ @final class UserInfo: USERNAME: Final[str] = os.getlogin() - PC_NAME: Final[str] = os.getenv("COMPUTERNAME") + PC_NAME: Final[str] = os.getenv("COMPUTERNAME") or "Unknown-PC" IP: Final[str] = getIPAddress() COMPUTER: Any = wmi.WMI() HWID: Final[str] = COMPUTER.Win32_ComputerSystemProduct()[0].UUID @@ -39,11 +38,11 @@ class LoggingInfo: KEY: bytes = Fernet.generate_key() CIPHER: Fernet = Fernet(KEY) - def encrypted_formatter(record) -> str: - encrypted: bytes = LoggingInfo.CIPHER.encrypt( - record["message"].encode("utf8")) - record["extra"]["encrypted"] = b64encode(encrypted).decode("latin1") - return "[{time:YYYY-MM-DD HH:mm:ss}] {module}::{function}({line}) - {extra[encrypted]}\n{exception}" + +def encrypted_formatter(record) -> str: + encrypted: bytes = LoggingInfo.CIPHER.encrypt(record["message"].encode("utf8")) + record["extra"]["encrypted"] = b64encode(encrypted).decode("latin1") + return "[{time:YYYY-MM-DD HH:mm:ss}] {module}::{function}({line}) - {extra[encrypted]}\n{exception}" @final @@ -288,17 +287,6 @@ class Lists: "213.33.190.22", "194.154.78.152", ] - BLACKLISTED_IMPORTS: Final[List[str]] = [ - "pydecipher", - "unpy2exe", - "uncompyle6", - "pefile", - "marshal", - "unpy2exe", - "pyarmor", - "pyarmor-webui", - "pyinject", - ] PROXY_IPS: Final[List[str]] = ["10.0.0.1", "10.0.0.2", "10.0.0.3"] PROXY_HEADERS: Final[List[str]] = ["Via", "Forwarded", "X-Forwarded-For"] diff --git a/pyprotector/keyauth/__init__.py b/pyprotector/keyauth/__init__.py deleted file mode 100644 index afcbfb3..0000000 --- a/pyprotector/keyauth/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -""" - ____ ____ __ __ - / __ \\ __ __ / __ \\ _____ ____ / /_ ___ _____ / /_ - / /_/ // / / // /_/ // ___// __ \\ / __// _ \\ / ___// __/ - / ____// /_/ // ____// / / /_/ // /_ / __// /__ / /_ -/_/ \\__, //_/ /_/ \\____/ \\__/ \\___/ \\___/ \\__/ - /____/ - -Made With ❤️ By Ghoul & Marci -""" - -from .utils import * -from .keyauth import Keyauth diff --git a/pyprotector/keyauth/_constants.py b/pyprotector/keyauth/_constants.py deleted file mode 100644 index 0460462..0000000 --- a/pyprotector/keyauth/_constants.py +++ /dev/null @@ -1,17 +0,0 @@ -""" - ____ ____ __ __ - / __ \\ __ __ / __ \\ _____ ____ / /_ ___ _____ / /_ - / /_/ // / / // /_/ // ___// __ \\ / __// _ \\ / ___// __/ - / ____// /_/ // ____// / / /_/ // /_ / __// /__ / /_ -/_/ \\__, //_/ /_/ \\____/ \\__/ \\___/ \\___/ \\__/ - /____/ - -Made With ❤️ By Ghoul & Marci -""" - -from typing import Final, final - - -@final -class API: - BASE_URL: Final[str] = "https://keyauth.win/api/1.2/" diff --git a/pyprotector/keyauth/exceptions.py b/pyprotector/keyauth/exceptions.py deleted file mode 100644 index 22990f3..0000000 --- a/pyprotector/keyauth/exceptions.py +++ /dev/null @@ -1,36 +0,0 @@ -""" - ____ ____ __ __ - / __ \\ __ __ / __ \\ _____ ____ / /_ ___ _____ / /_ - / /_/ // / / // /_/ // ___// __ \\ / __// _ \\ / ___// __/ - / ____// /_/ // ____// / / /_/ // /_ / __// /__ / /_ -/_/ \\__, //_/ /_/ \\____/ \\__/ \\___/ \\___/ \\__/ - /____/ - -Made With ❤️ By Ghoul & Marci -""" - - -class KeyauthException(BaseException): - """ - Base Class of All Keyauth Issues - """ - - -class NewVersionAvailable(KeyauthException): - def __init__(self, message: str) -> None: - super().__init__(message) - - -class ApplicationNotFound(KeyauthException): - def __init__(self, message: str) -> None: - super().__init__(message) - - -class RequestError(KeyauthException): - def __init__(self, message: str) -> None: - super().__init__(message) - - -class NotInitialized(KeyauthException): - def __init__(self, message: str) -> None: - super().__init__(message) diff --git a/pyprotector/keyauth/keyauth.py b/pyprotector/keyauth/keyauth.py deleted file mode 100644 index ed1d79e..0000000 --- a/pyprotector/keyauth/keyauth.py +++ /dev/null @@ -1,476 +0,0 @@ -""" - ____ ____ __ __ - / __ \\ __ __ / __ \\ _____ ____ / /_ ___ _____ / /_ - / /_/ // / / // /_/ // ___// __ \\ / __// _ \\ / ___// __/ - / ____// /_/ // ____// / / /_/ // /_ / __// /__ / /_ -/_/ \\__, //_/ /_/ \\____/ \\__/ \\___/ \\___/ \\__/ - /____/ - -Made With ❤️ By Ghoul & Marci -""" - -import uuid -import httpx -import subprocess - -from typing import Final, Optional, Union, Dict, List -from Crypto.Hash import SHA256 -from httpx import Response - -from ._constants import API -from .models import KeyauthAppData, KeyauthUser, KeyauthChat -from .exceptions import NewVersionAvailable, ApplicationNotFound, RequestError - - -class Keyauth: - def __init__( - self, - name: str, - ownerid: str, - secret: str, - version: str, - file_hash: Optional[str] = "", - ) -> None: - self.name: str = name - self.ownerid: str = ownerid - self.secret: str = secret - self.version: str = version - self.file_hash: str = file_hash - - self.__session_id: None = None - - self.hwid: Final[str] = ( - subprocess.check_output("wmic csproduct get uuid") - .decode() - .split("\n")[1] - .strip() - ) - self.initialized: bool = False - - def _post_data(self, type: str, data: Optional[Dict] = None) -> Dict: - _post_data = { - "type": type, - "sessionid": self.__session_id, - "name": self.name, - "ownerid": self.ownerid, - } - - if data is not None: - _post_data |= data - - return _post_data - - def __request(self, data: Dict) -> Response: - try: - response = httpx.post(API.BASE_URL, params=data, timeout=30) - response.raise_for_status() - return response.json() - except (httpx.TimeoutException, httpx.ConnectError, httpx.HTTPError) as e: - raise RequestError("Internal Request Failed!") from e - - def initialize(self) -> Union[bool, KeyauthAppData]: - """Initializes your Keyauth Application - - Raises: - RuntimeError: If you have already initialized - ApplicationNotFound: If your application does not exist - NewVersionAvailable: If there is a new version available - RequestError: There is an issue with the request - - Returns: - Union[bool, KeyauthAppData]: Returns self.initialized and a class representing your app data - """ - if self.__session_id is not None: - raise RuntimeError("This session has already been initialized!") - - self._enc_key: str = SHA256.new( - str(uuid.uuid4())[:8].encode()).hexdigest() - - response: Response = self.__request( - self._post_data( - type="init", - data={ - "ver": self.version, - "hash": self.file_hash, - "enckey": self._enc_key, - }, - ) - ) - - if response == "KeyAuth_Invalid": - raise ApplicationNotFound("This Application Doesn't Exist") - - if response["message"] == "invalidver": - raise NewVersionAvailable("This Version Is Out Of Date!") - - if not response["success"]: - raise RequestError(response["message"]) - - self.__session_id = response["sessionid"] - self.initialized: bool = True - return (self.initialized, KeyauthAppData(response["appinfo"])) - - def register( - self, - username: str, - password: str, - license: str, - hwid: Optional[str] = None) -> KeyauthUser: - """Creates user with license key - Args: - username (str): user's input for username - password (str): user's input for password - license (str): user's input for license key - hwid (Optional[str]): Hardware ID. Defaults to None. - - Raises: - RequestError: If the request has failed - - Returns: - KeyauthUser: The newly registered user - """ - if hwid is None: - hwid: str = self.hwid - - response: Response = self.__request( - self._post_data( - type="register", - data={ - "username": username, - "password": password, - "license": license, - "hwid": hwid, - }, - ) - ) - - if not response["success"]: - raise RequestError(response["message"]) - - return KeyauthUser(response["info"]) - - def upgrade(self, username: str, key: str) -> KeyauthUser: - """Add subscription to an user - - Args: - username (str): username you want upgraded - key (str): user's input for license key - - Raises: - RequestError: If the request has failed - - Returns: - KeyauthUser: Upgraded User - """ - response: Response = self.__request( - self._post_data( - type="upgrade", - data={ - "username": username, - "key": key})) - - if not response["success"]: - raise RequestError(response["message"]) - - return KeyauthUser(response["info"]) - - def login( - self, username: str, password: str, hwid: Optional[str] = None - ) -> KeyauthUser: - """Login with username & password - - Args: - username (str): user's input for username - password (str): user's input for password - hwid (Optional[str]): Hardware ID. Defaults to None. - - Raises: - RequestError: If the request has failed - - Returns: - KeyauthUser: Logged in User - """ - if hwid is None: - hwid: str = self.hwid - - response: Response = self.__request( - self._post_data( - type="login", - data={ - "username": username, - "password": password, - "hwid": hwid}, - )) - - if not response["success"]: - raise RequestError(response["message"]) - - return KeyauthUser(response["info"]) - - def license(self, license: str, hwid: Optional[str] = None) -> KeyauthUser: - """Login with license key - - Args: - license (str): user's input for license key - hwid (Optional[str]): Hardware ID. Defaults to None. - - Raises: - RequestError: If the request has failed - - Returns: - KeyauthUser: Licensed User - """ - if hwid is None: - hwid: str = self.hwid - - response: Response = self.__request( - self._post_data(type="license", data={"key": license}) - ) - - if not response["success"]: - raise RequestError(response["message"]) - - return KeyauthUser(response["info"]) - - def getOnlineUsers(self) -> Dict: - """Get Online Users - - Raises: - RequestError: If The Request has Failed - - Returns: - Dict: Dictionary of Online Users - """ - response: Response = self.__request( - self._post_data(type="fetchOnline")) - - if not response["success"]: - raise RequestError(response["message"]) - - return response["users"] - - def setvar(self, variable: str, data: str) -> None: - """Set Variable - - Args: - variable (str): Variable Name - data (str): Variable Value - - Raises: - RequestError: If The Reuqest has Failed - - Returns: - None - """ - response: Response = self.__request( - self._post_data( - type="setvar", - data={ - "var": variable, - "data": data})) - - if not response["success"]: - raise RequestError(response["message"]) - - return response - - def getvar(self, variable: str) -> str: - """Get Variable - - Args: - variable (str): Variable Name - - Raises: - RequestError: If The Reuqest has Failed - - Returns: - str: Variable - """ - response: Response = self.__request( - self._post_data(type="getvar", data={"var": variable}) - ) - - if not response["success"]: - raise RequestError(response["message"]) - - return response["success"] - - def var(self, variable: str) -> None: - """Variable - - Args: - variable (str): Variable Name - - Raises: - RequestError: If The Reuqest has Failed - - Returns: - str: Variable - """ - response: Response = self.__request( - self._post_data(type="var", data={"varid": variable}) - ) - - if not response["success"]: - raise RequestError(response["message"]) - - return response["success"] - - def checkBlacklist(self, hwid: Optional[str] = None) -> bool: - """Check The Blacklist - - Args: - hwid (Optional[str]): User HWID. Defaults to None. - - Raises: - RequestError: If The Reuqest has Failed - - Returns: - bool: If The User Is Blacklisted - """ - if hwid is None: - hwid: str = self.hwid - - response: Response = self.__request( - self._post_data(type="checkblacklist", data={"hwid": hwid}) - ) - - if not response["success"]: - raise RequestError(response["message"]) - - return response["success"] - - def getChat(self, channel: str) -> List[KeyauthChat]: - """Get Chats - - Args: - channel (str): Channel Name - - Raises: - RequestError: If The Reuqest has Failed - - Returns: - List[KeyauthChat]: List Of Keyauth Chats - """ - response: Response = self.__request( - self._post_data(type="chatget", data={"channel": channel}) - ) - - if not response["success"]: - raise RequestError(response["message"]) - - return [KeyauthChat(**chat) for chat in response["messages"]] - - def sendChat(self, channel: str, message: str) -> str: - """Send A Chat - - Args: - channel (str): Channel Name - message (str): Message - - Raises: - RequestError: If The Reuqest has Failed - - Returns: - str: Response - """ - response: Response = self.__request( - self._post_data( - type="chatsend", data={"channel": channel, "message": message} - ) - ) - - if not response["success"]: - raise RequestError(response["message"]) - - return response["message"] - - def download(self, file_id: str) -> bytes: - """Download File - - Args: - file_id (str): File ID - - Raises: - RequestError: If The Reuqest has Failed - - Returns: - bytes: Bytes Object - """ - response: Response = self.__request( - self._post_data(type="file", data={"fileid": file_id}) - ) - - if not response["success"]: - raise RequestError(response["message"]) - - return bytes.fromhex(response["contents"]) - - def checkSession(self) -> bool: - """Check Session - - Raises: - RequestError: If The Reuqest has Failed - - Returns: - bool: If The Session is Valid - """ - response: Response = self.__request(self._post_data(type="check")) - - if not response["success"]: - raise RequestError(response["message"]) - - return response["success"] - - def changeUsername(self, username: str) -> bool: - """Change Username - - Args: - username (str): New Username - - Raises: - RequestError: If The Reuqest has Failed - - Returns: - bool: If the username has changed or not - """ - response: Response = self.__request( - self._post_data( - type="changeUsername", data={ - "newUsername": username})) - - if not response["success"]: - raise RequestError(response["message"]) - - return response["success"] - - def log(self, user: str, message: str) -> None: - """Log Message - - Args: - user (str): Username - message (str): Message - """ - self.__request( - self._post_data( - type="log", - data={ - "user": user, - "message": message})) - - def webhook(self, webhook_id: str, params: str) -> None: - """Send Webhook - - Args: - webhook_id (str): Webhook ID - params (str): Parameters - """ - self.__request( - self._post_data( - type="webhook", data={"webid": webhook_id, "params": params} - ) - ) - - def ban(self) -> None: - """Ban User""" - self.__request(self._post_data(type="ban")) diff --git a/pyprotector/keyauth/models.py b/pyprotector/keyauth/models.py deleted file mode 100644 index 8248267..0000000 --- a/pyprotector/keyauth/models.py +++ /dev/null @@ -1,91 +0,0 @@ -""" - ____ ____ __ __ - / __ \\ __ __ / __ \\ _____ ____ / /_ ___ _____ / /_ - / /_/ // / / // /_/ // ___// __ \\ / __// _ \\ / ___// __/ - / ____// /_/ // ____// / / /_/ // /_ / __// /__ / /_ -/_/ \\__, //_/ /_/ \\____/ \\__/ \\___/ \\___/ \\__/ - /____/ - -Made With ❤️ By Ghoul & Marci -""" - -from dataclasses import dataclass - -from datetime import datetime - - -class KeyauthAppData: - def __init__(self, data: dict) -> None: - """Object representing JSON response from keyauth API - - Args: - data (dict): Data Received - """ - self.users: int = data["numUsers"] - self.keys: int = data["numKeys"] - self.version: int = data["version"] - self.customer_panel: str = data["customerPanelLink"] - self.onlineUsers: int = data["numOnlineUsers"] - - def __repr__(self) -> str: - return f"Keyauth App ({ - self.version}) with { - self.users} users, { - self.keys} keys and { - self.onlineUsers} online users" - - -class KeyauthUser: - def __init__(self, data: dict) -> None: - """Object representing JSON response from keyauth API - - Args: - data (dict): Data Received - """ - self.username: str = data["username"] - self.ip: str = data["ip"] - self.hwid: str = data["hwid"] - self.expiry: str = datetime.utcfromtimestamp( - int(data["subscriptions"][0]["expiry"]) - ).strftime("%Y-%m-%d %H:%M:%S") - self.date_created: str = datetime.utcfromtimestamp( - int(data["createdate"]) - ).strftime("%Y-%m-%d %H:%M:%S") - self.last_login: str = datetime.utcfromtimestamp( - int(data["lastlogin"]) - ).strftime("%Y-%m-%d %H:%M:%S") - self.current_subscription: Subscription = Subscription( - **data["subscriptions"][0] - ) - self.subscriptions: list[Subscription] = [Subscription( - **subscription) for subscription in data["subscriptions"]] - - def __repr__(self) -> str: - return self.username - - -@dataclass -class KeyauthChat: - author: str - message: str - timestamp: str - - def __post_init__(self) -> None: - self.timestamp = datetime.utcfromtimestamp( - int(self.timestamp)).strftime("%Y-%m-%d %H:%M:%S") - - -@dataclass -class Subscription: - subscription: str - key: str - expiry: str - timeleft: str - - def __post_init__(self) -> None: - self.expiry = datetime.utcfromtimestamp(int(self.expiry)).strftime( - "%Y-%m-%d %H:%M:%S" - ) - self.timeleft = datetime.utcfromtimestamp(int(self.timeleft)).strftime( - "%Y-%m-%d %H:%M:%S" - ) diff --git a/pyprotector/keyauth/seller.py b/pyprotector/keyauth/seller.py deleted file mode 100644 index b1b5a34..0000000 --- a/pyprotector/keyauth/seller.py +++ /dev/null @@ -1,12 +0,0 @@ -""" - ____ ____ __ __ - / __ \\ __ __ / __ \\ _____ ____ / /_ ___ _____ / /_ - / /_/ // / / // /_/ // ___// __ \\ / __// _ \\ / ___// __/ - / ____// /_/ // ____// / / /_/ // /_ / __// /__ / /_ -/_/ \\__, //_/ /_/ \\____/ \\__/ \\___/ \\___/ \\__/ - /____/ - -Made With ❤️ By Ghoul & Marci -""" - -# TBD, no seller key as yet :c diff --git a/pyprotector/keyauth/utils.py b/pyprotector/keyauth/utils.py deleted file mode 100644 index 9cae49e..0000000 --- a/pyprotector/keyauth/utils.py +++ /dev/null @@ -1,25 +0,0 @@ -""" - ____ ____ __ __ - / __ \\ __ __ / __ \\ _____ ____ / /_ ___ _____ / /_ - / /_/ // / / // /_/ // ___// __ \\ / __// _ \\ / ___// __/ - / ____// /_/ // ____// / / /_/ // /_ / __// /__ / /_ -/_/ \\__, //_/ /_/ \\____/ \\__/ \\___/ \\___/ \\__/ - /____/ - -Made With ❤️ By Ghoul & Marci -""" - -import sys -import hashlib - - -def getchecksum() -> str: - """Get's Current File Hash - - Returns: - str: File Hash - """ - md5_hash = hashlib.md5() - with open("".join(sys.argv), "rb") as file: - md5_hash.update(file.read()) - return md5_hash.hexdigest() diff --git a/pyprotector/modules/__init__.py b/pyprotector/modules/__init__.py index de3873d..3e242fd 100644 --- a/pyprotector/modules/__init__.py +++ b/pyprotector/modules/__init__.py @@ -4,7 +4,7 @@ / /_/ // / / // /_/ // ___// __ \\ / __// _ \\ / ___// __/ / ____// /_/ // ____// / / /_/ // /_ / __// /__ / /_ /_/ \\__, //_/ /_/ \\____/ \\__/ \\___/ \\___/ \\__/ - /____/ + /____/ Made With ❤️ By Ghoul & Marci """ diff --git a/pyprotector/modules/analysis.py b/pyprotector/modules/analysis.py index 3519d53..694f7c4 100644 --- a/pyprotector/modules/analysis.py +++ b/pyprotector/modules/analysis.py @@ -1,10 +1,10 @@ """ - ____ ____ __ __ + ____ ____ __ __ / __ \\ __ __ / __ \\ _____ ____ / /_ ___ _____ / /_ / /_/ // / / // /_/ // ___// __ \\ / __// _ \\ / ___// __/ / ____// /_/ // ____// / / /_/ // /_ / __// /__ / /_ /_/ \\__, //_/ /_/ \\____/ \\__/ \\___/ \\___/ \\__/ - /____/ + /____/ Made With ❤️ By Ghoul & Marci """ @@ -21,12 +21,8 @@ class AntiAnalysis(Module): def __init__( - self, - webhook: Webhook, - logger: Logger, - exit: bool, - report: bool, - event: Event) -> None: + self, webhook: Webhook, logger: Logger, exit: bool, report: bool, event: Event + ) -> None: self.webhook: Webhook = webhook self.logger: Logger = logger self.exit: bool = exit @@ -41,7 +37,7 @@ def name(self) -> str: return "Anti Analysis" @property - def version(self) -> int: + def version(self) -> float: return 1.0 def CheckDebugPrivilege(self) -> None: @@ -70,9 +66,9 @@ def CheckDebugPrivilege(self) -> None: self.ntdll.NtClose(hToken) return - debug_privilege = (ctypes.c_int * - (return_length.value // - 8)).from_buffer(privileges) + debug_privilege = (ctypes.c_int * (return_length.value // 8)).from_buffer( + privileges + ) for priv in debug_privilege: if priv.s_luid.LowPart == 21 and priv.s_attributes & 0x00000002: self.ntdll.NtClose(hToken) @@ -84,6 +80,7 @@ def CheckDebugPrivilege(self) -> None: self.name, ) if self.exit: + self.logger.info("Debug Privilege Enabled, Exiting") os._exit(1) self.ntdll.NtClose(hToken) @@ -102,9 +99,8 @@ def HideThreads(self) -> None: return self.ntdll.NtSetInformationThread( - hThread, 0x11, ctypes.byref( - (ctypes.c_int(1)), ctypes.sizeof( - ctypes.c_int))) + hThread, 0x11, ctypes.byref((ctypes.c_int(1)), ctypes.sizeof(ctypes.c_int)) + ) self.kernel32.CloseHandle(hThread) self.kernel32.CloseHandle(hProcess) @@ -137,6 +133,7 @@ def CheckDebugObject(self) -> None: self.name, ) if self.exit: + self.logger.info("Debug Object Handle Detected, Exiting") os._exit((1)) def CheckSEDebugName(self) -> None: @@ -168,6 +165,7 @@ def CheckSEDebugName(self) -> None: self.name, ) if self.exit: + self.logger.info("Debug Object Handle Detected, Exiting") os._exit((1)) def CheckNtGlobalFlag(self) -> None: @@ -193,47 +191,65 @@ def CheckNtGlobalFlag(self) -> None: ) if self.report: self.webhook.send( - "NT_GLOBAL_FLAG_DEBUGGED Found in the Process Environment Block", self.name, ) + "NT_GLOBAL_FLAG_DEBUGGED Found in the Process Environment Block", + self.name, + ) self.event.dispatch( ["nt_global_flag_debugged", "pyprotector_detect"], "NT_GLOBAL_FLAG_DEBUGGED Found in the Process Environment Block", self.name, ) if self.exit: + self.logger.info("NT_GLOBAL_FLAG_DEBUGGED Found, Exiting") os._exit(1) def CheckHardwareBreakpoints(self) -> None: - """Check For Exisiting Hardware Breakpoints""" - ThreadContext = ctypes.c_void_p() - TID = self.kernel32.GetCurrentThreadId() - hThread = self.kernel32.OpenThread(0x1F03FF, False, TID) - if hThread is None: - return + """Check For Existing Hardware Breakpoints""" + try: + + class CONTEXT(ctypes.Structure): + _fields_ = [ + ("ContextFlags", ctypes.c_ulong), + ("Dr0", ctypes.c_ulong), + ("Dr1", ctypes.c_ulong), + ("Dr2", ctypes.c_ulong), + ("Dr3", ctypes.c_ulong), + ("Dr6", ctypes.c_ulong), + ("Dr7", ctypes.c_ulong), + ] + + TID = self.kernel32.GetCurrentThreadId() + hThread = self.kernel32.OpenThread(0x1F03FF, False, TID) + if hThread is None or hThread == 0: + return + + context = CONTEXT() + context.ContextFlags = 0x00000010 + + if self.kernel32.GetThreadContext(hThread, ctypes.byref(context)): + if ( + context.Dr0 != 0 + or context.Dr1 != 0 + or context.Dr2 != 0 + or context.Dr3 != 0 + ): + self.kernel32.CloseHandle(hThread) + self.logger.info("Hardware Breakpoints Found Set") + if self.report: + self.webhook.send("Hardware Breakpoints Found Set", self.name) + self.event.dispatch( + ["hardware_breakpoint_set", "pyprotector_detect"], + "Hardware Breakpoints Found Set", + self.name, + ) + if self.exit: + self.logger.info("Hardware Breakpoints Found, Exiting") + os._exit(1) - if not self.kernel32.GetThreadContext( - hThread, ctypes.byref(ThreadContext)): self.kernel32.CloseHandle(hThread) - return - if ( - ThreadContext.contents.Dr0 != 0 - or ThreadContext.contents.Dr1 != 0 - or ThreadContext.contents.Dr2 != 0 - or ThreadContext.contents.Dr3 != 0 - ): - self.kernel32.CloseHandle(hThread) - self.logger.info("Hardware Breakpoints Found Set") - if self.report: - self.webhook.send("Hardware Breakpoints Found Set", self.name) - self.event.dispatch( - ["hardware_breakpoint_set", "pyprotector_detect"], - "Hardware Breakpoints Found Set", - self.name, - ) - if self.exit: - os._exit(1) - - self.kernel32.CloseHandle(hThread) + except Exception as e: + self.logger.error(f"Error checking hardware breakpoints: {e}") def CheckDebugFilterState(self) -> None: """Check Debug Filter State Being !=0""" @@ -254,6 +270,7 @@ def CheckDebugFilterState(self) -> None: self.name, ) if self.exit: + self.logger.info("Debug Filter State Detected, Exiting") os._exit(1) def CheckPEB(self) -> None: @@ -279,6 +296,7 @@ class PEB(ctypes.Structure): self.name, ) if self.exit: + self.logger.info("Process Being Debugged, Exiting") os._exit(1) def StartAnalyzing(self) -> None: diff --git a/pyprotector/modules/dll.py b/pyprotector/modules/dll.py index dedd6fd..0a3572c 100644 --- a/pyprotector/modules/dll.py +++ b/pyprotector/modules/dll.py @@ -1,10 +1,10 @@ """ - ____ ____ __ __ + ____ ____ __ __ / __ \\ __ __ / __ \\ _____ ____ / /_ ___ _____ / /_ / /_/ // / / // /_/ // ___// __ \\ / __// _ \\ / ___// __/ / ____// /_/ // ____// / / /_/ // /_ / __// /__ / /_ /_/ \\__, //_/ /_/ \\____/ \\__/ \\___/ \\___/ \\__/ - /____/ + /____/ Made With ❤️ By Ghoul & Marci """ @@ -24,12 +24,8 @@ class AntiDLL(Module): def __init__( - self, - webhook: Webhook, - logger: Logger, - exit: bool, - report: bool, - event: Event) -> None: + self, webhook: Webhook, logger: Logger, exit: bool, report: bool, event: Event + ) -> None: self.webhook: Webhook = webhook self.logger: Logger = logger self.exit: bool = exit @@ -41,7 +37,7 @@ def name(self) -> str: return "Anti DLL" @property - def version(self) -> int: + def version(self) -> float: return 1.0 def BlockDLLs(self) -> None: @@ -56,11 +52,12 @@ def BlockDLLs(self) -> None: hProcess: int = win32api.OpenProcess(0x0410, 0, pid) try: curProcessDLLs: tuple = win32process.EnumProcessModules( - hProcess) + hProcess + ) for dll in curProcessDLLs: dllName: str = str( - win32process.GetModuleFileNameEx( - hProcess, dll)).lower() + win32process.GetModuleFileNameEx(hProcess, dll) + ).lower() for sandboxDLL in Lists.BLACKLISTED_DLLS: if ( sandboxDLL in dllName @@ -74,7 +71,8 @@ def BlockDLLs(self) -> None: raise e if EvidenceOfSandbox: self.logger.info( - f"The Following DLL's: {EvidenceOfSandbox} Were Found Loaded") + f"The Following DLL's: {EvidenceOfSandbox} Were Found Loaded" + ) if self.report: self.webhook.send( f"The following DLLs were discovered loaded in processes running on the system. DLLS: {EvidenceOfSandbox}", @@ -84,10 +82,10 @@ def BlockDLLs(self) -> None: ["dll_attach", "pyprotector_detect"], f"The following DLLs were discovered loaded in processes running on the system. DLLS: {EvidenceOfSandbox}", self.name, - {EvidenceOfSandbox}, dlls=EvidenceOfSandbox, ) if self.exit: + self.logger.info("Exiting due to DLL detection") os._exit(1) except BaseException: pass diff --git a/pyprotector/modules/dump.py b/pyprotector/modules/dump.py index 74a0e01..b00696d 100644 --- a/pyprotector/modules/dump.py +++ b/pyprotector/modules/dump.py @@ -1,10 +1,10 @@ """ - ____ ____ __ __ + ____ ____ __ __ / __ \\ __ __ / __ \\ _____ ____ / /_ ___ _____ / /_ / /_/ // / / // /_/ // ___// __ \\ / __// _ \\ / ___// __/ / ____// /_/ // ____// / / /_/ // /_ / __// /__ / /_ /_/ \\__, //_/ /_/ \\____/ \\__/ \\___/ \\___/ \\__/ - /____/ + /____/ Made With ❤️ By Ghoul & Marci """ @@ -23,12 +23,8 @@ class AntiDump(Module): def __init__( - self, - webhook: Webhook, - logger: Logger, - exit: bool, - report: bool, - event: Event) -> None: + self, webhook: Webhook, logger: Logger, exit: bool, report: bool, event: Event + ) -> None: self.webhook: Webhook = webhook self.logger: Logger = logger self.exit: bool = exit @@ -43,7 +39,7 @@ def name(self) -> str: return "Anti Dump" @property - def version(self) -> int: + def version(self) -> float: return 1.0 def ErasePEHeaderFromMemory(self) -> None: @@ -57,12 +53,9 @@ def ErasePEHeaderFromMemory(self) -> None: self.kernel32.VirtualProtect( ctypes.pointer(baseAddress), 4096, 0x04, ctypes.pointer(oldProtect) ) - ctypes.memset( - ctypes.pointer(baseAddress), - 4096, - ctypes.sizeof(baseAddress)) + ctypes.memset(ctypes.pointer(baseAddress), 4096, ctypes.sizeof(baseAddress)) self.event.dispatch( - "pe_header_erased", "PE Header Erased From Memory", self.name + ["pe_header_erased"], "PE Header Erased From Memory", self.name ) def StartChecks(self) -> None: diff --git a/pyprotector/modules/miscellaneous.py b/pyprotector/modules/miscellaneous.py index c1ec1f1..1a72e86 100644 --- a/pyprotector/modules/miscellaneous.py +++ b/pyprotector/modules/miscellaneous.py @@ -1,29 +1,24 @@ """ - ____ ____ __ __ + ____ ____ __ __ / __ \\ __ __ / __ \\ _____ ____ / /_ ___ _____ / /_ / /_/ // / / // /_/ // ___// __ \\ / __// _ \\ / ___// __/ / ____// /_/ // ____// / / /_/ // /_ / __// /__ / /_ /_/ \\__, //_/ /_/ \\____/ \\__/ \\___/ \\___/ \\__/ - /____/ + /____/ Made With ❤️ By Ghoul & Marci """ import ctypes import os -import sys import time -import pkg_resources import socket import struct import requests import psutil import win32api -from functools import lru_cache -from typing import Literal - from ..types import Event, Logger from ..abc import Module from ..constants import UserInfo, Lists @@ -33,12 +28,8 @@ class Miscellaneous(Module): def __init__( - self, - webhook: Webhook, - logger: Logger, - exit: bool, - report: bool, - event: Event) -> None: + self, webhook: Webhook, logger: Logger, exit: bool, report: bool, event: Event + ) -> None: self.webhook: Webhook = webhook self.logger: Logger = logger self.exit: bool = exit @@ -50,10 +41,9 @@ def name(self) -> str: return self.__class__.__name__ @property - def version(self) -> int: + def version(self) -> float: return 1.0 - @lru_cache def CheckInternet(self) -> None: """ Checks If There Is A Valid Connection To The Internet @@ -64,11 +54,11 @@ def CheckInternet(self) -> None: if self.report: self.logger.info("CheckInternet Failed") if self.exit: + self.logger.info("Exiting Due To No Internet Connection") os._exit(1) else: pass - @lru_cache def CheckRAM(self) -> None: """Checks RAM Size For Being Less Than 4 GB""" memory: int = psutil.virtual_memory().total @@ -86,6 +76,7 @@ def CheckRAM(self) -> None: ram=memory, ) if self.exit: + self.logger.info("Exiting Due To Insufficient RAM") os._exit(1) def CheckIsDebuggerPresent(self) -> None: @@ -93,7 +84,7 @@ def CheckIsDebuggerPresent(self) -> None: isDebuggerPresent = ctypes.windll.kernel32.IsDebuggerPresent() if isDebuggerPresent: - self.logger.send("IsDebuggerPresent Returned True") + self.logger.info("IsDebuggerPresent Returned True") if self.report: self.webhook.send("IsDebuggerPresent Returned True", self.name) self.event.dispatch( @@ -102,6 +93,7 @@ def CheckIsDebuggerPresent(self) -> None: self.name, ) if self.exit: + self.logger.info("Exiting Due To Debugger Presence") os._exit(1) if ( @@ -110,7 +102,7 @@ def CheckIsDebuggerPresent(self) -> None: ) != 0 ): - self.logger.send("CheckRemoteDebuggerPresent Returned True") + self.logger.info("CheckRemoteDebuggerPresent Returned True") if self.report: self.webhook.send( "CheckRemoteDebuggerPresent Returned True", @@ -122,22 +114,23 @@ def CheckIsDebuggerPresent(self) -> None: self.name, ) if self.exit: + self.logger.info("Exiting Due To Remote Debugger Presence") os._exit(1) - @lru_cache def CheckDiskSize(self) -> None: """Check Disk Size""" - minDiskSizeGB: Literal[50] = 50 - if len(sys.argv) > 1: - minDiskSizeGB = float(sys.argv[1]) + minDiskSizeGB: float = 50.0 + _, diskSizeBytes, _ = win32api.GetDiskFreeSpaceEx() - diskSizeGB: int = diskSizeBytes / 1073741824 + diskSizeGB: float = diskSizeBytes / 1073741824 if diskSizeGB < minDiskSizeGB: self.logger.info("Disk Check Failed") if self.report: self.webhook.send( - f"The Current Disk Size Is {diskSizeGB}GB, Which Is Less Than The Minimum") + f"The Current Disk Size Is {diskSizeGB}GB, Which Is Less Than The Minimum", + self.name, + ) self.event.dispatch( ["disk_size_check", "pyprotector_detect"], f"The Current Disk Size Is {diskSizeGB}GB, Which Is Less Than The Minimum", @@ -145,6 +138,7 @@ def CheckDiskSize(self) -> None: disk_size=diskSizeGB, ) if self.exit: + self.logger.info("Exiting Due To Insufficient Disk Space") os._exit(1) def KillTasks(self) -> None: @@ -153,8 +147,7 @@ def KillTasks(self) -> None: os.system("taskkill /f /im HTTPDebuggerSvc.exe >nul 2>&1") os.system('taskkill /FI "IMAGENAME eq cheatengine*" /IM * /F /T >nul 2>&1') os.system('taskkill /FI "IMAGENAME eq httpdebugger*" /IM * /F /T >nul 2>&1') - os.system( - 'taskkill /FI "IMAGENAME eq processhacker*" /IM * /F /T >nul 2>&1') + os.system('taskkill /FI "IMAGENAME eq processhacker*" /IM * /F /T >nul 2>&1') os.system('taskkill /FI "IMAGENAME eq fiddler*" /IM * /F /T >nul 2>&1') os.system('taskkill /FI "IMAGENAME eq wireshark*" /IM * /F /T >nul 2>&1') os.system('taskkill /FI "IMAGENAME eq rawshark*" /IM * /F /T >nul 2>&1') @@ -162,8 +155,7 @@ def KillTasks(self) -> None: os.system('taskkill /FI "IMAGENAME eq cheatengine*" /IM * /F /T >nul 2>&1') os.system('taskkill /FI "IMAGENAME eq ida*" /IM * /F /T >nul 2>&1') os.system('taskkill /FI "IMAGENAME eq httpdebugger*" /IM * /F /T >nul 2>&1') - os.system( - 'taskkill /FI "IMAGENAME eq processhacker*" /IM * /F /T >nul 2>&1') + os.system('taskkill /FI "IMAGENAME eq processhacker*" /IM * /F /T >nul 2>&1') os.system("sc stop HTTPDebuggerPro >nul 2>&1") os.system("sc stop KProcessHacker3 >nul 2>&1") os.system("sc stop KProcessHacker2 >nul 2>&1") @@ -175,7 +167,6 @@ def KillTasks(self) -> None: 'cmd.exe /c @RD /S /Q "C:\\Users\\%username%\\AppData\\Local\\Microsoft\\Windows\\INetCache\\IE" >nul 2>&1' ) - @lru_cache def CheckPaths(self) -> None: """Checks Paths on Computer Against Blacklisted Paths""" for path in Lists.BLACKLISTED_PATHS: @@ -190,54 +181,11 @@ def CheckPaths(self) -> None: path=path, ) if self.exit: + self.logger.info(f"Exiting Due To Blacklisted Path: {path}") os._exit(1) else: pass - def CheckImports(self) -> None: - """Checks Current Installed PyPi Packages For Blacklisted Packages""" - for package in Lists.BLACKLISTED_IMPORTS: - try: - dist = pkg_resources.get_distribution(package) - if dist: - self.logger.info(f"{package} Was Found Installed") - if self.report: - self.webhook.send( - f"`{package}` Was Found Installed", - self.name, - ) - self.event.dispatch( - ["blacklisted_import", "pyprotector_detect"], - f"{package} Was Found Installed", - self.name, - package=package, - dist=dist, - ) - if self.exit: - os._exit(1) - else: - pass - except pkg_resources.DistributionNotFound: - pass - - def CheckOutPutDebugString(self) -> None: - """Checks OutPutDebugString""" - win32api.SetLastError(0) - win32api.OutputDebugString("PythonProtector Intruding...") - if win32api.GetLastError() != 0: - self.logger.info("OutputDebugString Is Not 0") - if self.report: - self.webhook.send( - "OutputDebugString Not Equal To 0", self.name) - self.event.dispatch( - ["output_debug_string", "pyprotector_detect"], - "OutputDebugString Not Equal To 0", - self.name, - ) - if self.exit: - os._exit(1) - - @lru_cache def CheckIPs(self) -> None: """Checks User IP Against Blacklisted List""" if UserInfo.IP in Lists.BLACKLISTED_IPS: @@ -253,14 +201,21 @@ def CheckIPs(self) -> None: ip=UserInfo.IP, ) if self.exit: + self.logger.info("Exiting Due To Blacklisted IP Address") os._exit(1) else: pass - @lru_cache def CheckCPUCores(self) -> None: """Checks CPU Core Count For Being Less Than 1""" - if int(psutil.cpu_count()) <= 1: + + cpu_count = psutil.cpu_count() + + if cpu_count is None: + self.logger.warning("Could Not Determine CPU Core Count") + return + + if cpu_count <= 1: self.logger.info("CPU Core Count Is Less Than Or Equal To 1") if self.report: self.webhook.send( @@ -272,6 +227,7 @@ def CheckCPUCores(self) -> None: self.name, ) if self.exit: + self.logger.info("Exiting Due To Insufficient CPU Cores") os._exit(1) def IsUsingProxy(self) -> None: @@ -290,6 +246,7 @@ def IsUsingProxy(self) -> None: header=header, ) if self.exit: + self.logger.info("Exiting Due To Proxy Headers Being Used") os._exit(1) if UserInfo.IP in Lists.PROXY_IPS: @@ -303,14 +260,14 @@ def IsUsingProxy(self) -> None: ip=UserInfo.IP, ) if self.exit: + self.logger.info("Exiting Due To Proxy IP Being Used") os._exit(1) try: _socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) _socket.settimeout(5) _socket.connect(("check.torproject.org", 9050)) - _socket.send( - b"GET / HTTP/1.1\r\nHost: check.torproject.org\r\n\r\n") + _socket.send(b"GET / HTTP/1.1\r\nHost: check.torproject.org\r\n\r\n") data: bytes = _socket.recv(1024) if "Congratulations" in data.decode(): self.logger.info("Tor Network Detected") @@ -322,6 +279,7 @@ def IsUsingProxy(self) -> None: self.name, ) if self.exit: + self.logger.info("Exiting Due To Tor Network Detection") os._exit(1) except Exception: pass @@ -331,14 +289,14 @@ def IsUsingProxy(self) -> None: if IP >> 24 in [0, 10, 100, 127, 169, 172, 192]: self.logger.info("Transparent Proxies Detected") if self.report: - self.webhook.send( - "Transparent Proxies Detected", self.name) + self.webhook.send("Transparent Proxies Detected", self.name) self.event.dispatch( ["transparent_proxies", "pyprotector_detect"], "Transparent Proxies Detected", self.name, ) if self.exit: + self.logger.info("Exiting Due To Transparent Proxies Detection") os._exit(1) except Exception: pass @@ -346,13 +304,11 @@ def IsUsingProxy(self) -> None: def StartChecks(self) -> None: if self.report: self.logger.info("Starting Miscellaneous Checks") - self.CheckImports() self.CheckPaths() self.CheckIPs() self.CheckCPUCores() self.CheckRAM() self.CheckIsDebuggerPresent() - self.CheckOutPutDebugString() self.CheckDiskSize() self.KillTasks() self.IsUsingProxy() diff --git a/pyprotector/modules/process.py b/pyprotector/modules/process.py index 0d7a806..affd07e 100644 --- a/pyprotector/modules/process.py +++ b/pyprotector/modules/process.py @@ -1,10 +1,10 @@ """ - ____ ____ __ __ + ____ ____ __ __ / __ \\ __ __ / __ \\ _____ ____ / /_ ___ _____ / /_ / /_/ // / / // /_/ // ___// __ \\ / __// _ \\ / ___// __/ / ____// /_/ // ____// / / /_/ // /_ / __// /__ / /_ /_/ \\__, //_/ /_/ \\____/ \\__/ \\___/ \\___/ \\__/ - /____/ + /____/ Made With ❤️ By Ghoul & Marci """ @@ -26,12 +26,8 @@ class AntiProcess(Module): def __init__( - self, - webhook: Webhook, - logger: Logger, - exit: bool, - report: bool, - event: Event) -> None: + self, webhook: Webhook, logger: Logger, exit: bool, report: bool, event: Event + ) -> None: self.webhook: Webhook = webhook self.logger: Logger = logger self.exit: bool = exit @@ -43,7 +39,7 @@ def name(self) -> str: return "Anti Process" @property - def version(self) -> int: + def version(self) -> float: return 1.0 def CheckProcessList(self) -> None: @@ -52,7 +48,7 @@ def CheckProcessList(self) -> None: """ while True: try: - time.sleep(0.7) + time.sleep(2.0) for process in psutil.process_iter(): if any( process_name in process.name().lower() @@ -60,8 +56,7 @@ def CheckProcessList(self) -> None: ): try: if self.report: - self.logger.info( - f"{process.name} Process Was Running") + self.logger.info(f"{process.name} Process Was Running") self.webhook.send( f"`{process.name()}` was detected running on the system.", self.name, @@ -74,6 +69,7 @@ def CheckProcessList(self) -> None: ) process.kill() if self.exit: + self.logger.info("Exiting Due to Blacklisted Process") os._exit(1) except (psutil.NoSuchProcess, psutil.AccessDenied): pass @@ -83,7 +79,7 @@ def CheckProcessList(self) -> None: def CheckWindowNames(self) -> None: """Checks Window Names Against Blacklisted List""" - def winEnumHandler(hwnd, ctx) -> None: + def winEnumHandler(hwnd, _ctx) -> None: if ( win32gui.GetWindowText(hwnd).lower() not in Lists.BLACKLISTED_WINDOW_NAMES @@ -102,9 +98,9 @@ def winEnumHandler(hwnd, ctx) -> None: self.logger.info(f"{win32gui.GetWindowText(hwnd)} Found") if self.report: self.webhook.send( - f"Debugger { - win32gui.GetWindowText(hwnd)}", - self.name) + f"Debugger {win32gui.GetWindowText(hwnd)}", + self.name, + ) self.event.dispatch( ["window_name_detected", "pyprotector_detect"], f"Debugger {win32gui.GetWindowText(hwnd)} Found Open", @@ -112,6 +108,7 @@ def winEnumHandler(hwnd, ctx) -> None: window_name=win32gui.GetWindowText(hwnd), ) if self.exit: + self.logger.info("Exiting Due to Blacklisted Window Name") os._exit(1) while True: diff --git a/pyprotector/modules/vm.py b/pyprotector/modules/vm.py index 09dc0c9..47d7701 100644 --- a/pyprotector/modules/vm.py +++ b/pyprotector/modules/vm.py @@ -1,21 +1,19 @@ """ - ____ ____ __ __ + ____ ____ __ __ / __ \\ __ __ / __ \\ _____ ____ / /_ ___ _____ / /_ / /_/ // / / // /_/ // ___// __ \\ / __// _ \\ / ___// __/ / ____// /_/ // ____// / / /_/ // /_ / __// /__ / /_ /_/ \\__, //_/ /_/ \\____/ \\__/ \\___/ \\___/ \\__/ - /____/ + /____/ Made With ❤️ By Ghoul & Marci """ import ctypes import os -import sys import httpx -from functools import lru_cache from typing import List from ..types import Event, Logger @@ -26,67 +24,80 @@ class AntiVM(Module): def __init__( - self, - webhook: Webhook, - logger: Logger, - exit: bool, - report: bool, - event: Event) -> None: + self, webhook: Webhook, logger: Logger, exit: bool, report: bool, event: Event + ) -> None: self.webhook: Webhook = webhook self.logger: Logger = logger self.exit: bool = exit self.report: bool = report self.event: Event = event - self.VMWARE_MACS: List[str] = [ - "00:05:69", "00:0c:29", "00:1c:14", "00:50:56"] + self.VMWARE_MACS: List[str] = ["00:05:69", "00:0c:29", "00:1c:14", "00:50:56"] - self.HWIDS: List[str] = httpx.get( - "https://raw.githubusercontent.com/xFGhoul/PythonProtector/dev/data/hwid_list.txt" - ).text - self.PC_NAMES: List[str] = httpx.get( - "https://raw.githubusercontent.com/xFGhoul/PythonProtector/dev/data/pc_name_list.txt" - ).text - self.PC_USERNAMES: List[str] = httpx.get( - "https://raw.githubusercontent.com/xFGhoul/PythonProtector/dev/data/pc_username_list.txt" - ).text - self.IPS: List[str] = httpx.get( - "https://raw.githubusercontent.com/xFGhoul/PythonProtector/dev/data/ip_list.txt" - ).text - self.MACS: List[str] = httpx.get( - "https://raw.githubusercontent.com/xFGhoul/PythonProtector/dev/data/mac_list.txt" - ).text - self.GPUS: List[str] = httpx.get( - "https://raw.githubusercontent.com/xFGhoul/PythonProtector/dev/data/gpu_list.txt" - ).text - self.PLATFORMS: List[str] = httpx.get( - "https://raw.githubusercontent.com/xFGhoul/PythonProtector/dev/data/pc_platforms.txt" - ).text + self.HWIDS: List[str] = ( + httpx.get( + "https://raw.githubusercontent.com/xFGhoul/PythonProtector/dev/data/hwid_list.txt" + ) + .text.strip() + .split("\n") + ) + self.PC_NAMES: List[str] = ( + httpx.get( + "https://raw.githubusercontent.com/xFGhoul/PythonProtector/dev/data/pc_name_list.txt" + ) + .text.strip() + .split("\n") + ) + self.PC_USERNAMES: List[str] = ( + httpx.get( + "https://raw.githubusercontent.com/xFGhoul/PythonProtector/dev/data/pc_username_list.txt" + ) + .text.strip() + .split("\n") + ) + self.IPS: List[str] = ( + httpx.get( + "https://raw.githubusercontent.com/xFGhoul/PythonProtector/dev/data/ip_list.txt" + ) + .text.strip() + .split("\n") + ) + self.MACS: List[str] = ( + httpx.get( + "https://raw.githubusercontent.com/xFGhoul/PythonProtector/dev/data/mac_list.txt" + ) + .text.strip() + .split("\n") + ) + self.GPUS: List[str] = ( + httpx.get( + "https://raw.githubusercontent.com/xFGhoul/PythonProtector/dev/data/gpu_list.txt" + ) + .text.strip() + .split("\n") + ) + self.PLATFORMS: List[str] = ( + httpx.get( + "https://raw.githubusercontent.com/xFGhoul/PythonProtector/dev/data/pc_platforms.txt" + ) + .text.strip() + .split("\n") + ) @property def name(self) -> str: return "Anti VM" @property - def version(self) -> int: + def version(self) -> float: return 1.0 - def _get_base_prefix_compat(self) -> None: - return ( - getattr(sys, "base_prefix", None) - or getattr(sys, "real_prefix", None) - or sys.prefix - ) - - @lru_cache def CheckLists(self) -> None: """ Checks if the user's HWID, PC username, PC name, IP, MAC address, or GPU is in the blacklists. """ if UserInfo.HWID in self.HWIDS: - self.logger.info( - f"Blacklisted HWID Detected. HWID: { - UserInfo.HWID}") + self.logger.info(f"Blacklisted HWID Detected. HWID: {UserInfo.HWID}") if self.report: self.webhook.send( f"Blacklisted HWID Detected: `{UserInfo.HWID}`", self.name @@ -98,6 +109,7 @@ def CheckLists(self) -> None: hwid=UserInfo.HWID, ) if self.exit: + self.logger.info("Exiting due to blacklisted HWID") os._exit(1) if UserInfo.USERNAME in self.PC_USERNAMES: @@ -113,6 +125,7 @@ def CheckLists(self) -> None: pc_username=UserInfo.USERNAME, ) if self.exit: + self.logger.info("Exiting due to blacklisted PC username") os._exit(1) if UserInfo.PC_NAME in self.PC_NAMES: @@ -128,14 +141,16 @@ def CheckLists(self) -> None: pc_name=UserInfo.PC_NAME, ) if self.exit: + self.logger.info("Exiting due to blacklisted PC name") os._exit(1) if UserInfo.IP in self.IPS: self.logger.info(f"Blacklisted IP: {UserInfo.IP}") if self.report: self.webhook.send( - f"Blacklisted IP: `{ - UserInfo.IP}`", self.name) + f"Blacklisted IP: `{UserInfo.IP}`", + self.name, + ) self.event.dispatch( ["blacklisted_ip", "pyprotector_detect"], "Blacklisted IP Detected", @@ -143,14 +158,16 @@ def CheckLists(self) -> None: ip=UserInfo.IP, ) if self.exit: + self.logger.info("Exiting due to blacklisted IP") os._exit(1) if UserInfo.MAC in self.MACS: self.logger.info(f"Blacklisted MAC: {UserInfo.MAC}") if self.report: self.webhook.send( - f"Blacklisted MAC: `{ - UserInfo.MAC}`", self.name) + f"Blacklisted MAC: `{UserInfo.MAC}`", + self.name, + ) self.event.dispatch( ["blacklisted_mac_address", "pyprotector_detect"], "Blacklisted MAC Detected", @@ -158,14 +175,16 @@ def CheckLists(self) -> None: mac_addr=UserInfo.MAC, ) if self.exit: + self.logger.info("Exiting due to blacklisted MAC address") os._exit(1) if UserInfo.GPU in self.GPUS: self.logger.info(f"Blacklisted GPU: {UserInfo.GPU}") if self.report: self.webhook.send( - f"Blacklisted GPU: `{ - UserInfo.GPU}`", self.name) + f"Blacklisted GPU: `{UserInfo.GPU}`", + self.name, + ) self.event.dispatch( ["blacklisted_gpu", "pyprotector_detect"], "Blacklisted GPU Detected", @@ -173,17 +192,9 @@ def CheckLists(self) -> None: gpu=UserInfo.GPU, ) if self.exit: + self.logger.info("Exiting due to blacklisted GPU") os._exit(1) - @lru_cache - def CheckVirtualEnv(self) -> None: - """ - Checks sys.prefix - """ - if self._get_base_prefix_compat() != sys.prefix and self.exit: - os._exit(1) - - @lru_cache def CheckRegistry(self) -> None: """ Checks VMWare Registry Keys @@ -207,6 +218,7 @@ def CheckRegistry(self) -> None: reg2=reg2, ) if self.exit: + self.logger.info("Exiting due to VMWare Registry Detection") os._exit(1) def CheckMacAddress(self) -> None: @@ -224,9 +236,9 @@ def CheckMacAddress(self) -> None: mac_addr=UserInfo.MAC, ) if self.exit: + self.logger.info("Exiting due to VMWare MAC Address Detection") os._exit(1) - @lru_cache def CheckScreenSize(self) -> None: """ Checks the screen size for being less than 200x200 @@ -236,8 +248,7 @@ def CheckScreenSize(self) -> None: if x <= 200 or y <= 200: self.logger.info(f"Screen Size X: {x} | Y: {y}") if self.report: - self.webhook.send( - f"Screen Size Is: **x**: {x} | **y**: {y}", self.name) + self.webhook.send(f"Screen Size Is: **x**: {x} | **y**: {y}", self.name) self.event.dispatch( ["screen_size", "pyprotector_detect"], f"Screen Size X: {x} | Y: {y}", @@ -246,6 +257,7 @@ def CheckScreenSize(self) -> None: y=y, ) if self.exit: + self.logger.info("Exiting due to small screen size") os._exit(1) def CheckProcessesAndFiles(self) -> None: @@ -255,8 +267,7 @@ def CheckProcessesAndFiles(self) -> None: vmware_dll: str = os.path.join( os.environ["SystemRoot"], "System32\\vmGuestLib.dll" ) - virtualbox_dll: str = os.path.join( - os.environ["SystemRoot"], "vboxmrxnp.dll") + virtualbox_dll: str = os.path.join(os.environ["SystemRoot"], "vboxmrxnp.dll") process: str = os.popen( 'TASKLIST /FI "STATUS eq RUNNING" | find /V "Image Name" | find /V "="' @@ -265,12 +276,7 @@ def CheckProcessesAndFiles(self) -> None: for processNames in process.split(" "): if ".exe" in processNames: - processList.append( - processNames.replace( - "K\n", - "").replace( - "\n", - "")) + processList.append(processNames.replace("K\n", "").replace("\n", "")) if any(Lists.VIRTUAL_MACHINE_PROCESSES) in processList: self.logger.info("Blacklisted Virtual Machine Process Running") @@ -285,6 +291,7 @@ def CheckProcessesAndFiles(self) -> None: processes=processList, ) if self.exit: + self.logger.info("Exiting due to blacklisted VM process") os._exit(1) if os.path.exists(vmware_dll): @@ -298,6 +305,7 @@ def CheckProcessesAndFiles(self) -> None: dll=vmware_dll, ) if self.exit: + self.logger.info("Exiting due to VMWare DLL Detection") os._exit(1) if os.path.exists(virtualbox_dll): @@ -311,12 +319,12 @@ def CheckProcessesAndFiles(self) -> None: dll=virtualbox_dll, ) if self.exit: + self.logger.info("Exiting due to VirtualBox DLL Detection") os._exit(1) def StartChecks(self) -> None: if self.report: self.logger.info("Starting VM Checks") - self.CheckVirtualEnv() self.CheckRegistry() self.CheckMacAddress() self.CheckScreenSize() diff --git a/pyprotector/protector.py b/pyprotector/protector.py index 83475b9..f600795 100644 --- a/pyprotector/protector.py +++ b/pyprotector/protector.py @@ -1,10 +1,10 @@ """ - ____ ____ __ __ + ____ ____ __ __ / __ \\ __ __ / __ \\ _____ ____ / /_ ___ _____ / /_ / /_/ // / / // /_/ // ___// __ \\ / __// _ \\ / ___// __/ / ____// /_/ // ____// / / /_/ // /_ / __// /__ / /_ /_/ \\__, //_/ /_/ \\____/ \\__/ \\___/ \\___/ \\__/ - /____/ + /____/ Made With ❤️ By Ghoul & Marci """ @@ -24,7 +24,7 @@ from command_runner.elevate import is_admin from loguru import logger -from .constants import ProtectorInfo, LoggingInfo, UserInfo, Valid +from .constants import ProtectorInfo, UserInfo, Valid, encrypted_formatter from .modules.process import AntiProcess from .modules.vm import AntiVM from .modules.dll import AntiDLL @@ -41,7 +41,7 @@ def __init__( self, debug: Optional[bool], modules: List[str], - webhook_url: Optional[str], + webhook_url: str, on_detect: Optional[List[str]], logs_path: Optional[Union[Path, str]] = None, ) -> None: @@ -67,7 +67,7 @@ def __init__( "List Of Modules Provided Does Not Match, Consider Checking Valid Modules." ) - self.detections: List[str] = on_detect + self.detections: List[str] = on_detect or [] _detections_valid: bool = Valid.Detections.issuperset(self.detections) if not _detections_valid: raise DetectionsNotValid( @@ -83,15 +83,14 @@ def __init__( raise LogsPathEmpty("Debug Enabled But No Log Path Was Provided.") if self.logs_path and not self.debug: - raise RuntimeWarning( - "Logs Path Was Provided But Debug Was Disabled.") + raise RuntimeWarning("Logs Path Was Provided But Debug Was Disabled.") if self.debug and self.logs_path: LOGGING_CONFIG: Dict = { "handlers": [ { - "sink": self.logs_path, - "format": LoggingInfo.encrypted_formatter, + "sink": str(self.logs_path), + "format": encrypted_formatter, "enqueue": True, "rotation": "daily", "mode": "w", @@ -116,11 +115,10 @@ def __init__( self.webhook_url: str = webhook_url if self.report and self.webhook_url is None: - raise RuntimeWarning( - "Reporting Was Set But No Webhook URL Was Provided.") + raise RuntimeWarning("Reporting Was Set But No Webhook URL Was Provided.") self.webhook: Webhook = Webhook( - self.webhook_url, self.logs_path, self.screenshot + self.webhook_url, str(self.logs_path), self.screenshot ) # -- Initialize Modules @@ -196,32 +194,32 @@ def _run_module_threads(self, debug: bool) -> None: if debug: if "Miscellaneous" in self.modules: self.logger.info("Starting Miscellaneous Thread") - Thread(name=self.Miscellaneous.name, - target=self.Miscellaneous.StartChecks).start() + Thread( + name=self.Miscellaneous.name, target=self.Miscellaneous.StartChecks + ).start() self.logger.info("Miscellaneous Thread Started") if "AntiProcess" in self.modules: self.logger.info("Starting Anti Process Thread") - Thread(name="Anti Process List", - target=self.AntiProcess.CheckProcessList).start() - Thread(name="Anti Window Names", - target=self.AntiProcess.CheckWindowNames).start() + Thread( + name="Anti Process List", target=self.AntiProcess.CheckProcessList + ).start() + Thread( + name="Anti Window Names", target=self.AntiProcess.CheckWindowNames + ).start() self.logger.info("Anti Process Thread Started") if "AntiDLL" in self.modules: self.logger.info("Starting Anti DLL Thread") - Thread( - name=self.AntiDLL.name, - target=self.AntiDLL.BlockDLLs).start() + Thread(name=self.AntiDLL.name, target=self.AntiDLL.BlockDLLs).start() self.logger.info("Anti DLL Thread Started") if "AntiVM" in self.modules: self.logger.info("Starting Anti VM Thread") - Thread( - name=self.AntiVM.name, - target=self.AntiVM.StartChecks).start() + Thread(name=self.AntiVM.name, target=self.AntiVM.StartChecks).start() self.logger.info("Anti VM Thread Started") if "AntiAnalysis" in self.modules: self.logger.info("Starting Anti Analysis Thread") - Thread(name=self.AntiAnalysis.name, - target=self.AntiAnalysis.StartAnalyzing).start() + Thread( + name=self.AntiAnalysis.name, target=self.AntiAnalysis.StartAnalyzing + ).start() self.logger.info("Anti Analysis Thread Started") if "AntiDump" in self.modules: self.logger.info("Starting Anti Dump Thread") @@ -231,41 +229,39 @@ def _run_module_threads(self, debug: bool) -> None: self.logger.info("Started Anti Dump Thread") else: if "Miscellaneous" in self.modules: - Thread(name=self.Miscellaneous.name, - target=self.Miscellaneous.StartChecks).start() + Thread( + name=self.Miscellaneous.name, target=self.Miscellaneous.StartChecks + ).start() if "AntiProcess" in self.modules: - Thread(name="Anti Process List", - target=self.AntiProcess.CheckProcessList).start() - Thread(name="Anti Window Names", - target=self.AntiProcess.CheckWindowNames).start() - if "AntiDLL" in self.modules: Thread( - name=self.AntiDLL.name, - target=self.AntiDLL.BlockDLLs).start() - if "AntiVM" in self.modules: + name="Anti Process List", target=self.AntiProcess.CheckProcessList + ).start() Thread( - name=self.AntiVM.name, - target=self.AntiVM.StartChecks).start() + name="Anti Window Names", target=self.AntiProcess.CheckWindowNames + ).start() + if "AntiDLL" in self.modules: + Thread(name=self.AntiDLL.name, target=self.AntiDLL.BlockDLLs).start() + if "AntiVM" in self.modules: + Thread(name=self.AntiVM.name, target=self.AntiVM.StartChecks).start() if "AntiAnalysis" in self.modules: - Thread(name=self.AntiAnalysis.name, - target=self.AntiAnalysis.StartAnalyzing).start() + Thread( + name=self.AntiAnalysis.name, target=self.AntiAnalysis.StartAnalyzing + ).start() if "AntiDump" in self.modules: Thread( name=self.AntiDump.name, target=self.AntiDump.StartChecks ).start() - def _run_debug_module_threads(self): + def _run_no_debug_module_threads(self): self.logger.info("PythonProtector Starting") self.logger.info(f"Version: {ProtectorInfo.VERSION}") self.logger.info(f"Current Path: {ProtectorInfo.ROOT_PATH}") self.logger.info( - f"Operating System: { - platform.uname().system} { - platform.uname().release} { - platform.win32_edition()} ({ - platform.architecture( - sys.executable)[0]})") + f"Operating System: {platform.uname().system} {platform.uname().release} { + platform.win32_edition() + } ({platform.architecture(sys.executable)[0]})" + ) bt = datetime.datetime.fromtimestamp(psutil.boot_time()) self.logger.info( f"Boot Time: {bt.year}/{bt.month}/{bt.day} {bt.hour}:{bt.minute}:{bt.second}" @@ -283,10 +279,7 @@ def _run_debug_module_threads(self): vmem = psutil.virtual_memory() self.logger.info(f"Total Memory: {humanize.naturalsize(vmem.total)}") - self.logger.info( - f"Memory Availability: { - humanize.naturalsize( - vmem.available)}") + self.logger.info(f"Memory Availability: {humanize.naturalsize(vmem.available)}") self.logger.info(f"Memory Percentage: {vmem.percent}%") self.logger.info("Starting PythonProtector Services") @@ -297,17 +290,17 @@ def start(self) -> None: """Main Function Of PythonProtector Raises: - DeprecationWarning: If Python Version < 3.12 + DeprecationWarning: If Python Version < 3.13 """ # -- Check If Windows Platform if sys.platform != "win32": os._exit(1) - if platform.python_version_tuple()[1] < "12": - raise DeprecationWarning("Python Is Not 3.12+") + if platform.python_version_tuple()[1] < "13": + raise DeprecationWarning("Python Is Not 3.13+") # -- Start Main Program if self.debug: - self._run_debug_module_threads() + self._run_module_threads(debug=True) else: - self._run_module_threads(debug=False) + self._run_no_debug_module_threads() diff --git a/pyprotector/types.py b/pyprotector/types.py index f1331cf..291a05d 100644 --- a/pyprotector/types.py +++ b/pyprotector/types.py @@ -1,18 +1,16 @@ """ - ____ ____ __ __ + ____ ____ __ __ / __ \\ __ __ / __ \\ _____ ____ / /_ ___ _____ / /_ / /_/ // / / // /_/ // ___// __ \\ / __// _ \\ / ___// __/ / ____// /_/ // ____// / / /_/ // /_ / __// /__ / /_ /_/ \\__, //_/ /_/ \\____/ \\__/ \\___/ \\___/ \\__/ - /____/ + /____/ Made With ❤️ By Ghoul & Marci """ -from typing import Type - from pyprotector.utils.events import ProtectorObservable from loguru import logger -Event = Type[ProtectorObservable] -Logger = Type[logger] +Event = ProtectorObservable +Logger = logger diff --git a/pyprotector/utils/__init__.py b/pyprotector/utils/__init__.py index de3873d..3e242fd 100644 --- a/pyprotector/utils/__init__.py +++ b/pyprotector/utils/__init__.py @@ -4,7 +4,7 @@ / /_/ // / / // /_/ // ___// __ \\ / __// _ \\ / ___// __/ / ____// /_/ // ____// / / /_/ // /_ / __// /__ / /_ /_/ \\__, //_/ /_/ \\____/ \\__/ \\___/ \\___/ \\__/ - /____/ + /____/ Made With ❤️ By Ghoul & Marci """ diff --git a/pyprotector/utils/events.py b/pyprotector/utils/events.py index 9327b31..da4473f 100644 --- a/pyprotector/utils/events.py +++ b/pyprotector/utils/events.py @@ -17,12 +17,7 @@ class ProtectorObservable: def __init__(self) -> None: self.obs: Observable = Observable() - def dispatch( - self, - events: List[str], - text: str, - module: str, - **kwargs) -> None: + def dispatch(self, events: List[str], text: str, module: str, **kwargs) -> None: """ It triggers an event. diff --git a/pyprotector/utils/exceptions.py b/pyprotector/utils/exceptions.py index fe75415..8ff45c1 100644 --- a/pyprotector/utils/exceptions.py +++ b/pyprotector/utils/exceptions.py @@ -1,10 +1,10 @@ """ - ____ ____ __ __ + ____ ____ __ __ / __ \\ __ __ / __ \\ _____ ____ / /_ ___ _____ / /_ / /_/ // / / // /_/ // ___// __ \\ / __// _ \\ / ___// __/ / ____// /_/ // ____// / / /_/ // /_ / __// /__ / /_ /_/ \\__, //_/ /_/ \\____/ \\__/ \\___/ \\___/ \\__/ - /____/ + /____/ Made With ❤️ By Ghoul & Marci """ diff --git a/pyprotector/utils/http.py b/pyprotector/utils/http.py index de34174..3d423d6 100644 --- a/pyprotector/utils/http.py +++ b/pyprotector/utils/http.py @@ -1,10 +1,10 @@ """ - ____ ____ __ __ + ____ ____ __ __ / __ \\ __ __ / __ \\ _____ ____ / /_ ___ _____ / /_ / /_/ // / / // /_/ // ___// __ \\ / __// _ \\ / ___// __/ / ____// /_/ // ____// / / /_/ // /_ / __// /__ / /_ /_/ \\__, //_/ /_/ \\____/ \\__/ \\___/ \\___/ \\__/ - /____/ + /____/ Made With ❤️ By Ghoul & Marci """ @@ -42,7 +42,9 @@ def hasInternet() -> bool: A boolean value. """ try: - return httpx.get("https://google.com") + response = httpx.get("https://www.google.com", timeout=5) + response.raise_for_status() + return True except ( httpx.TimeoutException, httpx.RequestError, diff --git a/pyprotector/utils/webhook.py b/pyprotector/utils/webhook.py index 3240c2b..8f5666e 100644 --- a/pyprotector/utils/webhook.py +++ b/pyprotector/utils/webhook.py @@ -1,10 +1,10 @@ """ - ____ ____ __ __ + ____ ____ __ __ / __ \\ __ __ / __ \\ _____ ____ / /_ ___ _____ / /_ / /_/ // / / // /_/ // ___// __ \\ / __// _ \\ / ___// __/ / ____// /_/ // ____// / / /_/ // /_ / __// /__ / /_ /_/ \\__, //_/ /_/ \\____/ \\__/ \\___/ \\___/ \\__/ - /____/ + /____/ Made With ❤️ By Ghoul & Marci """ @@ -12,7 +12,7 @@ import io from io import BytesIO -from PIL import Image, ImageGrab +from PIL import ImageGrab from base64 import b64decode from typing import Optional, List @@ -24,13 +24,11 @@ class Webhook: def __init__( - self, - webhook_url: str, - logs_path: Optional[str], - screenshot: Optional[bool]) -> None: + self, webhook_url: str, logs_path: str, screenshot: Optional[bool] + ) -> None: self.webhook_url: str = webhook_url self.logs_path: str = logs_path - self.screenshot: bool = screenshot + self.screenshot: bool = screenshot if screenshot else False def TakeScreenshot(self) -> bytes: """ @@ -39,18 +37,16 @@ def TakeScreenshot(self) -> bytes: Returns: A byte array of the screenshot. """ - screenshot: Image = ImageGrab.grab( - bbox=None, - include_layered_windows=False, - all_screens=True, - xdisplay=None) + screenshot = ImageGrab.grab( + bbox=None, include_layered_windows=False, all_screens=True, xdisplay=None + ) - screenshot_bytes_array: BytesIO = io.BytesIO() + screenshot_bytes_array = io.BytesIO() screenshot.save(screenshot_bytes_array, format="PNG") screenshot_bytes_array = screenshot_bytes_array.getvalue() return screenshot_bytes_array - def DecryptLogs(self) -> bytes: + def DecryptLogs(self) -> str: """ Decrypts Logs File @@ -64,8 +60,7 @@ def DecryptLogs(self) -> bytes: if not line.strip(): continue encrypted_message: str = line.split(" ")[4] - encoded_message: bytes = b64decode( - encrypted_message.encode("latin1")) + encoded_message: bytes = b64decode(encrypted_message.encode("latin1")) decrypted_message: str = LoggingInfo.CIPHER.decrypt( encoded_message ).decode("utf-8") @@ -87,23 +82,19 @@ def send(self, content: str, module: str) -> None: ) webhook.add_file( - file=self.DecryptLogs(), filename=f"{ - UserInfo.USERNAME}-[Security].log") + file=self.DecryptLogs().encode("utf-8"), + filename=f"{UserInfo.USERNAME}-[Security].log", + ) embed: DiscordEmbed = DiscordEmbed( title=EmbedConfig.TITLE, color=EmbedConfig.COLOR ) if self.screenshot: - webhook.add_file( - file=self.TakeScreenshot(), - filename="screenshot.jpg") + webhook.add_file(file=self.TakeScreenshot(), filename="screenshot.jpg") embed.set_image(url="attachment://screenshot.jpg") - embed.add_embed_field( - name="User", - value=UserInfo.USERNAME, - inline=True) + embed.add_embed_field(name="User", value=UserInfo.USERNAME, inline=True) embed.add_embed_field(name="IP", value=UserInfo.IP, inline=True) embed.add_embed_field(name="Module", value=module, inline=True) @@ -112,9 +103,9 @@ def send(self, content: str, module: str) -> None: embed.set_thumbnail(url=EmbedConfig.ICON) embed.set_footer( - text=f"PythonProtector | { - EmbedConfig.VERSION}", - icon_url=EmbedConfig.ICON) + text=f"PythonProtector | {EmbedConfig.VERSION}", + icon_url=EmbedConfig.ICON, + ) webhook.add_embed(embed) diff --git a/pyprotector/utils/windows.py b/pyprotector/utils/windows.py index 6af2414..a7d6bea 100644 --- a/pyprotector/utils/windows.py +++ b/pyprotector/utils/windows.py @@ -1,10 +1,10 @@ """ - ____ ____ __ __ + ____ ____ __ __ / __ \\ __ __ / __ \\ _____ ____ / /_ ___ _____ / /_ / /_/ // / / // /_/ // ___// __ \\ / __// _ \\ / ___// __/ / ____// /_/ // ____// / / /_/ // /_ / __// /__ / /_ /_/ \\__, //_/ /_/ \\____/ \\__/ \\___/ \\___/ \\__/ - /____/ + /____/ Made With ❤️ By Ghoul & Marci """ diff --git a/scripts/format.bat b/scripts/format.bat index 5994bce..0fd0316 100644 --- a/scripts/format.bat +++ b/scripts/format.bat @@ -1,8 +1,5 @@ -cd .. - -black -v . - -autopep8 --in-place --aggressive --aggressive --recursive -v . +@echo off +cd .. -autoflake --in-place --remove-unused-variables . +ruff format \ No newline at end of file diff --git a/scripts/format_linux.sh b/scripts/format_linux.sh index 3f7afc6..f7e3f5a 100644 --- a/scripts/format_linux.sh +++ b/scripts/format_linux.sh @@ -4,21 +4,7 @@ echo ------------------------------------- echo [*] Starting Format Process - -echo ------------------------------------- - -cd .. - -black -v . - -echo ------------------------------------- - -autopep8 --in-place --aggressive --aggressive --recursive -v . - - -echo ------------------------------------- - -autoflake --in-place --remove-unused-variables . +ruff format echo ------------------------------------- diff --git a/uv.lock b/uv.lock index 35e9700..9d2d7a7 100644 --- a/uv.lock +++ b/uv.lock @@ -134,45 +134,49 @@ wheels = [ [[package]] name = "command-runner" -version = "1.7.0" +version = "1.7.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "psutil" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ab/87/5588affc95b158ef639428122c990163fa5201cc0d473af788dd82af38f6/command_runner-1.7.0.tar.gz", hash = "sha256:0e37ab943ea577ac7fb55c5b1528bdb8339cc8b4ade71d48aac209da3b7d1f48", size = 39372 } +sdist = { url = "https://files.pythonhosted.org/packages/08/1d/f2b18a7b1340b05cebda250bc78cd68efac2d9994849739cac8cef556547/command_runner-1.7.4.tar.gz", hash = "sha256:2a711abcfc64608ec519b21aee539d19919184d0a9567454cab03f0e57ffdb64", size = 41432 } wheels = [ - { url = "https://files.pythonhosted.org/packages/11/65/3f68702725baf23e03a39f881444caee854979cfb8e63461486892d58db1/command_runner-1.7.0-py3-none-any.whl", hash = "sha256:cd48c701273fa4871abd368da01f458b54923a951896d4da112d046767633570", size = 25356 }, + { url = "https://files.pythonhosted.org/packages/3c/c5/81b39223db25c53cd023921ec46959bd97742d31a37397179b335fd0718a/command_runner-1.7.4-py3-none-any.whl", hash = "sha256:436f5a17813a57473b2123e9f14995c0972fc636665114de3db5941b7e953c38", size = 26195 }, ] [[package]] name = "cryptography" -version = "44.0.0" +version = "45.0.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cffi", marker = "platform_python_implementation != 'PyPy'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/91/4c/45dfa6829acffa344e3967d6006ee4ae8be57af746ae2eba1c431949b32c/cryptography-44.0.0.tar.gz", hash = "sha256:cd4e834f340b4293430701e772ec543b0fbe6c2dea510a5286fe0acabe153a02", size = 710657 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/55/09/8cc67f9b84730ad330b3b72cf867150744bf07ff113cda21a15a1c6d2c7c/cryptography-44.0.0-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:84111ad4ff3f6253820e6d3e58be2cc2a00adb29335d4cacb5ab4d4d34f2a123", size = 6541833 }, - { url = "https://files.pythonhosted.org/packages/7e/5b/3759e30a103144e29632e7cb72aec28cedc79e514b2ea8896bb17163c19b/cryptography-44.0.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b15492a11f9e1b62ba9d73c210e2416724633167de94607ec6069ef724fad092", size = 3922710 }, - { url = "https://files.pythonhosted.org/packages/5f/58/3b14bf39f1a0cfd679e753e8647ada56cddbf5acebffe7db90e184c76168/cryptography-44.0.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:831c3c4d0774e488fdc83a1923b49b9957d33287de923d58ebd3cec47a0ae43f", size = 4137546 }, - { url = "https://files.pythonhosted.org/packages/98/65/13d9e76ca19b0ba5603d71ac8424b5694415b348e719db277b5edc985ff5/cryptography-44.0.0-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:761817a3377ef15ac23cd7834715081791d4ec77f9297ee694ca1ee9c2c7e5eb", size = 3915420 }, - { url = "https://files.pythonhosted.org/packages/b1/07/40fe09ce96b91fc9276a9ad272832ead0fddedcba87f1190372af8e3039c/cryptography-44.0.0-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:3c672a53c0fb4725a29c303be906d3c1fa99c32f58abe008a82705f9ee96f40b", size = 4154498 }, - { url = "https://files.pythonhosted.org/packages/75/ea/af65619c800ec0a7e4034207aec543acdf248d9bffba0533342d1bd435e1/cryptography-44.0.0-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:4ac4c9f37eba52cb6fbeaf5b59c152ea976726b865bd4cf87883a7e7006cc543", size = 3932569 }, - { url = "https://files.pythonhosted.org/packages/c7/af/d1deb0c04d59612e3d5e54203159e284d3e7a6921e565bb0eeb6269bdd8a/cryptography-44.0.0-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ed3534eb1090483c96178fcb0f8893719d96d5274dfde98aa6add34614e97c8e", size = 4016721 }, - { url = "https://files.pythonhosted.org/packages/bd/69/7ca326c55698d0688db867795134bdfac87136b80ef373aaa42b225d6dd5/cryptography-44.0.0-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:f3f6fdfa89ee2d9d496e2c087cebef9d4fcbb0ad63c40e821b39f74bf48d9c5e", size = 4240915 }, - { url = "https://files.pythonhosted.org/packages/ef/d4/cae11bf68c0f981e0413906c6dd03ae7fa864347ed5fac40021df1ef467c/cryptography-44.0.0-cp37-abi3-win32.whl", hash = "sha256:eb33480f1bad5b78233b0ad3e1b0be21e8ef1da745d8d2aecbb20671658b9053", size = 2757925 }, - { url = "https://files.pythonhosted.org/packages/64/b1/50d7739254d2002acae64eed4fc43b24ac0cc44bf0a0d388d1ca06ec5bb1/cryptography-44.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:abc998e0c0eee3c8a1904221d3f67dcfa76422b23620173e28c11d3e626c21bd", size = 3202055 }, - { url = "https://files.pythonhosted.org/packages/11/18/61e52a3d28fc1514a43b0ac291177acd1b4de00e9301aaf7ef867076ff8a/cryptography-44.0.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:660cb7312a08bc38be15b696462fa7cc7cd85c3ed9c576e81f4dc4d8b2b31591", size = 6542801 }, - { url = "https://files.pythonhosted.org/packages/1a/07/5f165b6c65696ef75601b781a280fc3b33f1e0cd6aa5a92d9fb96c410e97/cryptography-44.0.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1923cb251c04be85eec9fda837661c67c1049063305d6be5721643c22dd4e2b7", size = 3922613 }, - { url = "https://files.pythonhosted.org/packages/28/34/6b3ac1d80fc174812486561cf25194338151780f27e438526f9c64e16869/cryptography-44.0.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:404fdc66ee5f83a1388be54300ae978b2efd538018de18556dde92575e05defc", size = 4137925 }, - { url = "https://files.pythonhosted.org/packages/d0/c7/c656eb08fd22255d21bc3129625ed9cd5ee305f33752ef2278711b3fa98b/cryptography-44.0.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:c5eb858beed7835e5ad1faba59e865109f3e52b3783b9ac21e7e47dc5554e289", size = 3915417 }, - { url = "https://files.pythonhosted.org/packages/ef/82/72403624f197af0db6bac4e58153bc9ac0e6020e57234115db9596eee85d/cryptography-44.0.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:f53c2c87e0fb4b0c00fa9571082a057e37690a8f12233306161c8f4b819960b7", size = 4155160 }, - { url = "https://files.pythonhosted.org/packages/a2/cd/2f3c440913d4329ade49b146d74f2e9766422e1732613f57097fea61f344/cryptography-44.0.0-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:9e6fc8a08e116fb7c7dd1f040074c9d7b51d74a8ea40d4df2fc7aa08b76b9e6c", size = 3932331 }, - { url = "https://files.pythonhosted.org/packages/7f/df/8be88797f0a1cca6e255189a57bb49237402b1880d6e8721690c5603ac23/cryptography-44.0.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:d2436114e46b36d00f8b72ff57e598978b37399d2786fd39793c36c6d5cb1c64", size = 4017372 }, - { url = "https://files.pythonhosted.org/packages/af/36/5ccc376f025a834e72b8e52e18746b927f34e4520487098e283a719c205e/cryptography-44.0.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a01956ddfa0a6790d594f5b34fc1bfa6098aca434696a03cfdbe469b8ed79285", size = 4239657 }, - { url = "https://files.pythonhosted.org/packages/46/b0/f4f7d0d0bcfbc8dd6296c1449be326d04217c57afb8b2594f017eed95533/cryptography-44.0.0-cp39-abi3-win32.whl", hash = "sha256:eca27345e1214d1b9f9490d200f9db5a874479be914199194e746c893788d417", size = 2758672 }, - { url = "https://files.pythonhosted.org/packages/97/9b/443270b9210f13f6ef240eff73fd32e02d381e7103969dc66ce8e89ee901/cryptography-44.0.0-cp39-abi3-win_amd64.whl", hash = "sha256:708ee5f1bafe76d041b53a4f95eb28cdeb8d18da17e597d46d7833ee59b97ede", size = 3202071 }, +sdist = { url = "https://files.pythonhosted.org/packages/13/1f/9fa001e74a1993a9cadd2333bb889e50c66327b8594ac538ab8a04f915b7/cryptography-45.0.3.tar.gz", hash = "sha256:ec21313dd335c51d7877baf2972569f40a4291b76a0ce51391523ae358d05899", size = 744738 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/82/b2/2345dc595998caa6f68adf84e8f8b50d18e9fc4638d32b22ea8daedd4b7a/cryptography-45.0.3-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:7573d9eebaeceeb55285205dbbb8753ac1e962af3d9640791d12b36864065e71", size = 7056239 }, + { url = "https://files.pythonhosted.org/packages/71/3d/ac361649a0bfffc105e2298b720d8b862330a767dab27c06adc2ddbef96a/cryptography-45.0.3-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d377dde61c5d67eb4311eace661c3efda46c62113ff56bf05e2d679e02aebb5b", size = 4205541 }, + { url = "https://files.pythonhosted.org/packages/70/3e/c02a043750494d5c445f769e9c9f67e550d65060e0bfce52d91c1362693d/cryptography-45.0.3-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fae1e637f527750811588e4582988932c222f8251f7b7ea93739acb624e1487f", size = 4433275 }, + { url = "https://files.pythonhosted.org/packages/40/7a/9af0bfd48784e80eef3eb6fd6fde96fe706b4fc156751ce1b2b965dada70/cryptography-45.0.3-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:ca932e11218bcc9ef812aa497cdf669484870ecbcf2d99b765d6c27a86000942", size = 4209173 }, + { url = "https://files.pythonhosted.org/packages/31/5f/d6f8753c8708912df52e67969e80ef70b8e8897306cd9eb8b98201f8c184/cryptography-45.0.3-cp311-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:af3f92b1dc25621f5fad065288a44ac790c5798e986a34d393ab27d2b27fcff9", size = 3898150 }, + { url = "https://files.pythonhosted.org/packages/8b/50/f256ab79c671fb066e47336706dc398c3b1e125f952e07d54ce82cf4011a/cryptography-45.0.3-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:2f8f8f0b73b885ddd7f3d8c2b2234a7d3ba49002b0223f58cfde1bedd9563c56", size = 4466473 }, + { url = "https://files.pythonhosted.org/packages/62/e7/312428336bb2df0848d0768ab5a062e11a32d18139447a76dfc19ada8eed/cryptography-45.0.3-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:9cc80ce69032ffa528b5e16d217fa4d8d4bb7d6ba8659c1b4d74a1b0f4235fca", size = 4211890 }, + { url = "https://files.pythonhosted.org/packages/e7/53/8a130e22c1e432b3c14896ec5eb7ac01fb53c6737e1d705df7e0efb647c6/cryptography-45.0.3-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:c824c9281cb628015bfc3c59335163d4ca0540d49de4582d6c2637312907e4b1", size = 4466300 }, + { url = "https://files.pythonhosted.org/packages/ba/75/6bb6579688ef805fd16a053005fce93944cdade465fc92ef32bbc5c40681/cryptography-45.0.3-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:5833bb4355cb377ebd880457663a972cd044e7f49585aee39245c0d592904578", size = 4332483 }, + { url = "https://files.pythonhosted.org/packages/2f/11/2538f4e1ce05c6c4f81f43c1ef2bd6de7ae5e24ee284460ff6c77e42ca77/cryptography-45.0.3-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:9bb5bf55dcb69f7067d80354d0a348368da907345a2c448b0babc4215ccd3497", size = 4573714 }, + { url = "https://files.pythonhosted.org/packages/f5/bb/e86e9cf07f73a98d84a4084e8fd420b0e82330a901d9cac8149f994c3417/cryptography-45.0.3-cp311-abi3-win32.whl", hash = "sha256:3ad69eeb92a9de9421e1f6685e85a10fbcfb75c833b42cc9bc2ba9fb00da4710", size = 2934752 }, + { url = "https://files.pythonhosted.org/packages/c7/75/063bc9ddc3d1c73e959054f1fc091b79572e716ef74d6caaa56e945b4af9/cryptography-45.0.3-cp311-abi3-win_amd64.whl", hash = "sha256:97787952246a77d77934d41b62fb1b6f3581d83f71b44796a4158d93b8f5c490", size = 3412465 }, + { url = "https://files.pythonhosted.org/packages/71/9b/04ead6015229a9396890d7654ee35ef630860fb42dc9ff9ec27f72157952/cryptography-45.0.3-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:c92519d242703b675ccefd0f0562eb45e74d438e001f8ab52d628e885751fb06", size = 7031892 }, + { url = "https://files.pythonhosted.org/packages/46/c7/c7d05d0e133a09fc677b8a87953815c522697bdf025e5cac13ba419e7240/cryptography-45.0.3-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5edcb90da1843df85292ef3a313513766a78fbbb83f584a5a58fb001a5a9d57", size = 4196181 }, + { url = "https://files.pythonhosted.org/packages/08/7a/6ad3aa796b18a683657cef930a986fac0045417e2dc428fd336cfc45ba52/cryptography-45.0.3-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:38deed72285c7ed699864f964a3f4cf11ab3fb38e8d39cfcd96710cd2b5bb716", size = 4423370 }, + { url = "https://files.pythonhosted.org/packages/4f/58/ec1461bfcb393525f597ac6a10a63938d18775b7803324072974b41a926b/cryptography-45.0.3-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:5555365a50efe1f486eed6ac7062c33b97ccef409f5970a0b6f205a7cfab59c8", size = 4197839 }, + { url = "https://files.pythonhosted.org/packages/d4/3d/5185b117c32ad4f40846f579369a80e710d6146c2baa8ce09d01612750db/cryptography-45.0.3-cp37-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:9e4253ed8f5948a3589b3caee7ad9a5bf218ffd16869c516535325fece163dcc", size = 3886324 }, + { url = "https://files.pythonhosted.org/packages/67/85/caba91a57d291a2ad46e74016d1f83ac294f08128b26e2a81e9b4f2d2555/cryptography-45.0.3-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:cfd84777b4b6684955ce86156cfb5e08d75e80dc2585e10d69e47f014f0a5342", size = 4450447 }, + { url = "https://files.pythonhosted.org/packages/ae/d1/164e3c9d559133a38279215c712b8ba38e77735d3412f37711b9f8f6f7e0/cryptography-45.0.3-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:a2b56de3417fd5f48773ad8e91abaa700b678dc7fe1e0c757e1ae340779acf7b", size = 4200576 }, + { url = "https://files.pythonhosted.org/packages/71/7a/e002d5ce624ed46dfc32abe1deff32190f3ac47ede911789ee936f5a4255/cryptography-45.0.3-cp37-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:57a6500d459e8035e813bd8b51b671977fb149a8c95ed814989da682314d0782", size = 4450308 }, + { url = "https://files.pythonhosted.org/packages/87/ad/3fbff9c28cf09b0a71e98af57d74f3662dea4a174b12acc493de00ea3f28/cryptography-45.0.3-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:f22af3c78abfbc7cbcdf2c55d23c3e022e1a462ee2481011d518c7fb9c9f3d65", size = 4325125 }, + { url = "https://files.pythonhosted.org/packages/f5/b4/51417d0cc01802304c1984d76e9592f15e4801abd44ef7ba657060520bf0/cryptography-45.0.3-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:232954730c362638544758a8160c4ee1b832dc011d2c41a306ad8f7cccc5bb0b", size = 4560038 }, + { url = "https://files.pythonhosted.org/packages/80/38/d572f6482d45789a7202fb87d052deb7a7b136bf17473ebff33536727a2c/cryptography-45.0.3-cp37-abi3-win32.whl", hash = "sha256:cb6ab89421bc90e0422aca911c69044c2912fc3debb19bb3c1bfe28ee3dff6ab", size = 2924070 }, + { url = "https://files.pythonhosted.org/packages/91/5a/61f39c0ff4443651cc64e626fa97ad3099249152039952be8f344d6b0c86/cryptography-45.0.3-cp37-abi3-win_amd64.whl", hash = "sha256:d54ae41e6bd70ea23707843021c778f151ca258081586f0cfa31d936ae43d1b2", size = 3395005 }, ] [[package]] @@ -226,11 +230,11 @@ wheels = [ [[package]] name = "humanize" -version = "4.11.0" +version = "4.12.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6a/40/64a912b9330786df25e58127194d4a5a7441f818b400b155e748a270f924/humanize-4.11.0.tar.gz", hash = "sha256:e66f36020a2d5a974c504bd2555cf770621dbdbb6d82f94a6857c0b1ea2608be", size = 80374 } +sdist = { url = "https://files.pythonhosted.org/packages/22/d1/bbc4d251187a43f69844f7fd8941426549bbe4723e8ff0a7441796b0789f/humanize-4.12.3.tar.gz", hash = "sha256:8430be3a615106fdfceb0b2c1b41c4c98c6b0fc5cc59663a5539b111dd325fb0", size = 80514 } wheels = [ - { url = "https://files.pythonhosted.org/packages/92/75/4bc3e242ad13f2e6c12e0b0401ab2c5e5c6f0d7da37ec69bc808e24e0ccb/humanize-4.11.0-py3-none-any.whl", hash = "sha256:b53caaec8532bcb2fff70c8826f904c35943f8cecaca29d272d9df38092736c0", size = 128055 }, + { url = "https://files.pythonhosted.org/packages/a0/1e/62a2ec3104394a2975a2629eec89276ede9dbe717092f6966fcf963e1bf0/humanize-4.12.3-py3-none-any.whl", hash = "sha256:2cbf6370af06568fa6d2da77c86edb7886f3160ecd19ee1ffef07979efc597f6", size = 128487 }, ] [[package]] @@ -329,17 +333,17 @@ wheels = [ [[package]] name = "psutil" -version = "6.1.1" +version = "7.0.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/1f/5a/07871137bb752428aa4b659f910b399ba6f291156bdea939be3e96cae7cb/psutil-6.1.1.tar.gz", hash = "sha256:cf8496728c18f2d0b45198f06895be52f36611711746b7f30c464b422b50e2f5", size = 508502 } +sdist = { url = "https://files.pythonhosted.org/packages/2a/80/336820c1ad9286a4ded7e845b2eccfcb27851ab8ac6abece774a6ff4d3de/psutil-7.0.0.tar.gz", hash = "sha256:7be9c3eba38beccb6495ea33afd982a44074b78f28c434a1f51cc07fd315c456", size = 497003 } wheels = [ - { url = "https://files.pythonhosted.org/packages/61/99/ca79d302be46f7bdd8321089762dd4476ee725fce16fc2b2e1dbba8cac17/psutil-6.1.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:fc0ed7fe2231a444fc219b9c42d0376e0a9a1a72f16c5cfa0f68d19f1a0663e8", size = 247511 }, - { url = "https://files.pythonhosted.org/packages/0b/6b/73dbde0dd38f3782905d4587049b9be64d76671042fdcaf60e2430c6796d/psutil-6.1.1-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:0bdd4eab935276290ad3cb718e9809412895ca6b5b334f5a9111ee6d9aff9377", size = 248985 }, - { url = "https://files.pythonhosted.org/packages/17/38/c319d31a1d3f88c5b79c68b3116c129e5133f1822157dd6da34043e32ed6/psutil-6.1.1-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b6e06c20c05fe95a3d7302d74e7097756d4ba1247975ad6905441ae1b5b66003", size = 284488 }, - { url = "https://files.pythonhosted.org/packages/9c/39/0f88a830a1c8a3aba27fededc642da37613c57cbff143412e3536f89784f/psutil-6.1.1-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:97f7cb9921fbec4904f522d972f0c0e1f4fabbdd4e0287813b21215074a0f160", size = 287477 }, - { url = "https://files.pythonhosted.org/packages/47/da/99f4345d4ddf2845cb5b5bd0d93d554e84542d116934fde07a0c50bd4e9f/psutil-6.1.1-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:33431e84fee02bc84ea36d9e2c4a6d395d479c9dd9bba2376c1f6ee8f3a4e0b3", size = 289017 }, - { url = "https://files.pythonhosted.org/packages/38/53/bd755c2896f4461fd4f36fa6a6dcb66a88a9e4b9fd4e5b66a77cf9d4a584/psutil-6.1.1-cp37-abi3-win32.whl", hash = "sha256:eaa912e0b11848c4d9279a93d7e2783df352b082f40111e078388701fd479e53", size = 250602 }, - { url = "https://files.pythonhosted.org/packages/7b/d7/7831438e6c3ebbfa6e01a927127a6cb42ad3ab844247f3c5b96bea25d73d/psutil-6.1.1-cp37-abi3-win_amd64.whl", hash = "sha256:f35cfccb065fff93529d2afb4a2e89e363fe63ca1e4a5da22b603a85833c2649", size = 254444 }, + { url = "https://files.pythonhosted.org/packages/ed/e6/2d26234410f8b8abdbf891c9da62bee396583f713fb9f3325a4760875d22/psutil-7.0.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:101d71dc322e3cffd7cea0650b09b3d08b8e7c4109dd6809fe452dfd00e58b25", size = 238051 }, + { url = "https://files.pythonhosted.org/packages/04/8b/30f930733afe425e3cbfc0e1468a30a18942350c1a8816acfade80c005c4/psutil-7.0.0-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:39db632f6bb862eeccf56660871433e111b6ea58f2caea825571951d4b6aa3da", size = 239535 }, + { url = "https://files.pythonhosted.org/packages/2a/ed/d362e84620dd22876b55389248e522338ed1bf134a5edd3b8231d7207f6d/psutil-7.0.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1fcee592b4c6f146991ca55919ea3d1f8926497a713ed7faaf8225e174581e91", size = 275004 }, + { url = "https://files.pythonhosted.org/packages/bf/b9/b0eb3f3cbcb734d930fdf839431606844a825b23eaf9a6ab371edac8162c/psutil-7.0.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b1388a4f6875d7e2aff5c4ca1cc16c545ed41dd8bb596cefea80111db353a34", size = 277986 }, + { url = "https://files.pythonhosted.org/packages/eb/a2/709e0fe2f093556c17fbafda93ac032257242cabcc7ff3369e2cb76a97aa/psutil-7.0.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5f098451abc2828f7dc6b58d44b532b22f2088f4999a937557b603ce72b1993", size = 279544 }, + { url = "https://files.pythonhosted.org/packages/50/e6/eecf58810b9d12e6427369784efe814a1eec0f492084ce8eb8f4d89d6d61/psutil-7.0.0-cp37-abi3-win32.whl", hash = "sha256:ba3fcef7523064a6c9da440fc4d6bd07da93ac726b5733c29027d7dc95b39d99", size = 241053 }, + { url = "https://files.pythonhosted.org/packages/50/1b/6921afe68c74868b4c9fa424dad3be35b095e16687989ebbb50ce4fceb7c/psutil-7.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:4cf3d4eb1aa9b348dec30105c55cd9b7d4629285735a102beb4441e38db90553", size = 244885 }, ] [[package]] @@ -408,19 +412,19 @@ dev = [ [package.metadata] requires-dist = [ - { name = "command-runner", specifier = ">=1.5.0" }, - { name = "cryptography", specifier = ">=44.0.0" }, + { name = "command-runner", specifier = ">=1.7.4" }, + { name = "cryptography", specifier = ">=45.0.3" }, { name = "discord-webhook", specifier = ">=1.1.0" }, { name = "httpx", specifier = ">=0.28.1" }, - { name = "humanize", specifier = ">=4.6.0" }, + { name = "humanize", specifier = ">=4.12.3" }, { name = "loguru", specifier = ">=0.7.3" }, { name = "observable", specifier = ">=1.0.3" }, { name = "pillow", specifier = ">=11.0.0" }, - { name = "psutil", specifier = ">=6.1.0" }, + { name = "psutil", specifier = ">=7.0.0" }, { name = "py-cpuinfo", specifier = ">=9.0.0" }, - { name = "pywin32", specifier = ">=308" }, + { name = "pywin32", specifier = ">=310" }, { name = "requests", specifier = ">=2.31.0" }, - { name = "setuptools", specifier = ">=75.6.0" }, + { name = "setuptools", specifier = ">=80.9.0" }, { name = "wmi", specifier = ">=1.5.1" }, ] @@ -433,12 +437,12 @@ dev = [ [[package]] name = "pywin32" -version = "308" +version = "310" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a9/a4/aa562d8935e3df5e49c161b427a3a2efad2ed4e9cf81c3de636f1fdddfd0/pywin32-308-cp313-cp313-win32.whl", hash = "sha256:1c44539a37a5b7b21d02ab34e6a4d314e0788f1690d65b48e9b0b89f31abbbed", size = 5938579 }, - { url = "https://files.pythonhosted.org/packages/c7/50/b0efb8bb66210da67a53ab95fd7a98826a97ee21f1d22949863e6d588b22/pywin32-308-cp313-cp313-win_amd64.whl", hash = "sha256:fd380990e792eaf6827fcb7e187b2b4b1cede0585e3d0c9e84201ec27b9905e4", size = 6542056 }, - { url = "https://files.pythonhosted.org/packages/26/df/2b63e3e4f2df0224f8aaf6d131f54fe4e8c96400eb9df563e2aae2e1a1f9/pywin32-308-cp313-cp313-win_arm64.whl", hash = "sha256:ef313c46d4c18dfb82a2431e3051ac8f112ccee1a34f29c263c583c568db63cd", size = 7974986 }, + { url = "https://files.pythonhosted.org/packages/1c/09/9c1b978ffc4ae53999e89c19c77ba882d9fce476729f23ef55211ea1c034/pywin32-310-cp313-cp313-win32.whl", hash = "sha256:5d241a659c496ada3253cd01cfaa779b048e90ce4b2b38cd44168ad555ce74ab", size = 8794384 }, + { url = "https://files.pythonhosted.org/packages/45/3c/b4640f740ffebadd5d34df35fecba0e1cfef8fde9f3e594df91c28ad9b50/pywin32-310-cp313-cp313-win_amd64.whl", hash = "sha256:667827eb3a90208ddbdcc9e860c81bde63a135710e21e4cb3348968e4bd5249e", size = 9503039 }, + { url = "https://files.pythonhosted.org/packages/b4/f4/f785020090fb050e7fb6d34b780f2231f302609dc964672f72bfaeb59a28/pywin32-310-cp313-cp313-win_arm64.whl", hash = "sha256:e308f831de771482b7cf692a1f308f8fca701b2d8f9dde6cc440c7da17e47b33", size = 8458152 }, ] [[package]] @@ -458,11 +462,11 @@ wheels = [ [[package]] name = "setuptools" -version = "75.8.0" +version = "80.9.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/92/ec/089608b791d210aec4e7f97488e67ab0d33add3efccb83a056cbafe3a2a6/setuptools-75.8.0.tar.gz", hash = "sha256:c5afc8f407c626b8313a86e10311dd3f661c6cd9c09d4bf8c15c0e11f9f2b0e6", size = 1343222 } +sdist = { url = "https://files.pythonhosted.org/packages/18/5d/3bf57dcd21979b887f014ea83c24ae194cfcd12b9e0fda66b957c69d1fca/setuptools-80.9.0.tar.gz", hash = "sha256:f36b47402ecde768dbfafc46e8e4207b4360c654f1f3bb84475f0a28628fb19c", size = 1319958 } wheels = [ - { url = "https://files.pythonhosted.org/packages/69/8a/b9dc7678803429e4a3bc9ba462fa3dd9066824d3c607490235c6a796be5a/setuptools-75.8.0-py3-none-any.whl", hash = "sha256:e3982f444617239225d675215d51f6ba05f845d4eec313da4418fdbb56fb27e3", size = 1228782 }, + { url = "https://files.pythonhosted.org/packages/a3/dc/17031897dae0efacfea57dfd3a82fdd2a2aeb58e0ff71b77b87e44edc772/setuptools-80.9.0-py3-none-any.whl", hash = "sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922", size = 1201486 }, ] [[package]] From b174435a72b6a50c54cd165c1ec2ded2bc6bcf2c Mon Sep 17 00:00:00 2001 From: xFGhoul Date: Wed, 4 Jun 2025 22:12:23 -0400 Subject: [PATCH 7/7] =?UTF-8?q?=F0=9F=8E=A8=20(core):=20Small=20Fixes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/launch.json | 16 ----- .vscode/settings.json | 118 ----------------------------------- AUTHORS.md | 6 +- pyprotector/utils/webhook.py | 1 - 4 files changed, 1 insertion(+), 140 deletions(-) delete mode 100644 .vscode/launch.json delete mode 100644 .vscode/settings.json diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index cdc755e..0000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "name": "Test PythonProtector", - "type": "python", - "request": "launch", - "program": "C:/Users/Ghoul/Documents/PythonProtector/_testing.py", - "console": "integratedTerminal", - "justMyCode": true - } - ] -} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 0b43991..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,118 +0,0 @@ -{ - "python.formatting.provider": "black", - "cSpell.words": [ - "autohide", - "cheatengine", - "codecracker", - "compat", - "COMPUTERNAME", - "csproduct", - "dbgclr", - "Decryptor", - "dnspy", - "dojandqwklndoqwd", - "dotmodded", - "equifox", - "exeinfope", - "extremedumper", - "folderchangesview", - "fontawesome", - "forthebadge", - "getlogin", - "ghidra", - "graywolf", - "httpanalyzer", - "httpdebug", - "httpdebugger", - "httpdebuggerui", - "httpx", - "HWID", - "HWIDS", - "ilspy", - "IMAGENAME", - "inlinehilite", - "joeboxcontrol", - "joeboxserver", - "keyauth", - "kgdb", - "ksdumper", - "ksdumperclient", - "kwargs", - "linenums", - "luid", - "mdbg", - "megadumper", - "mitmproxy", - "mkdocstrings", - "naturalsize", - "netdumper", - "ollydbg", - "opencv", - "pathlib", - "pefile", - "pestudio", - "petools", - "processhacker", - "procmon", - "proxifier", - "pstorec", - "pyarmor", - "pyautogui", - "pydecipher", - "pyinject", - "pymdownx", - "pywin", - "rawshark", - "regedit", - "rpyc", - "sbiedll", - "scyllahide", - "serv", - "sharpod", - "simpleassembly", - "simpleassemblyexplorer", - "Srvc", - "strongod", - "superfences", - "systemexplorer", - "systemexplorerservice", - "TASKLIST", - "taskmgr", - "titanhide", - "uncompyle", - "unpy", - "vboxmrxnp", - "vboxservice", - "vboxtray", - "vdagent", - "vdservice", - "vgauthservice", - "VM's", - "vmacthlp", - "vmcheck", - "vmem", - "vmsrvc", - "vmusrvc", - "vmwaretray", - "vmwareuser", - "webui", - "windbg", - "wireshark", - "wpespy", - "xenservice" - ], - "cSpell.ignoreWords": [ - "BSOD" - ], - "yaml.schemas": { - "https://squidfunk.github.io/mkdocs-material/schema.json": "mkdocs.yml" - }, - "yaml.customTags": [ - "!ENV scalar", - "!ENV sequence", - "tag:yaml.org,2002:python/name:materialx.emoji.to_svg", - "tag:yaml.org,2002:python/name:materialx.emoji.twemoji", - "tag:yaml.org,2002:python/name:pymdownx.superfences.fence_code_format" - ], - "docwriter.style": "Google" -} \ No newline at end of file diff --git a/AUTHORS.md b/AUTHORS.md index c478757..9cd6b05 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -1,7 +1,3 @@ # Ghoul -Discord - `ghoul#1337` - -# Marci - -Discord - `Marci#0101` +Discord - `heartghoul` diff --git a/pyprotector/utils/webhook.py b/pyprotector/utils/webhook.py index 8f5666e..2909f10 100644 --- a/pyprotector/utils/webhook.py +++ b/pyprotector/utils/webhook.py @@ -11,7 +11,6 @@ import io -from io import BytesIO from PIL import ImageGrab from base64 import b64decode