; This is the syscall gateway: ; - backs up the data from user space (kernel funcs trash many regs) ; - sets up the kernel stack ; - calls kernel funcs ; - exports a specified set of registers back to userspace ; ; The syscall table acts as a "export"-list for kernel near funcs. ; Code invoked via it can reply on SS being zero. section .bss curpsp: resw 1 section .data stab: ; syscall table ; cells: ptr to handler, ptr to sysret ; 0-7 dw restart, sret dw getc, sretb dw putc, sret dw err, sret ; reader input dw err, sret ; punch outout dw err, sret ; list output dw conio, sret ; direct console i/o dw err, sret ; 8-f dw err, sret dw err, sret ; print string dw err, sret ; read into buffer dw err, sret ; console status dw err, sret ; return version num dw err, sret ; reset disks dw err, sret ; select disk dw err, sret ; open file .end: section .text absolute 0 resb 2 ; ret 0 exit resb 2 ; allocation length resb 1 resb 5 ; CP/M entry point ; saved userdata PSPAX: resw 1 ; SS:SP PSPSP: resw 1 PSPSS: resw 1 ; DS:DX PSPDX: resw 1 PSPDS: resw 1 ; ES:BX PSPBX: resw 1 PSPES: resw 1 section .text ; Load current PSP segment into DS ; OUT ds PSP segment ; ax 0 pspds: xor ax, ax mov ds, ax mov ds, [curpsp] ret ; Fix CS:AX pointer for reloc fixax: call .l01 .l01: pop bx sub bx, .l01 add ax, bx ret int21: push ds ; load program PSP and save userdata push ax call pspds pop word [PSPAX] pop word [PSPDS] mov [PSPSS], ss mov [PSPSP], sp mov [PSPDX], dx mov [PSPES], es mov [PSPBX], bx mov ss, ax mov sp, ( stack+stacksize ) ; get ptr to syscall table mov al, [PSPAX+1] shl ax, 1 shl ax, 1 add ax, stab call fixax mov bx, ax ; load sysret ptr push bx mov ax, [cs:bx+2] call fixax pop bx push ax ; load handler ptr mov ax, [cs:bx] call fixax push ax ; restore user data mov bx, [PSPBX] mov ax, [PSPAX] mov ds, [PSPDS] ; launch ROP chain ret err: mov ah, 0xFF ret ; sysret handlers ; return ES:BX to user sretd: mov ds, [ss:curpsp] jmp sret.l02 ; return BX to user sretw: mov ds, [ss:curpsp] mov es, [PSPES] jmp sret.l02 ; return AL to user sretb: mov ds, [ss:curpsp] mov ah, [PSPAX+1] les bx, [PSPBX] jmp sret.l03 ; return without result sret: mov ds, [ss:curpsp] .l01: les bx, [PSPBX] .l02: mov ax, [PSPAX] .l03: mov ss, [PSPSS] mov sp, [PSPSP] lds dx, [PSPDX] iret