Xposed安装与使用

xposed是什么?

一个很牛逼的框架,可以在不修改APK的情况下影响程序的运行,比如:

  • 直接把APP的界面改成自己想要的样
  • 去掉界面里不喜欢的东西,
  • 自动抢红包
  • 消息防撤回
  • 步数修改等等

Xposed的工作原理

在开始修改之前,你应该大致了解Xposed如何工作(如果你觉得太无聊,你可以跳过这一部分)。方法如下:

有一个叫做“Zygote”的过程。从它的名字(中文含义——受精卵)这是Android运行时的核心。每个应用程序都作为它的副本(“fork”)启动。/init.rc手机启动时,脚本会启动此过程。进程开始完成/system/bin/app_process,加载所需的类并调用初始化方法。

这就是Xposed发挥作用的地方。安装框架时,会将扩展的app_process可执行文件复制到/system/bin。这个扩展的app_process就会把XposedBridge.jar加载到运行时环境,这样我们就可以在虚拟机启动之前,甚至是在Zygote的main方法被执行之前做一些爱做的事(捂脸,其实就是加载插件)。此时我们的插件被执行,就是Zygote进程的一部分,所以可以直接获取到应用的上下文Context,然后做很多超出想象的事情——对于任何一个app ,我们都可以hook或者替换掉其中的类或方法或对象。再加上已经root。我们可以为所欲为了。

jar位于,/data/data/de.robv.android.xposed.installer/bin/XposedBridge.jar其源代码可在此处找到。查看类XposedBridge,您可以看到该main方法。这就是我上面写的内容,这个过程在一开始就被调用了。在那里进行了一些初始化,并且还加载了??椋ㄉ院笪医氐侥?榧釉兀?/p>

方法挂钩/更换

真正创造Xposed力量的是“钩”方法调用的可能性。通过反编译APK进行修改时,可以直接在任意位置插入/更改命令。但是,您需要在之后重新编译/签署APK,并且您只能分发整个包。使用可以放置Xposed的钩子,你不能修改方法内的代码(不可能清楚地定义你想在哪个地方做什么样的改变)。相反,您可以在方法之前和之后注入自己的代码,这是Java中可以清楚解决的最小单元。

XposedBridge有一个私有的本机方法hookMethodNative。此方法也在扩展中实现app_process。它会将方法类型更改为“native”,并将方法实现链接到其自己的本机通用方法。这意味着每次调用hooked方法时,都会调用泛型方法,而不会让调用者知道它。在此方法中,handleHookedMethod调用XposedBridge中的方法,将参数传递给方法调用,this引用等。然后,此方法负责调用已为此方法调用注册的回调。这些可以更改调用的参数,更改实例/静态变量,调用其他方法,对结果执行某些操作...或者跳过任何内容。它非常灵活。

安装:

一、安装XposedInstalle(Xposed安装程序)

XposedInstalle.apk下载链接(安卓5.0以下不用这个,自己找去吧):
下载地址,论坛下面有下载地址

image.png

下载完软件打开:


Xposed

如果点击半天还是等待可以换一种方式安装

二、卡刷:

1、下载

SDK版本 安卓版本
SDK21 Android 5.0(Lollipop)
SDK22 Android 5.1 (也是Lollipop)
SDK23 Android 6.0(Marshmallow)
SDK24 Android 7.0
SDK25 Android 7.1
SDK26 Android 8.0
SDK27 Android 8.1

看到上图里的平台了吗?我是arm64,记住了然后下载的时候选择用
框架的下载链接

点击下载

暂时我还没发现签名有何用,我只下载了框架,以后发现了用处我再写
** 更新,中间出了点问题,代码当时也有问题,索性重装了一遍带着签名装好的,所以能带签名最好带着签名吧 **

二、安装

将下载好的压缩包放到手机根目录(前提装好adb,或者用其他方式发到手机)

adb push xposed-v90.1-sdk27-arm64-beta3-.zip /sdcard

开机按住开机键音量+键进入recovery(小米的进入方式,其他手机自己查),

recovery

点击安装, 选择压缩包,滑动刷入
安装完重启后我的手机一直卡在开机界面,等了半天也没反应,我就强制启动了,打开软件显示我框架已经安装了。

