Как выполнить код из кучи [дубликат]

Исключение нулевого указателя - это индикатор того, что вы используете объект, не инициализируя его.

Например, ниже - класс ученика, который будет использовать его в нашем коде.

public class Student {

    private int id;

    public int getId() {
        return this.id;
    }

    public setId(int newId) {
        this.id = newId;
    }
}

Приведенный ниже код дает вам исключение с нулевым указателем.

public class School {

    Student obj_Student;

    public School() {
        try {
            obj_Student.getId();
        }
        catch(Exception e) {
            System.out.println("Null Pointer ");
        }
    }
}

Поскольку вы используете Obj_Student, но вы забыли инициализировать его, как в правильном коде, показанном ниже:

public class School {

    Student obj_Student;

    public School() {
        try {
            obj_Student = new Student();
            obj_Student.setId(12);
            obj_Student.getId();
        }
        catch(Exception e) {
            System.out.println("Null Pointer ");
        }
    }
}
5
задан merlin2011 24 April 2014 в 19:03
поделиться

2 ответа

Реальное «неожиданное» поведение заключается в том, что установка флага делает исполняемый файл heap , а также стек. Флаг предназначен для использования с исполняемыми файлами, которые генерируют thunks на основе стека (например, gcc, когда вы берете адрес вложенной функции) и не должны влиять на кучу. Но Linux реализует это глобально, делая ВСЕ читаемые страницы исполняемыми.

Если вы хотите более тонкий элемент управления, вместо этого вы можете использовать системный вызов mprotect для управления исполняемыми разрешениями для каждой страницы - Добавить код:

uintptr_t pagesize = sysconf(_SC_PAGE_SIZE);
#define PAGE_START(P) ((uintptr_t)(P) & ~(pagesize-1))
#define PAGE_END(P)   (((uintptr_t)(P) + pagesize - 1) & ~(pagesize-1))
mprotect((void *)PAGE_START(shellcode), PAGE_END(shellcode+67) - PAGE_START(shellcode),
         PROT_READ|PROT_WRITE|PROT_EXEC);
4
ответ дан Chris Dodd 20 August 2018 в 09:19
поделиться

Является ли это ожидаемым поведением?

Глядя на код ядра Linux, я думаю, что внутреннее имя ядра для этого флага «read подразумевает exec». Итак, да, я думаю, что это ожидается.

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

Зачем вам нужна полная куча для выполнения? Если вам действительно нужно динамически генерировать машинный код и запускать его или так, вы можете явно выделить исполняемую память с помощью mmap syscall.

, что является обоснованием?

Я думаю, что идея состоит в том, что этот флаг можно использовать для устаревших программ, которые ожидают, что все, что доступно для чтения, также является исполняемым. Эти программы могут пытаться запустить материал в стеке, и они могут попытаться запустить материал в куче, поэтому все это разрешено.

4
ответ дан thejh 20 August 2018 в 09:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: