【问题标题】:How to print the location of Heap using java for a process?如何使用java为进程打印堆的位置?
【发布时间】:2011-08-14 17:57:08
【问题描述】:

我想测试为进程随机分配堆位置的 ASLR 是否真的有效。

【问题讨论】:

  • 你可以在 Java 中获得什么样的攻击,ASLR 可以帮助你?
  • 我只是想知道是否可以使用 java 代码区分 ASLR 和非 ASLR 可预测性

标签: java heap-memory


【解决方案1】:

你不能在纯 Java 中做到这一点。

  • 机器地址(指针)不会暴露给 Java 应用程序。

  • 即使他们这样做了,也没有 Java API 可以告诉您堆是什么。

我想您可以使用 System.identityHashcode() 返回的值作为 ersatz 机器地址。如果您编写了一个简单的 Java 测试应用程序来检查示例对象的身份哈希码,然后在启用和禁用 ASLR 的情况下多次运行它,您可能会观察到可预测性的差异。

【讨论】:

  • 目前正在使用 System.identityHashcode() 进行测试 也许我可以在 Vista 和 Windows 7 上运行它并比较 ASLR 的可预测性?我认为 ASLR 在 Windows 7 中实现得更好
【解决方案2】:

您可以在某些 JVM 上调用 Unsafe.allocateMemory(size)。这会返回一个内存位置。

我不建议你这样做,也不建议你担心 Java 的 ASLR。

【讨论】:

  • 需要注意的是Unsafe通常是sun.misc.Unsafe,是JVM特有的类。这绝对不是标准 API ;-)
  • 如果 Unsafe.getUnsafe() 不是从引导类加载器的类中调用,它不会抛出 SecurityException 吗?
  • @Paul Cager,你不能使用getUnsafe() 来获取Unsafe 的实例我想如果你不知道如何以另一种方式获取实例,你不应该使用Unsafe。 ;)
【解决方案3】:

您应该能够使用 JNI 做到这一点。分配一个堆大小或更小的 long 数组,然后调用 JNI 测试方法。

package com.example.aslrtest;

public class Test {
    private static native void test(long[] heapa);

    public void doTest()
    {
        long[] a=new long[size_of_available_heap/8];
        for (long i=0; i!=a.length; i++)
            a[i]=i;
        test(a);
        System.out.println(a[0]);
    }
}

然后使用类似这样的 JNI 代码,您可以获得该数组的地址。

JNIEXPORT void JNICALL Java_com_example_aslrtest_Test_test(JNIEnv * env, jclass jc, jlongArray heapa)
{
  jlong* heapp;
  jboolean jniNoCopy = JNI_FALSE;
  heapp = (*env)->GetLongArrayElements(env, heapa, &jniNoCopy);
  heapp[0] = (jlong)heapp;
  (*env)->ReleaseLongArrayElements(env,heapa,heapp,0);
}

当这段代码返回时,数组的第一个元素应该包含数组的地址。

这样做是否有意义是另一个问题。取决于你在做什么。我猜可能不会,但这是你的决定。

【讨论】:

    猜你喜欢
    • 2017-04-03
    • 2022-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-25
    • 1970-01-01
    相关资源
    最近更新 更多