2023-01-31 21:26:43 -06:00
|
|
|
global flushTSS
|
|
|
|
flushTSS:
|
|
|
|
mov ax, 0x28
|
|
|
|
ltr ax
|
|
|
|
ret
|
|
|
|
|
2023-02-02 00:50:16 -06:00
|
|
|
global task_ptr
|
2024-01-07 22:33:27 -06:00
|
|
|
task_ptr: equ (0x310000)
|
2022-09-19 16:06:01 -05:00
|
|
|
|
2023-02-06 03:55:13 -06:00
|
|
|
; extern void create_child(uint32_t esp, uint32_t eip, uint32_t argc, ...);
|
2023-02-06 03:07:15 -06:00
|
|
|
global create_child
|
|
|
|
create_child:
|
|
|
|
mov eax, [esp] ; return address
|
|
|
|
lea ecx, [esp+4] ; return stack, minus address
|
|
|
|
call save_current_task
|
|
|
|
mov eax, [esp+8] ; new eip
|
2023-02-06 03:55:13 -06:00
|
|
|
mov ecx, [esp+12] ; argc
|
|
|
|
mov esi, esp ; old esp
|
2023-02-06 03:07:15 -06:00
|
|
|
mov esp, [esp+4] ; new esp
|
2023-02-06 03:55:13 -06:00
|
|
|
lea esi, [esi+16] ; args
|
|
|
|
mov edx, ecx
|
|
|
|
neg edx
|
|
|
|
lea esp, [esp+edx*4] ; adjust for args
|
|
|
|
mov edi, esp
|
|
|
|
; copy varargs to new stack
|
|
|
|
rep movsd
|
2023-02-06 03:07:15 -06:00
|
|
|
push return_prev_task ; if child returns, return to prev task
|
|
|
|
push eax
|
|
|
|
ret
|
|
|
|
|
2023-02-06 05:49:03 -06:00
|
|
|
; extern void create_user_child(uint32_t esp, uint32_t eip, uint32_t argc, ...);
|
|
|
|
global create_user_child
|
|
|
|
create_user_child:
|
|
|
|
mov eax, [esp] ; return address
|
|
|
|
lea ecx, [esp+4] ; return stack, minus address
|
|
|
|
call save_current_task
|
|
|
|
mov eax, [esp+8] ; new eip
|
|
|
|
mov ecx, [esp+12] ; argc
|
|
|
|
mov esi, esp ; old esp
|
|
|
|
mov esp, [esp+4] ; new esp
|
|
|
|
lea esi, [esi+16] ; args
|
|
|
|
mov edx, ecx
|
|
|
|
neg edx
|
|
|
|
lea esp, [esp+edx*4] ; adjust for args
|
|
|
|
mov edi, esp
|
|
|
|
; copy varargs to new stack
|
|
|
|
rep movsd
|
|
|
|
push 0x00000000 ; if child returns, return to null, crashing
|
|
|
|
mov ecx, 0x20 | 3
|
|
|
|
mov ds, cx
|
|
|
|
mov es, cx
|
|
|
|
mov fs, cx
|
|
|
|
mov gs, cx
|
|
|
|
mov ecx, esp
|
|
|
|
push 0x20 | 3
|
|
|
|
push ecx
|
|
|
|
pushfd
|
|
|
|
push 0x18 | 3
|
|
|
|
push eax
|
|
|
|
iret
|
|
|
|
|
2024-01-07 22:33:27 -06:00
|
|
|
; save task
|
|
|
|
; stack contains caller, eip, cs, eflags(, esp, ss)
|
|
|
|
global save_current_task_new
|
|
|
|
save_current_task_new:
|
|
|
|
push ds
|
|
|
|
push ebx
|
|
|
|
push eax
|
|
|
|
push 0x10
|
|
|
|
pop ds
|
|
|
|
; 0 eax, 4 ebx, 8 ds, 12 caller, 16 eip, 20 cs, 24 eflags(, 28 esp, 32 ss)
|
|
|
|
; location to save task
|
|
|
|
mov ebx, dword [0x318000]
|
|
|
|
; code & stack
|
|
|
|
mov eax, dword [esp+16]
|
|
|
|
mov dword [ebx+0], eax ; eip
|
|
|
|
mov eax, dword [esp+20]
|
|
|
|
mov dword [ebx+4], eax ; cs
|
|
|
|
cmp ax, 0x08
|
|
|
|
; if we're not in code segment, save stack info
|
|
|
|
je .curr_stack
|
|
|
|
mov eax, dword [esp+24]
|
|
|
|
mov dword [ebx+8], eax ; eflags
|
|
|
|
mov eax, dword [esp+28]
|
|
|
|
mov dword [ebx+12], eax ; esp
|
|
|
|
mov eax, dword [esp+32]
|
|
|
|
mov dword [ebx+16], eax ; ss
|
|
|
|
jmp .seg_regs
|
|
|
|
; if we're in code segment, we save current info, minus interrupt stack
|
|
|
|
.curr_stack:
|
|
|
|
mov eax, dword [esp+24]
|
|
|
|
mov dword [ebx+8], eax ; eflags
|
|
|
|
lea eax, [esp+28]
|
|
|
|
mov dword [ebx+12], eax ; esp before interrupt
|
|
|
|
mov eax, ss
|
|
|
|
mov dword [ebx+16], eax
|
|
|
|
; segment regs
|
|
|
|
.seg_regs:
|
|
|
|
mov eax, dword [esp+8]
|
|
|
|
mov dword [ebx+20], eax ; ds
|
|
|
|
mov eax, es
|
|
|
|
mov dword [ebx+24], eax
|
|
|
|
mov eax, fs
|
|
|
|
mov dword [ebx+28], eax
|
|
|
|
mov eax, gs
|
|
|
|
mov dword [ebx+32], eax
|
|
|
|
; general regs besides esp
|
|
|
|
mov eax, dword [esp+0]
|
|
|
|
mov dword [ebx+36], eax ; eax
|
|
|
|
mov eax, dword [esp+4]
|
|
|
|
mov dword [ebx+40], eax ; ebx
|
|
|
|
mov dword [ebx+44], ecx
|
|
|
|
mov dword [ebx+48], edx
|
|
|
|
mov dword [ebx+52], esi
|
|
|
|
mov dword [ebx+56], edi
|
|
|
|
mov dword [ebx+60], ebp
|
|
|
|
pop eax
|
|
|
|
pop ebx
|
|
|
|
pop ds
|
|
|
|
xchg bx,bx
|
|
|
|
ret
|
|
|
|
|
|
|
|
; return to current task
|
|
|
|
global ret_current_task
|
|
|
|
ret_current_task:
|
|
|
|
xchg bx,bx
|
|
|
|
push 0x10
|
|
|
|
pop ds
|
|
|
|
; location to get task
|
|
|
|
mov ebx, dword [0x318000]
|
|
|
|
mov ebp, [ebx+60]
|
|
|
|
mov edi, [ebx+56]
|
|
|
|
mov esi, [ebx+52]
|
|
|
|
mov edx, [ebx+48]
|
|
|
|
mov ecx, [ebx+44]
|
|
|
|
mov gs, [ebx+32]
|
|
|
|
mov fs, [ebx+28]
|
|
|
|
mov es, [ebx+24]
|
|
|
|
mov ds, [ebx+20]
|
|
|
|
mov eax, [ebx+4] ; cs
|
|
|
|
cmp ax, 0x08
|
|
|
|
je .restore_stack
|
|
|
|
mov eax, [ebx+36]
|
|
|
|
mov esp, ebx
|
|
|
|
mov ebx, [ebx+40]
|
|
|
|
iret
|
|
|
|
.restore_stack:
|
|
|
|
mov esp, [ebx+12]
|
|
|
|
mov ss, [ebx+16]
|
|
|
|
mov eax, [ebx+36]
|
|
|
|
push dword [ebx+8]
|
|
|
|
push dword [ebx+4]
|
|
|
|
push dword [ebx]
|
|
|
|
mov ebx, [ebx+40]
|
|
|
|
iret
|
|
|
|
|
2022-09-21 17:14:11 -05:00
|
|
|
; return address in EAX
|
|
|
|
; return stack in ECX
|
|
|
|
; we can modify EAX, ECX, EDX
|
|
|
|
; i.e. save all others in task
|
2022-09-19 16:06:01 -05:00
|
|
|
global save_current_task
|
|
|
|
save_current_task:
|
2022-09-21 17:14:11 -05:00
|
|
|
push edx
|
|
|
|
mov edx, esp ; EDX holds our tmp stack, unsaved
|
2022-09-19 16:06:01 -05:00
|
|
|
mov esp, dword [task_ptr] ; load current task pointer
|
|
|
|
push ss
|
2022-09-21 17:14:11 -05:00
|
|
|
push ecx ; return stack
|
2022-09-19 16:06:01 -05:00
|
|
|
pushfd
|
|
|
|
push cs
|
|
|
|
push eax ; return address
|
|
|
|
push ds ; other segs, pop
|
|
|
|
push es ; before iret
|
|
|
|
push fs ; in exit handler
|
|
|
|
push gs
|
2022-09-21 17:14:11 -05:00
|
|
|
push ebp ; saved
|
|
|
|
push ebx ; saved
|
|
|
|
push esi ; saved
|
|
|
|
push edi ; saved
|
2022-09-19 16:06:01 -05:00
|
|
|
mov dword [task_ptr], esp ; save new task pointer
|
2022-09-21 17:14:11 -05:00
|
|
|
mov esp, edx
|
|
|
|
pop edx
|
2022-09-19 16:06:01 -05:00
|
|
|
ret
|
|
|
|
|
2023-02-06 03:07:15 -06:00
|
|
|
; FIXME System will crash if last task is invalid
|
2022-09-19 16:06:01 -05:00
|
|
|
global return_prev_task
|
|
|
|
return_prev_task:
|
2022-09-21 17:14:11 -05:00
|
|
|
mov ecx, eax ; save return value for later
|
|
|
|
mov edx, dword [task_ptr] ; load current task pointer
|
|
|
|
add dword [task_ptr], 52 ; adjust to last task pointer
|
|
|
|
mov edi, [edx+0]
|
|
|
|
mov esi, [edx+4]
|
|
|
|
mov ebx, [edx+8]
|
|
|
|
mov ebp, [edx+12]
|
|
|
|
mov eax, [edx+0+16] ; gs
|
2022-09-19 16:06:01 -05:00
|
|
|
mov gs, ax
|
2022-09-21 17:14:11 -05:00
|
|
|
mov eax, [edx+4+16] ; fs
|
2022-09-19 16:06:01 -05:00
|
|
|
mov fs, ax
|
2022-09-21 17:14:11 -05:00
|
|
|
mov eax, [edx+8+16] ; es
|
2022-09-19 16:06:01 -05:00
|
|
|
mov es, ax
|
|
|
|
; SS:ESP <- return stack
|
2023-02-02 00:50:16 -06:00
|
|
|
push ecx
|
|
|
|
mov eax, [edx+32+16] ; ss
|
|
|
|
mov ecx, [edx+20+16] ; cs
|
|
|
|
and eax, 3
|
|
|
|
and ecx, 3
|
|
|
|
or eax, ecx
|
|
|
|
pop ecx
|
|
|
|
cmp eax, 3
|
|
|
|
je .ret_stack
|
|
|
|
.ret_no_stack:
|
2022-09-21 17:14:11 -05:00
|
|
|
mov esp, [edx+28+16] ; esp
|
|
|
|
mov eax, [edx+32+16] ; ss
|
2022-09-19 16:06:01 -05:00
|
|
|
mov ss, ax
|
2022-09-21 17:14:11 -05:00
|
|
|
mov eax, [edx+24+16] ; eflags
|
|
|
|
push eax
|
|
|
|
mov eax, [edx+20+16] ; cs
|
|
|
|
push eax
|
|
|
|
mov eax, [edx+16+16] ; eip
|
|
|
|
push eax
|
|
|
|
mov eax, [edx+12+16] ; ds
|
2022-09-19 16:06:01 -05:00
|
|
|
mov ds, ax
|
2022-09-21 17:14:11 -05:00
|
|
|
mov eax, ecx ; restore return value
|
2022-09-19 16:06:01 -05:00
|
|
|
iret
|
2023-02-02 00:50:16 -06:00
|
|
|
.ret_stack:
|
|
|
|
mov eax, [edx+32+16] ; ss
|
|
|
|
push eax
|
|
|
|
mov eax, [edx+28+16] ; esp
|
|
|
|
push eax
|
|
|
|
mov eax, [edx+24+16] ; eflags
|
|
|
|
push eax
|
|
|
|
mov eax, [edx+20+16] ; cs
|
|
|
|
push eax
|
|
|
|
mov eax, [edx+16+16] ; eip
|
|
|
|
push eax
|
|
|
|
mov eax, [edx+12+16] ; ds
|
|
|
|
mov ds, ax
|
|
|
|
mov eax, ecx ; restore return value
|
|
|
|
iret
|
2023-01-31 21:26:43 -06:00
|
|
|
|
2023-02-02 14:52:26 -06:00
|
|
|
; extern void enter_v86(uint32_t ss, uint32_t esp, uint32_t cs, uint32_t eip, union V86Regs_t *regs);
|
2023-01-31 21:26:43 -06:00
|
|
|
global enter_v86
|
2023-02-02 00:50:16 -06:00
|
|
|
global _enter_v86_internal_no_task
|
2023-01-31 21:26:43 -06:00
|
|
|
enter_v86:
|
|
|
|
pop eax ; return address
|
|
|
|
mov ecx, esp ; return stack
|
|
|
|
call save_current_task
|
2023-02-02 00:50:16 -06:00
|
|
|
_enter_v86_internal_no_task:
|
2023-01-31 21:26:43 -06:00
|
|
|
mov ebp, esp ; save stack pointer
|
2023-02-17 01:41:30 -06:00
|
|
|
; push v86 stuff for iret
|
|
|
|
mov eax, 0x3000
|
|
|
|
push eax ; gs
|
|
|
|
push eax ; fs
|
|
|
|
push eax ; ds
|
|
|
|
push eax ; es
|
2023-01-31 21:26:43 -06:00
|
|
|
push dword [ebp+0] ; ss
|
|
|
|
push dword [ebp+4] ; esp
|
|
|
|
pushfd ; eflags
|
|
|
|
or dword [esp], (1 << 17) ; set VM flags
|
|
|
|
;or dword [esp], (3 << 12) ; IOPL 3
|
|
|
|
push dword [ebp+8] ; cs
|
|
|
|
push dword [ebp+12] ; eip
|
2023-02-17 01:41:30 -06:00
|
|
|
; check if we have regs
|
|
|
|
mov eax, dword [ebp+16] ; regs
|
|
|
|
test eax, eax
|
|
|
|
jz .no_regs
|
|
|
|
; load regs: ebp, edi, esi, ebx, edx, ecx, eax
|
|
|
|
mov ebp, dword [eax+0]
|
|
|
|
mov edi, dword [eax+4]
|
|
|
|
mov esi, dword [eax+8]
|
|
|
|
mov ebx, dword [eax+12]
|
|
|
|
mov edx, dword [eax+16]
|
|
|
|
mov ecx, dword [eax+20]
|
|
|
|
mov eax, dword [eax+24]
|
|
|
|
.no_regs:
|
2023-01-31 21:26:43 -06:00
|
|
|
iret
|
|
|
|
|
|
|
|
; return address in eax, return stack in ebp
|
|
|
|
;extern save_current_task
|
|
|
|
|
2023-02-06 05:49:03 -06:00
|
|
|
;extern user_test
|
|
|
|
;global jmp_usermode_test
|
|
|
|
;jmp_usermode_test:
|
|
|
|
;pop eax ; return address
|
|
|
|
;mov ecx, esp ; return stack
|
|
|
|
;call save_current_task
|
|
|
|
;mov esp, 0x800000 ; usermode stack
|
|
|
|
;mov eax, 0x20 | 3
|
|
|
|
;mov ds, ax
|
|
|
|
;mov es, ax
|
|
|
|
;mov fs, ax
|
|
|
|
;mov gs, ax
|
|
|
|
;mov eax, esp
|
|
|
|
;push 0x20 | 3
|
|
|
|
;push eax
|
|
|
|
;pushfd
|
|
|
|
;push 0x18 | 3
|
|
|
|
;push user_test
|
|
|
|
;iret
|