Segfault при запуске функции в куче с разрешениями на исполняемый файлLinux

Ответить
Anonymous
 Segfault при запуске функции в куче с разрешениями на исполняемый файл

Сообщение Anonymous »

Насколько я понимаю, указатели функций после компиляции программы указывают на место в сегменте .text структуры процесса, где сохраняется скомпилированный байт-код. Я экспериментировал с некоторым кодом, который считывает байт-код до 0xC3, инструкции возврата в моей архитектуре, в память кучи, изменяет разрешения через mprotect, чтобы они были исполняемыми, а затем вызывает байт-код в куче, как если бы это была функция. Байт-код в обоих указателях абсолютно одинаков, но при запуске второго указателя как функции я все равно получаю ошибку сегментации. Это мой код:

Код: Выделить всё

#include 
#include 
#include 
#include 
#include 
#include 

void a() {
printf("a");
}

int main() {
char * heap_pointer;
char * func_pointer;
int ret;
int pagesize;
int c;

func_pointer = (char *) a;
pagesize = sysconf(_SC_PAGE_SIZE);
heap_pointer = aligned_alloc(pagesize, pagesize); //alligned memory allocation

c = 0;
while(func_pointer[c] != (char)0xc3) {      //copying the instructions from one pointer to the other
heap_pointer[c] = func_pointer[c];
c++;
}
heap_pointer[c] = (char)0xc3;

mprotect(heap_pointer, pagesize, PROT_WRITE | PROT_READ | PROT_EXEC);   //allowing execution

(*(void (*)())(func_pointer))();
(*(void (*)())(heap_pointer))();

mprotect(heap_pointer, pagesize, PROT_READ);
return 0;

}
Хотя, как отметил Андреас, проверка 0xc3 не является хорошим способом проверки выхода из функции, в этом случае все должно быть в порядке, поскольку objdump функции a не содержит никаких других байтов 0xc3, а также заканчивается оператором return. Это точный objdump:

Код: Выделить всё

00000000000011a9 :
11a9:   f3 0f 1e fa             endbr64
11ad:   55                      push   %rbp
11ae:   48 89 e5                mov    %rsp,%rbp
11b1:   bf 61 00 00 00          mov    $0x61,%edi
11b6:   e8 c5 fe ff ff          call   1080
11bb:   90                      nop
11bc:   5d                      pop    %rbp
11bd:   c3                      ret
Запуск через gdb показывает, что mprotect вернул 0, размер страницы — 4096, и все выделения вернули действительный указатель. Я использую компилятор gcc без каких-либо флагов на машине с Ubuntu.


Подробнее здесь: https://stackoverflow.com/questions/798 ... ermissions
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Linux»