Как напечатать местоположение кучи, используя java для процесса?

#java #heap-memory

#java #куча-память

Вопрос:

Я хочу проверить, действительно ли работает ASLR, который рандомизирует местоположение кучи для процесса.

Комментарии:

1. Какого рода атаке вы можете подвергнуться в Java, с которой ASLR помогла бы вам?

2. Я просто хотел знать, возможно ли различать предсказуемость ASLR и не ASLR, используя Java-код

Ответ №1:

Вы можете вызвать Unsafe.allocateMemory(size) на некоторых JVM. Это возвращает местоположение в памяти.

Я не рекомендую вам делать это, и я не рекомендую вам беспокоиться об ASLR с Java.

Комментарии:

1. Следует отметить, что Unsafe обычно sun.misc.Unsafe это класс, специфичный для JVM. Это определенно не стандартный API 😉

2. Не вызовет ли Unsafe.getUnsafe() исключение SecurityException, если оно вызвано не из класса из загрузчика классов bootstrap?

3. @Paul Cager, вы не можете использовать getUnsafe() для получения экземпляра Unsafe Я полагаю, если вы не можете решить, как получить экземпляр другим способом, вам не следует использовать Unsafe . 😉

Ответ №2:

Вы не можете сделать это на чистой Java.

  • Машинный адрес (указатели) не предоставляется приложениям Java.

  • Даже если бы они это сделали, нет Java API, который сообщал бы вам, где находится куча.

Я полагаю, что вы могли бы использовать значения, возвращаемые System.identityHashcode() в качестве эрзац-адресов компьютеров. Если вы написали простое тестовое приложение Java, которое проверяло хэш-код идентификатора образца объекта, затем запускало его несколько раз с включенным и отключенным ASLR, вы могли бы заметить разницу в предсказуемости.

Комментарии:

1. В настоящее время тестируется с System.identityHashCode () Может быть, я могу запустить это в Vista и Windows 7 и сравнить предсказуемость ASLR? Я думаю, что ASLR лучше реализован в Windows 7

Ответ №3:

Вы должны быть в состоянии сделать это с помощью JNI. Выделите массив длинных файлов размером с вашу кучу или чуть меньше и вызовите тестовый метод 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, amp;jniNoCopy);
  heapp[0] = (jlong)heapp;
  (*env)->ReleaseLongArrayElements(env,heapa,heapp,0);
}
  

Когда этот код возвращается, первый элемент массива должен содержать адрес массива.

Имеет ли смысл это делать — другой вопрос. Зависит от того, что вы делаете. Я предполагаю, что, вероятно, нет, но это ваше решение.