元始天尊 发表于 2016-6-12 20:38:58

android hook框架总结

Java正常执行调用逻辑
dvmCallVoidMethod
dvmCallMethod
dvmCallMethodV
dvmInterpret
dvmMterpStd
dvmMterpStdRun
循环
HANDLE_OPCODE(OP_INVOKE_STATIC)
GOTO_invoke(invokeStatic)
GOTO_invokeMethod
dvmMterp_invokeMethod
GOTO_TARGET(invokeMethod)
Pc=methodToCall->insns/methodToCall->nativeFunc

用反射的调用逻辑:
Constructor getDeclaredConstructor = clazz. getDeclaredConstructor()
Method m = clazz.getDeclaredMethod()
m.Invoke()
---->

Constructor. newInstance=>
Dalvik_java_lang_reflect_Constructor_constructNative =>
dvmInvokeMethod =>
method->nativeFunc/dvmInterpret insns

Method.invoke =>
Method.invokeNative =>
Dalvik_java_lang_reflect_Method_invokeNative =>
dvmInvokeMethod =>
method->nativeFunc/dvmInterpret

nativeFunc => dvmResolveNativeMethod
dfunc = dvmLookupInternalNativeMethod
dfunc()

GOTO_TARGET(invokeMethod, bool methodCallRange, const Method* _methodToCall, u2 count, u2 regs)

Hook方式:
1.        静态修改apk中的函数调用,插入语句(droidbox)
2.        用反射获取java函数Method类型对应c层结构Method*,修改insns域的dex字节码(未发现)
3.        修改method->nativeFunc域,自己实现dvmResolveNativeMethod以重新映射(xposed/substrate)

ART虚拟机和DALVIK虚拟机对比
1、Ahead-of-time (AOT) compilation instead of Just-in-time (JIT)
2、Improved garbage collection
3、Improved memory usage and reduce fragmentation

Ahead-of-time (AOT) compilation instead of Just-in-time (JIT)

在dalvik中(实际为android2.2以上引入的技术),如同其他大多数jvm一样,都采用的是jit来做及时翻译(动态翻译),将dex或odex中并排的dalvik code(或者叫smali指令集)运行态翻译成native code去执行.jit的引入使得dalvik提升了3~6倍的性能

而在art中,完全抛弃了dalvik的jit,使用了aot直接在安装时用dex2oat将其完全翻译成native code.这一技术的引入,使得虚拟机执行指令的速度又一重大提升

Improved garbage collection

Xposed特点
1兼容性方面,支持selinux,对某些厂商做适配
2提供多种hook功能,可以hook系统api,应用app函数,资源操作,am pm等调用,插件扩展方便
3开源,不断更新,支持art虚拟机,android5.x/6.x


Hook类型
Xpose 支持4种hook类型:package:robv.android.xposed
IXposedHookZygoteInit       
        在Zygote进程启动初始化时执行hook,framework/system
IXposedHookLoadPackage
        在包加载时刻hook,此时可以hook用户app的函数
IXposedHookInitPackageResources
        在资源操作时刻回调
IXposedHookCmdInit
        在执行am,pm等时回调
de.rovb.android.xposed.XposedBridge.main                XposedBridge.java
        initForZygote:
        findAndHookMethod        handleBindApplication                在进程首次加载apk时hook
        findAndHookMethod        initAndLoop/systemMain        system_server启动时初始化hook
        hookAllConstructors        LoadedApk.class                        在app进程中加载多个apk
        loadModules:
                IXposedHookZygoteInit                initZygote()
                IXposedHookLoadPackage        加入sLoadedPackageCallbacks表
IXposedHookCmdInit                initCmdApp()

Xposed文件结构
Xposed => app_process
        Xposed_service.cpp        提供文件操作接口(libc.so尚未加载)
        Libxposed_dalvik.cpp        提供dalvik虚拟机hook接口(jni层实现)
        Libxposed_art.cpp                提供art虚拟机hook接口(jni层实现)
        Libxposed_command.cpp提供其他通用接口
        Xposed.cpp                        c++层一些实现,用于app_main
        App_main.cpp                        app_process入口,用于替换app_process(重写main和AppRuntime)api>=21
        App_main2.cpp                app_process入口,用于替换app_process(重写main和AppRuntime)api<21
Xposedbridge => xposedbridge.jar
        XposedHelpers.java                提供反射能力
        XposedBridge.java                xposedbridge入口,代替系统ZygoteInit类,主要的hook逻辑
        XC_MethodHook.java        为插件提供hook接口(java层实现)

问题1:何时加载framework.jar?
ActivityThread.class => const-class ActivityThread => OP_CONST_CLASS.cpp
dvmResolveClass
        dvmFindClassNoInit
                findClassFromLoaderNoInit
                        dvmCallMethod(loadClass)
                dvmFindSystemClassNoInit
                        findClassNoInit
                                searchBootPathForClass
java.boot.class.path        bootClassPath
        /system/framework/core.jar:/system/framework/ext.jar:/system/framework/framework.jar:/system/framework/android.policy.jar:/system/framework/services.jar

问题2:为何IXposedHookZygoteInit可以hook framework/system api
XposedBridge.main
        initForZygote
                findAndHookMethod                加载系统jar
        loadModules
                loadModule       
                        moduleInstance.initZygote()
                        hookLoadPackage(moduleInstance)

