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
144
145
146
147
|
.intel_syntax noprefix
.global outsw
.global outb
.global outw
.global outl
.global inb
.global inw
.global inl
.global rep_outsw
.global rep_insw
.global flush_tss
.global load_idtr
# ebx, esi, edi, ebp, and esp;
outsw:
push ebp
mov ebp, esp
push esi
mov dx, [ebp + 4+4]
mov esi, [ebp + 8+4]
outsw
pop esi
mov esp, ebp
pop ebp
ret
outl:
mov eax, [esp + 8]
mov dx, [esp + 4]
out dx, eax
ret
outb:
mov al, [esp + 8]
mov dx, [esp + 4]
out dx, al
ret
outw:
mov ax, [esp + 8]
mov dx, [esp + 4]
out dx, ax
ret
inl:
mov dx, [esp + 4]
in eax, dx
ret
inw:
mov dx, [esp + 4]
in ax, dx
ret
inb:
mov dx, [esp + 4]
in al, dx
ret
rep_outsw:
push ebp
mov ebp, esp
push edi
mov ecx, [ebp + 4+4] #ECX is counter for OUTSW
mov edx, [ebp + 8+4] #Data port, in and out
mov edi, [ebp + 12+4] #Memory area
rep outsw #in to [RDI]
pop edi
mov esp, ebp
pop ebp
ret
rep_insw:
push ebp
mov ebp, esp
push edi
mov ecx, [ebp + 4+4] #ECX is counter for INSW
mov edx, [ebp + 8+4] #Data port, in and out
mov edi, [ebp + 12+4] #Memory area
rep insw #in to [RDI]
pop edi
mov esp, ebp
pop ebp
ret
flush_tss:
mov ax, 40
ltr ax
ret
load_idtr:
mov edx, [esp + 4]
lidt [edx]
ret
test_user_function:
mov eax, 0x00
int 0x80
mov ecx, 0x03
mov ebx, 0x04
mov eax, 0x02
int 0x80
mov ebx, eax
mov eax, 0x01
int 0x80
loop:
jmp loop
ret
.global spin_lock
.global spin_unlock
.extern locked
spin_lock:
mov eax, 1
xchg eax, ebx
test eax, eax
jnz spin_lock
ret
spin_unlock:
xor eax, eax
xchg eax, ebx
ret
.global jump_usermode
jump_usermode:
mov ax, (4 * 8) | 3 # user data segment with RPL 3
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax # sysexit sets SS
# setup wrmsr inputs
xor edx, edx # not necessary; set to 0
mov eax, 0x100008 # SS=0x10+0x10=0x20, CS=0x8+0x10=0x18
mov ecx, 0x174 # MSR specifier: IA32_SYSENTER_CS
wrmsr # set sysexit segments
# setup sysexit inputs
mov edx, [esp + 4] # to be loaded into EIP
mov ecx, [esp + 8] # to be loaded into ESP
mov esp, ecx
mov ebp, ecx
sti
sysexit
|