2023-03-30 12:25:09 +02:00
|
|
|
from json import loads
|
2023-03-30 11:26:52 +02:00
|
|
|
from time import sleep
|
|
|
|
|
|
|
|
from pymem import Pymem
|
2023-03-30 12:25:09 +02:00
|
|
|
from requests import get
|
2023-03-30 11:26:52 +02:00
|
|
|
from win32api import GetAsyncKeyState
|
2023-03-30 15:29:29 +02:00
|
|
|
from win32con import EM_LINEINDEX, VK_SPACE
|
2023-03-30 11:26:52 +02:00
|
|
|
|
|
|
|
|
2023-03-30 12:25:09 +02:00
|
|
|
class Hack():
|
|
|
|
def __init__(self) -> None:
|
2023-03-30 13:03:32 +02:00
|
|
|
# Loading offsets
|
|
|
|
self.offsets = self._find_offsets()
|
|
|
|
|
2023-03-30 13:00:39 +02:00
|
|
|
self.pm = self._find_process(True)
|
2023-03-30 12:53:37 +02:00
|
|
|
|
2023-03-30 13:23:44 +02:00
|
|
|
self.wait_time = 0.01
|
|
|
|
self.timeout = self.wait_time * 50
|
|
|
|
|
2023-03-30 13:03:32 +02:00
|
|
|
def _find_offsets(self) -> dict[str, int]:
|
|
|
|
hazedumper_data = get(
|
|
|
|
"https://raw.githubusercontent.com/frk1/hazedumper/master/csgo.min.json")
|
|
|
|
serial_data = loads(hazedumper_data.text)
|
2023-03-30 14:26:15 +02:00
|
|
|
|
|
|
|
return serial_data["signatures"] | serial_data["netvars"] | {
|
2023-03-30 14:55:45 +02:00
|
|
|
"entity_size": 0x10,
|
|
|
|
"glow_obj_size": 0x38,
|
|
|
|
"glow_R": 0x8,
|
|
|
|
"glow_G": 0xC,
|
|
|
|
"glow_B": 0x10,
|
|
|
|
"glow_A": 0x14
|
2023-03-30 14:26:15 +02:00
|
|
|
}
|
2023-03-30 13:03:32 +02:00
|
|
|
|
2023-03-30 13:00:39 +02:00
|
|
|
def _find_process(self, verbose: bool = False) -> Pymem:
|
2023-03-30 12:25:09 +02:00
|
|
|
"""Find game process"""
|
|
|
|
process_found = False
|
|
|
|
print("Looking for process...") if verbose else None
|
2023-03-30 11:26:52 +02:00
|
|
|
|
2023-03-30 12:25:09 +02:00
|
|
|
pm = None
|
|
|
|
while not process_found:
|
|
|
|
try:
|
|
|
|
pm = Pymem("csgo.exe")
|
|
|
|
except:
|
|
|
|
# Timeout
|
|
|
|
sleep(.5)
|
|
|
|
else:
|
|
|
|
print("Process found!") if verbose else None
|
|
|
|
process_found = True
|
2023-03-30 11:26:52 +02:00
|
|
|
|
2023-03-30 12:25:09 +02:00
|
|
|
if pm:
|
|
|
|
return pm
|
|
|
|
exit(1)
|
2023-03-30 11:26:52 +02:00
|
|
|
|
2023-03-30 13:00:39 +02:00
|
|
|
def find_module(self, module: str):
|
2023-03-30 13:23:44 +02:00
|
|
|
"""Find module address"""
|
2023-03-30 13:00:39 +02:00
|
|
|
found = None
|
|
|
|
for internal_module in list(self.pm.list_modules()):
|
|
|
|
if internal_module.name == module + ".dll":
|
|
|
|
found = internal_module.lpBaseOfDll
|
2023-03-30 11:26:52 +02:00
|
|
|
|
2023-03-30 13:00:39 +02:00
|
|
|
if found:
|
|
|
|
return found
|
|
|
|
else:
|
|
|
|
raise MemoryError
|
|
|
|
|
2023-03-30 14:22:25 +02:00
|
|
|
def find_uint(self, base, offset: int) -> int:
|
2023-03-30 14:03:43 +02:00
|
|
|
"""Find integer in memory for sure"""
|
2023-03-30 13:23:44 +02:00
|
|
|
local_element = None
|
|
|
|
while not local_element:
|
2023-03-30 13:27:35 +02:00
|
|
|
local_element = self.pm.read_uint(base + offset)
|
2023-03-30 14:03:43 +02:00
|
|
|
|
2023-03-30 13:23:44 +02:00
|
|
|
sleep(self.timeout)
|
|
|
|
|
|
|
|
return local_element
|
|
|
|
|
2023-03-30 14:33:14 +02:00
|
|
|
def hack_loop(self, method):
|
|
|
|
"""Run the hack loop"""
|
|
|
|
while True:
|
|
|
|
# Reduce CPU usage
|
|
|
|
sleep(self.wait_time)
|
|
|
|
|
|
|
|
# Cheat
|
|
|
|
method()
|
|
|
|
|
2023-03-30 13:14:24 +02:00
|
|
|
|
|
|
|
class Cheat(Hack):
|
|
|
|
def __init__(self) -> None:
|
|
|
|
super().__init__()
|
|
|
|
|
|
|
|
self.cheats_list = [func for func in dir(self)
|
|
|
|
# Function
|
|
|
|
if callable(getattr(self, func))
|
|
|
|
# User defined
|
|
|
|
if not func.startswith("_")
|
2023-03-30 14:33:14 +02:00
|
|
|
# Hack loop
|
|
|
|
if not func == "hack_loop"
|
2023-03-30 13:14:24 +02:00
|
|
|
# Utils
|
|
|
|
if not func.startswith("find_")]
|
|
|
|
|
2023-03-30 13:00:39 +02:00
|
|
|
def bhop(self) -> None:
|
2023-03-30 13:03:32 +02:00
|
|
|
# Aliases
|
2023-03-30 13:00:39 +02:00
|
|
|
mem = self.pm
|
2023-03-30 13:03:32 +02:00
|
|
|
offset = self.offsets
|
2023-03-30 11:26:52 +02:00
|
|
|
|
2023-03-30 13:23:44 +02:00
|
|
|
# Get client
|
2023-03-30 13:00:39 +02:00
|
|
|
client = self.find_module("client")
|
2023-03-30 11:26:52 +02:00
|
|
|
|
2023-03-30 13:23:44 +02:00
|
|
|
# Get player
|
2023-03-30 14:22:25 +02:00
|
|
|
local_player = self.find_uint(client, offset["dwLocalPlayer"])
|
2023-03-30 13:14:24 +02:00
|
|
|
|
2023-03-30 14:33:14 +02:00
|
|
|
def cheat():
|
2023-03-30 14:20:03 +02:00
|
|
|
# Pressing space bar
|
2023-03-30 15:29:29 +02:00
|
|
|
if not GetAsyncKeyState(VK_SPACE):
|
2023-03-30 14:33:14 +02:00
|
|
|
return
|
2023-03-30 12:25:09 +02:00
|
|
|
|
|
|
|
# Check if player is alive
|
2023-03-30 14:03:43 +02:00
|
|
|
if not mem.read_uint(local_player + offset["m_iHealth"]):
|
2023-03-30 14:33:14 +02:00
|
|
|
return
|
2023-03-30 12:25:09 +02:00
|
|
|
|
|
|
|
# Check if player on ground
|
2023-03-30 13:00:39 +02:00
|
|
|
if mem.read_uint(local_player + offset["m_fFlags"]) & (1 << 0):
|
|
|
|
mem.write_uint(client + offset["dwForceJump"], 5)
|
2023-03-30 14:10:01 +02:00
|
|
|
sleep(0.01)
|
2023-03-30 13:00:39 +02:00
|
|
|
mem.write_uint(client + offset["dwForceJump"], 4)
|
2023-03-30 11:26:52 +02:00
|
|
|
|
2023-03-30 14:33:14 +02:00
|
|
|
self.hack_loop(cheat)
|
|
|
|
|
2023-03-30 13:47:28 +02:00
|
|
|
def radar_hack(self) -> None:
|
|
|
|
# Aliases
|
|
|
|
mem = self.pm
|
|
|
|
offset = self.offsets
|
|
|
|
|
|
|
|
# Get module address
|
|
|
|
client = self.find_module("client")
|
|
|
|
|
|
|
|
# Get local player
|
2023-03-30 14:22:25 +02:00
|
|
|
local_player = self.find_uint(client, offset["dwLocalPlayer"])
|
2023-03-30 13:47:28 +02:00
|
|
|
|
|
|
|
# Get local team
|
2023-03-30 14:22:25 +02:00
|
|
|
local_team = self.find_uint(local_player, offset["m_iTeamNum"])
|
2023-03-30 13:47:28 +02:00
|
|
|
|
2023-03-30 14:33:14 +02:00
|
|
|
def cheat():
|
2023-03-30 14:55:45 +02:00
|
|
|
# Loop all entities
|
2023-03-30 14:03:43 +02:00
|
|
|
for i in range(1, 64): # 0 is world
|
|
|
|
entity = mem.read_uint(
|
2023-03-30 14:26:15 +02:00
|
|
|
client + offset["dwEntityList"] + i * offset["entity_size"])
|
2023-03-30 14:03:43 +02:00
|
|
|
|
2023-03-30 14:55:45 +02:00
|
|
|
# Ignore if entity doesn't exist
|
2023-03-30 14:03:43 +02:00
|
|
|
if not entity:
|
|
|
|
continue
|
|
|
|
|
|
|
|
# Ignore allies
|
|
|
|
if mem.read_uint(entity + offset["m_iTeamNum"]) == local_team:
|
|
|
|
continue
|
|
|
|
|
2023-03-30 13:47:28 +02:00
|
|
|
# Check if ennemy is alive
|
2023-03-30 14:03:43 +02:00
|
|
|
if not mem.read_uint(entity + offset["m_iHealth"]):
|
2023-03-30 13:47:28 +02:00
|
|
|
continue
|
|
|
|
|
2023-03-30 14:03:43 +02:00
|
|
|
mem.write_bool(entity + offset["m_bSpotted"], True)
|
2023-03-30 13:47:28 +02:00
|
|
|
|
2023-03-30 14:33:14 +02:00
|
|
|
self.hack_loop(cheat)
|
|
|
|
|
2023-03-30 14:55:45 +02:00
|
|
|
def glow(self) -> None:
|
|
|
|
# Aliases
|
|
|
|
mem = self.pm
|
|
|
|
offset = self.offsets
|
|
|
|
|
|
|
|
# Get module address
|
|
|
|
client = self.find_module("client")
|
|
|
|
|
|
|
|
# Get local player
|
|
|
|
local_player = self.find_uint(client, offset["dwLocalPlayer"])
|
|
|
|
|
|
|
|
# Get local team
|
|
|
|
local_team = self.find_uint(local_player, offset["m_iTeamNum"])
|
|
|
|
|
|
|
|
# Get glow object manager
|
|
|
|
glow_obj_manager = self.find_uint(
|
|
|
|
client, offset["dwGlowObjectManager"])
|
|
|
|
|
|
|
|
def cheat():
|
|
|
|
# Loop all entities
|
|
|
|
for i in range(1, 64): # 0 is world
|
|
|
|
entity = mem.read_uint(
|
|
|
|
client + offset["dwEntityList"] + i * offset["entity_size"])
|
|
|
|
|
|
|
|
# Ignore if entity doesn't exist
|
|
|
|
if not entity:
|
|
|
|
continue
|
|
|
|
|
|
|
|
# Ignore allies
|
|
|
|
if mem.read_uint(entity + offset["m_iTeamNum"]) == local_team:
|
|
|
|
continue
|
|
|
|
|
2023-03-30 15:04:53 +02:00
|
|
|
# Check if ennemy is alive
|
|
|
|
if not mem.read_uint(entity + offset["m_iHealth"]):
|
|
|
|
continue
|
|
|
|
|
2023-03-30 14:55:45 +02:00
|
|
|
# Space between values
|
|
|
|
i = mem.read_int(
|
|
|
|
entity + offset["m_iGlowIndex"]) * offset["glow_obj_size"]
|
|
|
|
|
2023-03-30 15:06:02 +02:00
|
|
|
# TODO: Reduce write call
|
|
|
|
|
2023-03-30 14:55:45 +02:00
|
|
|
# Change color glow
|
|
|
|
mem.write_float(glow_obj_manager + i + offset["glow_R"], 1.)
|
|
|
|
mem.write_float(glow_obj_manager + i + offset["glow_G"], 0.)
|
|
|
|
mem.write_float(glow_obj_manager + i + offset["glow_B"], 0.)
|
|
|
|
mem.write_float(glow_obj_manager + i + offset["glow_A"], 1.)
|
|
|
|
|
|
|
|
# Render when not visible
|
|
|
|
mem.write_bool(glow_obj_manager + i + 0x27, True)
|
|
|
|
|
|
|
|
# Render when visible
|
|
|
|
mem.write_bool(glow_obj_manager + i + 0x28, True)
|
|
|
|
|
|
|
|
self.hack_loop(cheat)
|
|
|
|
|
2023-03-30 15:55:26 +02:00
|
|
|
def trigger(self) -> None:
|
2023-03-30 15:29:29 +02:00
|
|
|
# Aliases
|
|
|
|
mem = self.pm
|
|
|
|
offset = self.offsets
|
|
|
|
|
|
|
|
# Get module address
|
|
|
|
client = self.find_module("client")
|
|
|
|
|
|
|
|
# Get local player
|
|
|
|
local_player = self.find_uint(client, offset["dwLocalPlayer"])
|
|
|
|
|
|
|
|
# Get local team
|
|
|
|
local_team = self.find_uint(local_player, offset["m_iTeamNum"])
|
|
|
|
|
|
|
|
def cheat():
|
|
|
|
# Pressing trigger key
|
|
|
|
if not GetAsyncKeyState(EM_LINEINDEX):
|
|
|
|
return
|
|
|
|
|
|
|
|
# Check if player is alive
|
|
|
|
if not mem.read_int(local_player + offset["m_iHealth"]):
|
|
|
|
return
|
|
|
|
|
|
|
|
# Get crosshair info about what we aiming at
|
|
|
|
crosshair_id = mem.read_int(
|
|
|
|
local_player + offset["m_iCrosshairId"])
|
|
|
|
|
|
|
|
# 0 is wall, +64 isn't a player
|
|
|
|
if (crosshair_id == 0) or (crosshair_id > 64):
|
|
|
|
return
|
|
|
|
|
|
|
|
# Get ennemy under crosshair
|
|
|
|
ennemy = mem.read_uint(
|
|
|
|
client + offset["dwEntityList"] + (crosshair_id - 1) * offset["entity_size"])
|
|
|
|
|
|
|
|
# Check if ennemy is alive
|
|
|
|
if not mem.read_int(ennemy + offset["m_iHealth"]):
|
|
|
|
return
|
|
|
|
|
|
|
|
# Ignore allies
|
|
|
|
if mem.read_int(ennemy + offset["m_iTeamNum"]) == local_team:
|
|
|
|
return
|
|
|
|
|
|
|
|
# Shoot
|
|
|
|
mem.write_uint(client + offset["dwForceAttack"], 6)
|
|
|
|
sleep(0.2)
|
|
|
|
mem.write_uint(client + offset["dwForceAttack"], 4)
|
|
|
|
|
|
|
|
self.hack_loop(cheat)
|
|
|
|
|
2023-03-30 15:55:36 +02:00
|
|
|
def no_recoil(self) -> None:
|
|
|
|
# Aliases
|
|
|
|
mem = self.pm
|
|
|
|
offset = self.offsets
|
|
|
|
|
|
|
|
# Get module addresses
|
|
|
|
client = self.find_module("client")
|
|
|
|
engine = self.find_module("engine")
|
|
|
|
|
|
|
|
# Get local player
|
|
|
|
local_player = self.find_uint(client, offset["dwLocalPlayer"])
|
|
|
|
|
|
|
|
old_punch_x = 0.
|
|
|
|
old_punch_y = 0.
|
|
|
|
|
|
|
|
def cheat():
|
|
|
|
# TODO: Reduce read/write call
|
|
|
|
|
|
|
|
# Check if player is shooting
|
|
|
|
if mem.read_int(local_player + offset["m_iShotsFired"]):
|
|
|
|
client_state = mem.read_uint(engine + offset["dwClientState"])
|
|
|
|
|
|
|
|
# 4 = offset of integer
|
|
|
|
|
|
|
|
# view angle
|
|
|
|
view_angles_x = mem.read_float(
|
|
|
|
client_state + offset["dwClientState_ViewAngles"])
|
|
|
|
view_angles_y = mem.read_float(
|
|
|
|
client_state + offset["dwClientState_ViewAngles"] + 4)
|
|
|
|
|
|
|
|
server_mult = 2.
|
|
|
|
|
|
|
|
# recoil
|
|
|
|
aim_punch_x = mem.read_float(
|
|
|
|
client_state + offset["m_aimPunchAngle"]) * server_mult
|
|
|
|
aim_punch_y = mem.read_float(
|
|
|
|
client_state + offset["m_aimPunchAngle"] + 4) * server_mult
|
|
|
|
|
|
|
|
# New angles
|
|
|
|
new_angle_x = view_angles_x + old_punch_x - aim_punch_x
|
|
|
|
new_angle_y = view_angles_y + old_punch_y - aim_punch_y
|
|
|
|
|
|
|
|
# Sanity check
|
|
|
|
if new_angle_x > 89.:
|
|
|
|
new_angle_x = 89.
|
|
|
|
if new_angle_x < -89.:
|
|
|
|
new_angle_x = -89
|
|
|
|
while (new_angle_y > 180.):
|
|
|
|
new_angle_y -= 360.
|
|
|
|
while (new_angle_y < -180.):
|
|
|
|
new_angle_y += 360.
|
|
|
|
|
|
|
|
# Cancel recoil
|
|
|
|
mem.write_float(
|
|
|
|
client_state + offset["dwClientState_ViewAngles"], new_angle_x)
|
|
|
|
mem.write_float(
|
|
|
|
client_state + offset["dwClientState_ViewAngles"] + 4, new_angle_y)
|
|
|
|
|
|
|
|
old_punch_x = aim_punch_x
|
|
|
|
old_punch_y = aim_punch_y
|
|
|
|
|
|
|
|
else:
|
|
|
|
# Not spraying
|
|
|
|
old_punch_x = 0.
|
|
|
|
old_punch_y = 0.
|
|
|
|
|
|
|
|
self.hack_loop(cheat)
|
|
|
|
|
2023-03-30 11:26:52 +02:00
|
|
|
|
|
|
|
if __name__ == "__main__":
|
2023-03-30 12:25:09 +02:00
|
|
|
# Cheat
|
2023-03-30 13:14:24 +02:00
|
|
|
c = Cheat()
|
2023-03-30 12:25:09 +02:00
|
|
|
|
2023-03-30 13:03:32 +02:00
|
|
|
# Cheat list
|
2023-03-30 12:53:37 +02:00
|
|
|
print("Enter 0 to exit.")
|
|
|
|
print("Available cheats:")
|
|
|
|
for idx, cheat in enumerate(c.cheats_list):
|
|
|
|
print(f"#{idx + 1} - {cheat}")
|
|
|
|
|
|
|
|
# Select cheat
|
|
|
|
c_id = None
|
|
|
|
while c_id == None:
|
|
|
|
try:
|
|
|
|
match int(input("Enter ID: #")):
|
|
|
|
case 0:
|
|
|
|
exit(0)
|
|
|
|
case i if i > len(c.cheats_list):
|
|
|
|
raise IndexError
|
|
|
|
case _ as i:
|
|
|
|
c_id = i - 1
|
2023-03-30 14:20:03 +02:00
|
|
|
except KeyboardInterrupt:
|
|
|
|
print("??\nBye.")
|
|
|
|
exit(1)
|
2023-03-30 12:53:37 +02:00
|
|
|
except:
|
|
|
|
print("Invalid ID.")
|
|
|
|
|
|
|
|
# Run cheat
|
|
|
|
getattr(c, c.cheats_list[c_id])()
|