• Cydia for Android


    在Android设备上使用Cydia框架的前提条件

    1、Android设备必须ROOT  
    2、Android设备上需要安装substrate.apk  

    编写Java层cydia插件的前提条件

    1、搭建好Android开发环境
    2、下载substrate-api.jar并导入到Android工程

    1、在application节点下声明一个元数据,name字段设置成com.saurik.substrate.main,value字段设置为用于hook别人的api的类的全称(包括包名和类名)

    1     <application android:label="@string/app_name">
    2         <meta-data android:name="com.saurik.substrate.main" android:value=".Main" />
    3     </application>

    2、声明用于访问substrate.apk的用户权限。

    1 <uses-permission android:name="cydia.permission.SUBSTRATE" />

    3、创建一个类,创建一个静态无参无返回值的initialize函数

    public static void initialize()

    4、实现initialize函数,设置需要hook的类并在该类加载完成后对相应的API进行hook

     1       MS.hookClassLoad("com.example.usertest.MainActivity", new ClassLoadHook() {
     2         
     3         @Override
     4         public void classLoaded(Class<?> arg0) {
     5             Method toast;
     6             try {
     7                 toast=arg0.getMethod("toast", String.class);                
     8             } catch (NoSuchMethodException e) {
     9                 // TODO Auto-generated catch block
    10                 e.printStackTrace();
    11                 return ;
    12             }
    13             MS.hookMethod(arg0, toast, new MS.MethodAlteration() {
    14 
    15                 @Override
    16                 public Object invoked(Object arg0, Object... arg1)
    17                         throws Throwable {
    18                     
    19                     invoke(arg0, "hook before");
    20                     invoke(arg0, arg1);
    21                     invoke(arg0, arg1);
    22                     invoke(arg0, "hook end");
    23                     return null;
    24                 }
    25             });
    26         }
    27     });
    com.example.usertest.MainActivity是需要HOOK的类的包名+类名
    ClassLoadHook回调接口用于在类加载完成后进行HOOK
    具体完成HOOK操作的步骤:
    1、利用Java反射技术获取需要HOOK的类的某个方法。
    2、调用MS.hookMethod方法对指定的类,方法和hook具体实现的接口进行hook。
    3、实现具体hook的接口,利用invoke方法调用指定类的指定方法,arg1参数数组是原始API的原始参数列表,比如这个toast方法,原始的参数是"toast start",arg1[0]就是
    "toast start"。
    MS.MethodAlteration接口是扩展于MS.MethodPointer类和MethodHook接口,就不用创建MethodPointer对象,使用它调用原始API,现在调用原始API的方法是直接调用invoke方法。
    官网文档建议使用MethodAlteration接口代替MethodPointer类+MethodHook接口,因为更容易使用,减少使用MethodPointer对象出现的错误。

    5、需要HOOK的类源码
    1     @Override
    2     protected void onCreate(Bundle savedInstanceState) {
    3         super.onCreate(savedInstanceState);
    4         setContentView(R.layout.activity_main);
    5         toast("toast start"); 
    6     }
    7     public void toast(String str){
    8         Toast.makeText(this, str, Toast.LENGTH_LONG).show();
    9     }

    最后附上完整源码

    cydia插件源码:

                                                      Main.java 
    1
    package com.example.cydiaexample; 2 3 import java.lang.reflect.Field; 4 import java.lang.reflect.Method; 5 import java.lang.reflect.Type; 6 7 import android.util.Log; 8 import android.widget.Toast; 9 10 import com.saurik.substrate.MS; 11 import com.saurik.substrate.MS.ClassLoadHook; 12 13 //hook 方法 14 15 public class Main { 16 17 public static void initialize() { 18 19 20 //设置需要hook的类 21 MS.hookClassLoad("android.content.res.Resources", new MS.ClassLoadHook() { 22 public void classLoaded(Class<?> resources) { 23 // ... code to modify the class when loaded 24 25 //定义方法 26 Method getColor; 27 28 try { 29 //hook的方法为获取颜色的方法 30 getColor = resources.getMethod("getColor", Integer.TYPE); 31 } catch (NoSuchMethodException e) { 32 33 getColor = null; 34 } 35 36 if (getColor != null) { 37 //新建一个MethodPointer对象,hookMethod方法中要使用 38 final MS.MethodPointer old = new MS.MethodPointer(); 39 40 //开始hook方法,写入自己想改变的数据 41 MS.hookMethod(resources, getColor, new MS.MethodHook<Object, Object>() { 42 public Object invoked(Object resources, Object... args) 43 throws Throwable 44 { 45 46 int color = (Integer) old.invoke(resources, args); 47 48 //返回颜色 49 // return color & ~0x0000ff00 | 0x00ff0000; 50 return color; 51 } 52 }, old); 53 54 } 55 } 56 }); 57 58 59 MS.hookClassLoad("com.example.usertest.MainActivity", new ClassLoadHook() { 60 61 @Override 62 public void classLoaded(Class<?> arg0) { 63 Method toast; 64 try { 65 toast=arg0.getMethod("toast", String.class); 66 } catch (NoSuchMethodException e) { 67 // TODO Auto-generated catch block 68 e.printStackTrace(); 69 return ; 70 } 71 MS.hookMethod(arg0, toast, new MS.MethodAlteration() { 72 73 @Override 74 public Object invoked(Object arg0, Object... arg1) 75 throws Throwable { 76 77 invoke(arg0, "hook before"); 78 invoke(arg0, arg1); 79 invoke(arg0, arg1); 80 invoke(arg0, "hook end"); 81 82 return null; 83 } 84 }); 85 } 86 }); 87 88 } 89 }
                                                         Manifest.xml
    1
    <?xml version="1.0" encoding="utf-8"?> 2 <manifest android:versionCode="1" android:versionName="1.0" package="com.example.cydiaexample" 3 xmlns:android="http://schemas.android.com/apk/res/android"> 4 <application android:label="@string/app_name"> 5 <meta-data android:name="com.saurik.substrate.main" android:value=".Main" /> 6 </application> 7 8 <uses-permission android:name="cydia.permission.SUBSTRATE" /> 9 </manifest>

    需要HOOK端的源码:

                                                                                          MainActivity.java 
    1
    package com.example.usertest; 2 3 import android.app.Activity; 4 import android.os.Bundle; 5 import android.view.Menu; 6 import android.view.MenuItem; 7 import android.widget.TextView; 8 import android.widget.Toast; 9 10 public class MainActivity extends Activity { 11 12 @Override 13 protected void onCreate(Bundle savedInstanceState) { 14 super.onCreate(savedInstanceState); 15 setContentView(R.layout.activity_main); 16 TextView mTextView=(TextView) findViewById(R.id.info); 17 mTextView.setText(android.os.Build.ID); 18 toast("toast start"); 19 } 20 public void toast(String str){ 21 Toast.makeText(this, str, Toast.LENGTH_LONG).show(); 22 } 23 @Override 24 public boolean onCreateOptionsMenu(Menu menu) { 25 // Inflate the menu; this adds items to the action bar if it is present. 26 getMenuInflater().inflate(R.menu.main, menu); 27 return true; 28 } 29 30 @Override 31 public boolean onOptionsItemSelected(MenuItem item) { 32 // Handle action bar item clicks here. The action bar will 33 // automatically handle clicks on the Home/Up button, so long 34 // as you specify a parent activity in AndroidManifest.xml. 35 int id = item.getItemId(); 36 if (id == R.id.action_settings) { 37 return true; 38 } 39 return super.onOptionsItemSelected(item); 40 } 41 }
  • 相关阅读:
    streamsets 集成 cratedb 测试
    streamsets k8s 部署试用
    streamsets rest api 转换 graphql
    StreamSets sdc rpc 测试
    StreamSets 相关文章
    StreamSets 多线程 Pipelines
    StreamSets SDC RPC Pipelines说明
    StreamSets 管理 SDC Edge上的pipeline
    StreamSets 部署 Pipelines 到 SDC Edge
    StreamSets 设计Edge pipeline
  • 原文地址:https://www.cnblogs.com/xushihai/p/4502703.html
Copyright © 2020-2023  润新知