From a87059e01a63375259059beac7f592547fead84e Mon Sep 17 00:00:00 2001 From: Mate Hegedus Date: Thu, 12 Jun 2025 15:38:00 +0200 Subject: [PATCH 1/3] Add glow override option --- deadlock/aimbot.py | 3 +++ deadlock/aimbot_gui.py | 19 +++++++++++++++++++ deadlock/memory.py | 38 +++++++++++++++++++++++++++++++++++++- 3 files changed, 59 insertions(+), 1 deletion(-) diff --git a/deadlock/aimbot.py b/deadlock/aimbot.py index ee216ec..996fba8 100644 --- a/deadlock/aimbot.py +++ b/deadlock/aimbot.py @@ -89,6 +89,9 @@ class AimbotSettings: headshot_on_acquire: bool = True #: force headshots for 0.4s when locking on after a 2s gap + glow_override: bool = False + #: if ``True`` NOP the in-game glow check + class Aimbot: """Basic aimbot controller.""" diff --git a/deadlock/aimbot_gui.py b/deadlock/aimbot_gui.py index 39bcffa..7660766 100644 --- a/deadlock/aimbot_gui.py +++ b/deadlock/aimbot_gui.py @@ -184,6 +184,13 @@ def _build_settings_frame(self, parent: ttk.Frame) -> None: ttk.Entry(hero_frame, textvariable=self.paradox_e_key, width=3).grid(row=hero_row, column=2, sticky="w") hero_row += 1 row += 1 + self.glow_override_var = tk.BooleanVar(value=self.settings.glow_override) + ttk.Checkbutton( + frame, + text="Bypass glow check", + variable=self.glow_override_var, + ).grid(row=row, column=0, columnspan=2, sticky="w") + row += 1 control_frame = ttk.Frame(frame) control_frame.grid(row=row, column=0, columnspan=2, pady=10, sticky="ew") self.start_button = ttk.Button(control_frame, text="Start", command=self.start) @@ -278,6 +285,8 @@ def _apply_widget_values(self) -> None: if self.paradox_e_key.get(): self.settings.paradox_e_key = ord(self.paradox_e_key.get().upper()[0]) + self.settings.glow_override = self.glow_override_var.get() + def start(self) -> None: """Start the aimbot.""" if self.is_running: @@ -321,6 +330,11 @@ def _initialise_and_run(self) -> None: """Initialise memory and run the aimbot.""" try: mem = DeadlockMemory() + if self.settings.glow_override: + try: + mem.toggle_glow_override(True) + except Exception as exc: + self.log_queue.put(f"Glow override failed: {exc}") self.bot = Aimbot(mem, self.settings) self.log_queue.put("Aimbot started successfully.") self.root.after(0, lambda: ( @@ -380,6 +394,11 @@ def stop(self) -> None: return if self.bot: + if self.settings.glow_override: + try: + self.bot.mem.toggle_glow_override(False) + except Exception: + pass self.bot.stop() self.is_running = False diff --git a/deadlock/memory.py b/deadlock/memory.py index 7da9799..a0a48e1 100644 --- a/deadlock/memory.py +++ b/deadlock/memory.py @@ -3,7 +3,7 @@ """Thin wrapper over :mod:`pymem` for reading Deadlock game memory.""" from dataclasses import dataclass -from typing import Dict, Tuple +from typing import Dict, Tuple, Optional import pymem @@ -12,6 +12,14 @@ from . import mem_offsets as mo import offset_finder +# Pattern to locate the glow check conditional in client.dll +GLOW_PATTERN = bytes.fromhex( + "0F 85 70 02 00 00 44 0F 11 54 24 58 C7 44 24 68 FF FF 7F FF " + "48 8B CB C7 44 24 6C FF FF 7F FF 48" +) +GLOW_PATCH = b"\x90" * 6 +GLOW_ORIGINAL = bytes.fromhex("0F 85 70 02 00 00") + @dataclass class Offsets: @@ -34,6 +42,8 @@ def __init__(self, process: str = "deadlock.exe") -> None: self.pm.process_handle, "client.dll" ).lpBaseOfDll self.offsets = self._read_offsets() + self._glow_addr: Optional[int] = None + self._glow_original: bytes | None = None def _read_offsets(self) -> Offsets: """Read offsets via :mod:`offset_finder`.""" @@ -144,3 +154,29 @@ def read_entity(self, index: int) -> Dict: "hero": hero_id, "aim_angle": aim_angle, } + + # Glow override ----------------------------------------------------- + def _find_glow_address(self) -> Optional[int]: + module = pymem.process.module_from_name( + self.pm.process_handle, "client.dll" + ) + data = self.pm.read_bytes(module.lpBaseOfDll, module.SizeOfImage) + idx = data.find(GLOW_PATTERN) + if idx == -1: + return None + return module.lpBaseOfDll + idx + + def toggle_glow_override(self, enable: bool) -> bool: + """Enable or disable the glow check NOP patch.""" + + if self._glow_addr is None: + self._glow_addr = self._find_glow_address() + if self._glow_addr is None: + return False + + if self._glow_original is None: + self._glow_original = self.pm.read_bytes(self._glow_addr, len(GLOW_PATCH)) + + patch = GLOW_PATCH if enable else self._glow_original + self.pm.write_bytes(self._glow_addr, patch, len(patch)) + return True From 33a146f77682fa7c870a1cd5d7616b70d05dfc9a Mon Sep 17 00:00:00 2001 From: Mate Hegedus Date: Thu, 12 Jun 2025 17:39:23 +0200 Subject: [PATCH 2/3] Update deadlock/aimbot_gui.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- deadlock/aimbot_gui.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deadlock/aimbot_gui.py b/deadlock/aimbot_gui.py index 7660766..68398fc 100644 --- a/deadlock/aimbot_gui.py +++ b/deadlock/aimbot_gui.py @@ -397,8 +397,8 @@ def stop(self) -> None: if self.settings.glow_override: try: self.bot.mem.toggle_glow_override(False) - except Exception: - pass + except Exception as e: + self.log_queue.put(f"Error disabling glow override: {str(e)}") self.bot.stop() self.is_running = False From 1b70d2e3d697c6353109df022bad443fb76a6d81 Mon Sep 17 00:00:00 2001 From: Mate Hegedus Date: Thu, 12 Jun 2025 17:39:39 +0200 Subject: [PATCH 3/3] Update deadlock/memory.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- deadlock/memory.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/deadlock/memory.py b/deadlock/memory.py index a0a48e1..a2431a4 100644 --- a/deadlock/memory.py +++ b/deadlock/memory.py @@ -175,8 +175,11 @@ def toggle_glow_override(self, enable: bool) -> bool: return False if self._glow_original is None: - self._glow_original = self.pm.read_bytes(self._glow_addr, len(GLOW_PATCH)) - + try: + self._glow_original = self.pm.read_bytes(self._glow_addr, len(GLOW_PATCH)) + except pymem.exception.MemoryReadError as e: + print(f"Failed to read glow bytes: {e}") + self._glow_original = None patch = GLOW_PATCH if enable else self._glow_original self.pm.write_bytes(self._glow_addr, patch, len(patch)) return True