HermesAgent群控系统使用教程

41次阅读
没有评论

HermesAgent是virjar大神写的一个Android群控系统,基于xposed+RPC实现方法级别的群控。HermesAgent是hermes系统的客户端模块,他是种植在手机里面的一个agent,同时也是一个xposed的模块插件。

一、原理

agent本身启动了一个service,agent插件模块将会自动注册钩子函数,并且和service通信。Android设备外部请求可以通过暴露在agent上面的一个http端口,和agent通信,然后agent和目标apkRPC。 如此实现外部请求到任何一个app的任何功能的外部调用。

HermesAgent群控系统使用教程

二、使用教程

2.1 安装

下载hermesagent项目源码,编译后安装到手机上,然后在Xposed模块界面开启hermesagent模块,重启手机既可。

2.2 代码编写

本教程以调用我前面写的Xposed Hook教程《Xposed框架Hook Demo实例教程》中MainActivity类中的toastMsg方法为例

在hookagent包下新建类TestAgent,实现AgentCallback接口,并重写targetPackageName、needHook、invoke、onXposedHotLoad四个方法。

  • targetPackageName方法返回目标APK包名,此处为”com.hyb.hookdemo”;
  • needHook方法返回一个boolean类型,一个app可能有多个进程,当进程为你需要hook的进程时,返回True;
  • invoke方法为远程调用时执行的方法,可根据你请求中传入的参数反射调用你hook到的目标方法,反正方法的执行结果;
  • onXposedHotLoad方法内部可编写具体的hook代码,可对目标方法进行hook,并存储方法对象和类对象,以便invoke方法中调用;

具体代码见文章最后。

2.3 测试

  • 代码编写完毕后,首先需重新编译安装到手机并重启;
  • 重启后,hermesagent程序会自动打开(如无法自动打开,请检查手机自启动权限),并且还会自动打开HookDemo程序;
  • 通过浏览器访问app所在ip的5597端口,查看服务列表;
  • 通过invoke接口,调用服务api,此处地址为http://127.0.0.1:5597/invoke?invoke_package=com.hyb.hookdemo,执行后返回如下界面就代码调用成功:
HermesAgent群控系统使用教程

ps:如果调用后,返回异常,则可能是未hook到方法导致方法对象为空,你需要现在HookDemo程序中点击按钮调用一次,使Xposed能Hook到方法并保存方法。

三、最终代码

package com.virjar.hermes.hermesagent.hookagent;

import com.virjar.hermes.hermesagent.aidl.InvokeRequest;
import com.virjar.hermes.hermesagent.aidl.InvokeResult;
import com.virjar.hermes.hermesagent.plugin.AgentCallback;
import com.virjar.hermes.hermesagent.plugin.SharedObject;

import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage;

/**
 * HookDemo Test
 *
 * @author HuaYunBin
 */
public class TestAgent implements AgentCallback {

    private Object toastMsgMethodObject;
    private Method toastMsgMethod;

    @Override
    public String targetPackageName() {
        return "com.hyb.hookdemo";
    }

    @Override
    public boolean needHook(XC_LoadPackage.LoadPackageParam loadPackageParam) {
        return StringUtils.equalsIgnoreCase(loadPackageParam.processName, "com.hyb.hookdemo");
    }

    @Override
    public InvokeResult invoke(InvokeRequest invokeRequest) {
        String returnMsg = null;
        try {
            returnMsg = (String) toastMsgMethod.invoke(toastMsgMethodObject);
        } catch (IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
        return InvokeResult.success(returnMsg, SharedObject.context);
    }

    @Override
    public void onXposedHotLoad() {
        ClassLoader classLoader = SharedObject.loadPackageParam.classLoader;
        try {
            Class clazz = classLoader.loadClass("com.hyb.hookdemo.MainActivity");
            XposedHelpers.findAndHookMethod(clazz, "toastMsg", new XC_MethodHook() {

                @Override
                protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                    super.beforeHookedMethod(param);
                }

                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                    super.afterHookedMethod(param);
                    toastMsgMethodObject = param.thisObject;
                    toastMsgMethod = (Method) param.method;
                }
            });
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

评论(没有评论)
载入中...