安卓逆向_23 --- Hook 框架 Cydia Substrate( Hook Java层 和 so层)

 

From:Android Hook 框架 Cydia_substrate 详解:https://www.cnblogs.com/lkislam/p/4859957.html

通过 cydia substrate 对 framework API进行注入:https://www.jianshu.com/p/cc49b30c5b5b

Android逆向之旅—Native层的Hook神器Cydia Substrate使用详解:http://www.520monkey.com/archives/1028

 

CydiaSubstrate hook

 

 

1. Cydia_Substrate 框架简介

 

Cydia Substrate 和 Xposed:

  • Cydia Substrate 可以修改任何主进程的代码,不管是 Java、/C/C++(native代码)编写的。(hook Java层和C++层)
  • Xposed 只支持 HOOK app_process 中的 java 函数。( 只能 hook java 层 )

其实 cydia substrate 与 xposed 的 hook 原理是一样的,二者都可以作为 Java Hook 的框架,看使用习惯了。

 

官网地址:http://www.cydiasubstrate.com/

安卓逆向_23 --- Hook 框架 Cydia Substrate( Hook Java层 和 so层)_第1张图片

注意:从官网可以看到,Cydia Substrate 支持安卓 2.3 到 4.3 版本。。。手机需要 root

Demo地址:https://github.com/zencodex/cydia-android-hook

官方教程:http://www.cydiasubstrate.com/id/20cf4700-6379-4a14-9bc2-853fde8cc9d1

SDK下载地址:http://asdk.cydiasubstrate.com/zips/cydia_substrate-r2.zip

 

 

使用方法

 

安装 Cydiastrate 框架 Android 本地服务

首先就是在 Android 设备中安装 Cydia substrate 框架的本地服务应用 substrate.apk。

官方下载地址为:http://www.cydiasubstrate.com/download/com.saurik.substrate.apk

安装完 substrate 后,需要 "Link Substrate Files"(连接本地的 Substrate 服务文件),这一步是需要 Root权限,连接后还需要 重启设备 才能够生效。

 

下载使用 Cydiasubstrate 库

Cydiasubstrate 官方建议在 Android SDK Manager 中添加它们插件地址的方式进行更新下载。

如:在用户自定义网址中添加http://asdk.cydiasubstrate.com/addon.xml。

通过使用 Android SDK Manager 工具下载完 Cydiasubstrate 框架后,

其存储于目录 ${ANDROID_HOME}\sdk\extras\saurikit\cydia_substrate下。

但是,由于 Android SDK Manager 在国内使用起来存在很多的限制,下载的时候也不是非常稳定,所以还是建议大家直接去官网下载开发库。官方下载地址为:http://asdk.cydiasubstrate.com/zips/cydia_substrate-r2.zip

下载完成后,将得到的所有文件(很多的 jar包 与 so库 ),都拷贝都 Android 项目下的 libs 文件夹中,就可以直接使用了。

安卓逆向_23 --- Hook 框架 Cydia Substrate( Hook Java层 和 so层)_第2张图片

其中的 substrate.h 头文件与 lib 文件夹下的 so文件是提供在使用 NDK 进行原生 Hook 程序开发中的函数支持库。

注意:CydiaSubstrate 框架对于 inline Hook 的操作目前还是存在一些 bug,使用的时候可能会出现崩溃的现象,部分使用了国内定制的 ROM 的设备在使用 CydiaSubstrate 框架时会造成设备无法重新启动或无法 Hook 的现象。

 

CydiaSubstrate怎么用 ?

CydiaSubstrate怎么用,其实很简单,CydiaSubstrate 提供了三个静态的方法工具类,我们只需要学会使用它就好 。

MS.hookClassLoad           拿到指定Class载入时的通知
MS.hookMethod              使用一个Java方法去替换另一个Java方法
MS.moveUnderClassLoader    使用不同的ClassLoder重载对象

具体说明如下:

/**
 * Hook一个指定的Class
 * 
 * @param name Class的包名+类名,如android.content.res.Resources
 * @param hook 成功Hook一个Class后的回调
 */
void hookClassLoad(String name, MS.ClassLoadHook hook);

/**
 * Hook一个指定的方法,并替换方法中的代码
 * 
 * @param _class Hook的calss
 * @param member Hook class的方法参数
 * @param hook 成功Hook方法后的回调
 * @param old Hook前方法,类似C中的方法指针
 */
void hookMethod(Class _class, Member member, MS.MethodHook hook, MS.MethodPointer old);

