在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 block10                 e.printStackTrace();11                 return ;12             }13             MS.hookMethod(arg0, toast, new MS.MethodAlteration() {14 15                 @Override16                 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     @Override2     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 loaded24 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 Throwable44 {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 @Override62 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 block68 e.printStackTrace();69 return ;70 }71 MS.hookMethod(arg0, toast, new MS.MethodAlteration() {72 73 @Override74 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 @Override13 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 @Override24 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 @Override31 public boolean onOptionsItemSelected(MenuItem item) {32 // Handle action bar item clicks here. The action bar will33 // automatically handle clicks on the Home/Up button, so long34 // 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 }

更多相关文章

  1. android设置Activity背景色为透明的2种方法
  2. Android(安卓)Handler机制7之消息发送
  3. 当GridView中的一项被点中的时候显示的背景图片:android:listSele
  4. android中设置分隔线几种方法
  5. Android(安卓)Service总结01 目录
  6. 自定义组件
  7. android 使用DigestUtilsmd5加密的方法
  8. Android短信----发送流程---框架层(Frameworks)
  9. Android开机广播

随机推荐

  1. 【Android】Lambda表达式
  2. Android(安卓)SDK 中常用的几个命令
  3. android 团队开发技巧1 - activity 启动
  4. Android(安卓)TabHost的使用 .
  5. Android定义字符串数组资源并在程序中使
  6. 【解决方法】ADT在线安装
  7. Android(安卓)中文API (33) —— Checkable
  8. Android(安卓)Toolchain与Bionic Libc
  9. Android(安卓)OpenGL学习笔记(二)之----
  10. adroid app权限实现方式