def __get__(fget_self, obj, cls=None): if cls is None: if obj is None: return fget_self else: cls = obj.__class__ if cls._binary is None: raise ValueError('_binary was not specified.') # Create a binary object binary = find_binary(cls._binary, cls._srv_check) # Create the function object func = binary[identifier].make_function( convention, args, return_type) # Called with a this pointer? if obj is not None: # Wrap the function using MemberFunction, so we don't have # to pass the this pointer anymore func = MemberFunction(self, return_type, func, obj) func.__doc__ = doc return func
def get_offset(binary, identifier, offset, size=4, srv_check=True): """Return the offset.""" # Get the binary if not isinstance(binary, BinaryFile): binary = find_binary(binary, srv_check) return getattr(binary.find_address(identifier), 'get_' + _unsinged_size_type[size])(offset)
def get_relative_pointer(binary, identifier, offset, size=4, srv_check=True): """Return the relative pointer.""" # Get the binary if not isinstance(binary, BinaryFile): binary = find_binary(binary, srv_check) # Get the pointer pointer = binary.find_address(identifier) pointer += getattr( pointer, 'get_' + _singed_size_type[size])(offset) + offset + size return pointer
def get_pointer(binary, identifier, offset=0, level=0, srv_check=True): """Return the pointer.""" # Get the binary if not isinstance(binary, BinaryFile): binary = find_binary(binary, srv_check) # Get the pointer pointer = binary.find_pointer(identifier, offset, level) # Raise an error if the pointer is invalid if not pointer: raise ValueError("Unable to find the pointer.") return pointer
def global_pointer( self, cls, binary, identifier, offset=0, level=0, srv_check=True): """Search for a global pointer and wrap the it.""" # Get the binary binary = find_binary(binary, srv_check) # Get the global pointer ptr = binary.find_pointer(identifier, offset, level) # Raise an error if the pointer is invalid if not ptr: raise ValueError('Unable to find the global pointer.') # Wrap the pointer using the given class and save the instance ptr = self.global_pointers[cls.__name__] = make_object(cls, ptr) return ptr
def pipe_function( self, binary, identifier, args=(), return_type=DataType.VOID, convention=Convention.CDECL, srv_check=True, doc=None): """Create a simple pipe function.""" # Create a converter, if it's not a native type if return_type not in DataType.values: return_type = self.create_converter(return_type) # Find the binary binary = find_binary(binary, srv_check) # Find the address and make it to a function func = binary[identifier].make_function(convention, args, return_type) # Add documentation func.__doc__ = doc return func
def __get__(fget_self, obj, cls): if cls._binary is None: raise ValueError('_binary was not specified.') # Create a binary object binary = find_binary(cls._binary, cls._srv_check) # Create the function object func = binary[identifier].make_function( convention, args, return_type ) # Called with a this pointer? if obj is not None: # Wrap the function using MemberFunction, so we don't have # to pass the this pointer anymore func = MemberFunction(self, return_type, func, obj) func.__doc__ = doc return func
def pipe_function(self, binary, identifier, args=(), return_type=DataType.VOID, convention=Convention.CDECL, srv_check=True, doc=None): """Create a simple pipe function.""" # Create a converter, if it's not a native type if return_type not in DataType.values: return_type = self.create_converter(return_type) # Find the binary binary = find_binary(binary, srv_check) # Find the address and make it to a function func = binary[identifier].make_function(convention, args, return_type) # Add documentation func.__doc__ = doc return func
def global_pointer(self, cls, binary, identifier, offset=0, level=0, srv_check=True): """Search for a global pointer and wrap the it.""" manager_logger.log_debug('Retrieving global pointer for {}...'.format( cls.__name__)) # Get the binary binary = find_binary(binary, srv_check) # Get the global pointer ptr = binary.find_pointer(identifier, offset, level) # Raise an error if the pointer is invalid if not ptr: raise ValueError('Unable to find the global pointer.') # Wrap the pointer using the given class and save the instance ptr = self.global_pointers[cls.__name__] = make_object(cls, ptr) return ptr
def load(): try: server = memory.find_binary('server') except: print('[saveWeaponHook] find binary server failed!') return logging.basicConfig(filename='saveWeaponHook.log', format='%(asctime)s %(levelname)s %(message)s') logging.info('plugin saveWeaponHook loaded.') UTIL_KeyValues_SetString = server[identifier_KeyValues_SetString].make_function( Convention.THISCALL, (DataType.POINTER, DataType.STRING, DataType.STRING), # KeyValues::SetString(KeyValues *this, const char *s, const char *) DataType.VOID ) @PreHook(UTIL_KeyValues_SetString) def _pre_keyvalues_set_string(args): if args[1] == 'restoreSecondaryWeaponName': logging.info('setting restoreSecondaryWeaponName') args[2] = "weapon_pistol_magnum" return # args[2] may be not NUL-terminated value = memory.helpers.Array(TypeManager, false, "char", args[2], 20) weapon_name = args[2][:20] # not good enough logging.info('server_srv.so!KeyValues::SetString({}, {}).'.format(args[1], weapon_name)) print('server_srv.so!KeyValues::SetString({}, {}).'.format(args[1], weapon_name)) if not weapon_name in secondaryWEaponName: # sometimes value "weapon_chainsaw" occurres, could this crash the server? logging.info('invalid restoreSecondaryWeaponName: {}, set to {}'.format(weapon_name, "weapon_pistol_magnum")) print('invalid restoreSecondaryWeaponName: {}, set to {}'.format(weapon_name, "weapon_pistol_magnum")) # fallback value is "weapon_pistol_magnum" args[2] = "weapon_pistol_magnum"
RE_DEFAULT = re.compile('#default', re.IGNORECASE) RE_GREEN = re.compile('#green', re.IGNORECASE) RE_LIGHTGREEN = re.compile('#lightgreen', re.IGNORECASE) RE_DARKGREEN = re.compile('#darkgreen', re.IGNORECASE) RE_MULTI = re.compile('#multi', re.IGNORECASE) # ============================================================================= # >> GLOBAL VARIABLES # ============================================================================= NO_SRV_CHECK_GAMES = [ 'csgo' ] if PLATFORM == 'windows': clib = memory.find_binary('msvcrt.dll') tier1 = memory.find_binary('bin/tier0') else: clib_path = find_library('c') if clib_path is None: raise ValueError('Unable to find C library.') clib = memory.find_binary(clib_path, check_extension=False) tier1 = memory.find_binary( 'bin/libtier0', SOURCE_ENGINE_BRANCH not in NO_SRV_CHECK_GAMES) sv_cheats = cvar.find_var('sv_cheats') # =============================================================================
# ============================================================================= # >> GLOBAL VARIABLES # ============================================================================= _data_file = GUNGAME_DATA_PATH / info.name + '.json' with _data_file.open() as _open_file: _data = json.load(_open_file).get(GAME_NAME, {}).get(PLATFORM, {}) if not _data: raise NotImplementedError( f'Game "{GAME_NAME}" on platform "{PLATFORM}" not currently supported' ) if PLATFORM == 'windows': for _key, _value in _data.items(): _data[_key] = binascii.unhexlify(_value.replace(' ', '')) server = find_binary('server') GetTeamNumber = server[_data['GetTeamNumber']].make_function( Convention.THISCALL, [DataType.POINTER], DataType.INT, ) InSameTeam = server[_data['InSameTeam']].make_function( Convention.THISCALL, [DataType.POINTER, DataType.POINTER], DataType.BOOL, ) OnAudibleEvent = server[_data['OnAudibleEvent']].make_function( Convention.THISCALL,
def get_type_from_dict(raw_data, manager=manager): type_dict = dict() binary = raw_data.get(Key.BINARY, None) if binary is not None: binary = Key.as_str(manager, binary) type_dict["_binary"] = binary srv_check = raw_data.get(Key.SRV_CHECK, None) if srv_check is not None: srv_check = Key.as_bool(manager, srv_check) type_dict["_srv_check"] = srv_check else: srv_check = True size = raw_data.get(Key.SIZE, None) if size is not None: type_dict["_size"] = Key.as_int(manager, size) # Prepare pointer and instance attributes for method in (manager.instance_attribute, manager.pointer_attribute): attributes = parse_data( manager, raw_data.get(method.__name__, {}), ((Key.TYPE_NAME, Key.as_attribute_type, NO_DEFAULT), (Key.OFFSET, Key.as_int, NO_DEFAULT), (Key.DOC, Key.as_str, None))) # Create the attributes for name, data in attributes: type_dict[name] = method(*data) # Prepare arrays for method in (manager.static_instance_array, manager.dynamic_instance_array, manager.static_pointer_array, manager.dynamic_pointer_array): arrays = parse_data( manager, raw_data.get(method.__name__, {}), ((Key.TYPE_NAME, Key.as_attribute_type, NO_DEFAULT), (Key.OFFSET, Key.as_int, NO_DEFAULT), (Key.LENGTH, Key.as_int, None), (Key.DOC, Key.as_str, None))) # Create the arrays for name, data in arrays: type_dict[name] = method(*data) # Prepare virtual functions vfuncs = parse_data( manager, raw_data.get("virtual_function", {}), ((Key.OFFSET, Key.as_int, NO_DEFAULT), (Key.ARGS, Key.as_args_tuple, ()), (Key.RETURN_TYPE, Key.as_return_type, DataType.VOID), (Key.CONVENTION, Key.as_convention, Convention.THISCALL), (Key.DOC, Key.as_str, None))) # Create the virtual functions for name, data in vfuncs: type_dict[name] = manager.virtual_function(*data) # Prepare functions funcs = parse_data( manager, raw_data.get("function", {}), ((Key.BINARY, Key.as_str, binary if binary is not None else NO_DEFAULT), (Key.SRV_CHECK, Key.as_bool, srv_check), (Key.IDENTIFIER, Key.as_identifier, NO_DEFAULT), (Key.ARGS, Key.as_args_tuple, ()), (Key.RETURN_TYPE, Key.as_return_type, DataType.VOID), (Key.CONVENTION, Key.as_convention, Convention.THISCALL), (Key.DOC, Key.as_str, None))) # Create the functions for name, data in funcs: ptr = find_binary(*data[:2]).find_address(data[2]) type_dict[name] = manager.function_pointer(ptr, *data[3:]) # Via binary. # Prepare binary attributes attributes = parse_data( manager, raw_data.get("binary_attribute", {}), (("method", Key.as_str, "instance_attribute"), (Key.BINARY, Key.as_str, binary if binary is not None else NO_DEFAULT), (Key.IDENTIFIER, Key.as_identifier, NO_DEFAULT), (Key.OFFSET, Key.as_int, NO_DEFAULT), (Key.SIZE, Key.as_int, 4), (Key.SRV_CHECK, Key.as_bool, srv_check), (Key.TYPE_NAME, Key.as_attribute_type, NO_DEFAULT), (Key.DOC, Key.as_str, None))) # Create the attributes for name, data in attributes: method = getattr(manager, data[0]) offset = get_offset(*data[1:6]) type_dict[name] = method(data[6], offset, data[7]) # Prepare binary arrays arrays = parse_data( manager, raw_data.get("binary_array", {}), (("method", Key.as_str, "static_instance_array"), (Key.BINARY, Key.as_str, binary if binary is not None else NO_DEFAULT), (Key.IDENTIFIER, Key.as_identifier, NO_DEFAULT), (Key.OFFSET, Key.as_int, NO_DEFAULT), (Key.SIZE, Key.as_int, 4), (Key.SRV_CHECK, Key.as_bool, srv_check), (Key.TYPE_NAME, Key.as_attribute_type, NO_DEFAULT), (Key.LENGTH, Key.as_int, None), (Key.DOC, Key.as_str, None))) # Create the arrays for name, data in arrays: method = getattr(manager, data[0]) offset = get_offset(*data[1:6]) type_dict[name] = method(data[6], offset, data[7], data[8]) # Prepare binary virtual functions vfuncs = parse_data( manager, raw_data.get("binary_virtual_function", {}), ((Key.BINARY, Key.as_str, binary if binary is not None else NO_DEFAULT), (Key.IDENTIFIER, Key.as_identifier, NO_DEFAULT), (Key.OFFSET, Key.as_int, NO_DEFAULT), (Key.SIZE, Key.as_int, 4), (Key.SRV_CHECK, Key.as_bool, srv_check), (Key.ARGS, Key.as_args_tuple, ()), (Key.RETURN_TYPE, Key.as_return_type, DataType.VOID), (Key.CONVENTION, Key.as_convention, Convention.THISCALL), (Key.DOC, Key.as_str, None))) # Create the virtual functions for name, data in vfuncs: index = get_offset(*data[:5]) // 4 type_dict[name] = manager.virtual_function(index, *data[5:]) # Prepare binary absolute functions funcs = parse_data( manager, raw_data.get("binary_absolute_function", {}), ((Key.BINARY, Key.as_str, binary if binary is not None else NO_DEFAULT), (Key.IDENTIFIER, Key.as_identifier, NO_DEFAULT), (Key.OFFSET, Key.as_int, NO_DEFAULT), (Key.LEVEL, Key.as_int, 1), (Key.SRV_CHECK, Key.as_bool, srv_check), (Key.ARGS, Key.as_args_tuple, ()), (Key.RETURN_TYPE, Key.as_return_type, DataType.VOID), (Key.CONVENTION, Key.as_convention, Convention.THISCALL), (Key.DOC, Key.as_str, None))) # Create the functions for name, data in funcs: ptr = get_pointer(*data[:5]) type_dict[name] = manager.function_pointer(ptr, *data[5:]) # Prepare binary relative functions funcs = parse_data( manager, raw_data.get("binary_relative_function", {}), ((Key.BINARY, Key.as_str, binary if binary is not None else NO_DEFAULT), (Key.IDENTIFIER, Key.as_identifier, NO_DEFAULT), (Key.OFFSET, Key.as_int, NO_DEFAULT), (Key.SIZE, Key.as_int, 4), (Key.SRV_CHECK, Key.as_bool, srv_check), (Key.ARGS, Key.as_args_tuple, ()), (Key.RETURN_TYPE, Key.as_return_type, DataType.VOID), (Key.CONVENTION, Key.as_convention, Convention.THISCALL), (Key.DOC, Key.as_str, None))) # Create the functions for name, data in funcs: ptr = get_relative_pointer(*data[:5]) type_dict[name] = manager.function_pointer(ptr, *data[5:]) # Prepare binary pointers ptrs = parse_data(manager, raw_data.get("binary_pointer", {}), ((Key.BINARY, Key.as_str, binary if binary is not None else NO_DEFAULT), (Key.IDENTIFIER, Key.as_identifier, NO_DEFAULT), (Key.OFFSET, Key.as_int, NO_DEFAULT), (Key.LEVEL, Key.as_int, 0), (Key.SRV_CHECK, Key.as_bool, srv_check))) # Create the pointers for name, data in ptrs: type_dict[name] = get_pointer(*data) return type_dict
def argument_ptr_changed(self, index, registers, arg_ptr): pass def get_return_ptr(self, registers): pass def return_ptr_changed(self, registers, return_ptr): pass # ============================================================================= # >> GLOBAL VARIABLES # ============================================================================= MEMORY_PATH = PLRBOTS_DATA_PATH / 'memory' server = memory.find_binary('server') if PLATFORM == "windows": _server_tools_interface = core.get_interface( "tf/bin/server.dll", 'VSERVERTOOLS002') else: _server_tools_interface = core.get_interface( "tf/bin/server_srv.so", 'VSERVERTOOLS002') # ============================================================================= # >> CLASSES # ============================================================================= class PLRTypeManager(TypeManager): def function( self, identifier, args=(), return_type=DataType.VOID,
COLOR_LIGHTGREEN = '\3' COLOR_DARKGREEN = '\5' RE_DEFAULT = re.compile('#default', re.IGNORECASE) RE_GREEN = re.compile('#green', re.IGNORECASE) RE_LIGHTGREEN = re.compile('#lightgreen', re.IGNORECASE) RE_DARKGREEN = re.compile('#darkgreen', re.IGNORECASE) RE_MULTI = re.compile('#multi', re.IGNORECASE) # ============================================================================= # >> GLOBAL VARIABLES # ============================================================================= NO_SRV_CHECK_GAMES = ['csgo'] if PLATFORM == 'windows': clib = memory.find_binary('msvcrt.dll') tier1 = memory.find_binary('bin/tier0') else: clib_path = find_library('c') if clib_path is None: raise ValueError('Unable to find C library.') clib = memory.find_binary(clib_path, check_extension=False) tier1 = memory.find_binary('bin/libtier0', SOURCE_ENGINE_BRANCH not in NO_SRV_CHECK_GAMES) sv_cheats = cvar.find_var('sv_cheats') # ============================================================================= # >> ConVar structure for es.forcevalue() # =============================================================================
if PLATFORM == 'windows': # PLAYER HURT ON_TAKE_DAMAGE_IDENTIFIER = b'\x55\x8B\xEC\x81\xEC\x44\x01\x2A\x2A\x56' \ b'\x89\x4D\xFC' # RESTRICT identifier = b'\x55\x8B\xEC\x83\xEC\x38\x89\x4D\xF4' else: # PLAYER HURT ON_TAKE_DAMAGE_IDENTIFIER = '_ZN20CBaseCombatCharacter12OnTakeDamageERK15CTakeDamageInfo' # RESTRICT identifier = '_ZN9CCSPlayer10BumpWeaponEP17CBaseCombatWeapon' # ============================================================================= # >> GLOBAL VARIABLES # ============================================================================= server = find_binary('cstrike/bin/server') OnTakeDamage = server[ON_TAKE_DAMAGE_IDENTIFIER].make_function(Convention.THISCALL, (DataType.POINTER, DataType.POINTER), DataType.VOID) BUMP_WEAPON = server[identifier].make_function(Convention.THISCALL, (DataType.POINTER, DataType.POINTER), DataType.BOOL)
def get_data_from_dict(raw_data): data_dict = dict() binary = raw_data.get(Key.BINARY, None) if binary is not None: binary = Key.as_str(manager, binary) srv_check = Key.as_bool(manager, raw_data.get(Key.SRV_CHECK, "True")) for method_name in ("instance_attribute", "pointer_attribute", "static_instance_array", "dynamic_instance_array", "static_pointer_array", "dynamic_pointer_array", "virtual_function"): offsets_data = parse_data(manager, raw_data.get(method_name, {}), ((Key.OFFSET, Key.as_int, NO_DEFAULT), )) for name, data in offsets_data: data_dict[name] = data[0] pointers_data = parse_data(manager, raw_data.get( "function", {}), ((Key.IDENTIFIER, Key.as_identifier, NO_DEFAULT), (Key.BINARY, Key.as_str, binary if binary is not None else NO_DEFAULT), (Key.SRV_CHECK, Key.as_bool, srv_check))) for name, data in pointers_data: data_dict[name] = find_binary(*data[1:]).find_address(data[0]).address for method_name in ("binary_attribute", "binary_array"): offsets_data = parse_data( manager, raw_data.get(method_name, {}), ((Key.BINARY, Key.as_str, binary if binary is not None else NO_DEFAULT), (Key.IDENTIFIER, Key.as_identifier, NO_DEFAULT), (Key.OFFSET, Key.as_int, NO_DEFAULT), (Key.SIZE, Key.as_int, 4), (Key.SRV_CHECK, Key.as_bool, srv_check))) for name, data in offsets_data: data_dict[name] = get_offset(*data) offsets_data = parse_data(manager, raw_data.get("binary_virtual_function", {}), ((Key.BINARY, Key.as_str, binary if binary is not None else NO_DEFAULT), (Key.IDENTIFIER, Key.as_identifier, NO_DEFAULT), (Key.OFFSET, Key.as_int, NO_DEFAULT), (Key.SIZE, Key.as_int, 4), (Key.SRV_CHECK, Key.as_bool, srv_check))) for name, data in offsets_data: data_dict[name] = get_offset(*data) // 4 pointers_data = parse_data( manager, raw_data.get("binary_absolute_function", {}), ((Key.BINARY, Key.as_str, binary if binary is not None else NO_DEFAULT), (Key.IDENTIFIER, Key.as_identifier, NO_DEFAULT), (Key.OFFSET, Key.as_int, NO_DEFAULT), (Key.LEVEL, Key.as_int, 1), (Key.SRV_CHECK, Key.as_bool, srv_check))) for name, data in pointers_data: data_dict[name] = get_pointer(*data).address pointers_data = parse_data( manager, raw_data.get("binary_relative_function", {}), ((Key.BINARY, Key.as_str, binary if binary is not None else NO_DEFAULT), (Key.IDENTIFIER, Key.as_identifier, NO_DEFAULT), (Key.OFFSET, Key.as_int, NO_DEFAULT), (Key.SIZE, Key.as_int, 4), (Key.SRV_CHECK, Key.as_bool, srv_check))) for name, data in pointers_data: data_dict[name] = get_relative_pointer(*data).address pointers_data = parse_data( manager, raw_data.get("binary_pointer", {}), ((Key.BINARY, Key.as_str, binary if binary is not None else NO_DEFAULT), (Key.IDENTIFIER, Key.as_identifier, NO_DEFAULT), (Key.OFFSET, Key.as_int, NO_DEFAULT), (Key.LEVEL, Key.as_int, 0), (Key.SRV_CHECK, Key.as_bool, srv_check))) for name, data in pointers_data: data_dict[name] = get_pointer(*data).address return data_dict