Cydiasubstrate對於果粉來說一點也不陌生,越獄必備也提供了很多modules供用戶個性化使用。當然Cydiasubstrate也推出了Android版。當然Xposed也能實現了對應的功能,但兩者實現的技術手段有些不一樣,由於Xposed開源,也有不少相關文章分析了實現方式,其主要原理是替換了/system/bin/app_process這個程序,在機子啓動時加載自身的XposedBridge.jar完成對虛擬機的劫持。而Cydiasubstratet並不開源但根據比對兩者"installer",我猜測Cydiasubstrate應該是採用注入的方式完成hook的:
總的來說,要學習還是建議Xposed畢竟是開源,要快速部署我還是比較推薦Cydiasubstrate,畢竟開發簡潔,也支持Native。這一篇文章主要介紹Cydiasubstrate modules 的java開發。官方網站 http://www.cydiasubstrate.com/ 文檔簡單明瞭,也提供了下載地址,也有saurik 就Xposed區別的聲明http://www.cydiasubstrate.com/id/34058d37-3198-414f-a696-73e97e0a80db/
編寫模塊之前我們需要一些部署工作:
1.root手機
由於不捨得拿自己的機子開刀,索性在模擬器上進行了部署我們需要下載一些必備的工具su busybox mkfs.yaffs2.arm下載好了上面必備的工具,我們就開始root 吧
adb shell #mount -o remount,rw /dev/block/mtdblock0 /system adb push su /system/bin/ #chmod 4755 /system/bin/su #exit adb install super.apk adb install busybox.apk
各種安裝好後,在adb shell中執行 su grep等擴展命令成功後,證明我們完成了相應的工作,但這時候別急,如果關掉模擬器的話,是不會寫到對應system.img裏的,當我們下次重新啓動模擬器的時候,一切又回到的原點,所以我們還需要如下操作:
adb shell #mkdir /filesname #exit adb push mkfs.yaffs2.arm /filesname adb shell #cd /filesname #./mkfs.yaffs2.arm /system /filesname/my_system.img #exit adb pull /filesname/my_system.img
接着將該my_system.img替換 $ANDROID_SDK/sdk/system-images/android-xx 下的system.img即可
2.應用設置
3.模塊開發
首先得先下載Cydiasubstrate SDK,打開AndroidSDK Manager -> tools -> add on site
不一會就下好了,之後可以開始進行開發,創建一個新工程吧,完成的功能是對系統發送的短信進行監聽,首先將如下關鍵字加入到AndroidManifestxml中:
<meta-data android:name="com.saurik.substrate.main" android:value=".Main"/>
<uses-permission android:name="cydia.permission.SUBSTRATE"/>
AndroidManifestxml如下:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.rois.hookdroid"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="15" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<meta-data android:name="com.saurik.substrate.main" android:value=".Main"/>
<activity
android:name="com.rois.hookdroid.CydiaTest"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="cydia.permission.SUBSTRATE"/>
</manifest>
我新建的項目src目錄如下:
package com.rois.hookdroid;
import com.rois.core.SmsHookClassLoader;
import com.saurik.substrate.MS;
public class Main {
static void initialize(){
MS.hookClassLoad("android.telephony.SmsManager", SmsHookClassLoader.getInstance());
}
}
當然這裏我把對應的ClassLoader繼續了一次封裝,因爲要是對多個類進行hook,代碼也實現在同一個文件我會有強迫症,看官網的教程更加簡潔,SmsHookClassLoader如
下:
package com.rois.core;
import java.lang.reflect.Method;
import android.app.PendingIntent;
import android.util.Log;
import com.rois.utils.Config;
import com.saurik.substrate.MS;
public class SmsHookClassLoader implements MS.ClassLoadHook{
private static SmsHookClassLoader smsHookClassLoader;
public SmsHookClassLoader() {
super();
}
public static SmsHookClassLoader getInstance(){
if (smsHookClassLoader == null) {
smsHookClassLoader = new SmsHookClassLoader();
}
return smsHookClassLoader;
}
@SuppressWarnings({ "unchecked", "rawtypes" })
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(Config.TAG,"SEND_SMS");
Log.i(Config.TAG,"destination:"+_args[0]);
Log.i(Config.TAG,"source:"+_args[1]);
Log.i(Config.TAG,"text:"+_args[2]);
return invoke(_this, _args);
}
});
}
}
主要是我們需要實現:
1.MS.ClassLoadHook中的classLoaded(Class<?> xxxx)函數,其表示在android.telephony.SmsManager第一次被加載的時候,我們要執行的classLoaded的功能,這裏我通過反射找到sendTextMessage函數。
2.利用void hookMethod(Class _class, Member member, MS.MethodAlteration alteration);對方法進行hook,第一個參數爲classLoaded傳下來的類參數,第二個參數爲之前反射得到需要hook的方法,第三個參數爲MS.MethodAlteration它完成了最後跳轉的封裝。
3.我們需要實現MS.MethodAlteration.invoked(Object _this, Object... args),在這個方法中完成我們的自定義功能,this表示類,args爲該函數的參數,由於我們是監聽短信發送,所以,僅僅打印log……
通過這個Application標籤,我們知道這段代碼被加載在了com.android.mms 我們的短信進程中進行
Cydiasubstrate很簡潔,這樣下來在hook幾個方法動態分析的demo就搞定了,當然官網說支持native,我看了下demo感覺只是說可以通過native實現功能,好像不能hook native函數,也希望瞭解的人給我一個答案。折騰了一天,雖然實現了功能,沒有學到任何東西,除非分析它的工作原理,那麼還是洗洗睡吧