开发???/h1>

一、创建Xposed???/h2>

首先需要知道,Xposed??槭且訟PK的格式提供的,本身也是需要安装到手机上的,也像普通应用一样可以启动,只是因为APK中包含了一些声明,被Xposed框架检测到了,所以同时也可以以Xposed??榈姆绞嚼唇衕ook操作。那么这些声明是什么呢?
在AndroidManifest.xml中添加下面的声明,
meta-data中的内容分别用于声明是否为插件,插件的描述和兼容的最低Xposed版本。加入3个meta-data就好了。

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.sxkj_mg.xposeddome">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <meta-data
            android:name="xposedmodule"
            android:value="true"/>
        <meta-data
            android:name="xposeddescription"
            android:value="我就是个简单的Xposed Demo"/>
        <meta-data
            android:name="xposedminversion"
            android:value="83"/>
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

二、添加依赖

apply plugin: 'com.android.application'

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.example.sxkj_mg.xposeddome"
        minSdkVersion 23
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    
//    主要是下面这两行,再下面的是自动生成的
    compileOnly 'de.robv.android.xposed:api:82'
    //如果需要引入文档,方便查看的话
    compileOnly 'de.robv.android.xposed:api:82:sources'
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

三、创建xposed_init

xposed_init创建位置

在图片位置创建xposed_init,写入代码为:

# 我的是这个,你们根据自己的路径改,最后一个是文件名,一会创建这个文件
com.example.sxkj_mg.xposeddome.HookModule

修改MainActivity.java

修改id
package com.example.sxkj_mg.xposeddome;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {
    private TextView tv;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv=findViewById(R.id.tv);
        tv.setText("我是渣渣辉");
    }
}

编写HookModule

package com.example.sxkj_mg.xposeddome;

import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;

import java.lang.reflect.Field;

import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage;
public class HookModule implements IXposedHookLoadPackage {
    public static final String TAG = "MyHook";
    @Override
    public void handleLoadPackage(final XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
        Log.d(TAG, "重启手机后,我执行了,说明这个 Xposed 模块生效了");
        if (loadPackageParam.packageName.equals("com.example.sxkj_mg.xposeddome")){
            Log.d(TAG, "进入到这个app了");
            XposedHelpers.findAndHookMethod("com.example.sxkj_mg.xposeddome.MainActivity",loadPackageParam.classLoader,
                    "onCreate", Bundle.class,new XC_MethodHook(){

                        @Override
                        protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                             Log.d(TAG, "这里是hook方法之前");
                            super.beforeHookedMethod(param);

                        }
                        @Override
                        protected void afterHookedMethod(MethodHookParam param) throws Throwable{
                            Log.d(TAG, "这个是hook方法之后");
                            Class c= loadPackageParam.classLoader.loadClass("com.example.sxkj_mg.xposeddome.MainActivity");
                            Field field = c.getDeclaredField("tv");
                            field.setAccessible(true);
                            Log.d(TAG, "这次到这里了2");
                            TextView tv = (TextView) field.get(param.thisObject);
                            tv.setText("王境泽");
                        }
                    });
        }
    }
}

此时运行一下,就装到手机上了。(前提USB连接手机)
手机打开,是不是还是渣渣辉,然后XposedInstalle启用??楹?,手机重启,就显示王境泽了。

API介绍

  • IXposedHookLoadPackage接口:App被加载的时候调用,用于App应用的Hook
    回调方法是:handleLoadPackage(final XC_LoadPackage.LoadPackageParam lpparam)

  • XC_LoadPackage.LoadPackageParam:包含与正在加载的应用程序的有关信息。

  • XposedHelpers.findAndHookMethod(要Hook的类,classLoader,方法名,参数,回调对象)

    • Hook一个方法的时候使用,回调对象XC_MethodHook()需重写两个方法
    • beforeHookedMethod(MethodHookParam param):方法调用前执行
    • afterHookedMethod(MethodHookParam param) 方法调用后执行
    • 注:可以调用param.setResult()设置方法的返回值!
  • MethodHookParam:包含与调用方法有关的信息
    比较关注的是这个thisObject,代表调用该方法的对象实例,如果是静态方法
    的话,返回一个Null,比如这里调用onCreate()方法的是MainActivity,获得
    的自然是MainActivity实例。

