level 1
Slowargo
楼主
dexspy是小米基于著名的xposed框架修改的新patchrom框架。这几天瞄了一下反编译的代码,做个笔记。
与smali注入相比,新的机制借助xposed的hook机制可以使未来MIUI移植适配变得更简单。
dexspy的java部分代码在framework_ext中,核心类是miui/dexspy/*,代码和xposed旧机制的源码还是挺类似的,不过做了一个修改:
arrayOfString[0] = "android.app.Activity";
arrayOfString[1] = "android.app.ActivityManager";
arrayOfString[2] = "android.app.ApplicationPackageManager";
arrayOfString[3] = "android.app.Dialog";
arrayOfString[4] = "android.app.DownloadManager$CursorTranslator";
arrayOfString[5] = "android.app.LoadedApk";
....
sHookedClassNames = arrayOfString;
这个数组定义了所有需要hook的类。在初始化时,会对每个类的特定方法挂上before和after钩子:
private static void initDexspyZygote() throws Exception {
for(String className : sHookedClassNames) {
hookMethodsThroughHandler(className, getHookClassName(className));
}
}
public static void hookMethodsThroughHandler(String className, String handlerClassName) {
Class<?> clazz = ReflectionUtils.findClass(className, 0x0);
Class<?> handlerClazz = ReflectionUtils.findClass(handlerClassName, 0x0);
Method[] methods = handlerClazz.getMethods();
for(Method method : methods) {
if((!method.getName().startsWith("before_")) && (!method.getName().startsWith("after_"))) {
}
Member hookedMethod = findHookedMethod(clazz, method);
hookMethod(hookedMethod, MethodHookTemplate.sInstance);
}
}
然而每个类都可能有n多方法,dexspy怎么知道要hook哪些呢?
framework_ext反编译出来后,可以看到很多Injector.java文件,比如android/app/Injector.java放的就是前面那些android.app.*的钩子:
static class ActivityHook
{
private static final String TAG = "Activity";
public static void after_onCreate(MethodHook.MethodHookParam paramMethodHookParam, Bundle paramBundle)
{
Activity localActivity = (Activity)paramMethodHookParam.thisObject;
if ((UiUtils.isV5Ui(localActivity)) && (UiUtils.resolveAttribute(localActivity, 16842926) == 101515270))
localActivity.getWindow().setGravity(80);
}
public static void after_onOptionsItemSelected(MethodHook.MethodHookParam paramMethodHookParam, MenuItem paramMenuItem)
{
Activity localActivity = (Activity)paramMethodHookParam.thisObject;
if ((UiUtils.isV5Ui(localActivity)) && (paramMenuItem.getItemId() == 16908332))
{
localActivity.finish();
paramMethodHookParam.setResult(Boolean.valueOf(true));
}
}
...
比如这个就是android.app.Activity类的钩子了,里面hook了onCreate(), onOptionsItemSelected()等方法。dexspy加载时会对扫描这些Injector,将相应方法的before和after钩子挂上。
跟xposed主要的区别就在这里,好处就是以后这套框架如果开放了,模块编写自己的Injector类就能方便实现挂钩。当然现在的xposed也挺方便,但代码没这么直观清晰就是了。
另外就是dexspy是基于旧xposed的,效率不如目前版本的xposed,尤其hook很多时效率会比较糟糕,估计未来会对dexspy做一次升级吧。
2014年04月27日 12点04分
1
与smali注入相比,新的机制借助xposed的hook机制可以使未来MIUI移植适配变得更简单。
dexspy的java部分代码在framework_ext中,核心类是miui/dexspy/*,代码和xposed旧机制的源码还是挺类似的,不过做了一个修改:
arrayOfString[0] = "android.app.Activity";
arrayOfString[1] = "android.app.ActivityManager";
arrayOfString[2] = "android.app.ApplicationPackageManager";
arrayOfString[3] = "android.app.Dialog";
arrayOfString[4] = "android.app.DownloadManager$CursorTranslator";
arrayOfString[5] = "android.app.LoadedApk";
....
sHookedClassNames = arrayOfString;
这个数组定义了所有需要hook的类。在初始化时,会对每个类的特定方法挂上before和after钩子:
private static void initDexspyZygote() throws Exception {
for(String className : sHookedClassNames) {
hookMethodsThroughHandler(className, getHookClassName(className));
}
}
public static void hookMethodsThroughHandler(String className, String handlerClassName) {
Class<?> clazz = ReflectionUtils.findClass(className, 0x0);
Class<?> handlerClazz = ReflectionUtils.findClass(handlerClassName, 0x0);
Method[] methods = handlerClazz.getMethods();
for(Method method : methods) {
if((!method.getName().startsWith("before_")) && (!method.getName().startsWith("after_"))) {
}
Member hookedMethod = findHookedMethod(clazz, method);
hookMethod(hookedMethod, MethodHookTemplate.sInstance);
}
}
然而每个类都可能有n多方法,dexspy怎么知道要hook哪些呢?
framework_ext反编译出来后,可以看到很多Injector.java文件,比如android/app/Injector.java放的就是前面那些android.app.*的钩子:
static class ActivityHook
{
private static final String TAG = "Activity";
public static void after_onCreate(MethodHook.MethodHookParam paramMethodHookParam, Bundle paramBundle)
{
Activity localActivity = (Activity)paramMethodHookParam.thisObject;
if ((UiUtils.isV5Ui(localActivity)) && (UiUtils.resolveAttribute(localActivity, 16842926) == 101515270))
localActivity.getWindow().setGravity(80);
}
public static void after_onOptionsItemSelected(MethodHook.MethodHookParam paramMethodHookParam, MenuItem paramMenuItem)
{
Activity localActivity = (Activity)paramMethodHookParam.thisObject;
if ((UiUtils.isV5Ui(localActivity)) && (paramMenuItem.getItemId() == 16908332))
{
localActivity.finish();
paramMethodHookParam.setResult(Boolean.valueOf(true));
}
}
...
比如这个就是android.app.Activity类的钩子了,里面hook了onCreate(), onOptionsItemSelected()等方法。dexspy加载时会对扫描这些Injector,将相应方法的before和after钩子挂上。
跟xposed主要的区别就在这里,好处就是以后这套框架如果开放了,模块编写自己的Injector类就能方便实现挂钩。当然现在的xposed也挺方便,但代码没这么直观清晰就是了。
另外就是dexspy是基于旧xposed的,效率不如目前版本的xposed,尤其hook很多时效率会比较糟糕,估计未来会对dexspy做一次升级吧。