ART 虚拟机下Hook工具:VirtualHook
http://bbs.pediy.com/thread-216786.htm
Github: https://github.com/rk700/VirtualHook
代码结构:
Plugin (apk in sd card) |
YAHFA |
VirtualApp |
YAHFA是一个ART的Hook框架(可以Hook应用层、Java API、native code)
VirtualApp是一个开源Android sandbox,其为App伪造了一套Java Framework,让OS认为App是运行在VA的一个子进程。
Hook原理:
利用VirtualApp提供的虚拟空间,我们就可以实现很多事情了。应用启动时,会初始化Application,此时会在应用所在的进程中调用bindApplication()。而VirtualApp重写了相关代码,那么我们就可以在把注入代码的窗口放在这里,从而实现应用启动时,加载外部的hook代码。
其具体实现也非常简单,在类VClientImpl的方法bindApplicationNoCheck()中,完成了对应用Application的创建:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
... try { mInstrumentation.callApplicationOnCreate(mInitialApplication); PatchManager.getInstance().checkEnv(HCallbackHook. class ); if (conflict) { PatchManager.getInstance().checkEnv(AppInstrumentation. class ); } Application createdApp = ActivityThread.mInitialApplication.get(mainThread); if (createdApp != null ) { mInitialApplication = createdApp; } } catch (Exception e) { if (!mInstrumentation.onException(mInitialApplication, e)) { throw new RuntimeException( "Unable to create application " + mInitialApplication.getClass().getName() + ": " + e.toString(), e); } } VActivityManager.get().appDoneExecuting(); } |
我们只需要在这个方法的末尾处,添加注入窗口即可。从而,所有在VirtualApp中运行的应用,都会被附加上注入窗口。所以,本文所说的非root权限hook应用,更准确来说,hook的是在VirtualApp中运行的应用。
调用过程:应用启动 -- bindApplication() -- bindApplicationNoCheck() -- 1)startIOUniformer()//IO重定向
sdcard路径重定向
---2)applyHookPlugin() //加载Hook插件(内部调用HookMain.doHookDefault(...),使用YAHFA框架)
VA伪造的“公共空间”绝对路径:
/data/user/0/io.virtualhook/virtual/data/app/com.google.android.gms/lib
VEnvironment.getRoot()返回值:
/data/user/0/io.virtualhook/virtual/data/
Android 7.0下path(package安装路径)等于
/data/app/packagename-1/base.apk