问题3:为何IXposedHookLoadPackage可以hook app自身函数
首次加载:
initForZygote        beforeHookedMethod        handleBindApplication
Process.start        “android.app.ActivityThread”
android.app.ActivityThread.main
android.app.ActivityThread.attach
ActivityManagerService. attachApplication
ActivityManagerService. attachApplicationLocked
android.app.ActivityThread.bindApplication
handleBindApplication
                                ActivityStack.realStartActivityLocked
                                        scheduleLaunchActivity
                                                getPackageInfoNoCheck

getPackageInfoNoCheck
        LoadedApk()构造
                LoadedApk.getClassLoader
                        ApplicationLoaders.getDefault().getClassLoader(zip,libpath,null)

问题4:何时加载xposedbridge?
Xposed app_main->main():
        xposed::initialize()        ->env中加入xposedbridge.jar
        runtime.start(“de.robv.android.xposed.XposedBridge”) -> AndroidRuntime
                startVm()
                onVmCreated()
                        xposed::onVmCreated        加载xposedbridge.jar
                startReg()
                XposedBridge.main()

问题5:底层实现hook?
强制吧函数设置为native,并修改native函数使其返调java函数libxposed_dalvik.cpp
    hookInfo->reflectedMethod = dvmDecodeIndirectRef(dvmThreadSelf(), env->NewGlobalRef(reflectedMethodIndirect));
    hookInfo->additionalInfo = dvmDecodeIndirectRef(dvmThreadSelf(), env->NewGlobalRef(additionalInfoIndirect));
        SET_METHOD_FLAG(method, ACC_NATIVE);//设置Method->AccessFlag强制为native函数
    method->nativeFunc = &hookedMethodCallback;//修改默认回调dvmResolveNativeMethod为自定义函数,该函数原先从系统函数和so中的jni函数中寻找java对应的c层方法,hookedMethodCallback函数则调用dvmCallMethod执行java层方法
    method->insns = (const u2*) hookInfo;//该域原用于非native模式下保存dex字节码用于解释执行,现用于存储Method指针
    method->registersSize = method->insSize;
method->outsSize = 0;

SUBSTRATE
特点:
1 hook时机早,因此支持hook so函数
2重定向liblog.so,较易适配
3支持ios、android平台
4不支持dalvik,不支持selinux,不支持api>=5.0

文件:
substrate.h             //c++ header file used in JNI layer hook
substrate-api.jar       //import package used in java layer hook
substrate-bless.jar   //used to remove properties(private,protect,etc...) in java layer hook
com.saurik.substrate.apk//host apk, we can only develop plugin for it to install package
\lib\armeabi\lib\x86//real operation for hooking
libAndroidBootstrap0.so //used to fake /system/lib/liblog.so and pull up libAndroidLoader.so   
libAndroidLoader.so   //used to pull all *.cy.so
        //MSLoadExtensions
libAndroidCydia.cy.so   //still in research
libDalvikLoader.cy.so   //still in research
libsubstrate.so         //provide jni layer hook low-level api
        //MSFindSymbol MSGetImageByName MSCloseFunction MSDebug MSHookFunction
libsubstrate-dvm.so   //provide java layer hook low-level api
        //MSDecodeIndirectReference MSJavaHookClassLoad MSJavaHookBridge MSJavaHookMethod
        // MSJavaCreateObjectKey MSJavaReleaseObjectKey MSJavaGetObjectKey MSJavaSetObjectKey MSJavaBlessClassLoader
libSubstrateJNI.so      //used by substrate.apk to do c++ layer work
        //getppid readlink grep unlink symlink mkdir kill chown chmod
libSubstrateRun.so      //used by substrate.apk to do patch/unpatch/link/unlink operation
        //patch unpatch link unlink nm rpl
update-binary.so      //used by substrate.apk to recover patch/link operation
1.xposed框架一定会支持art框架以及安卓L

2.@Rovo89已经有在开发和测试支持art引擎的xposed框架,只是由于两个原因他没有发布,一个是由于需要经过大量的测试才行,第二是因为art本身还不够稳定,而且谷歌还在不停的修改和更新art引擎,而这些变化会导致xposed框架编码上会带来一些重构,同时还需要关注dual-stack 32/64 bit Zygote,以及严格SELinux的策略对xposed框架的影响。@Rovo89想等art引擎的正式版发布后再发布对于art的支持。

3.由于kitkat里的art测试版和android l里的art正式版是完全不同的环境,所以后续xposed框架将主要支持android l,如果测试和开发量不大的话,可能会考虑兼容kitkat里的art环境

待研究的点:
1.特殊情况hook,如隐藏java函数(@hide)及native函数测试
2.稳定性测试,包括api版本支持、厂商支持


   substrate框架xposed框架dexposed框架
dalvik/art虚拟机支持dalvikdalvik/artdalvik/art
android版本支持2.x 3.x 4.x2.x 3.x 4.x 5.x 6.x2.x 3.x 4.x 5.x 6.x
hook能力java/c apijava apijava/c api(自身模块)
修改文件app_processliblog.so自身文件
hook时机app_process启动时app_process启动前加载so的时刻未知
hook方式修改method结构体重新映射java层对应的jni函数修改method结构体
c层hook类型无inline未知
是否需要root是是否
使用形式宿主+插件宿主+插件未知
风险app_process随每个版本变化加载so较多未知
ABIx86/armx86/arm未知
操作系统ios/androidandroid



ghosting 发表于 2018-11-30 17:09:35

不错不错,@@@@
页: [1]
查看完整版本: android hook框架总结