hook的根基是反射司忱,并且反射的根基是系統(tǒng)的方法或者屬性是
static
的割去,這樣才能攔截到系統(tǒng)的服務(wù)始锚。之后才是基于動態(tài)代理修改系統(tǒng)行為阿迈。
系統(tǒng)服務(wù)獲取原理:
常用的調(diào)用系統(tǒng)服務(wù)代碼:
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
各種Service
都被ServiceManager
統(tǒng)一管理,其偽代碼:
IBinder b = ServiceManager.getService("service_name"); // 獲取原始的IBinder對象
IXXInterface in = IXXInterface.Stub.asInterface(b); // 轉(zhuǎn)換為Service接口
public static android.os.IBinder getService(String name) {
// ... omissions
android.os.IBinder service = sCache.get(name);
if (service != null) {
return service;
} else {
return createService(name);
}
}
public static android.content.IClipboard asInterface(android.os.IBinder obj) {
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR); // Hook點
if (((iin != null) && (iin instanceof android.content.IClipboard))) {
return ((android.content.IClipboard) iin);
}
return new android.content.IClipboard.Stub.Proxy(obj);
}
Binder Hook實現(xiàn)原理:
- 使用反射hook到
ServiceManager
對象 - 使用反射調(diào)用其
getService()
方法稚伍,獲取到一個IBinder實例 - 動態(tài)代理這個
IBinder
實例的queryLocalInterface()
方法,在此方法invoke()
執(zhí)行時戚宦,先利用XXIInterface.Stub.asInterface(IBinder binder)
為static
方法的便利个曙,使用反射創(chuàng)建出一個IInterface
的實例 - 動態(tài)代理這個
IInterface
對象的指定的某些方法,達到修改系統(tǒng)服務(wù)的目的受楼。 - 通過反射垦搬,獲取到
ServiceManager
的靜態(tài)屬性sCache
,里面保存了已經(jīng)創(chuàng)建過的IBinder
對象實例 - 將hook了的
Ibinder
保存進sCache
艳汽。
下面的只是推測猴贰,有待驗證:
這樣,在之后每次獲取系統(tǒng)服務(wù)的時候河狐,
IBinder b = ServiceManager.getService("service_name"); // 獲取原始的IBinder對象
這里獲取到的就已經(jīng)是Hook之后的IBinder
實例米绕,那么,在下一步
IXXInterface in = IXXInterface.Stub.asInterface(b); // 轉(zhuǎn)換為Service接口
中馋艺,由于b
已經(jīng)被hook栅干,b
返回的就會是hook之后的IInterface
了,達到hook的目的捐祠。
因此碱鳞,IBinder
會被動態(tài)代理hook一次,而IBinder
的queryLocalInterface
則會在每次調(diào)用系統(tǒng)服務(wù)的時候被hook代理踱蛀,每次返回hook之后的IInterface
實例窿给。