原生代码会导致Android中Java代码内存损坏吗



在Android中,当我们通过JNI调用本机代码时,它会损坏Dalvik VM及其内部运行的Java代码吗?

例如,假设我们有这个C方法,并通过JNI:调用它

JNIEXPORT void JNICALL Java_MemoryCorruptor_corruptMemory()
{
while (1) {
char *p = randomAddress();
*p = randomChar();
}
}

如果虚拟机只是加载.so文件,并且本机代码与虚拟机在相同的上下文/地址空间中运行,那么我认为虚拟机可能会损坏。

另一方面,如果VM创建一个子进程来保存.so文件,并使用某种形式的IPC来调用方法,那么Java代码就不会被本机代码损坏。

本机代码与通过JNI与之交互的Java代码在同一进程中运行,因此,是的,它非常能够破坏关键数据结构。大多数情况下,您可能会将其视为实现VM本身的库中的崩溃,在行为不端的本机代码返回后不久,但理论上另一个线程可能会错误操作。

在某种程度上,同一进程的本机代码和虚拟机托管代码之间存在隔离,这只是有效安全修改实现数据结构所需的信息在某些JNI支持调用下只能在有限的程度上使用,但如果您的本机码这样做,则所有信息都会被蒙住眼睛戳。当然,您的代码也有可能通过尝试非法访问本身而使进程崩溃。根据虚拟机实现的细节,应用程序的一些"代码"很可能在只读内存页中,尝试写入这些页面会导致内存保护故障。然而,数据和任何JIT"动态编译"的代码可能都在可写的页面中。主动恶意代码可以更改保护设置,在必要时将只读文件支持的映射交换为具有相同内容的可写匿名页。

在一个不同的过程中运行Android应用程序的组件是可能的,但它将有自己的VM来包装你在那里使用的任何JNI代码——像Activity和Service这样的类基本上是Java级别的,即使你在本机版本中使用普通的JNI粘合Java代码来完成这项工作。例如,一些网络浏览器应用程序可能会这样做,以使其javascript解释器引擎更加孤立。

(到目前为止)也可以启动一个独立的纯原生进程,并通过IPC与之对话,但这是不鼓励的,因为它将缺乏Android管理的生命周期挂钩,而且其中有一些棘手的部分你必须自己完成。此外,这样的程序不能使用大多数Java定义的Android平台API,或者至少不能以可移植的方式使用。从历史上看,人们主要是在被黑客入侵的设备上使用"su"根填充程序来启动作为超级用户运行的辅助进程时,或者偶尔作为移植复杂Linux风格工具的途径,而不将其重新构建为JNI库。

相关内容

  • 没有找到相关文章

最新更新