接着是获取成员变量,分为私有与非私有变量,非私有直接调用下述方法
即可获得class

Class c = lpparam.classLoader.loadClass("com.coderpig.cpwechatxposed.MainActivity");
Field field = c.getField("tv");

如果是私有,则需要先设置访问权限(setAccessible)

Class c = lpparam.classLoader.loadClass("com.coderpig.cpwechatxposed.MainActivity");
Field field = c.getDeclaredField("tv");
field.setAccessible(true);

接着调用获得该对象

TextView tv = (TextView) field.get(param.thisObject);
tv.setText("贪玩难约");

代码外内容

  • IXposedHookZygoteInit:在Zygote启动时调用,用于系统服务的Hook
    回调方法initZygote()

  • IXposedHookInitPackageResources:在资源布局初始化时会回被执行(inflate方法)
    回调方法:handleInitPackageResources(XC_InitPackageResources.InitPackageResourcesParam resparam)

  • InitPackageResourcesParam包含两个参数,包名和XResource(资源相关)
    有了这个XResource对象,就可以拿到布局资源树了,通过重写hookLayout方法,

  • LayoutInflatedParam,里面这个view就是布局资源树了,你可以拿到遍历,拿到某个特定控件,然后做一些骚操作。

  • XposeHelpers提供了一些辅助方法

    • callMethod(Object obj,String methodName, Object… args):在APP中调用特定方法; 参数依次是:调用方法的所在类,调用方法名,方法参数

    • findClass(String className,ClassLoader classLoader):获取class类实例
      参数依次是类名,类加载器

    • findMethodExact:通过反射查找类的成员方法(可setAccessible(true)设置非私有)

    • findConstructorExact:通过反射查找构造函数(同样可设置可访问下性)

    • findAndHookXXX:查找并Hook

    • setXxx:通过反射设置对象数据成员的值

    • setStaticXxx:通过反射设置静态变量的值

    • XposedBridge.log(“日志内容”):输入日志和写入到/data/xposed/debug.log
      Xposed Installer日志那里可以看到!

内部类:通过$符号链接内部类

只能Hook方法与构造方法,不能Hook接口和抽象方法

通过这些api是不是大概清楚Xposed能干啥了,除了Xposed,还有其他的框架可以干这些事比如下面:

Magisk框架,Xposed框架比较,VirtualXposed框架

框架 Magisk Xposed Vxp
平台 android5.0~8.1 android4.4以下,android5.0 ~ 8.1,但是8.0~8.1稳定版还没出来,出来的beta版本 android5.0~9.0
模拟器,真机支持情况 都支持 都支持 不支持 x86,也就是不支持模拟器
更新情况 更新快一直在更新 已经停更了 框架一直在更新
稳定性 ??樯伲强梢宰皊ystemless版Xposed??槔疵植?/td> 最稳定、??樽疃?/td> 不会变砖、??樯?/td>
激活???/td> 必须重启激活???/td> 必须重启激活模块 支持免重启手机激活???/td>
root 内置ROOT 需要root 免root
hook 支持 支持 暂不支持资源以及系统api的HOOK
使用必须将需要 hook 的 APP 和???APP 安装到VirtualXposed
github地址 Magisk Xposed VirtualXposed
原理 对系统侵入较少,仅修改boot.img,同时能够对系统隐藏自身存在,支持OTA升级,可以实现Multirom多系统等功能 Xposed框架的原理是通过替换/system/bin/app_process程序控制zygote进程,使得app_process在启动过程中会加载XposedBridge.jar这个jar包,从而完成对Zygote进程及其创建的Dalvik或者art虚拟机的劫持 它去启动别的App,在启动过程中通过 epic Hook本进程,从而控制被启动的App

部分抄袭此博客
部分抄袭此博客

最后编辑于
?著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,172评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,346评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事?!?“怎么了?”我有些...
    开封第一讲书人阅读 159,788评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,299评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,409评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,467评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,476评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,262评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,699评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,994评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,167评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,827评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,499评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,149评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,387评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,028评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,055评论 2 352