Skip to content

Invisible Lan fredir.exe fails control-break lookup #255

@PerditionC

Description

@PerditionC

It took me a while, but this issue is that in procsupt.asm the kernel builds on the stack a return and int23h so we can properly pass the correct stack between handler and C code. Invisible Lan fredir.exe does a check to verify and find the kernel's code that invokes the int 23h when a control-break occurs. It installs its own handler then causes a control-C to invoke it, and it saves the return address. Then it cleans up some (it redirected stdout to avoid showing the ^C on the console) which overwrites the [unused] stack in the process which overwrites the data at the address previously saved. Then it checks the address returned to verify the previous instruction was int 23h, however, by now that call stack has been overwritten the int 23h instruction so the check fails and the redir aborts loading. There is secondary issues with ctrl-break handling as the ^C is printed to the CON device when it should be redirected to NUL device. The NUL device also misses checking for control-break when output since it just immediately returns success.

The relevant code in fredir.exe (note: original executable is some form of lzexe compressed)

        ; ... setup and invoke control-break, cleanup, and now check if we found kernel's int 23h call site
        mov dx, OFFSET errormsg
        cmp word [cs:0x44], 2   ; memory 0x44 & 0x46 initialized to 0x02 when exe loaded, now iret return address
        jb .ctrlbreak_return
        les bx, [cs:0x44]
        cmp word [es:bx - 2], 0x23cd  ; <-- succeeds in MSDOS, by now overwritten in FD kernel since was on stack
        jne .ctrlbreak_return
        xor dx, dx ; success
.ctrlbreak_return:
        pop ax
        pop bx
        pop cx
        pop si
        pop di
        pop bp
        pop ds
        pop es
        ret

; transient INT 23h handler: capture DOS return CS:IP
ctrlbreak_handler:
        pop word [cs:0x44] 
        pop word [cs:0x46]
        push word [cs:0x46]
        push word [cs:0x44]
        iret

In kernel procsupt.asm chunk of _spawn_int23 call:

  		sub sp, byte 8		;; code piece needs 7 bytes --> 4 words
  		push ss			;; prepare jump to INT-23 via RETF
  		push bp			;; will be offset / temp: saved BP
  		mov bp, sp
  		add bp, byte 4		;; position BP onto INT-23
  		mov word [bp], 23cdh		;; INT 23h
  		mov byte [bp+2], 9ah			;; CALL FAR immediate
  		mov word [bp+3], ??regain_control_int23
  		mov word [bp+5], cs

  		;; complete the jump to INT-23 via RETF and restore BP
  		xchg word [bp-4], bp

  		clc			;; set default action --> resume
  		; invoke the int 23 handler its address has been constructed
  		;; on the stack
  		retf

??regain_control_int23:

So we need to rework this so the int 23h call is in static [patchable] location and not on stack.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions