package me.ele.amigo.hook;
import android.content.Context;
import android.util.AndroidRuntimeException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import me.ele.amigo.compat.ActivityManagerNativeCompat;
import me.ele.amigo.compat.IActivityManagerCompat;
import me.ele.amigo.compat.SingletonCompat;
import me.ele.amigo.reflect.FieldUtils;
import me.ele.amigo.reflect.Utils;
import me.ele.amigo.utils.Log;
public class IActivityManagerHook extends ProxyHook {
private static final String TAG = IActivityManagerHook.class.getSimpleName();
private Object original_gDefault = null;
private Object gDefault_mInstance = null;
public IActivityManagerHook(Context context) {
super(context);
}
@Override
public BaseHookHandle createHookHandle() {
return new IActivityManagerHookHandle(context);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
return super.invoke(proxy, method, args);
} catch (SecurityException e) {
String msg = String.format("msg[%s],args[%s]", e.getMessage(), Arrays.toString(args));
throw new SecurityException(msg, e);
}
}
@Override
public void onInstall(ClassLoader classLoader) throws Throwable {
Class cls = ActivityManagerNativeCompat.Class();
Object gDefault = FieldUtils.readStaticField(cls, "gDefault");
if (gDefault == null) {
ActivityManagerNativeCompat.getDefault();
gDefault = FieldUtils.readStaticField(cls, "gDefault");
}
if (IActivityManagerCompat.isIActivityManager(gDefault)) {
setProxyObj(gDefault);
Class<?> objClass = proxyObj.getClass();
List<Class<?>> interfaces = Utils.getAllInterfaces(objClass);
Class[] ifs = interfaces != null && interfaces.size() > 0 ? interfaces.toArray(new
Class[interfaces.size()]) : new Class[0];
Object proxyActivityManager = MyProxy.newProxyInstance(objClass.getClassLoader(),
ifs, this);
FieldUtils.writeStaticField(cls, "gDefault", proxyActivityManager);
Log.i(TAG, "Install ActivityManager Hook 1 old=%s,new=%s", proxyObj,
proxyActivityManager);
original_gDefault = gDefault;
} else if (SingletonCompat.isSingleton(gDefault)) {
Object mInstance = FieldUtils.readField(gDefault, "mInstance");
if (mInstance == null) {
SingletonCompat.get(gDefault);
mInstance = FieldUtils.readField(gDefault, "mInstance");
}
setProxyObj(mInstance);
List<Class<?>> interfaces = Utils.getAllInterfaces(proxyObj.getClass());
Class[] ifs = interfaces != null && interfaces.size() > 0 ? interfaces.toArray(new
Class[interfaces.size()]) : new Class[0];
final Object object = MyProxy.newProxyInstance(proxyObj.getClass().getClassLoader(),
ifs, IActivityManagerHook.this);
Object iam1 = ActivityManagerNativeCompat.getDefault();
Object instance = FieldUtils.readField(gDefault, "mInstance");
FieldUtils.writeField(gDefault, "mInstance", object);
FieldUtils.writeStaticField(cls, "gDefault", new android.util.Singleton<Object>() {
@Override
protected Object create() {
Log.e(TAG, "Install ActivityManager 3 Hook old=%s,new=%s", proxyObj, object);
return object;
}
});
Log.i(TAG, "Install ActivityManager Hook 2 old=%s,new=%s", proxyObj.toString(), object);
Object iam2 = ActivityManagerNativeCompat.getDefault();
if (iam1 == iam2) {
FieldUtils.writeField(gDefault, "mInstance", object);
}
original_gDefault = gDefault;
gDefault_mInstance = instance;
} else {
throw new AndroidRuntimeException("Can not install IActivityManagerNative hook, " +
"gDefault=" + gDefault);
}
}
private void rollbackProxyActivityManager() {
if (original_gDefault == null) {
return;
}
try {
Class cls = ActivityManagerNativeCompat.Class();
FieldUtils.writeStaticField(cls, "gDefault", original_gDefault);
if (gDefault_mInstance != null) {
FieldUtils.writeField(original_gDefault, "mInstance", gDefault_mInstance);
}
} catch (Exception e) {
e.printStackTrace();
}
original_gDefault = null;
original_gDefault = null;
}
@Override
protected void onUnInstall(ClassLoader classLoader) throws Throwable {
super.onUnInstall(classLoader);
rollbackProxyActivityManager();
}
}