• Android Hook 框架 Cydia_substrate 详解


    目录(?)[-]

    1. 使用方法
    2. 短信监控实例

    1、Cydia_Substrate 框架简介

    Cydia Substrate是一个代码修改平台。它可以修改任何主进程的代码,不管是用Java还是C/C++(native代码)编写的。而Xposed只支持 HOOK app_process中的java函数,因此Cydia Substrate是一款强大而实用的HOOK工具。
    其实 cydia_substrate 与xposed 的hook原理是一样的,二者都可以作为Java Hook的框架,看使用习惯了。下面简单介绍一下 cydia_substrate 的使用方法。
     

    使用方法

    下面以官网的一个实例来说明cydia substrate的使用方法。该实例是实现将多个接口组件颜色修改为紫罗兰色。

    需要安装:http://www.cydiasubstrate.com/download/com.saurik.substrate.apk

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

    步骤二:配置Manifest文件

    (1)需要指定权限:cydia.permission.SUBSTRATE

    (2)添加meta标签,name为cydia.permission.SUBSTRATE,value为下一步中创建的类名.Main

     

    1. <manifest xmlns:android="http://schemas.android.com/apk/res/android">   
    2.     <application>   
    3.         <meta-data android:name="com.saurik.substrate.main" android:value=".Main"/>   
    4.     </application>   
    5.     <uses-permission android:name="cydia.permission.SUBSTRATE"/>   
    6. </manifest>   
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"> 
        <application> 
            <meta-data android:name="com.saurik.substrate.main" android:value=".Main"/> 
        </application> 
        <uses-permission android:name="cydia.permission.SUBSTRATE"/> 
    </manifest> 

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

    1. import com.saurik.substrate.MS;   
    2.   
    3. public class Main {   
    4.     static void initialize() {    
    5.         // ... code to run when extension is loaded   
    6.     }   
    7. }   
        import com.saurik.substrate.MS; 
        
        public class Main { 
            static void initialize() {  
                // ... code to run when extension is loaded 
            } 
        } 

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

     

    1. public class Main {   
    2.     static void initialize() {   
    3.         MS.hookClassLoad("android.content.res.Resources", new MS.ClassLoadHook() {   
    4.             public void classLoaded(Class<?> resources) {   
    5.                 // ... code to modify the class when loaded   
    6.             }   
    7.         });   
    8.     }   
    9. }  
        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对象原始代码的调用和修改,将所有绿色修改成了紫罗兰色。

     

    1. public void classLoaded(Class<?> resources) {   
    2.     Method getColor;    
    3.     try {   
    4.             getColor = resources.getMethod("getColor", Integer.TYPE);   
    5.         } catch (NoSuchMethodException e) {   
    6.             getColor = null;   
    7.         }   
    8.         
    9.         if (getColor != null) {   
    10.             final MS.MethodPointer old = new MS.MethodPointer();   
    11.         
    12.             MS.hookMethod(resources, getColor, new MS.MethodHook() {   
    13.                 public Object invoked(Object resources, Object... args)   
    14.                     throws Throwable   
    15.                 {   
    16.                     int color = (Integer) old.invoke(resources, args);   
    17.                     return color & ~0x0000ff00 | 0x00ff0000;   
    18.                 }   
    19.             }, old);   
    20.         }   
    21.     }    
        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); 
                } 
            }  

    安装运行,重启系统后发现很多字体颜色都变了。        

    示例中MS.hookMethod的代码可以改成:

     

    1. MS.hookMethod(resources, getColor, new MS.MethodAlteration<Resources, Integer>() {   
    2.     public Integer invoked(Resources resources, Object... args)   
    3.             throws Throwable   
    4.             {   
    5.         int color = invoke(resources, args);   
    6.         return color & ~0x0000ff00 | 0x00ffee00;   
    7.             }   
    8. });  
        MS.hookMethod(resources, getColor, new MS.MethodAlteration<Resources, Integer>() { 
            public Integer invoked(Resources resources, Object... args) 
                    throws Throwable 
                    { 
                int color = invoke(resources, args); 
                return color & ~0x0000ff00 | 0x00ffee00; 
                    } 
        });

    2、短信监控实例

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

     

    1. <span style="font-size:12px;">import java.lang.reflect.Method;   
    2. import android.app.PendingIntent;   
    3. import android.util.Log;   
    4. import com.saurik.substrate.MS;   
    5. public class Main {  
    6.     static void initialize() {     
    7.         MS.hookClassLoad("android.telephony.SmsManager", new MS.ClassLoadHook() {   
    8.             @Override   
    9.             public void classLoaded(Class<?> SmsManager) {   
    10.                 //code to modify the class when loaded   
    11.                 Method sendTextMessage;   
    12.                 try {   
    13.                     sendTextMessage = SmsManager.getMethod("sendTextMessage",   
    14.                             new Class[]{String.class,String.class,String.class,PendingIntent.class,PendingIntent.class});   
    15.                 } catch (NoSuchMethodException e) {   
    16.                     sendTextMessage = null;   
    17.                 }   
    18.                 MS.hookMethod(SmsManager, sendTextMessage, new MS.MethodAlteration() {   
    19.                     public Object invoked(Object _this,Object... _args) throws Throwable{   
    20.                         Log.i("SMSHOOK","SEND_SMS");   
    21.                         Log.i("SMSHOOK","destination:"+_args[0]);   
    22.                         Log.i("SMSHOOK","source:"+_args[1]);   
    23.                         Log.i("SMSHOOK","text:"+_args[2]);   
    24.                         return invoke(_this, _args);   
    25.                     }   
    26.                 });   
    27.             }   
    28.         });   
    29.     }   
    30. }</span>  
    <span style="font-size:12px;">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); 
                        } 
                    }); 
                } 
            }); 
        } 
    }</span>

     运行步骤

    • ROOT过的手机一部,没有ROOT的,请自行搜索方法。
    • Eclipse 上安装 Android Substrate SDK,参考:http://www.cydiasubstrate.com/id/73e45fe5-4525-4de7-ac14-6016652cc1b8/ 
    • 手机端去下载安装 Cydia Substrate http://www.cydiasubstrate.com/download/com.saurik.substrate.apk
    • 按照章节1上面的例程,编译本代码后安装到手机
    • 手机上运行Substrate,界面上点击“Link Substrate Files”,再点击 “Restart System(Soft)”(这些都是Hook 步骤)
    • 最后再编写一个Test.apk, 调用hook 后的class,检验hook 结果。
  • 相关阅读:
    python 如何将md5转为16字节
    linux非root用户执行开机启动程序
    python 正则表达式的使用
    Go随机数的使用
    Go 的类型断言type assertion
    go get中的...
    Go语言圣经
    python入门第三十五天--事件驱动模型(补)练习理解
    MySQL_Ubuntu安装
    JAVA入门基础--数据类型
  • 原文地址:https://www.cnblogs.com/lkislam/p/4859957.html
Copyright © 2020-2023  润新知