

Show HN: Use BIOS ram hacks to make an SSH server for MS-DOS, INT 10 13h OS's - benjojo12
https://github.com/benjojo/dos_ssh

======
0x0
So this server won't actually run hosted on an MSDOS int 10 13h OS, but it
will screenscrape the BIOS video memory area from such a machine across an
already running remote GDB session, it looks like. It also requires an already
running remote VNC server to inject keypresses.

------
fotcorn
How do you run this? I tried with qemu and a DOS 6.22 floppy image, but it
crashed.

    
    
      qemu-system-i386 -fda Dos6.22.img -boot a -vnc :0 -s
      QEMU: Terminated via GDBstub
    
      2014/09/06 16:49:59 Starting GDB client
      2014/09/06 16:49:59 Starting VNC client
      2014/09/06 16:49:59 Starting SSH server
      2014/09/06 16:49:59 Waiting for TCP conns on 0.0.0.0:2222
      2014/09/06 16:50:00 Sent FB out
      2014/09/06 16:50:01 write tcp 127.0.0.1:1234: connection reset by peer

~~~
benjojo12
May I ask what version of qemu are you using?

~~~
fotcorn
The official one from the Ubuntu 12.04 LTS repo:

    
    
      qemu-system-i386  --version
      QEMU emulator version 1.0 (qemu-kvm-1.0), Copyright (c) 2003-2008 Fabrice Bellard
    

Should i try to compile a current version without qemu-kvm patches?

~~~
benjojo12
Here is the version that I am using:

$ qemu-system-i386 --version QEMU emulator version 1.1.2 (Debian
1.1.2+dfsg-6a), Copyright (c) 2003-2008 Fabrice Bellard

~~~
fotcorn
It works now with qemu 1.7.2 compiled from source and with this change in
server.go:

    
    
      -               for ptr <= len(FB) {
      +               for ptr < len(FB) {

~~~
benjojo12
_facepalm_

Yeah woops. I forgot to commit that fix.

------
ah-
That's really cool. From the way the cursor flashes in the video, it seems to
refresh the screen pretty often? Does it do that constantly, 30/60 frames per
second or only if something changes?

------
jacob019
"Use BIOS ram hacks to make a SSH server out of any INT 10 13h app (MS-DOS is
one of those)" would like to know how this is achieved.

~~~
CyberShadow
As I understand from looking at the code, there is a VNC server and a GDB
server "running" on the machine already. These are probably provided by a
virtual machine. VMware and Bochs both seem to support GDB-like debugging to
some extent, and remote access through the VNC protocol.

This package simply queries the screen via GDB, sends it off to SSH
connections, and sends any keystrokes via VNC to the DOS machine. From the
title I thought the SSH server runs directly on the DOS box, but as I
understand, no Go code actually runs on the DOS machine.

~~~
jacob019
thank you. So you would need to be running DOS under windows, it wouldn't work
on bare metal.

~~~
benjojo12
Correct, However (when I get around to tearing out the VNC dependency) you
could use this to SSHerize bare metal machines (using gPXE's GDB stack)

------
orf
Looks awesome, could do with a write up though. Also there must be a 'nicer'
way to do this[1] in Go, rather than a huge bunch of if statements?

1\.
[https://github.com/benjojo/dos_ssh/blob/master/data.go](https://github.com/benjojo/dos_ssh/blob/master/data.go)

~~~
benjojo12
I sorta cleaned up the _giant_ if tree there. It was on my todo list :)

~~~
dbaupp
Can't it at least be something like

    
    
      high := code / 16;
      low := code % 16;
    
      switch high {
      case 0: template += "40"
      case 1: template += "44"
      case 2: template += "42"
      // ...
      case 15: template += "43"
      }
    
      switch low {
      case 0: template += ";30"
      case 1: template += ";34"
      // ...
      case 15: template += ";33"
      }
    

Or even

    
    
      s := [...]string{"0", "4", "2", ..., "3"}
    
      template := "\x1B[4" + s[code / 16] + ";3" + s[code % 16] + "m"
    

(I don't know Go, so you will have to adjust to be valid, and I'm sure there's
some sort of string formatting or something that makes the last suggestion
more efficient.)

~~~
lunixbochs
I'd probably do something like this:

    
    
        colors := []string{"0", "4", "2", "6", "1", "5", "3", "7", "0", "4", "2", "6", "1", "5", "3"}
        bg := colors[(b & 0xF0) >> 8]
        fg := colors[b & 0x0F]
        fmt.Sprintf("\x1B[4%d;3%dm", bg, fg)

~~~
benjojo12
Yup! Thats much better, Thanks

------
benjojo12
Yeah, this was written fairly quickly. I was considering making a terminate
and persist executable, however that would mean it would work less with other
non MS-DOS systems.

The VNC server is a complete fudge though, however I could not figure out a
easy way to hook the keyboard interrupt fromGDB

~~~
CyberShadow
> terminate and persist executable

I believe those are called Terminate and Stay Resident programs (TSRs).

> The VNC server is a complete fudge though, however I could not figure out a
> easy way to hook the keyboard interrupt fromGDB

How about pushing events into the circular BIOS keyboard queue at 40:1A?

~~~
benjojo12
Neat! Didn't know about the 40:1A location. I'll add that in and hopefully get
rid of the VNC server need (that way I can also use gPXE's GDB server and make
this SSH'ize real boxes