/**
 * Hook一个指定的方法,并替换方法中的代码
 * 
 * @param _class Hook的calss
 * @param member Hook class的方法参数
 * @param alteration
 */
void hookMethod(Class _class, Member member, MS.MethodAlteration alteration);

/**
 * 使用一个ClassLoader重载一个对象
 * 
 * @param loader 使用的ClassLoader
 * @param object 带重载的对象
 * @return 重载后的对象
 */
 T moveUnderClassLoader(ClassLoader loader, T object);

 

 

Substrate 几个重要 API 介绍

 

MS.hookClassLoad 

  • 函数原型:void hookClassLoad(String name, MS.ClassLoadHook hook);
  • 说明:该方法实现在指定的类被加载的时候发出通知。因为一个类可以在任何时候被加载,所以Substrate提供了一个方法用来检测用户感兴趣的类何时被加载。参数
参数 描述

name

包名+类名,使用 java 的.符号

hook

MS.ClassLoadHook 的一个实例,当这个类被加载的时候,它的 classLoaded 方法会被执行。

 

MS.hookMethod 

该 API 允许开发者提供一个回调函数替换原来的方法,这个回调函数是一个实现了MS.MethodHook接口的对象,是一个典型的匿名内部类。它包含一个 invoked 函数。

函数原型:

void hookMethod(Class _class, Member member, MS.MethodHook hook, MS.MethodPointer old);
void hookMethod(Class _class, Member member, MS.MethodAlteration alteration);

参数描述(一)

参数

描述

_class

加载的目标类,为classLoaded传下来的类参数

member

通过反射得到的需要hook的方法(或构造函数). 注意:不能HOOK字段 (在编译的时候会进行检测).

hook

MS.MethodHook的一个实例,其包含的invoked方法会被调用,用以代替member中的代码

参数描述(二)

参数   描述

_class

加载的目标类,为classLoaded传下来的类参数

member

通过反射得到的需要hook的方法(或构造函数). 注意:不能HOOK字段 (在编译的时候会进行检测).

alteration

An instance of MS.MethodAlteration whose boxedinvoked method will be called instead of member. This instance will also be filled in using information from   the original implementation, allowing you to use invoke to call the original method implementation。

建议开发者使用第二种方式,这种方式使用起来简单并且很少出错,不需要一个单独的MS.MethodPointer类实例。

 

 

 

示例 1:接口组件颜色修改为紫罗兰色hook Java层

 

下面以官网的一个实例来说明 cydia substrate 的使用方法。

该实例是实现将多个接口组件颜色修改为紫罗兰色。

 

步骤 一:

创建一个空的 Android 工程。由于创建的工程将以插件的形式被加载,所以不需要 activity。将 SDK 中的 substrate-api.jar 复制到 project/libs 文件夹中。

 

步骤 二:

配置 androidmanifest.xml 文件

  • (1)需要指定权限:cydia.permission.SUBSTRATE
  • (2)添加 meta 标签,name 为 cydia.permission.SUBSTRATE,value 为下一步中创建的类名 .Main

图示:

安卓逆向_23 --- Hook 框架 Cydia Substrate( Hook Java层 和 so层)_第3张图片

配置代码:

   
       
           
       
       
   

 

步骤 三:

创建一个类,类名为 Main。类中包含一个 static 方法 initialize,当插件被加载的时候,该方法中的代码就会运行,完成一些必要的初始化工作。

import com.saurik.substrate.MS;   
  
public class Main {   
    static void initialize() {    
        // ... code to run when extension is loaded   
    }   
}   

 

步骤 四:

为了实现 HOOK,达到修改目标类中的代码的目的,我们需要得到目标类的一个实例,如示例中的 resources。

public class Main {   
    static void initialize() {   
        MS.hookClassLoad("android.content.res.Resources", new MS.ClassLoadHook() {   
            public void classLoaded(Class resources) {   
                // ... code to modify the class when loaded   
            }   
        });   
    }   
}  

 

步骤 五:

通过 MS.MethodHook 实例实现原代码的修改。

为了调用原来代码中的方法,我们需要创建一个 MS.MethodPointer 类的实例,它可以在任何时候运行原来的代码。

在这里我们通过对原代码中 resources 对象原始代码的调用和修改,将所有绿色修改成了紫罗兰色。

安卓逆向_23 --- Hook 框架 Cydia Substrate( Hook Java层 和 so层)_第4张图片

代码:

