-
Notifications
You must be signed in to change notification settings - Fork 115
/
linux_kernel_x64.asm
143 lines (122 loc) · 2.12 KB
/
linux_kernel_x64.asm
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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
bits 64
%define ARCH_SET_GS 0x1001
%define ARCH_SET_FS 0x1002
%define ARCH_GET_FS 0x1003
%define ARCH_GET_GS 0x1004
%define IA32_EFER 0xc0000080
%define IA32_STAR 0xc0000081
%define IA32_LSTAR 0xc0000082
%define IA32_FS_BASE 0xc0000100
%define IA32_GS_BASE 0xc0000101
%define EINVAL 22
SYSCALL_MAX equ 325+1
times 0xc00 db 0
ENTRY:
mov rax, 0x4141414141414141 ; replace with desired fs_base
call set_fs_base
; setup syscall handler address
lea rax, [rel syscall_handler]
call set_lstar
; setup sysret and syscall segments
mov rax, 0x230010 << 32
call set_star
xor rax, rax
xor rdx, rdx
xor rcx, rcx
iretq
set_fs_base:
mov ecx, IA32_FS_BASE
call do_wrmsr
ret
get_fs_base:
mov ecx, IA32_FS_BASE
call do_rdmsr
shl rax, 32
shrd rax, rdx, 32
ret
set_gs_base:
mov ecx, IA32_GS_BASE
call do_wrmsr
ret
get_gs_base:
mov ecx, IA32_GS_BASE
call do_rdmsr
shl rax, 32
shrd rax, rdx, 32
ret
do_wrmsr:
mov rdx, rax
shr rdx, 32
wrmsr
ret
do_rdmsr:
rdmsr
ret
set_star:
mov ecx, IA32_STAR
call do_wrmsr
ret
set_lstar: ; syscall addr:
mov ecx, IA32_LSTAR
call do_wrmsr
ret
syscall_handler:
mov [rel kstack + 0x1000 - 8], rsp
lea rsp, [rel kstack + 0x1000 - 8]
push rcx
push r11
push rdi
push rsi
push rdx
push r10
push r8
push r9
prctl:
cmp eax, 158 ; arch_prctl
jnz others
cmp edi, ARCH_SET_FS
jnz get_fs
mov rax, rsi
call set_fs_base
jmp success
get_fs:
cmp edi, ARCH_GET_FS
jnz set_gs
call get_fs_base
mov [rsi], rax
jmp success
set_gs:
cmp edi, ARCH_SET_GS
jnz get_gs
mov rax, rsi
call set_gs_base
jmp success
get_gs:
cmp edi, ARCH_GET_GS
jnz einval
call get_gs_base
mov [rsi], rax
jmp success
einval:
mov eax, EINVAL
neg rax
jmp doret
success:
xor rax, rax
jmp doret
others:
; break here and handle all syscalls via conditional break
nop
doret:
pop r9
pop r8
pop r10
pop rdx
pop rsi
pop rdi
pop r11
pop rcx
pop rsp
o64 sysret ; force 64-bit operad size
align 0x1000
kstack: