在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中设置分隔线几种方法
  3. android 使用DigestUtilsmd5加密的方法
  4. Android Studio 官方示例源码地址
  5. Android Email程序源码
  6. Android getWindow().setFlags方法与SD卡权限
  7. android源码分享
  8. Android天气提醒程序源码
  9. android 浏览器怎么支持 window.close() 和window.opener.locati

随机推荐

  1. Android关机流程
  2. Android去广告技术总结
  3. Android Studio 运行项目 报错误:You need
  4. Android中如何实现高亮显示即选中状态
  5. Android 3.1 r1 API中文文档(6)――ImageVi
  6. 笔试碎片
  7. Android 开发之日志打印封装log
  8. Android Framework架构浅析之【近期任务
  9. Android UI 介绍1
  10. android device ID获取