91 lines
1.6 KiB
NASM
91 lines
1.6 KiB
NASM
org 100h
|
|
bits 16
|
|
|
|
section .text
|
|
jmp _start
|
|
|
|
yesDosbox db "Yep, that is a DOSBox!",0dh,0ah,'$'
|
|
noDosbox db "Probably not a DOSBox.",0dh,0ah,'$'
|
|
|
|
oldUDAddr dw 0
|
|
oldUDSeg dw 0
|
|
|
|
isDosbox db 1
|
|
|
|
_catchUD:
|
|
push ax
|
|
push bx
|
|
|
|
mov bx, sp
|
|
mov bx, WORD [ss:bx+4]
|
|
mov ax, bx
|
|
|
|
mov bx, WORD [cs:bx]
|
|
and bh, 38h ; Keep only the opcode bits
|
|
cmp bx, 38feh ; little-endian FE 38
|
|
je .notDosbox
|
|
; uhh, we shouldn't end up here. clean up the IVT and IRET so the actual
|
|
; #UD handler is called.
|
|
push es
|
|
xor ax, ax
|
|
mov es, ax
|
|
mov bx, [oldUDAddr]
|
|
mov [es:18h], bx
|
|
mov bx, [oldUDSeg]
|
|
mov [es:1ah], bx
|
|
pop es
|
|
jmp .catchDone
|
|
|
|
.notDosbox:
|
|
; Not DOSBox -- increment the IP and unset the flag
|
|
add ax, 4
|
|
mov bx, sp
|
|
mov WORD [ss:bx+4], ax
|
|
mov [isDosbox], 0
|
|
|
|
.catchDone:
|
|
pop bx
|
|
pop ax
|
|
iret
|
|
|
|
_start:
|
|
push es
|
|
; store the old #UD...
|
|
xor ax, ax
|
|
mov es, ax
|
|
mov bx, [es:18h]
|
|
mov [oldUDAddr], bx
|
|
mov bx, [es:1ah]
|
|
mov [oldUDSeg], bx
|
|
; ... and set the new #UD handler
|
|
mov bx, cs
|
|
mov [es:1ah], bx
|
|
mov bx, _catchUD
|
|
mov [es:18h], bx
|
|
pop es
|
|
|
|
; DOSBoxCB 0x0000
|
|
db 0xfe, 0x38, 0x00, 0x00
|
|
mov ax, [isDosbox]
|
|
cmp ax, 0
|
|
jz .notDosbox
|
|
mov dx, yesDosbox
|
|
jmp .printAndQuit
|
|
.notDosbox:
|
|
mov dx, noDosbox
|
|
.printAndQuit:
|
|
mov ah, 09h
|
|
int 21h
|
|
|
|
; restore the old #UD handler
|
|
push es
|
|
xor ax, ax
|
|
mov es, ax
|
|
mov [es:1ah], oldUDSeg
|
|
mov [es:18h], oldUDAddr
|
|
pop ax
|
|
|
|
; and we're done!
|
|
mov ax, 4c00h
|
|
int 21h
|
|
hlt
|