Skip to content

Commit 53e7712

Browse files
committed
Init
0 parents  commit 53e7712

File tree

3 files changed

+116
-0
lines changed

3 files changed

+116
-0
lines changed

consts.py

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import ctypes
2+
from ctypes import wintypes
3+
4+
PROCESS_ALL_ACCESS = (0x000F0000 | 0x00100000 | 0xFFFF)
5+
PAGE_EXECUTE_READWRITE = 0x40
6+
TH32CS_SNAPMODULE = 0x8
7+
TH32CS_SNAPMODULE32 = 0x10
8+
TH32CS_SNAPPROCESS = 0x2
9+
INVALID_HANDLE_VALUE = -1
10+
11+
class PROCESSENTRY32(ctypes.Structure):
12+
_fields_ = [('dwSize', ctypes.wintypes.DWORD),
13+
('cntUsage', ctypes.wintypes.DWORD),
14+
('th32ProcessID', ctypes.wintypes.DWORD),
15+
('th32DefaultHeapID', ctypes.POINTER(ctypes.wintypes.ULONG)),
16+
('th32ModuleID', ctypes.wintypes.DWORD),
17+
('cntThreads', ctypes.wintypes.DWORD),
18+
('th32ParentProcessID', ctypes.wintypes.DWORD),
19+
('pcPriClassBase', ctypes.wintypes.LONG),
20+
('dwFlags', ctypes.wintypes.DWORD),
21+
('szExeFile', ctypes.c_char * 260)]
22+
23+
24+
class MODULEENTRY32(ctypes.Structure):
25+
_fields_ = [('dwSize', ctypes.wintypes.DWORD),
26+
('th32ModuleID', ctypes.wintypes.DWORD),
27+
('th32ProcessID', ctypes.wintypes.DWORD),
28+
('GlblcntUsage', ctypes.wintypes.DWORD),
29+
('ProccntUsage', ctypes.wintypes.DWORD),
30+
('modBaseAddr', ctypes.POINTER(ctypes.wintypes.BYTE)),
31+
('modBaseSize', ctypes.wintypes.DWORD),
32+
('hModule', ctypes.wintypes.HMODULE),
33+
('szModule', ctypes.c_char * 256),
34+
('szExePath', ctypes.c_char * 260)]

main.py

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import pymem, utility
2+
3+
process = pymem.Pymem("ac_client.exe")
4+
current_ammo_base = process.base_address + 0x0016F338
5+
ammo_decrement = process.base_address + 0xC73EF
6+
current_ammo = utility.FindDMAAddy(process.process_handle, current_ammo_base, [0x0, 0xB8, 0x140], 32)
7+
process.write_bytes(ammo_decrement, b"9090", 2)
8+
process.write_int(current_ammo, 9999)

utility.py

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import ctypes
2+
from ctypes import wintypes
3+
from consts import *
4+
5+
kernel32 = ctypes.windll.kernel32
6+
7+
def GetProcId(processName):
8+
procId = None
9+
hSnap = kernel32.CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
10+
11+
if (hSnap != INVALID_HANDLE_VALUE):
12+
procEntry = PROCESSENTRY32()
13+
procEntry.dwSize = ctypes.sizeof(PROCESSENTRY32)
14+
15+
if (kernel32.Process32First(hSnap, ctypes.byref(procEntry))):
16+
def processCmp(procEntry):
17+
if (procEntry.szExeFile.decode('utf-8') == processName):
18+
nonlocal procId #Means that the variable is not local to the function, and we use the procId from the outer scope (above)
19+
procId = int(procEntry.th32ProcessID)
20+
21+
processCmp(procEntry) #Check the first process (the one we already have) before we start the loop (so we don't have to check it twice)
22+
while (kernel32.Process32Next(hSnap, ctypes.byref(procEntry))):
23+
processCmp(procEntry)
24+
25+
kernel32.CloseHandle(hSnap)
26+
return procId
27+
28+
def GetModuleBaseAddress(pid, moduleName):
29+
baseAddress = None
30+
hSnap = kernel32.CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, pid)
31+
if (hSnap != INVALID_HANDLE_VALUE):
32+
modEntry = MODULEENTRY32()
33+
modEntry.dwSize = ctypes.sizeof(MODULEENTRY32)
34+
35+
if (kernel32.Module32First(hSnap, ctypes.byref(modEntry))):
36+
def moduleCmp(modEntry):
37+
if (modEntry.szModule.decode('utf-8') == moduleName):
38+
nonlocal baseAddress
39+
baseAddress = int(hex(ctypes.addressof(modEntry.modBaseAddr.contents)), 16)
40+
41+
moduleCmp(modEntry)
42+
while (kernel32.Module32Next(hSnap, ctypes.byref(modEntry))):
43+
moduleCmp(modEntry)
44+
45+
kernel32.closeHandle(hSnap)
46+
return baseAddress
47+
48+
def FindDMAAddy(hProc, base, offsets, arch=64):
49+
size = 8
50+
if (arch == 32): size = 4
51+
address = ctypes.c_uint64(base)
52+
53+
for offset in offsets:
54+
kernel32.ReadProcessMemory(hProc, address, ctypes.byref(address), size, 0)
55+
address = ctypes.c_uint64(address.value + offset)
56+
57+
return (address.value)
58+
59+
def patchBytes(handle, src, destination, size):
60+
src = bytes.fromhex(src)
61+
size = ctypes.c_size_t(size)
62+
destination = ctypes.c_ulonglong(destination)
63+
oldProtect = ctypes.wintypes.DWORD()
64+
65+
kernel32.VirtualProtectEx(handle,destination,size, PAGE_EXECUTE_READWRITE, ctypes.byref(oldProtect))
66+
kernel32.WriteProcessMemory(handle, destination, src, size, None)
67+
kernel32.VirtualProtectEx(handle,destination,size, oldProtect, ctypes.byref(oldProtect))
68+
69+
def nopBytes(handle,destination,size):
70+
hexString = ""
71+
for i in range(size):
72+
hexString += "90"
73+
patchBytes(handle, hexString, destination, size)
74+

0 commit comments

Comments
 (0)