Загрузка данных
# language: Python, file: cs2_cheat.py
# external CS2 cheat with auto-updating offsets
import ctypes
import ctypes.wintypes as wt
import json
import math
import os
import struct
import sys
import threading
import time
import tkinter as tk
import urllib.request
from dataclasses import dataclass, field
from typing import Optional
import pymem
# ---------- AUTO OFFSETS ----------
# Мы берем оффсеты напрямую из открытого репозитория, который обновляется сам.
OFFSETS_URL = "https://raw.githubusercontent.com/a2x/cs2-dumper/main/output/offsets.json"
CLIENT_DLL_URL = "https://raw.githubusercontent.com/a2x/cs2-dumper/main/output/client_dll.json"
@dataclass
class Offsets:
dwEntityList: int = 0
dwLocalPlayer: int = 0
dwViewMatrix: int = 0
m_iHealth: int = 0
m_iTeamNum: int = 0
m_vecOrigin: int = 0
m_dwBoneMatrix: int = 0
m_angEyeAngles: int = 0
def fetch_url(url: str) -> dict:
try:
req = urllib.request.Request(url, headers={'User-Agent': 'Mozilla/5.0'})
with urllib.request.urlopen(req, timeout=10) as response:
return json.loads(response.read().decode())
except Exception as e:
print(f"[!] Ошибка скачивания оффсетов: {e}")
return {}
def load_offsets() -> Offsets:
o = Offsets()
print("[*] Скачиваем свежие оффсеты...")
data_offsets = fetch_url(OFFSETS_URL)
data_client = fetch_url(CLIENT_DLL_URL)
if not data_offsets or not data_client:
print("[!] Не удалось скачать. Проверь интернет.")
return o
# Парсим offsets.json (там client.dll)
client = data_offsets.get("client.dll", {})
o.dwEntityList = client.get("dwEntityList", 0)
o.dwLocalPlayer = client.get("dwLocalPlayer", 0)
o.dwViewMatrix = client.get("dwViewMatrix", 0)
# Парсим client_dll.json (там netvars для классов)
# В a2x дампере netvars лежат в структуре классов
classes = data_client.get("client.dll", {}).get("classes", {})
# Ищем нужные поля в классах C_CSPlayerPawn и т.д.
for class_name, class_data in classes.items():
fields = class_data.get("fields", {})
for field_name, field_offset in fields.items():
if field_name == "m_iHealth":
o.m_iHealth = field_offset
elif field_name == "m_iTeamNum":
o.m_iTeamNum = field_offset
elif field_name == "m_vecOrigin":
o.m_vecOrigin = field_offset
elif field_name == "m_dwBoneMatrix":
o.m_dwBoneMatrix = field_offset
elif field_name == "m_angEyeAngles":
o.m_angEyeAngles = field_offset
print(f"[+] Оффсеты загружены: EntityList={hex(o.dwEntityList)}, Health={hex(o.m_iHealth)}")
return o
# ---------- math ----------
@dataclass
class Vec3:
x: float = 0.0
y: float = 0.0
z: float = 0.0
def v3sub(a: Vec3, b: Vec3) -> Vec3:
return Vec3(a.x - b.x, a.y - b.y, a.z - b.z)
def calc_angle(src: Vec3, dst: Vec3) -> Vec3:
d = v3sub(dst, src)
hyp = math.sqrt(d.x * d.x + d.y * d.y)
return Vec3(
math.atan2(-d.z, hyp) * 57.29578,
math.atan2(d.y, d.x) * 57.29578,
0.0,
)
def world_to_screen(w: Vec3, vm: list[float], sw: int, sh: int) -> Optional[tuple[float, float]]:
cx = w.x * vm[0] + w.y * vm[4] + w.z * vm[8] + vm[12]
cy = w.x * vm[1] + w.y * vm[5] + w.z * vm[9] + vm[13]
cw = w.x * vm[3] + w.y * vm[7] + w.z * vm[11] + vm[15]
if cw < 0.01:
return None
return ((sw * 0.5) * ((cx / cw) + 1.0), (sh * 0.5) * (1.0 - (cy / cw)))
# ---------- memory ----------
class GameMemory:
def __init__(self) -> None:
self.pm: Optional[pymem.Pymem] = None
self.client: int = 0
self.off = Offsets()
def attach(self) -> bool:
try:
self.pm = pymem.Pymem("cs2.exe")
self.client = pymem.process.module_from_name(
self.pm.process_handle, "client.dll"
).lpBaseOfDll
self.off = load_offsets()
return True
except Exception as e:
print(f"[!] Ошибка подключения: {e}")
return False
def read(self, addr: int, fmt: str):
try:
size = struct.calcsize(fmt)
buf = self.pm.read_bytes(addr, size)
return struct.unpack(fmt, buf)[0]
except Exception:
return None
def read_vec3(self, addr: int) -> Vec3:
try:
buf = self.pm.read_bytes(addr, 12)
return Vec3(*struct.unpack("fff", buf))
except Exception:
return Vec3()
def read_view_matrix(self, addr: int) -> list[float]:
try:
buf = self.pm.read_bytes(addr, 64)
return list(struct.unpack("16f", buf))
except Exception:
return [0.0] * 16
# ---------- entities ----------
@dataclass
class Player:
addr: int
health: int
team: int
origin: Vec3
bones: int
@dataclass
class WorldState:
local: int = 0
local_origin: Vec3 = field(default_factory=Vec3)
local_team: int = 0
local_angles: Vec3 = field(default_factory=Vec3)
view_matrix: list[float] = field(default_factory=lambda: [0.0] * 16)
players: list[Player] = field(default_factory=list)
def read_world(mem: GameMemory) -> WorldState:
ws = WorldState()
if not mem.pm or not mem.client:
return ws
o = mem.off
ws.local = mem.read(mem.client + o.dwLocalPlayer, "Q") or 0
if not ws.local:
return ws
ws.local_origin = mem.read_vec3(ws.local + o.m_vecOrigin)
ws.local_team = mem.read(ws.local + o.m_iTeamNum, "i") or 0
ws.local_angles = mem.read_vec3(ws.local + o.m_angEyeAngles)
ws.view_matrix = mem.read_view_matrix(mem.client + o.dwViewMatrix)
ent_list = mem.read(mem.client + o.dwEntityList, "Q") or 0
if not ent_list:
return ws
for i in range(1, 64):
ent = mem.read(ent_list + i * 0x8, "Q")
if not ent:
continue
hp = mem.read(ent + o.m_iHealth, "i")
if hp is None or hp <= 0 or hp > 100:
continue
ws.players.append(Player(
addr=ent,
health=hp,
team=mem.read(ent + o.m_iTeamNum, "i") or 0,
origin=mem.read_vec3(ent + o.m_vecOrigin),
bones=mem.read(ent + o.m_dwBoneMatrix, "Q") or 0,
))
return ws
HEAD_BONE = 6
def bone_pos(mem: GameMemory, bones: int, bone_id: int) -> Vec3:
if not bones:
return Vec3()
base = bones + bone_id * 0x40
return Vec3(
mem.read(base + 0x30, "f") or 0.0,
mem.read(base + 0x34, "f") or 0.0,
mem.read(base + 0x38, "f") or 0.0,
)
# ---------- mouse / aim ----------
class MOUSEINPUT(ctypes.Structure):
_fields_ = [
("dx", wt.LONG),
("dy", wt.LONG),
("mouseData", wt.DWORD),
("dwFlags", wt.DWORD),
("time", wt.DWORD),
("dwExtraInfo", ctypes.POINTER(wt.ULONG)),
]
class INPUT(ctypes.Structure):
class _I(ctypes.Union):
_fields_ = [("mi", MOUSEINPUT)]
_anonymous_ = ("i",)
_fields_ = [("type", wt.DWORD), ("i", _I)]
INPUT_MOUSE = 0
MOUSEEVENTF_MOVE = 0x0001
def move_mouse(dx: float, dy: float) -> None:
inp = INPUT()
inp.type = INPUT_MOUSE
inp.mi = MOUSEINPUT(int(dx), int(dy), 0, MOUSEEVENTF_MOVE, 0, None)
ctypes.windll.user32.SendInput(1, ctypes.byref(inp), ctypes.sizeof(INPUT))
@dataclass
class AimConfig:
enabled: bool = True
fov: float = 8.0
smooth: float = 0.35
bone: int = HEAD_BONE
vk: int = 0x02 # RBUTTON
px_per_deg: float = 10.0
def do_aim(ws: WorldState, mem: GameMemory, cfg: AimConfig) -> None:
if not cfg.enabled or not ws.local:
return
if not (ctypes.windll.user32.GetAsyncKeyState(cfg.vk) & 0x8000):
return
view = ws.local_angles
best_ang: Optional[Vec3] = None
best_d = cfg.fov
for p in ws.players:
if p.team == ws.local_team:
continue
target = bone_pos(mem, p.bones, cfg.bone)
if target.x == 0.0 and target.y == 0.0 and target.z == 0.0:
continue
ang = calc_angle(ws.local_origin, target)
dy = ang.y - view.y
while dy > 180: dy -= 360
while dy < -180: dy += 360
dp = ang.x - view.x
d = math.sqrt(dy * dy + dp * dp)
if d < best_d:
best_d = d
best_ang = ang
if best_ang is None:
return
dy = best_ang.y - view.y
while dy > 180: dy -= 360
while dy < -180: dy += 360
dp = best_ang.x - view.x
move_mouse(dy * cfg.px_per_deg * cfg.smooth,
-dp * cfg.px_per_deg * cfg.smooth)
# ---------- overlay (tkinter, click-through) ----------
TRANSPARENT = "#010203"
class Overlay:
def __init__(self, mem: GameMemory) -> None:
self.mem = mem
self.root = tk.Tk()
self.root.title("overlay")
self.root.attributes("-topmost", True)
self.root.attributes("-fullscreen", True)
self.root.configure(bg=TRANSPARENT)
try:
self.root.wm_attributes("-transparentcolor", TRANSPARENT)
except tk.TclError:
pass
self.canvas = tk.Canvas(self.root, bg=TRANSPARENT, highlightthickness=0)
self.canvas.pack(fill="both", expand=True)
self.sw = self.root.winfo_screenwidth()
self.sh = self.root.winfo_screenheight()
self.root.after(10, self.tick)
def tick(self) -> None:
try:
ws = read_world(self.mem)
self.draw(ws)
except Exception:
pass
self.root.after(10, self.tick)
def draw(self, ws: WorldState) -> None:
self.canvas.delete("all")
if not ws.local:
return
for p in ws.players:
if p.team == ws.local_team:
continue
head = bone_pos(self.mem, p.bones, HEAD_BONE)
feet = Vec3(p.origin.x, p.origin.y, p.origin.z - 72.0)
tp = world_to_screen(head, ws.view_matrix, self.sw, self.sh)
bp = world_to_screen(feet, ws.view_matrix, self.sw, self.sh)
if not tp or not bp:
continue
h = bp[1] - tp[1]
if h <= 2 or h > self.sh:
continue
w = h * 0.5
x1, x2 = tp[0] - w / 2, tp[0] + w / 2
self.canvas.create_rectangle(x1, tp[1], x2, bp[1], outline="red", width=2)
self.canvas.create_rectangle(x1 - 6, tp[1], x1 - 3, bp[1], fill="#333", outline="")
hp_h = (bp[1] - tp[1]) * (p.health / 100.0)
self.canvas.create_rectangle(x1 - 6, bp[1] - hp_h, x1 - 3, bp[1], fill="#0f0", outline="")
self.root.update_idletasks()
def run(self) -> None:
self.root.mainloop()
# ---------- main ----------
def main() -> int:
mem = GameMemory()
print("[*] Ожидание запуска cs2.exe...")
while not mem.attach():
time.sleep(2)
print(f"[+] Подключено. client.dll @ {hex(mem.client)}")
cfg = AimConfig()
overlay = Overlay(mem)
def aim_loop() -> None:
while True:
try:
ws = read_world(mem)
do_aim(ws, mem, cfg)
except Exception:
pass
time.sleep(0.002)
threading.Thread(target=aim_loop, daemon=True).start()
overlay.run()
return 0
if __name__ == "__main__":
sys.exit(main())