Преобразование стека успешно, но позже SEGV повышен - PullRequest
0 голосов
/ 04 июля 2019

Я запустил простую программу, написанную на ассемблере, которая под strace просто выполняет SYS_exit.

_start:
    mov rax, 0x3C
    mov rdi, 0x0
    syscall

И заметил, что для стека нет ничего похожего на mmap память:

alrorp@dmspc:~$ strace ./bin 
execve("./bin", ["./bin"], 0x7ffd591eda80 /* 65 vars */) = 0
exit(0)                                 = ?
+++ exited with 0 +++

Итак, я попытался сделать mmap с MAP_FIXED для адреса, выровненного по стеку, следующим образом:

int main(void){
    int a = 1;
    void *ptr = &a;
    void *page_aligned_ptr = (void *)((intptr_t) ptr & -4096);
    mmap(page_aligned_ptr, 4096, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
}

Дело в том, что он вызывает ошибку после вызова mmap(т. е. он возвращает запрошенный адрес вместо MAP_FAILED).

mmap(0x7ffdf50db000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7ffdf50db000
--- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=NULL} ---
+++ killed by SIGSEGV (core dumped) +++
Segmentation fault

Можете ли вы дать намек на это поведение?Дамп ядра кажется (почти) бесполезным в этом случае с поврежденным стеком.

Имеет ли смысл что-то вроде создания настраиваемого отображения для стека?

1 Ответ

4 голосов
/ 04 июля 2019

Замена страницы стека, содержащей ваш адрес возврата, новой анонимной страницей с нулевым байтом, очевидно, приводит к segfault, как только возвращается main, и выдает 0 в RIP.

Обратите внимание на si_addr=NULL, IIRC это кодовый адрес, где произошла ошибка.Поэтому RIP = 0 после запуска ret с RSP, указывающим на 0.( * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 101 '*' * '' '' '') ".что само по себе ret.

Используйте отладчик для пошагового ассемблера asm, созданного для вас компилятором C.

...