public void classLoaded(Class resources) {   
    Method getColor;    
    try {   
            getColor = resources.getMethod("getColor", Integer.TYPE);   
        } catch (NoSuchMethodException e) {   
            getColor = null;   
        }   
        
        if (getColor != null) {   
            final MS.MethodPointer old = new MS.MethodPointer();   
        
            MS.hookMethod(resources, getColor, new MS.MethodHook() {   
                public Object invoked(Object resources, Object... args)   
                    throws Throwable   
                {   
                    int color = (Integer) old.invoke(resources, args);   
                    return color & ~0x0000ff00 | 0x00ff0000;   
                }   
            }, old);   
        }   
    }   

安装运行,重启系统后发现很多字体颜色都变了。如下图所示:

安卓逆向_23 --- Hook 框架 Cydia Substrate( Hook Java层 和 so层)_第5张图片

安装运行,重启系统后发现很多字体颜色都变了。示例中 MS.hookMethod 的代码可以改成:

MS.hookMethod(resources, getColor, new MS.MethodAlteration() {   
    public Integer invoked(Resources resources, Object... args)   
            throws Throwable   
            {   
        int color = invoke(resources, args);   
        return color & ~0x0000ff00 | 0x00ffee00;   
            }   
}); 

 

 

 

示例 2:短信监控实例(hook Java层

 

在下面的例子中我们实现了短信监听功能,将短信发送人、接收人以及短信内容打印出来:

import java.lang.reflect.Method;   
import android.app.PendingIntent;   
import android.util.Log;   
import com.saurik.substrate.MS;   
public class Main {  
    static void initialize() {     
        MS.hookClassLoad("android.telephony.SmsManager", new MS.ClassLoadHook() {   
            @Override   
            public void classLoaded(Class SmsManager) {   
                //code to modify the class when loaded   
                Method sendTextMessage;   
                try {   
                    sendTextMessage = SmsManager.getMethod("sendTextMessage",   
                            new Class[]{String.class,String.class,String.class,PendingIntent.class,PendingIntent.class});   
                } catch (NoSuchMethodException e) {   
                    sendTextMessage = null;   
                }   
                MS.hookMethod(SmsManager, sendTextMessage, new MS.MethodAlteration() {   
                    public Object invoked(Object _this,Object... _args) throws Throwable{   
                        Log.i("SMSHOOK","SEND_SMS");   
                        Log.i("SMSHOOK","destination:"+_args[0]);   
                        Log.i("SMSHOOK","source:"+_args[1]);   
                        Log.i("SMSHOOK","text:"+_args[2]);   
                        return invoke(_this, _args);   
                    }   
                });   
            }   
        });   
    }   
}

 

运行步骤

  • ROOT 的手机一部,没有 ROOT 的,请自行搜索方法。
  • 手机端安装 Cydia Substrate。下载地址: http://www.cydiasubstrate.com/download/com.saurik.substrate.apk
  • 按照上面的例程,编译代码后安装到手机
  • 手机上运行 Substrate,界面上点击"Link Substrate Files",再点击 "Restart System(Soft)"(这些都是Hook 步骤)
  • 最后再编写一个 Test.apk,调用 hook 后的 class,检验 hook 结果。

运行后的结果为:

安卓逆向_23 --- Hook 框架 Cydia Substrate( Hook Java层 和 so层)_第6张图片

 

 

 

示例 3:广告注入 (hook Java层

 

From:https://blog.csdn.net/yzzst/article/details/47318751

 

使用Cydiasubstrate框架我们能够任意的Hook系统中的Java API,当然其中也用到了很多的反射机制,那么除了系统中给开发者提供的API以外,我们能否也Hook应用程序中的一些方法呢?答案是肯定的。下面我们就以一个实际的例子讲解一下如何Hook一个应用程序。

下面我们针对Android操作系统的浏览器应用,Hook其首页Activity的onCreate方法(其他方法不一定存在,但是onCreate方法一定会有),并在其中注入我们的广告。根据上面对Cydiasubstrate的介绍,我们有了一个简单的思路。

首先,我们根据某广告平台的规定,在我们的AndroidManifest.xml文件中填入一些广告相关的ID。并且在AndroidManifest.xml文件中填写一些使用Cydiasubstrate相关的配置与权限。当然,我们还会声明一个广告的Activity,并设置此Activity为背景透明的Activity,为什么设置透明背景的Activity,如下图:

安卓逆向_23 --- Hook 框架 Cydia Substrate( Hook Java层 和 so层)_第7张图片

好了,下面我们就来实操一下。其 AndroidManifest.xml 文件的部分内容如下所示:













    
    
    
    
    

    
    
        
            
            
            
            
        
    

对于 Cydiasubstrate的主入口 Main 类,依照之前的步骤新建一个包含有 initialize 方法的 Main 类。

这个时候我们希望使用 MS.hookClassLoad 方式找到浏览器主页的 Activity 名称。

这里我们使用 adb shell 下使用 dumpsys activity 命令找到浏览器主页的 Activity 名称为 com.android.browser.BrowserActivity。

使用 MS.hookClassLoad 方法获取了 BrowserActivity 之后再 hook 其 onCreate 方法,在其中启动一个含有广告的 Activity。Main 类的代码如下所示:

public class Main {

    /**
     * substrate 初始化后的入口
     */
    static void initialize() {

        //Hook 浏览器的主Activity,BrowserActivity
        MS.hookClassLoad("com.android.browser.BrowserActivity", new MS.ClassLoadHook() {
            public void classLoaded(Class resources) {

                Log.e("test", "com.android.browser.BrowserActivity");
                // 获取BrowserActivity的onCreate方法
                Method onCreate;
                try {
                    onCreate = resources.getMethod("onCreate", Bundle.class);
                } catch (NoSuchMethodException e) {
                    onCreate = null;
                }

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

                    // hook onCreate方法
                    MS.hookMethod(resources, onCreate, new MS.MethodHook() {
                        public Object invoked(Object object, Object...args) throws Throwable {

                            Log.e("test", "show ad");
                            // 执行Hook前的onCreate方法,保证浏览器正常启动
                            Object result =  old.invoke(object, args);
                            // 没有Context
                            // 执行一个shell 启动我们的广告Activity
                            CMD.run("am start -a com.example.hook.AD");

                            return result;
                        }
                    }, old);
                }
            }
        });
    }
}

对于启动的广告MainActivity,在其中就是弹出一个插屏广告。当然可也可是其他形式的广告或者浮层,内容比较简单这里不做演示了。对整个项目进行编译,运行。这个时候我们重新启动 Android 自带的浏览器的时候发现,浏览器会弹出一个广告弹框。

安卓逆向_23 --- Hook 框架 Cydia Substrate( Hook Java层 和 so层)_第8张图片

从上面的图片我们可以看出来了,之前我们设置插屏广告 MainActivity 为无标题透明(Theme.Translucent.NoTitleBar)就是为了使得弹出来的广告与浏览器融为一体,让用户感觉是浏览器弹出的广告。也是恶意广告程序为了防止自身被卸载掉的一些通用隐藏手段。

这里演示的注入广告是通过 Hook 指定的 Activity 中的 onCreate 方法来启动一个广告 Activity。当然,这里我们演示的 Activity 只是简单的弹出来了一个广告。如果启动的 Activity 带有恶意性,如将 Activity 做得与原 Activity一模一样的钓鱼 Activity,那么对于移动设备用户来说是极具欺骗性的。

 

 

示例 4:修改 主题颜色和游戏金币值(hook java层 so 层

 

From:https://www.bilibili.com/video/BV1UE411A7rW?p=76

 

 

hook java 层

 

Main.class 代码:

 

 

hook so 层

 

需要的 jar 包 和 lib

安卓逆向_23 --- Hook 框架 Cydia Substrate( Hook Java层 和 so层)_第9张图片

Androidmainfest.xml 添加权限:

安卓逆向_23 --- Hook 框架 Cydia Substrate( Hook Java层 和 so层)_第10张图片

添加 libs 文件

安卓逆向_23 --- Hook 框架 Cydia Substrate( Hook Java层 和 so层)_第11张图片

添加 .h 文件 和 so 库文件

安卓逆向_23 --- Hook 框架 Cydia Substrate( Hook Java层 和 so层)_第12张图片

安卓逆向_23 --- Hook 框架 Cydia Substrate( Hook Java层 和 so层)_第13张图片

安卓逆向_23 --- Hook 框架 Cydia Substrate( Hook Java层 和 so层)_第14张图片

test.cpp 代码:

安卓逆向_23 --- Hook 框架 Cydia Substrate( Hook Java层 和 so层)_第15张图片

IDA 打开 so 库,定位 函数名:

安卓逆向_23 --- Hook 框架 Cydia Substrate( Hook Java层 和 so层)_第16张图片

 

 

 

 

 

你可能感兴趣的:(Android,逆向)