下面列出了怎么用android.util.Singleton的API类实例代码及写法,或者点击链接到github查看源代码。
/**
* hookSystemServices, but need to compatible with Android O in future.
*/
protected void hookSystemServices() {
try {
Singleton<IActivityManager> defaultSingleton;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
defaultSingleton = Reflector.on(ActivityManager.class).field("IActivityManagerSingleton").get();
} else {
defaultSingleton = Reflector.on(ActivityManagerNative.class).field("gDefault").get();
}
IActivityManager origin = defaultSingleton.get();
IActivityManager activityManagerProxy = (IActivityManager) Proxy.newProxyInstance(mContext.getClassLoader(), new Class[] { IActivityManager.class },
createActivityManagerProxy(origin));
// Hook IActivityManager from ActivityManagerNative
Reflector.with(defaultSingleton).field("mInstance").set(activityManagerProxy);
if (defaultSingleton.get() == activityManagerProxy) {
this.mActivityManager = activityManagerProxy;
Log.d(TAG, "hookSystemServices succeed : " + mActivityManager);
}
} catch (Exception e) {
Log.w(TAG, e);
}
}
@Override
public void inject() throws Throwable {
Field f_gDefault = ActivityManagerNative.class.getDeclaredField("gDefault");
if (!f_gDefault.isAccessible()) {
f_gDefault.setAccessible(true);
}
if (f_gDefault.getType() == IActivityManager.class) {
f_gDefault.set(null, getHookObject().getProxyObject());
} else if (f_gDefault.getType() == Singleton.class) {
Singleton gDefault = (Singleton) f_gDefault.get(null);
Field f_mInstance = Singleton.class.getDeclaredField("mInstance");
if (!f_mInstance.isAccessible()) {
f_mInstance.setAccessible(true);
}
f_mInstance.set(gDefault, getHookObject().getProxyObject());
} else {
// 不会经过这里
throw new UnsupportedOperationException("Singleton is not visible in AMN.");
}
HookBinder<IActivityManager> hookAMBinder = new HookBinder<IActivityManager>() {
@Override
protected IBinder queryBaseBinder() {
return ServiceManager.getService(Context.ACTIVITY_SERVICE);
}
@Override
protected IActivityManager createInterface(IBinder baseBinder) {
return getHookObject().getProxyObject();
}
};
hookAMBinder.injectService(Context.ACTIVITY_SERVICE);
}