2016-04-15 4 views
1

Я пытаюсь оживить процесс от дампа ядра после SIGQUIT. Я действительно хочу эту часть виртуальной памяти, но я получаю SIGSEGV, когда пытаюсь ее сопоставить.SIGSEGV, после mmapping area

EDIT: Эта область не является бесплатной: 0xf75d2000 - 0xf7774000, но все же я хочу ее иметь. enter image description here

#define _GNU_SOURCE 
#include <stdio.h> 
#include <stdlib.h> 
#include <sys/mman.h> 
#include <string.h> 
#include <stdbool.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <errno.h> 
#include <sys/types.h> 
#include <unistd.h> 
#include <fcntl.h> 
#include <stdlib.h> 
#include <ucontext.h> 
#include <elf.h> 
#include <sys/procfs.h> 
#include <sys/user.h> 
#include <linux/unistd.h> 
#include <linux/unistd.h> 
#include <asm/ldt.h> 
#include <signal.h> 
bool flag = false; 
int argc2; 
char ** argv2; 
int main2(){ 
    FILE * file = fopen("/proc/self/maps", "r"); 
    if (file) { 
     char c; 
     while ((c = getc(file)) != EOF) 
     putchar(c); 
     fclose(file); 
    } 
    fflush(stdout); 
    void* res = mmap((void*)(0xf75d2000), 0x001a5000, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS, -1, 0); 
    return 0; 
} 
int main(int argc, char ** argv){ 
    argc2 = argc; 
    argv2 = argv; 
    ucontext_t cont; 
    getcontext (&cont); 
    if(!flag){ 
     void* a = mmap((void*)0x34B000, 81920, PROT_EXEC | PROT_WRITE | PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0); 
     if(a == MAP_FAILED){ 
     printf("mmapfail"); 
     return 1; 
     } 
     cont.uc_mcontext.gregs[REG_ESP] = 0x355000; 
     flag = true; 
     setcontext(&cont); 
    } else{ 
     exit(main2()); 
    } 
} 

Я компиляции с:

gcc -static -Wl,-Ttext=0x4A9480,--build-idone,-Tdata=0x639480,--section-start=.plt=0x3B9480,--section-start=.rel.plt=0x3AF480,--section-start=.note.ABI-tag=0x39B480 main.c -o main -m32 

ответ

0

Конечно, вы получите SEGV. Вы сопоставляете вещи с MAP_FIXED на какой-то адрес, который не принадлежит вам, затем вы вытаскиваете стек из-под ног. Ты не сможешь это сделать.

Адресное пространство не для вашего удобства. MAP_FIXED безопасен только для перезаписи ранних сопоставлений. Вы можете поиграть в нем в одном эксперименте, после чего вы выбросите программу позже, но любое другое использование просто не сработает.

Прямо сейчас ваш звонок в setcontext приведет к сбою, потому что он не знает, куда вернуться. Вы даже знаете, как взаимодействуют вызовы функций и стек? Ваш вызов setcontext сохраняет адрес возврата в стеке, а затем setcontext меняет указатель стека, затем он пытается вернуться и умирает, потому что он читает 0 в качестве обратного адреса (или setcontext может сохранить старый указатель стека в каком-либо другом регистре и восстановить его из этого регистра, прежде чем он вернется, и какие сбои - это ваш другой mmap, который перезаписывает реальный стек). Пожалуйста, не делайте этого. Ваш единственный шанс надежно изменить стеки, не являясь операционной системой, - настроить обработчик сигналов с помощью sigaltstack, поймать этот сигнал и никогда не возвращаться из обработчика сигнала.

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

+0

Это явно неправильно. Программа не сбой, вы можете, например, замените mmap на printf, и он будет работать. Вы можете распечатать esp в функции, и вы увидите, что она действительно меняет указатель стека. – JKS

1

Адрес, который вы пытаетесь сопоставить (0xf75d2000), находится выше разделов пользовательского пространства/ядра в виртуальной памяти. Если ваше ядро ​​настроено с CONFIG_VMSPLIT_3G, вы не можете сопоставить произвольные адреса выше 0xc0000000.

Существующие сопоставления были установлены в ядре, чтобы открыть пространство vDSO (чтобы помочь с системными вызовами).

+0

, что было бы правдой, если бы у меня был чистый x86, но я запускаю его на x64, неплохо попробую хотя бы – JKS

+0

Если вы компилируете с -m32, не создадите 32-битный исполняемый файл с 32-битным виртуальным адресным пространством? –

+0

это просто x86, эмулированный в x64, я могу mmap все это – JKS