-
-
[原创]Android应用进程fork出来的子进程能运行虚拟机吗?
-
发表于:
2019-10-18 15:38
5977
-
[原创]Android应用进程fork出来的子进程能运行虚拟机吗?
今天(几个月前)有人问了这个问题,需求还有些奇葩,想在fork出来的子进程中去运行一部分动态下发的代码,而且不知道动态下发的代码的具体内容,有可能导致崩溃,所以想在子进程中执行。
这里不从系统源码和安全上分析,就从写出实现代码,执行,根据异常信息去分析。
我们写过双进程反调试,知道fork应用进程去执行是没有问题的,jni调用生成一个字符串之类的也没问题。但是一般的反调试代码都是一个死循环,阻塞了子进程,并没有继续去往下执行。而如果你放开循环,比如以下代码:
定义了一个jni函数,fork自身并返回一个字符串,通过点击事件触发调用。
执行后,通过日志发现两个进程都执行了,子进程也返回了字符串打印了,但是接下来就异常了。
这个异常可以通过分析函数调用逐步定位,或者分析过looper实现的应该看到looper的那条日志有印象:
http://androidxref.com/4.4_r1/xref/frameworks/base/core/java/android/os/Looper.java
因为ident != newIdent,所以触发异常,调用Log.wtf,http://androidxref.com/4.4_r1/xref/frameworks/base/core/java/android/util/Log.java#255
这是这个流程,但是异常还不是在这里,但我们也能看出关系了,当远程调用调用binder并调用进程内部的接口的时候我们调用clearCallingIdentity清除并保存一个long类型的值,执行完再调用restoreCallingIdentity还原。http://androidxref.com/4.4_r1/xref/frameworks/native/libs/binder/IPCThreadState.cpp#375
返回long类型其实就是uid和pid,父进程pid=27638=0x6BF6,子进程pid=28273=0x6E71,结合日志发现就是因为进程pid变了,触发这条日志。
而真实产生异常的函数为readAligned, http://androidxref.com/4.4_r1/xref/frameworks/native/libs/binder/Parcel.cpp#911
执行到*pArg = *reinterpret_cast<const T*>(data);时出错,内存
。。。草稿箱发现未发表,但是后面的部分丢失了,懒得再追代码再写了,直接说结论,如果不阻塞肯定会崩溃的,如果阻塞,确认调用的代码不会触发到binder的执行,也可以运行。
补充:凭记忆大概是zygote fork完成后,新进程中执行onZygoteInit(),启动binder线程池。
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课