forked from AntonKozlov/os226-2022
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathkernel.c
45 lines (34 loc) · 869 Bytes
/
kernel.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#define _GNU_SOURCE
#include "syscall.h"
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <ucontext.h>
#include <sys/ucontext.h>
extern int shell(int argc, char *argv[]);
static void sighnd(int sig, siginfo_t *info, void *ctx) {
ucontext_t *uc = (ucontext_t *) ctx;
greg_t *regs = uc->uc_mcontext.gregs;
uint16_t insn = *(uint16_t*)regs[REG_RIP];
if (insn != 0x81cd) {
abort();
}
regs[REG_RAX] = syscall_do(regs[REG_RAX], regs[REG_RBX],
regs[REG_RCX], regs[REG_RDX],
regs[REG_RSI], (void *) regs[REG_RDI]);
regs[REG_RIP] += 2;
}
int main(int argc, char *argv[]) {
struct sigaction act = {
.sa_sigaction = sighnd,
.sa_flags = SA_RESTART,
};
sigemptyset(&act.sa_mask);
if (-1 == sigaction(SIGSEGV, &act, NULL)) {
perror("signal set failed");
return 1;
}
shell(0, NULL);
}