|
Author |
Topic:
Cracking the Q-link Disk (Read 608 times) |
Jim
Brain Full Member
member is online
Joined: Mar 2004 Posts:
183
|
|
Re: Cracking the Q-link
Disk « Reply #15 on 7/5/05 at
1:08 » |
|
SInce I
spent months running around in the state machine/OS
before I took a breather, cna you tell me how you got
this far? Namely:
How did you find the cmd
lists? How did you decipher that much of the
protocol? As noted, I figured out the checksum and the
$5a stuff, but you found the cmd pairs, etc.
And,
the final question:
Are you actively working on
this, or what is your status?
Jim
|
|
Logged |
-- Jim Brain
| |
Keith
Henrickson Guest
|
|
Re: Cracking the Q-link
Disk « Reply #16 on 7/5/05 at
2:16 » |
|
Ok, Keith
Henrickson's guide to reverse engineering
QLink:
USE AN EMULATOR! One with a monitor
feature. I recommend Vice. It can emulate QLink's
(fast?) loader, and also has a built in
monitor.
First of all, do not load "0006". The
four digit files are never accessed by name. They simply
reserve space so that when a user validates the disk,
the blocks are not deallocated. The three letter
filenames contain track/sector pointers to load. Each
'load' consists of many many operations. Each file
'fork' has a header and some light
obfuscation.
So, load "*",8,1
Break into
the monitor and search for BASIC text, which we find at
$1301. Soft reset the emulator. Type "POKE 44,19". Now
we can accurately list the program.
Now I broke
the program down into three logical blocks. The green
screen, the blue screen (flashy qlink logo within blue
boxes), main menu. I could see by listing the program
that everything up to the main menu was printed by this
program. I begain making notes.
Line 13 - Call
dialer on line 40000 (Green screen starts here) Line
500 - Connect to the correct X.25 network (second half
of green screen) Line 600 - Initialize machine code
half of Qlink, and draw the blue screen on 630 Line
900 - Drawing main menu
So, I begin working on
how to make it through each of these sections of
code.
Line 13 - set modem type to manual dial.
<RETURN> skips this block Line 500 - Dragged up
some memories that "/555-1212" would correspond with the
section of code expecting "IDENTIFIER". Wrote a little
test app to print the expected values COM2, and mapped
Vice to COM1. Null modem cable between the two. A couple
of tries, and I was at the blue screen.
The first
place the BASIC program sits is on line 650. The GOSUB
15000 just cycles the colors in the logo. Boring. But
the SYS is interesting, and it is looking for 782 to be
0 or 10. Hmmmmm.... 0 or 10. I pulled one out of my butt
here and said, "Hey, it's trying to start a protocol.
That location is the number of bad attempts. If it
reaches 10, we're dead. When it succeeds, it will be set
to 0." So, we look at the assembly for the routine being
SYSed.
It turns out to be a VERY simple routine
at $9AC0, that flips out BASIC ROM, reads the location
$B9B5 underneath it to Y, and restores BASIC ROM. 782 is
of course the shadow register for Y. So, we're
retreiving a value from the ML code. And flipping out
ROMS in my monitor, and looking at that location, YEP,
it's a $01 by default. Ok, so, now I need to know how to
set this to 0.
A simple hunt for "b5 b9" gives me
5 easy possibilities. $BB2F is the ONLY case where it is
being set to 0. Look back two instructions to find a
JMP. So, let's guess that $BB27 is the first instruction
of this subroutine. Hunt for it. ONE reference in all of
memory, a JMP from B82F.
Looking back up, and
around $B883, we look for the 5a. $B890 starts
processing packets in earnest. The CRC is unpacked on
$B8A0, it is calculated in one of the calls around
$B8B6, and it is checked in $B8CF.
One good
resource I had was when the CRC fails, an error packet
is sent. This is done by a routine at $BACA. It puts
together a perfectly normal packet 23. That ALSO taught
me a lot about the packet format.
Anyway, we
finally have a valid packet, and begin seeing what type
it is. The JMP $BB27 that we need to kick things off is
going to be called if a certain byte in the packet is
$24.
So, I wrote a program (which I don't have
anymore), that waited for the first packet from the
client, and printed out everything I could tell about
it. This is how I validated my CRC routine. Took me
several hours to find all the typos I'd made in it.
Slowed me up HARD for a while. Once I had that, I sent
back a packet 24, no payload. The client immediately
printed, "Verifying your account
information".
The next packet I got was of type
$20. It contained "DD1234567890ABCD". I guessed that DD
was the command, and the rest was some type of login
info. But what POSSIBLE responses could their
be?
Again, BACK to the Batmobile! I mean, the
monitor!
This time, use the 'interrogate' command
to see things as text, just in case I could find a DD
anywhere in text. At $BDD2, there it is. Every possible
command the client can send. Keep looking.
And at
$C86C, we have another list of two letter commands.
Everything the client expects to receive?
Hopehope!
So, I modified my program to send a
command in a packet type $20 in response to the DD
packet, made a list of the possible commands, and went
to it. One by one.
At DO, I saw the client clear
the screen in an all too familar fashion, as if it
WANTED to go to the main menu, but couldn't.
I
found lots of commands that did nothing. Much pain, some
that gave errors on the client screen, like "no time
left on account, goodbye".
FINALLY, at D3, the
client responded with SS, and said, "Verifying your
disk..." I'm like, "Oo! That was the next step!" It sent
me an SS. and waited. Huh.
Well, I have an "SS"
too. So, I'll send it an SS if it sends me an SS. This
makes the emulated disk run. "Oo! It was supposed to do
that!" and then it sends me an "SG" and a "D6".
I
noticed that between line 650 (where we start layer to
with the $24 packet), and line 900, there is one other
place the BASIC program can loop. I'm like, "I'll bet
it's waiting for the disk to be validated before it lets
it go to the main menu." So, rework the program to wait
for DD, send D3, wait for SS, send SS, wait for D6, send
DO. And BANG! I was at the main
menu.
Now, layer 2 is very fiddly
with it's sequence numbers. All command packets $20 type
with two letter commands in them, MUST increment the
sequence number. All control packets $21 and greater,
MUST NOT increment the sequence number. Also, getting
the second number right takes a while. My fingers are
very tired, so I'm not going to go into that right
now.
As to whether I am still interested, yes.
I have not touched the server for some time.
But I still poke at learning more commands. I spend my
xmas vacation with a server simulator I knocked up on my
mac (and then lost), learning the command set for SuperQ
and puzzler. I played a game of puzzler. Painfully at
times. No player graphics, but the puzzle was up, and
the letters popped up and everything.
|
|
Logged | | |
Jeff
Ledger Administrator
member is offline
Joined: Feb 2004 Posts:
180
|
|
Re: Cracking the Q-link
Disk « Reply #17 on 7/5/05 at
10:47 » |
|
K:
With
your contribution of information regarding the protocol
itself, it looks like a public, "multiuser" Qlink server
could be put online using the existing TelBBS interface
configuration for client connection.
My own test
setup includes an actual 64 connected with an RS232
interface to the PC running Tom Stock's old hayes
emulator. (Only because it allows interactive
communication to the client from the PC
keyboard)
I've got a multiuser petscii chatroom
running on my linux box, written in Perl. I suspect that
once I wrap my head around your protocol information, it
should be very easy to incorporate the expected server
responses into my code. It should allow the multiple
clients to connect, then share data between them in the
Qlink chatroom.
The part I'm still hazy on is the
actual packet itself. My brain doesn't work well in HEX,
but IIUC, I should be able to send an standard expected
line of characters to the client and get it to move
correctly. How important is it to actually examine the
data from the client software to do this?
Jeff
|
|
Logged |
"My computer boots in 2 seconds!" --Microsoft
Beat That! | |
Keith
Henrickson Guest
|
|
Re: Cracking the Q-link
Disk « Reply #18 on 7/5/05 at
12:28 » |
|
Hmmmmmmrf.....
You
still pretty much have to implement the entire People
Connection command set. Let me give you an
example.
Let's say the user selects 'Change to a
private room'. At the very least, you have to do
SOMETHING.
Better yet, what about the 'Box
Office' option?
Or trying to start a
game?
The menu is fixed and hard
coded.
Plus the command syntax isn't great,
either.
Client will send MR, asking for a
lobby
Server should send CMLobby
Server
will send CE\x01(first user screen name) Server will
send CE\x02(second user screen name) Server will send
CL\x03(third and last user screen name)
First
user type 'Booga!'
First user's client sends
AABooga!
Server sends to ALL clients
AA\x01Booga!
Second user disconnects, server
sends CB\x02
New user connects, server must keep
track of which positions are available and send
CA\x02(newest user)
You must also respect the
original limits of 23 users in a room, ten char screen
names, etc, etc...
Plus, you still need the full
layer 2 engine. Have to keep letting the client free
it's packets from the retransmission buffer, or it fills
up and the client waits.
|
|
Logged | | |
Jim
Brain Full Member
member is online
Joined: Mar 2004 Posts:
183
|
|
Re: Cracking the Q-link
Disk « Reply #19 on 7/7/05 at
20:59 » |
|
Ahh, I used
VICE, but as WinVICE doesn't have COM port bindings, I
was not able to simply rig up a dummy server to use.
Thus, I tried my hand at disassembling the code. Your
option is much faster.
I appreciate the insight.
Now that WinVICE has TCP/IP serial port bindings, I can
try my hand at this again.
Jim
|
|
Logged |
-- Jim Brain
| |
Keith
Henrickson Guest
|
|
Re: Cracking the Q-link
Disk « Reply #20 on 7/13/05
at 3:39 » |
|
Yes,
unfortunately, I have not made a DENT in figuring out
the actual Q-Link OS.
Except, that it is a real
OS. The server must spawn processes, send RPC messages,
and kill processes to make the client do it's
thing.
All while the OS is frantically flipping
between the ML tasks and a BASIC task, slamming ROMS in
and out as need be.
I used UNIX VICE for my early
explorations, for exactly this reason. Now that WinVICE
supports RS232 redirection, I have an interest again. |
|
Logged | | |
David
Murray Guest
|
|
Re: Cracking the Q-link
Disk « Reply #21 on 7/13/05
at 21:08 » |
|
Pitty there
are no Qlink servers to connect to anymore. Otherwise
you could just watch the data stream between your C= and
the server. I somehow doubt anyone thought to log any of
this years ago while it was still available.
|
|
Logged | | |
Jim
Brain Full Member
member is online
Joined: Mar 2004 Posts:
183
|
|
Re: Cracking the Q-link
Disk « Reply #22 on 7/15/05
at 2:48 » |
|
Keith:
Working
on some code. But, I have a couple questions:
Do
you have names for the various commands (23,
24,26,etc.?) I noticed in the large list of two
letter commands that some can only be used at certain
times. Have you a state machine showing the various
states the main system can be in? Are your fingers
better and you might be able to explain the 2 sequence
numbers. As to your code, is there any rundown? I'm
scanning through it, but not sure the
organization.
I lost my old DATAPAC emu code, so
I rewrote
some.
|
|
Logged |
-- Jim Brain
| |
Keith
Henrickson Guest
|
|
Re: Cracking the Q-link
Disk « Reply #23 on 7/16/05
at 19:02 » |
|
The sequnce
numbers aren't really that hard, just took me a while to
divine from the code
Sequence number 1: Every
time you send a packet 0x20, this increments by
one.
Sequence number 2: Every time you send a
packet, include the last packet number you received.
This way the far end knows which packet #'s you've seen,
and he can free his memory.
Sequence numbers
increment in the range 0x10-0x7F
0x21 -- Client
is out of memory for sliding windows buffers. It needs a
packet to come back so that it can free some memory and
send you more data. 0x22 -- ACK. Used to explicitly
ack packets from the client. The client will use the
second sequence number to free any packets it is able
to. NOT REQUIRED UNLESS the client sends you a 0x21
moaning that he is out of memory.
0x23 --
Protocol reset. Used when the client is confused or has
otherwise lost his place. Happens at the initial
connection, on a CRC error, or after a SuperQ load.
Everyone resets all sequence #'s to 0x7f and throws away
anything in retransmit queues. ONLY VALID CLIENT TO
SERVER. 0x24 -- Protocol reset ACK.
0x25
-- Client has found a packet sequence error. First
sequence number of packet just received is not one
greater than first sequence number of previous packet.
Only checked on 0x20 packets.
0x26 -- Ping.
Respond with a 0x24 and current sequence numbers.
Failure to respond to three pings will result in
connection termination by client.
In the
'qclient' directory, you can find the miniteletym
source. miniteletym was run by UNIX Vice and attached to
the emulated modem port. It answered the Tymnet logon
sequence and then proxied everything between stdio and a
TCP socket.
'qserver' layout.
TCPManager,
TCPListener, TCPConnection work togehter to handle the
incoming connections. TCPManager::Manage is called
repeatedly to process any
connections/data
qclientconn.cpp implements layer
2 and sends all layer 3 data up to
quser.cpp
quser.cpp breaks up the command and
calls the different support objects to process things
like logins, room joins, and such.
qporch.cpp
validates a user, sending back the appropriate responses
based on a mysql lookup.
And so on...
|
|
Logged | | |
| |