import win32api
import win32process
import win32con
from ctypes import *
ntdll = windll.ntdll
k32 = windll.kernel32
u32 = windll.user32
class PROCESSENTRY32(Structure):
_fields_ = [
("dwSize", c_uint32),
("cntUsage", c_uint32),
("th32ProcessID", c_uint32),
("th32DefaultHeapID", c_uint64),
("th32ModuleID", c_uint32),
("cntThreads", c_uint32),
("th32ParentProcessID", c_uint32),
("pcPriClassBase", c_uint32),
("dwFlags", c_uint32),
("szExeFile", c_char * 260)
]
class Process:
@staticmethod
def get_process_handle(name):
handle = 0
entry = PROCESSENTRY32()
snap = k32.CreateToolhelp32Snapshot(0x00000002, 0)
entry.dwSize = sizeof(PROCESSENTRY32)
while k32.Process32Next(snap, pointer(entry)):
if entry.szExeFile == name.encode("ascii", "ignore"):
handle = k32.OpenProcess(0x430, 0, entry.th32ProcessID)
break
k32.CloseHandle(snap)
return handle
@staticmethod
def get_process_peb(handle, wow64):
buffer = (c_uint64 * 6)(0)
if wow64:
if ntdll.NtQueryInformationProcess(handle, 26, pointer(buffer), 8, 0) == 0:
return buffer[0]
else:
if ntdll.NtQueryInformationProcess(handle, 0, pointer(buffer), 48, 0) == 0:
return buffer[1]
return 0
def __init__(self, name):
self.mem = self.get_process_handle(name)
if self.mem == 0:
raise Exception("Process [" + name + "] not found!")
self.peb = self.get_process_peb(self.mem, True)
if self.peb == 0:
self.peb = self.get_process_peb(self.mem, False)
self.wow64 = False
else:
self.wow64 = True
self.pid = win32process.GetWindowThreadProcessId(self.mem)
def is_running(self):
buffer = c_uint32()
k32.GetExitCodeProcess(self.mem, pointer(buffer))
return buffer.value == 0x103
def read_vec3(self, address):
buffer = Vector3()
ntdll.NtReadVirtualMemory(self.mem, c_long(address), pointer(buffer), 12, 0)
return buffer
def read_buffer(self, address, length):
buffer = (c_uint8 * length)()
ntdll.NtReadVirtualMemory(self.mem, address, buffer, length, 0)
return buffer
def read_string(self, address, length=120):
buffer = create_string_buffer(length)
ntdll.NtReadVirtualMemory(self.mem, address, buffer, length, 0)
return buffer.value
def read_unicode(self, address, length=120):
buffer = create_unicode_buffer(length)
ntdll.NtReadVirtualMemory(self.mem, address, pointer(buffer), length, 0)
return buffer.value
def read_float(self, address, length=4):
buffer = c_float()
ntdll.NtReadVirtualMemory(self.mem, c_long(address), pointer(buffer), length, 0)
return buffer.value
def read_i8(self, address, length=1):
buffer = c_uint8()
ntdll.NtReadVirtualMemory(self.mem, address, pointer(buffer), length, 0)
return buffer.value
def read_i16(self, address, length=2):
buffer = c_uint16()
ntdll.NtReadVirtualMemory(self.mem, address, pointer(buffer), length, 0)
return buffer.value
def read_i32(self, address, length=4):
buffer = c_uint32()
ntdll.NtReadVirtualMemory(self.mem, address, pointer(buffer), length, 0)
return buffer.value
def read_i64(self, address, length=8):
buffer = c_uint64()
ntdll.NtReadVirtualMemory(self.mem, c_uint64(address), pointer(buffer), length, 0)
return buffer.value
def write_float(self, address, value):
buffer = c_float(value)
return ntdll.NtWriteVirtualMemory(self.mem, address, pointer(buffer), 4, 0) == 0
def write_i8(self, address, value):
buffer = c_uint8(value)
return ntdll.NtWriteVirtualMemory(self.mem, address, pointer(buffer), 1, 0) == 0
def write_i16(self, address, value):
buffer = c_uint16(value)
return ntdll.NtWriteVirtualMemory(self.mem, address, pointer(buffer), 2, 0) == 0
def write_i64(self, address, value):
buffer = c_uint64(value)
return ntdll.NtWriteVirtualMemory(self.mem, address, pointer(buffer), 8, 0) == 0
def get_module(self, name):
if self.wow64:
a0 = [0x04, 0x0C, 0x14, 0x28, 0x10]
else:
a0 = [0x08, 0x18, 0x20, 0x50, 0x20]
a1 = self.read_i64(self.read_i64(self.peb + a0[1], a0[0]) + a0[2], a0[0])
a2 = self.read_i64(a1 + a0[0], a0[0])
while a1 != a2:
val = self.read_unicode(self.read_i64(a1 + a0[3], a0[0]))
if str(val).lower() == name.lower():
return self.read_i64(a1 + a0[4], a0[0])
a1 = self.read_i64(a1, a0[0])
raise Exception("Module [" + name + "] not found!")
def get_export(self, module, name):
if module == 0:
return 0
a0 = self.read_i32(module + self.read_i16(module + 0x3C) + (0x88 - self.wow64 * 0x10)) + module
a1 = [self.read_i32(a0 + 0x18), self.read_i32(a0 + 0x1c), self.read_i32(a0 + 0x20), self.read_i32(a0 + 0x24)]
while a1[0] > 0:
a1[0] -= 1
export_name = self.read_string(module + self.read_i32(module + a1[2] + (a1[0] * 4)), 120)
if name.encode('ascii', 'ignore') == export_name:
a2 = self.read_i16(module + a1[3] + (a1[0] * 2))
a3 = self.read_i32(module + a1[1] + (a2 * 4))
return module + a3
raise Exception("Export [" + name + "] not found!")
def find_pattern(self, module_name, pattern, mask):
a0 = self.get_module(module_name)
a1 = self.read_i32(a0 + 0x03C) + a0
a2 = self.read_i32(a1 + 0x01C)
a3 = self.read_i32(a1 + 0x02C)
a4 = self.read_buffer(a0 + a3, a2)
for a5 in range(0, a2):
a6 = 0
for a7 in range(0, pattern.__len__()):
if mask[a7] == 'x' and a4[a5 + a7] != pattern[a7]:
break
a6 = a6 + 1
if a6 == pattern.__len__():
return a0 + a3 + a5
return 0