Xposed 源码剖析(一)

本文介绍了Xposed框架的工作原理,包括核心进程的启动、系统类加载和Hook流程。通过分析示例代码,展示了如何使用Xposed修改系统时钟样式。详细剖析了Hook流程,从MethodHooker类的调用逻辑到Method的查找和替换,揭示了在运行时如何拦截和修改方法执行的过程。文章以Xposed的源码分析为基础,为理解Android系统动态修改行为提供了深入的理解。
摘要由CSDN通过智能技术生成

0x00 简介

  • 是什么:
      Xposed framework是一个基于Android系统实现的能够给用户提供修改系统层面或第三方APP功能的框架服务。
  • 如何工作:
      Android中有一个叫做Zygote的核心进程,它会随Android系统的启动而启动,然后加载系统所需的类,最后再调用初始化方法。每一个APP的进程都是从Zygote进程fork出的子进程,这个进程的文件是/system/bin/app_process
      当安装Xposed framework后,Xposed framework会替换一个新的app_process/system/bin/中,同时还会替换虚拟机和其他若干文件。Zygote启动时,会加载Xposed所需的JAR包(/data/data/de.robv.android.xposed.installer/bin/XposedBridge.jar)至系统目录,并启动Xposed替换的虚拟机。
      Xposed framework的主要接口由XposedBridge.jar提供,框架的核心功能在替换的虚拟机中实现。

0x01 示例代码

用户可以使用Xposed frameworkHook方法,下面是作者本人给出的一个示例:

package de.robv.android.xposed.mods.tutorial;

import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;
import android.graphics.Color;
import android.widget.TextView;
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam;

public class Tutorial implements IXposedHookLoadPackage {
   
    public void handleLoadPackage(final LoadPackageParam lpparam) throws Throwable {
        if (!lpparam.packageName.equals("com.android.systemui"))
            return;

        findAndHookMethod("com.android.systemui.statusbar.policy.Clock", lpparam.classLoader, "updateClock", new XC_MethodHook() {
            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                TextView tv = (TextView) param.thisObject;
                String text = tv.getText().toString();
                tv.setText(text + " :)");
                tv.setTextColor(Color.RED);
            }
        });
    }
}

这个示例代码实现了对Andoird系统时钟输出样子和颜色的修改,完整的源码地址是https://github.com/rovo89/XposedExamples/tree/master/RedClock。如此简单的几行代码,它的内部实现机制是怎么的呢?想知道这些,最好的办法当然是分析源码。

0x02 Hook流程分析

这里使用Xposed framework Hook java.net.URLEncoder类的encode方法作为例子分析,调用逻辑如下所示:

public class Tutorial implements IXposedHookLoadPackage {
   
    public void handleLoadPackage(final LoadPackageParam lpparam) throws Throwable {
        findAndHookMethod("java.net.URLEncoder", lpparam.classLoader, "encode", String.class, String.class, new XC_MethodHook() {
            @Override
            protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
            }
            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
            }
        });

handleLoadPackage会在任意一个APP加载的时候被调用,然后就可以在这个接口内部根据包名做逻辑判断,如果是Hook方法所在的包,则进一步调用findAndHookMethodHook指定的方法。
通过findAndHookMethod()接口找到指定方法并进行Hook。它的参数较多,第一个参数是类名,第二个参数是类加载器,第三个参数是方法名,后面是可变参数,把方法的参数类型依次作为参数,最后一个参数是XC_MethodHook()对象。另外,在其内部重写beforeHookedMethodafterHookedMethod方法,这两个方法分别会在Hook方法执行的前后执行,用户可以在其中实现自己的逻辑。
findAndHookMethod这个接口的实现在XposedHelpers.java这个文件中,代码如下:

public static XC_MethodHook.Unhook findAndHookMethod(String className, ClassLoader classLoader, String methodName, Object... parameterTypesAndCallback) {
    return findAndHookMethod(findClass(className, classLoader), methodName, parameterTypesAndCallback);
}
    
public static XC_MethodHook.Unhook findAndHookMethod(Class<?> clazz, String methodName, Object... parameterTypesAndCallback) {
    if (parameterTypesAndCallback.length == 0 || !(parameterTypesAndCallback[parameterTypesAndCallback.length-1] instanceof XC_MethodHook))
        throw new IllegalArgumentException("no callback defined");

    XC_MethodHook callback = (XC_MethodHook) parameterTypesAndCallback[parameterTypesAndCallback.length-1];
    Method m = findMethodExact(clazz, methodName, getParameterClasses(clazz.getClassLoader(), parameterTypesAndCallback));

    return XposedBridge.hookMethod(m, callback);
}

首先,接口内部会根据类名和类加载器查找Class对象,再根据Class对象和方法名去查找Method对象,最后调用XposedBridge.hookMethod完成对方法的Hook
看一下方法查找的实现:

public static Method findMethodExact(String className, ClassLoader classLoader, String methodName, Object... parameterTypes) {
        return findMethodExact(findClass(classNam
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值