Загрузка данных
# language: Python, file: cs2_cheat.py, target: Windows 11 x64, Python 3.11+
# external CS2 cheat: memory read, ESP overlay, aimbot
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
from dataclasses import dataclass, field
from typing import Optional
import pymem
import win32api
import win32con
import win32gui
import win32process
# ---------- offsets ----------
# загружаются из cs2.json (hazedumper-формат) рядом со скриптом.
# при патче игры — обновить файл, код не трогать.
OFFSETS_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), "cs2.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
m_iShotsFired: int = 0
def load_offsets() -> Offsets:
o = Offsets()
if not os.path.exists(OFFSETS_PATH):
print(f"[!] {OFFSETS_PATH} missing — fill offsets manually or drop cs2.json")
return o
with open(OFFSETS_PATH, "r", encoding="utf-8") as f:
data = json.load(f)
# hazedumper формат: {"client.dll": {"dwEntityList": ..., ...}, "netvars": {...}}
client = data.get("client.dll", {})
netvars = data.get("netvars", {})
o.dwEntityList = client.get("dwEntityList", 0)
o.dwLocalPlayer = client.get("dwLocalPlayer", 0)
o.dwViewMatrix = client.get("dwViewMatrix", 0)
o.m_iHealth = netvars.get("m_iHealth", 0)
o.m_iTeamNum = netvars.get("m_iTeamNum", 0)
o.m_vecOrigin = netvars.get("m_vecOrigin", 0)
o.m_dwBoneMatrix = netvars.get("m_dwBoneMatrix", 0)
o.m_angEyeAngles = netvars.get("m_angEyeAngles", 0)
o.m_iShotsFired = netvars.get("m_iShotsFired", 0)
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"[!] attach failed: {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" # TK transparency color
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 as e:
print(f"[overlay] {e}")
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)
# health bar
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("[*] waiting for cs2.exe ...")
while not mem.attach():
time.sleep(2)
print(f"[+] attached. client.dll @ {hex(mem.client)}")
if mem.off.dwEntityList == 0:
print("[!] offsets are zero — drop cs2.json next to the exe and restart")
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())