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
|
bits 64
global start_user_mode
section .text
extern do_syscall
syscall_entry:
mov r11, rsp
mov rsp, 0xfffffffffffff000
push r11
push rcx
push rdx
push rsi
push rdi
push rax
mov rdi, rsp
lea rsi, [rsp + 8]
lea rdx, [rsp + 16]
lea rcx, [rsp + 24]
call do_syscall
pop rax
pop rdi
pop rsi
pop rdx
xor r8, r8
xor r9, r9
xor r10, r10
xor r11, r11
or r11, 0x200
pop rcx
pop rsp
o64 sysret
start_user_mode:
;intended rip in rdi
;intended rsp in rsi
;intended p4_paddr in rdx
mov rax, rdx
mov cr3, rax
;efer <- efer | 0x1
mov rcx, 0xc0000080
rdmsr
or al, 1
wrmsr
;lstar <- syscall_entry
mov rdx, syscall_entry
mov eax, edx
shr rdx, 32
mov ecx, 0xc0000082
wrmsr
;star <- 0x0030.0028.0000.0000
mov edx, 0x00300028
xor eax, eax
mov ecx, 0xc0000081
wrmsr
mov rcx, rdi
mov rsp, rsi
xor r11, r11
or r11, 0x200
xor rax, rax
xor rbx, rbx
xor rdx, rdx
xor rdi, rdi
xor rsi, rsi
xor rbp, rbp
xor r8, r8
xor r9, r9
xor r10, r10
xor r12, r12
xor r13, r13
xor r14, r14
xor r15, r15
o64 sysret
|