您现在的位置是:网站首页>文章详情文章详情

Android hook框架之Cydia插件开发

inlike2019-11-23 原创文章 浏览(2356) 评论(0) 喜欢(30)

简介Cydia全称是Cydia基板,与Xposed框架是安卓领域最著名的插件开发框架,尤其是Cydia在早期苹果越狱方面大部分出众,同时Cydia在Android hook尽管Cycy功能强大,但是因为其不开源所以该框架的发展并不如人意,目前官方声明支持Android2.3至4.3,亲测4.4也可以使用。

Cydia全称是Cydia Substrate,与Xposed框架是安卓领域最著名的插件开发框架,尤其是Cydia在早期苹果越狱方面较多出众,同时Cydia在Android hook 。

尽管Cydia功能强大,但是因为其不开源所以该框架的发展并不如人意,目前官方声明支持Android 2.3至4.3,亲测4.4也可以使用。

Cydia同Xposed一样提供了简洁的接口,我们可以通过这些接口锁定需要hook类,然后进一步处理该类下的函数,在使用该框架过程中环境构建,插件开发花费了很多时间,总算一个个坑的躺过来。

本篇文章将通过一个案例讲述Cydia框架下的插件开发流程。首先准备一个简单的app,这个app就是helloWord,在Androidstudio样式的项目中,helloWord界面如下:

image.png


我们先对这个重置的helloWord项目做一些修改,我们首先修改一下红色框部分,让这部分的内容是一个内部函数返回的字符串,我们就通过写一个插件来拦截并修改这个内部函数返回的字符串内容,在我们的样本app的java代码做出如下修改:


image.png


修改后的效果如下:


image.png


将原本显示文字的地方使用一个函数的返回结果来替代,这个类Word就是我们要hook的函数,我们在这个函数返回值的结果上有另外几个文字。
下面将是插件开发的流程和接口的介绍,也是本篇文章的核心内容,这也是大部分基于Cydia和xposed外挂的制作原理。
首先我们需要下载Cydia开发的jar包(substrate-api.jar)放到我们项目的libs目录下并导入项目中。


image.png


然后就是修改AndroidManifest.xml文件,增加插件类的入口和权限,在应用程序标签下增加:
<meta-data android:name="com.saurik.substrate.main"
            android:value=".Main"/>
其中。Main是插件的入口函数,然后在应用标签结束后增加权限申请标签:
<uses-permission android:name="cydia.permission.SUBSTRATE"/>
修改后应该是这样的:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.cydiahook">


    <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="com.saurik.substrate.main"
            android:value=".Main"/>

        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:theme="@style/AppTheme.NoActionBar">

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

</manifest>
权限设置后我们开始写插件类,在项目包路径文件夹下再添加一个类Main和上面的关联的类对应,在MAin中引入Cydia开发的接口:
import com.saurik.substrate.MS;
import java.lang.reflect.Method;
然后是初始化函数,函数名是固定的写法:
package com.example.cydiahook;
import com.saurik.substrate.MS;
import java.lang.reflect.Method;

public class Main {
    static void initialize() {
//代码部分
}
}
这也是插件的骨架,接着在代码部分先实现MS.hookClassLoad()方法:
void hookClassLoad(String name, MS.ClassLoadHook hook)
//name是要hook的类,hook是被hook类的实例化也是我们实现逻辑修改的地方

package com.example.cydiahook;
import com.saurik.substrate.MS;
import java.lang.reflect.Method;

public class Main {
    static void initialize() {
        MS.hookClassLoad("com.example.cydia.MainActivity"new MS.ClassLoadHook() {
            public void classLoaded(Class<?> resources) {
                Method word;
                try {
                    word = resources.getMethod("word");
                } catch (NoSuchMethodException e) {
                    word = null;
                }
                    }
                }}
该处的作用是监听com.example.cydia.MainActivity类,当其活动的时候查找该类下的Word函数,即被hook函数。
当存在该函数的时候,就需要实现对原函数的操作,可以调用原函数,并修改写入的参数,也可以对原函数的执行结果进行处理后再返回,逻辑如下:
package com.example.cydiahook;
import com.saurik.substrate.MS;
import java.lang.reflect.Method;

public class Main {
    static void initialize() {
        MS.hookClassLoad("com.example.cydia.MainActivity"new MS.ClassLoadHook() {
            public void classLoaded(Class<?> resources) {
                Method word;
                try {
                    word = resources.getMethod("word");
                } catch (NoSuchMethodException e) {
                    word = null;
                }

                if (word != null) {
                    final MS.MethodPointer old = new MS.MethodPointer();

                    MS.hookMethod(resources, word, new MS.MethodHook() {
                        public Object invoked(Object resources, Object... args)
                                throws Throwable
                        
{

                            String text = (String) old.invoke(resources, args);
                            return text+"测试hook";
                        }
                    }, old);
                }
            }
        });
    }
}
当查找到word函数后,我们将原函数进行调用方法是:
final MS.MethodPointer old = new MS.MethodPointer();

                    MS.hookMethod(resources, word, new MS.MethodHook() {
                        public Object invoked(Object resources, Object... args)
                                throws Throwable
                        {
                            String text = (String) old.invoke(resources, args);
                            return text+"测试hook";
                        }
                    }, old);
即在原函数返回结果的基础上在加上“测试hook”的字符,使用Cydia插件比较简单,框架部分是固定的写法,我们只需要锁定hook的类及该类下的函数,并实现结果处理的逻辑即可。
总结一下:Cydia开发注意两点第一是修改配置文件链接插件类并增加权限,第二个是在插件开发框架下导致我们需要的逻辑替换即可。
然后在满足要求的系统中安装Substrate框架,如下:


image.png




image.png



当插件开发完成,我们即打包成app,安装到Android系统中,这里用的是逍遥安卓模拟器的最低版本,安装后Substrate会自动检测到插件以安装并提示重启,重启后打开我们的helloWord效果然后:


image.png


现在Android版本已经迭代了好几代了,并且安全策略越来越强,而Cydia还是原地踏步的状态,引用到Xposed框架不是那么受欢迎,后面介绍了Xposed框架。
用Cydia框架有什么用呢?能对爬虫开发有什么实际意义帮助呢?如此所见,他的作用主要在于外挂开发,在不对原应用程序的基础上达到想要的效果,多年前使用过的微信红包插件大致也是这么个原理,当时还觉得很神奇,现在看来他的实现并不难。
当然对于爬虫的作用机理是不必重点去研究应用的加固,不必绞尽脑汁去脱壳反纠正等,只需要找到关键函数进行进行一个劫持直接获取结果密钥等,即可通过接口反复钩挂调用应用程序内部的方法进行加密解密,而不必分析其过程;上面也只是一些试图在实际项目中应用。


很赞哦! ( 30)
    《Python实战进阶》
    None
    None
    夏至已深

站点信息

  • 建站时间:2019-5-24
  • 网站程序:like in love
  • 主题模板《今夕何夕》
  • 文章统计:104条
  • 文章评论:***条
  • 微信公众号:扫描二维码,关注我们
  • 个人微信公众号