forked from Dregu/Spelunky2ls
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdev.py
98 lines (81 loc) · 2.58 KB
/
dev.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import struct
import time
import sys
from injectlib import Injector
def find(sep, offset=-7, type='pc', start=0):
off = data.find(bytes.fromhex(sep), start)
if type == 'off':
return off + offset, None
inst = data[off + offset:off]
off2, = struct.unpack_from("<L", inst, 3)
if type == 'imm':
gm = off2
elif type == 'pc':
gm = off + offset + 7 + off2 + delta
return off + delta, gm
proc = Injector.from_name_re('Spel2.*\.exe')
base = proc.find_base_re('Spel2.*\.exe')
target = proc.proc.cmdline()[0]
data = open(target, 'rb').read()
delta = 0xc00
_, state = find('83 78 0C 05 0F 85 ', -15)
state = proc.r64(base + state)
_, layer_off = find('C6 80 58 44 06 00 01 ', -7, 'imm')
layer = proc.r64(state + layer_off)
def signed(x):
return x if x & 0x80000000 == 0 else x - 0x100000000
inst, _ = find('BA 88 02 00 00', 1, 'off')
load_item, _ = find('BA 88 02 00 00', 8, 'off', start=inst)
load_item += signed(struct.unpack_from("<L", data, load_item + 1)[0]) + 5
load_item += delta
load_item += base
main_thread = proc.threads()[0]
print(hex(state + layer_off))
oldscreen = 0
oldplayer = 0
oldigt = 0
spawnid = 0
while True:
_, items_off = find('33 D2 8B 41 28 01', -7, 'imm')
items = proc.r64(state + items_off)
player_index = proc.r8(items)
size = proc.r8(items + 1)
player = proc.r64(items + 8 + player_index * 8)
screen = int.from_bytes(proc.read(state+0x10, 1), "little")
igt = int.from_bytes(proc.read(state+0x60, 1), "little")
if screen != 12:
spawnid = 0
if screen == 12 and (oldscreen in [11, 13] or igt == 1):
spawnid = 23
if spawnid != 0 and player != 0 and player != oldplayer:
x, y = struct.unpack("<2f", proc.read(player + 0x40, 8))
proc.run(rf"""
import ctypes
import sys
import os
def hook(name, *args):
if name != 'ctypes.seh_exception':
return
sys.addaudithook(hook)
class CriticalSection:
def __enter__(self, *args):
ctypes.windll.kernel32.SuspendThread({main_thread})
def __exit__(self, *args):
ctypes.windll.kernel32.ResumeThread({main_thread})
# load_item(state.layer[0], entity_name, x, y)
try:
with CriticalSection():
load_item = (ctypes.CFUNCTYPE(ctypes.c_void_p,
ctypes.c_void_p,
ctypes.c_int64,
ctypes.c_float,
ctypes.c_float))({load_item})
instance = load_item({layer}, {spawnid}, {x}, {y})
except Exception as e:
import os
os.system("msg * \"%s\"" % e)
""".strip().encode())
spawnid = 0
oldplayer = player
oldscreen = screen
time.sleep(0.1)