-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathget_ldt.c
90 lines (72 loc) · 1.61 KB
/
get_ldt.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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#define _DEFAULT_SOURCE
#include <sys/types.h>
#include <asm/ldt.h>
#include <stdio.h>
#include <syscall.h>
#include <unistd.h>
#include <stdint.h>
#include <err.h>
#define SEGMENTS X(cs) X(ds) X(es) X(fs) X(gs) X(ss)
#define GET(X) uint16_t get_##X(void); \
__asm__(".global get_" #X "\n" \
"get_" #X ":\n\t" \
"movw %" #X ", %ax\n\t" \
"ret\n")
#define SET(X) void set_##X(uint16_t eax) { \
__asm__ volatile("mov %[ax], %%" #X "\n" : : [ax] "r"(eax)); \
}
#define X(S) GET(S); SET(S);
SEGMENTS
#undef X
#define LDT_ENTRIES 8192
static int modify_ldt(int func, struct user_desc* ptr, unsigned long count) {
return syscall(SYS_modify_ldt, func, ptr, count);
}
static void dump_ldt(void) {
struct user_desc arr[LDT_ENTRIES];
int ret = modify_ldt(0, arr, sizeof(arr));
#if 1
for (size_t i = 0; i < ret / sizeof(struct user_desc); i++) {
printf("[%d] = { %d }\n", i, arr[i].base_addr);
}
#endif
}
union selector {
uint16_t n;
struct {
uint16_t rpl:2;
uint16_t ti:1;
uint16_t index:13;
};
};
int main(void) {
dump_ldt();
#include <string.h>
for (int i = 3; i < 24; i++) {
struct user_desc entry;
memset(&entry, -1, sizeof(entry));
entry.entry_number = i;
entry.contents = 0;
#if 1
if (modify_ldt(1, &entry, sizeof(entry)) < 0)
err(1, "modify_ldt");
#endif
}
//GDT_ENTRY_INIT(0xc0f3, 0, 0xfffff),
struct user_desc entry = {
.entry_number = 1,
.base_addr = 2,
.limit = 0xfffff,
.seg_32bit = 1,
.contents = 1,
};
if (modify_ldt(1, &entry, sizeof(entry)) < 0)
err(1, "modify_ldt");
union selector a = {
.rpl = 3,
.ti = 1,
.index = 1,
};
set_ds(a.n);
//dump_ldt();
}