Hooks
zwylib.HookUtils wraps exteraGram’s Xposed-based method hooking with a friendlier, function-based API, plus a few reflection helpers for finding and reading Java members. Hooking is automatically skipped (and returns None) while the client’s Plugins Safe Mode is enabled.
Getting Started
# ... metadata and zwylib import ...
from zwylib import HookUtils
def on_before_send(param):
print("About to call the hooked method:", param.args)
class MyPlugin(BasePlugin):
def on_plugin_load(self):
method = SomeJavaClass.getClass().getDeclaredMethod("someMethod", ...)
self.unhook = HookUtils.hook_before(method, on_before_send)
def on_plugin_unload(self):
if self.unhook:
HookUtils.unhook(self.unhook)zwylib.HookUtils
class HookUtilsMethods
hook
HookUtils.hook(
plugin_id: str,
method_or_constructor: Member,
xposed_hook: Optional[Any] = None,
priority: Optional[int] = None,
*,
before: Optional[(XC_MethodHook.MethodHookParam) -> None] = None,
after: Optional[(XC_MethodHook.MethodHookParam) -> None] = None,
before_filters: Optional[List[Any]] = None,
after_filters: Optional[List[Any]] = None
) -> Optional[XC_MethodHook.Unhook]An equivalent to BasePlugin.hook(), but without using a class instance.
Low-level entry point for hooking a Java method or constructor. Accepts either a full xposed_hook object (a MethodHook, MethodReplacement, or BaseHook-style instance) or plain before/after callables — you’ll usually want one of the more convenient hook_before, hook_after, or hook_replace instead. Registers the resulting hook with PluginsController so it’s automatically removed when the plugin unloads.
Parameters
plugin_id(str): ID of the plugin performing the hook.method_or_constructor(Member): The JavaMethodorConstructorto hook.xposed_hook(Optional[Any], defaultNone): A pre-built hook object.priority(Optional[int], defaultNone): Hook priority, if applicable.before(keyword-only, optional): Callback run before the original method.after(keyword-only, optional): Callback run after the original method.before_filters/after_filters(keyword-only, optional): Argument filters restricting whenbefore/afterrun.
Raises
TypeError: If none ofxposed_hook,before, orafterare provided.
Example
HookUtils.hook(__id__, method, before=lambda param: print(param.args))hook_before
HookUtils.hook_before(
member: Member,
callback: (XC_MethodHook.MethodHookParam) -> None,
**kwargs
) -> Optional[XC_MethodHook.Unhook]Hooks member to run callback right before the original method executes. The calling plugin’s ID is inferred automatically from the call stack. callback is automatically wrapped so any exception it raises is caught and logged instead of crashing the hooked method.
Parameters
member(Member): The JavaMethodorConstructorto hook.callback((XC_MethodHook.MethodHookParam) ->None): Function to run before the original method.**kwargs: Forwarded tohook(e.g.priority,before_filters).
Example
HookUtils.hook_before(method, lambda param: print("before!"))hook_after
HookUtils.hook_after(
member: Member,
callback: (XC_MethodHook.MethodHookParam) -> None,
**kwargs
) -> Optional[XC_MethodHook.Unhook]Hooks member to run callback right after the original method executes. The calling plugin’s ID is inferred automatically from the call stack.
Parameters
member(Member): The JavaMethodorConstructorto hook.callback((XC_MethodHook.MethodHookParam) ->None): Function to run after the original method.**kwargs: Forwarded tohook(e.g.priority,after_filters).
Example
HookUtils.hook_after(method, lambda param: print("after!", param.getResult()))hook_replace
HookUtils.hook_replace(
member: Member,
callback: (XC_MethodHook.MethodHookParam) -> None,
**kwargs
) -> Optional[XC_MethodHook.Unhook]Hooks member so callback entirely replaces the original method’s implementation. The calling plugin’s ID is inferred automatically from the call stack.
Parameters
member(Member): The JavaMethodorConstructorto hook.callback((XC_MethodHook.MethodHookParam) ->None): Function that replaces the original method.**kwargs: Forwarded tohook(e.g.priority).
Example
HookUtils.hook_replace(method, lambda param: param.setResult(None))unhook
HookUtils.unhook(unhook: XC_MethodHook.Unhook, plugin_id: Optional[str] = None) -> NoneRemoves a previously installed hook.
Parameters
unhook(XC_MethodHook.Unhook): The unhook handle returned byhook/hook_before/hook_after/hook_replace.plugin_id(Optional[str], defaultNone): ID of the plugin that owns the hook. Inferred automatically from the call stack if omitted.
get_private_field
HookUtils.get_private_field(obj: JObject, field_name: str) -> Optional[Any]Reads a private (or otherwise inaccessible) field’s value off a Java object via reflection, walking up the class hierarchy until it finds a declaring class for field_name.
Parameters
obj(JObject): The Java object to read from.field_name(str): Name of the field to read.
Example
contacts = HookUtils.get_private_field(adapter, "contacts")find_method_by_args_count
HookUtils.find_method_by_args_count(
clazz: Union[JClass, JavaClass],
method_name: str,
args_count: int = 0
) -> Optional[Method]Finds a declared method by name and parameter count, and makes it accessible.
Parameters
clazz(Union[JClass, JavaClass]): The Java class to search.method_name(str): Name of the method to find.args_count(int, default0): Exact number of parameters the method must have.
Example
method = HookUtils.find_method_by_args_count(SomeClass.getClass(), "onCreate", 1)find_method_by_args
HookUtils.find_method_by_args(
clazz: Union[JClass, JavaClass],
method_name: str,
python_arg_types: List[JClass]
) -> Optional[Method]Finds a declared method by name and exact parameter types, and makes it accessible.
Parameters
clazz(Union[JClass, JavaClass]): The Java class to search.method_name(str): Name of the method to find.python_arg_types(List[JClass]): Expected parameter types, in order.
Example
method = HookUtils.find_method_by_args(SomeClass.getClass(), "setValue", [jint])find_max_args_method
HookUtils.find_max_args_method(clazz: Union[JClass, JavaClass], method_name: str) -> Optional[Method]Finds the overload of method_name with the most parameters, and makes it accessible. Useful when a method has several overloads and you want the most complete one without knowing its exact signature.
Parameters
clazz(Union[JClass, JavaClass]): The Java class to search.method_name(str): Name of the method to find.
Example
method = HookUtils.find_max_args_method(SomeClass.getClass(), "someOverloadedMethod")