android - native 代码会导致 Android 中的 Java 代码发生内存损坏吗?

标签 android android-ndk dalvik memory-corruption

在 Android 中,当我们通过 JNI 调用 native 代码时,它会破坏 Dalvik VM 以及在其中运行的 Java 代码吗?

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

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

如果 VM 仅加载 .so 文件并且 native 代码在与 VM 相同的上下文/地址空间 中运行,那么我认为 VM 可能已损坏。

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

最佳答案

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

就同一进程的 native 代码和 VM 托管代码之间存在隔离而言,仅仅是有用安全修改实现数据所需的信息structures 在某些 JNI 支持调用下仅在有限的程度上可用 - 但如果您的 native 代码这样做,它就会全部暴露给蒙住眼睛的戳戳。当然,您的代码也有可能通过尝试非法访问本身而使进程崩溃。根据 VM 实现的细节,应用程序的某些“代码”很可能位于只读内存页面中,尝试写入这些页面会导致内存保护错误。但是,数据和任何“即时编译”的 JIT 代码大概都位于可写页面中。恶意代码可以更改保护设置,必要时将只读文件支持的映射交换为具有相同内容的可写匿名页面。

可以在不同的进程中运行 Android 应用程序的组件,但是它将有自己的 VM 包装您在那里使用的任何 JNI 代码 - 像 Activity 和 Service 这样的类基本上是 Java 级别的,即使您使用普通的 JNI 胶水在 native 版本中完成工作的 Java 代码。例如,某些 Web 浏览器应用程序可能会这样做,以对其 javascript 解释器引擎进行更多隔离。

也有可能(迄今为止)启动一个独立的纯原生进程并通过 IPC 与其通信,但是不鼓励这样做,因为它缺少由 Android 管理的生命周期 Hook ,并且有一些棘手的问题它的一部分你必须自己完成。此外,这样的程序不能使用大多数 Java 定义的 Android 平台 API,或者至少不能以可移植的方式使用。从历史上看,人们主要是在被黑客攻击的设备上使用“su”root shim 来启动以 super 用户身份运行的辅助进程时,或者偶尔作为一种途径来移植复杂的 Linux 风格的工具,而无需将其重新构建为JNI 库。

关于android - native 代码会导致 Android 中的 Java 代码发生内存损坏吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29970143/

相关文章:

android - 如何解决 Dalvik 编译器对 64K 方法的限制问题?

javascript - onRequestPermissionsResult 没有扩展

java - 如何在阿拉伯语言环境中以简单日期格式解析日期?

android - 如何实现注销功能

java - TextView 阻止底部导航

java - Android AudioRecord 强制另一个流到 MIC 音频源

android - 没有与请求的版本匹配的 NDK 版本

android - arm-linux-androideabi-strip 无法重命名

android - 在 Android 中使用 org.apache.poi.ss.examples.html.ToHtml.create(...) 会崩溃

android - 通过 ADB 的 JDWP VS 通过 DDMS 的 JDWP