Cydiasubstrate modules 簡單程式設計之Java Hook 心得篇
Cydiasubstrate對於果粉來說一點也不陌生,越獄必備也提供了很多modules供使用者個性化使用。當然Cydiasubstrate也推出了Android版。當然Xposed也能實現了對應的功能,但兩者實現的技術手段有些不一樣,由於Xposed開源,也有不少相關文章分析了實現方式,其主要原理是替換了/system/bin/app_process這個程式,在機子啟動時載入自身的XposedBridge.jar完成對虛擬機器的劫持。而Cydiasubstratet並不開源但根據比對兩者"installer",我猜測Cydiasubstrate應該是採用注入的方式完成hook的:
編寫模組之前我們需要一些部署工作:
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函式,也希望瞭解的人給我一個答案。折騰了一天,雖然實現了功能,沒有學到任何東西,除非分析它的工作原理,那麼還是洗洗睡吧