Android开发学习之路--XPosed插件开发

Posted 东月之神

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android开发学习之路--XPosed插件开发相关的知识,希望对你有一定的参考价值。

1. Xposed插件Hello World

  • 新建工程:MyXposed
  • 引入xposed:
 provided 'de.robv.android.xposed:api:82'
 provided 'de.robv.android.xposed:api:82:sources'

官方链接

  • 修改AndroidManifest
    在AndroidManifest中修改如下:
<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="xposedminversion"
            android:value="82" />

        <!-- 模块描述 -->
        <meta-data
            android:name="xposeddescription"
            android:value="Xposed Test" />
    </application>
  • 新建xpose_init

新建assets文件夹,并在该文件夹中新建xposed_init文件,在文件中添加启动的main:

com.jared.myxposed.Main
  • 新建Main

在对应的包名下新建Main类,添加代码如下:

class Main : IXposedHookLoadPackage 
    override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam?) 
        XposedBridge.log("Main: " + lpparam?.packageName)
        XposedBridge.log("Hook已经成功了")
    

这里打印了包名。

  • 编译安装

因为android studio运行需要MainActivity,所以在工程下命令行运行

./gradlew app:assembleDebug

virtualxposed下安装MyXposed,安装完成如下:

打开一个virtualxposed下的一个apk,然后可以查看下日志,发现已经有了我们加上的log信息

至此,最简单的xposed插件已经开发完成了,我们就可以hook我们需要hook的东西了。

2. Xposed的一些类的介绍

  • IXposedHookLoadPackage.java

加载回调接口,在xposed入口类继承,实现handleLoadPackage方法。

handleLoadPackage用于在加载应用程序的包的时候执行用户的操作
LoadPackageParam loadPackageParam包含了加载的应用程序的一些基本信息
  • IXposedHookInitPackageResources.java

加载回调接口,用于修改app的资源文件,在xposed入口类继承,实现handleInitPackageResources(InitPackageResourcesParam resparam)方法

handleInitPackageResources用于在加载应用程序的包的时候执行用户的操作
InitPackageResourcesParam resparam包含了加载的应用程序的一些资源基本信息
  • XposedHelpers.java

一些辅助方法,简化连接和调用方法/构造函数,获取和设置字段

findAndHookMethodhook一个类中的方法
className要hook的方法的所在类
classloader要hook的包的classLoader,一般都写loadPackageParam.classLoader
methodName要hook的方法
parameterTypesAndCallback方法的参数和监听器
callMethod在目标app中调用方法
Object要调用方法的所在类
methodName要调用的方法名称
args方法的参数
findClass获取class类实例
className类名
classLoader类加载器
  • XposedBridge.java
log在Xposed的app的日志功能里输出日志
text要输出的内容
  • XC_MethodHook中定义了回调方法:

3. Hook掉加固后的ApkTest的点击

  • 承接反编译

首页显示如下:

通过上一篇文章,我们已经反编译了加固的ApkTest,得知其中的“Hello, I am ApkTest”是通过方法showStr来获取的。button点击是通过gotoSecondActivity方法来跳转的,接下来我们分别来hook这两个方法。

  • hook显示内容

现在我们来hook下这个方法的内容。按照要求我们如下操作:

XposedHelpers.findAndHookMethod(hookclass, "showStr",
    object : XC_MethodHook() 
        override fun afterHookedMethod(param: MethodHookParam?) 
            super.afterHookedMethod(param)
            val result = "你被劫持了哦!!!!"
            param?.result = result
        
    )

但是运行后发现根本找不到类,因为是加固的apk,所以我们需要先hook application后再去hook对应的类和方法,修改代码如下:

XposedHelpers.findAndHookMethod(
    Application::class.java,
    "attach",
    Context::class.java,
    object : XC_MethodHook() 
        @Throws(Throwable::class)
        override fun afterHookedMethod(param: MethodHookParam?) 
            val cl = (param!!.args[0] as Context).classLoader
            var hookclass: Class<*>? = null
            try 
                hookclass = cl.loadClass("com.jared.apktest.MainActivity")
             catch (e: Exception) 
                Log.e("MyXposed", "寻找com.jared.apktest.MainActivity报错", e)
                return
            

            Log.i("MyXposed", "寻找com.jared.apktest.MainActivity成功")
             XposedHelpers.findAndHookMethod(hookclass, "showStr",
                object : XC_MethodHook() 
                    override fun afterHookedMethod(param: MethodHookParam?) 
                        super.afterHookedMethod(param)
                        val result = "你被劫持了哦!!!!"
                        param?.result = result
                    
                )
        
    )

然后我们编译安装后,就可以去查看对应的效果了:

很明显我们成功了,显示内容被更改了,变成我们需要的内容

  • hook按钮点击
    既然有了前一步的铺垫,那么这里就十分简单了,我们直接hook掉
    gotoSecondActivity方法,在方法执行后谈一个吐司,表示我们已经hook成功了,代码如下:
XposedHelpers.findAndHookMethod(
    Application::class.java,
    "attach",
    Context::class.java,
    object : XC_MethodHook() 
        @Throws(Throwable::class)
        override fun afterHookedMethod(param: MethodHookParam?) 
            val cl = (param!!.args[0] as Context).classLoader
            var hookclass: Class<*>? = null
            try 
                hookclass = cl.loadClass("com.jared.apktest.MainActivity")
             catch (e: Exception) 
                Log.e("MyXposed", "寻找com.jared.apktest.MainActivity报错", e)
                return
            

            Log.i("MyXposed", "寻找com.jared.apktest.MainActivity成功")
            XposedHelpers.findAndHookMethod(hookclass, "gotoSecondActivity",
                object : XC_MethodHook() 

                    override fun afterHookedMethod(param: MethodHookParam?) 
                        super.afterHookedMethod(param)
                        param?.thisObject?.let 
                            Toast.makeText(it as Context, "你被劫持了哦!!!!", Toast.LENGTH_SHORT).show()
                        
                    
                )
        
    )

再安装看下效果:

已经得到了我们需要的答案,至此,简单的xposed插件开发也完成了,我们在不修改原有apk的一行代码,就能控制原有apk,当然一些登录啊,vip啊都可以通过这个来实现,还有些比如支付宝的能量收取,微信的抢红包也都有类似的插件。不过我们主要是为了学习技术,可不能用在非法的事情上,要不然迟早一天251等着你!

详细代码看这里: MyXposed

关于Android的加固,脱壳反编译以及xposed插件学习也就告一小段落,之后Android安全方向的学习还有很远很远的路。比如:基础算法和安全协议;Android系统结构深入分析,自定义 ClassLoader,自定义注解和元注解原理分析;Android 漏洞分析和挖掘;虚拟机技术、系统源码分析、刷机机制介绍、制作ROM刷机包等等。

以上是关于Android开发学习之路--XPosed插件开发的主要内容,如果未能解决你的问题,请参考以下文章

Android开发学习之路--插件化基础动态代理Hook

Xposed 插件开发入门教程

xposed微信插件大全

Android开发学习之路-加固实践

Android开发学习之路-加固实践

Xposed获取微信用户名密码