Beachten Sie, dass ich den regulären mprotect aufgrund von Strace nicht wirklich verstanden habe
mprotect (2) ist ein Systemaufruf, der die Speicherbereichsberechtigungen steuert.
#include <sys/mman.h>
int mprotect(const void *addr, size_t len, int prot);
Übergeben Sie den Zeiger, die Größe und die logische Summe der Bits.
Derzeit können Schutzbits kombiniert werden, indem das folgende ODER verwendet wird
Flaggenname | Überblick |
---|---|
PROT_NONE | Überhaupt kein Schutz |
PROT_READ | Seite ist lesbar |
PROT_WRITE | Seite ist beschreibbar |
PROT_EXEC | Seite ist ausführbar |
Bei Erfolg gibt mprotect () 0 zurück. Im Fehlerfall wird -1 zurückgegeben und errno entsprechend eingestellt.
errno | Überblick |
---|---|
EACCES | Der angegebene Zugriff auf den Speicher kann nicht festgelegt werden |
EINVAL | addr ist kein gültiger Zeiger oder ein Vielfaches der Systemseitengröße |
ENOMEM | Struktur im Kernel konnte nicht zugeordnet werden |
ENOMEM | [addr, addr+len-1]Die Adresse im Bereich ist ungültig, da der Adressraum des Prozesses oder die Adresse im Bereich auf eine oder mehrere Seiten verweist, die nicht zugeordnet sind. |
Ein Beispielprogramm, das SIGSEGV generiert, indem es in den Speicher im Bereich READ_ONLY schreibt.
SIGSEGV selbst führt die mit Sigaction behandelte Verarbeitung aus.
mprotect.c
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/mman.h>
#define handle_error(msg) \
do { perror(msg); exit(EXIT_FAILURE); } while (0)
static char *buffer;
static void handler(int sig, siginfo_t *si, void *unused)
{
printf("Got SIGSEGV at address: 0x%lx\n",
(long) si->si_addr);
exit(EXIT_FAILURE);
}
int main(int argc, char **argv)
{
char *p;
int pagesize;
//Änderungen im Signalverhalten
struct sigaction sa;
sa.sa_flags = SA_SIGINFO;
sigemptyset(&sa.sa_mask);
sa.sa_sigaction = handler;
if (sigaction(SIGSEGV, &sa, NULL) == -1)
handle_error("sigaction");
pagesize = sysconf(_SC_PAGE_SIZE);
if (pagesize == -1)
handle_error("sysconf");
//Ordnen Sie den ausgerichteten Speicher zu
buffer = memalign(pagesize, 4 * pagesize);
if (buffer == NULL)
handle_error("memalign");
printf("Start of region: 0x%lx\n", (long) buffer);
//Steuern Sie die Speicherbereichsberechtigungen
if (mprotect(buffer + pagesize * 2, pagesize, PROT_READ) == -1)
handle_error("mprotect");
for (p = buffer ; ; )
*(p++) = 'a';
printf("Loop completed\n"); /* Should never happen */
exit(EXIT_SUCCESS);
}
Recommended Posts