Previous Entry Share Next Entry
"Небезопасная" Java
Белка
lerm_ru
Оказывается, в Java вполне можно использовать прямой доступ к памяти, выделение/высвобождение памяти и адресную арифметику. Вот так - живешь, живешь, а потом как грянет... Случайно встретил упоминание о такой возможности, не поверил - полез проверять. Таки оказалось да, можно такие извращения на Java делать, по крайне мере, в реализации JDK от Sun. Привычный мир пошатнулся... Нет, понятно, что это всегда можно было сделать, написав свою нативную библиотеку. Но вот так, в стандартной поставке... Душевно.

import sun.misc.Unsafe;
import java.lang.reflect.Field;

public class Test
{
    public static Unsafe getUnsafe()
    {
        try
        {
            Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe");
            boolean acc=unsafeField.isAccessible();
            unsafeField.setAccessible(true);
            Unsafe unsafe = (Unsafe) unsafeField.get(null);
            unsafeField.setAccessible(acc);
            return unsafe;
        } catch (NoSuchFieldException e)
        {
            e.printStackTrace();
        } catch (IllegalAccessException e)
        {
            e.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args)
    {
        Unsafe unsafe = getUnsafe();
        if (unsafe!=null)
        {
            // Выделяем память и получаем указатели
            long mem = unsafe.allocateMemory(100); // 100 байт
            long mem2 = unsafe.allocateMemory(200); // 200 байт
            System.out.println("mem="+mem);
            System.out.println("mem2="+mem2);

            // Пишем и читаем
            unsafe.putInt(mem,1);
            System.out.println("vl="+unsafe.getInt(mem));

            // Пишем последовательно два числа, а затем считываем
            // "между" ними (адресная арифметика)
            // Так пишем:  | 00 00 FF 00 | 00 00 00 00 |
            // Так читаем: 00 00 | FF 00 00 00 | 00 00
            unsafe.putInt(mem2+4,0x00FF0000);
            unsafe.putInt(mem2+8,0);
            System.out.println("v2="+unsafe.getInt(mem2+6));

            // Освобождаем память
            unsafe.freeMemory(mem);
            unsafe.freeMemory(mem2);

            // Считываем значение из объекта по смещению
            try
            {
                Integer testI=new Integer(2);
                // Получаем смещение поля внутри объекта
                Field valueField = Integer.class.getDeclaredField("value");
                long valueOffset = unsafe.objectFieldOffset(valueField);
                System.out.println("Value offset: "+valueOffset);
                // Читаем...
                System.out.println("Test: "+unsafe.getInt(testI,valueOffset));
            } catch (NoSuchFieldException e)
            {
                e.printStackTrace();
            }
        }
    }
}

Tags:

  • 1
Интересно, а сам пакет sun.misc поставляется с открытыми исходниками? :)

  • 1
?

Log in

No account? Create an account