Invoking method via broadcast receiver

1k Views Asked by At

I want to invoke a system method at runtime from my app using Xposed. I think a broadcast receiver should be the right way.

How can I set up a broadcast receiver in the right context so it is able to invoke that method? Do I need some kind of proxy instance for the class? A short example code would be nice:)

1

There are 1 best solutions below

0
On

I tried this too. You can use reflection to do this.

Example:

in com.your.package.app.XModuleBridge

public static abstract class HandleHook {
    public abstract void before(Object paramObj);

    public abstract void after(Object paramObj);
}

public boolean unhook(Object key) {
    return false;
}

/* handle must be instance of HandleHook */
public Object hook(Method method, Object handle) {
    return null;
}

in Xposed module.

       /* bridge = Class object of XModuleBridge */
        XposedBridge.hookMethod(bridge.getDeclaredMethod("hook",
                Method.class, Object.class), new XC_MethodHook() {
            {
                System.out.println(">>>>>  some log ");
            }

            @Override
            protected void afterHookedMethod(MethodHookParam param)
                    throws Throwable {
                param.setResult(hookMethod(param));
            }
        });

        XposedBridge.hookMethod(
                bridge.getDeclaredMethod("unhook", Object.class),
                new XC_MethodHook() {
            {
                System.out.println(">>>>>  some log ");
            }


                    @Override
                    protected void afterHookedMethod(MethodHookParam param)
                            throws Throwable {
                        XC_MethodHook.Unhook hook = hookedMethod
                                .remove(param.args[0]);
                        if (hook != null) {
                            hook.unhook();
                        }
                        param.setResult(true);
                    }
                });

--

private Object hookMethod(XC_MethodHook.MethodHookParam param) {
    final Object[] args = param.args;
    // TODO check args.
    XC_MethodHook.Unhook unhook = XposedBridge.hookMethod((Method) args[0],
            new XC_MethodHook() {
                private Object call = args[1];
                {
                    System.out.println(">>>>>  some log ");
                }

                @Override
                protected void beforeHookedMethod(MethodHookParam param)
                        throws Throwable {
                    call.getClass()
                            .getDeclaredMethod("before", Object.class)
                            .invoke(call, param);
                }

                @Override
                protected void afterHookedMethod(MethodHookParam param)
                        throws Throwable {
                    call.getClass()
                            .getDeclaredMethod("after", Object.class)
                            .invoke(call, param);
                }
            });

    Object key = new Object();
    hookedMethod.put(key, unhook);
    return key;
}

Usage:

        XModuleBridge bridge = new XModuleBridge();
        Method method = null;
        try {
            method = textView.getClass().getDeclaredMethod("append",
                    CharSequence.class);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        Object hooked = bridge.hook(method, new HandleHook() {
            @Override
            public void before(Object paramObj) {
                /* paramObj is instance of XC_MethodHook.MethodHookParam */
                /* reflect paramObj in ParamConverter.
                   or cast to XC_MethodHook.MethodHookParam*/
                ParamConverter param = new ParamConverter(
                        paramObj);
                System.out.println(">>>>>>>   1" + param.args[0]);
                param.args[0] = "changed.";
                System.out.println(">>>>>>>   2" + param.args[0]);
            }

            @Override
            public void after(Object paramObj) {}
        });

        // ...

        bridge.unhook(hooked);

I don't know how to hook method for all app at runtime, because I found that each app has different xposed module instance of different Class object. They don't share object each other. (I don't want using database or disk file if bad performance)