Tags: dsky space satellites 15-bit apollo
Rating:
# Space and Things: 1201 Alarm
## Description
The premise of this challenge is straightforward. We have to connect a DSKY to the AGC Commanche055 instance that is given in the netcat. Then, figure out the value of PI on the machine.
## Connecting to the Server
Compiling the virtualagc from source (https://github.com/virtualagc/virtualagc) turned out to be a challenge, since we were using Macbooks. Compiling from source also did not work even using modern Windows 10. Luckily, you can download a virtualbox vm with AGC preinstalled: https://www.ibiblio.org/apollo/download.html
Power on the VM, and the yaDSKY executable is located at /home/virtualagc/VirtualAGC/bin
Use this to connect to the server:
`./yaDSKY2 --ip=3.22.223.17 --port=6942`
At first, you might get an error message like “Can’t load image…”. In this case, just copy the images from https://github.com/virtualagc/virtualagc/tree/master/yaDSKY2 to /home/virtualagc/VirtualAGC/bin.
## Getting PI
Initially, we found some documentation stating that the instruction “Verb 27, Noun 01” would display fixed memory on the system. (https://www.ibiblio.org/apollo/hrst/archive/1706.pdf, https://www.ibiblio.org/apollo/A17_VN_Checklist.png) We also found in the source code for Comanche055, the constant PI/16 appeared in the file TIME_OF_FREE_FALL.agc. Now the challenge was to find the address corresponding to this entry in the code.
The next important discovery was that listing files for the Comanche055 source were available in addition to the raw assembly, the relevant file accessible here: http://www.ibiblio.org/apollo/listings/Comanche055/TIME_OF_FREE_FALL.agc.html. The format of the listing file is not documented, so we didn’t initially know which value was the address. However, the first entry on each line was listed for lines with only comments or nothing at all, so that was most likely just a line number. Out of the remaining values, one which took the form xx,yyyy incremented on each line of code, while the other was simply a single value which varied. This led us to believe the first was the memory address of each line of code, supported by the fact that Apollo memory was organized into one-kiloword banks, and documentation found later on revealed that xx,yyyy is a format for relative addresses referring to the memory at address yyyy in bank xx. This got us nearly there, but verb 27 only accepts fixed addresses, not a bank plus relative address within the bank. In order to experiment, we used VirtualAGC to boot up our own emulated AGC with DSKY, running Comanche055 with the unmodified value of PI/16. Attempts to guess at the correct way to combine bank 27 and relative address 3355, combined with verb 27 noun 01, were not successful at returning the expected value of PI/16 found in the source.
Next, we found some documentation stating “The addresses will be 00000-01777 for memory bank 00, 02000-03777 for memory bank 01, and so forth, up to 76000-77777 for memory bank 37.” (https://virtualagc.github.io/virtualagc/index.html) This documentation was helpful, and revealed the conversion from relative “bank,address” notation to absolute address. The initial assumption was that the fixed address would be the bank number multiplied by a constant plus the relative address within the bank. Since the addresses within each bank span a space of 2000 words, it would make sense for the absolute address to be (bank number)*2000+(relative address). However, testing with our own AGC and unmodified version of Comanche055, this did not get us the unmodified value of pi using its relative address. Upon further investigation of the listing files for Comanche055, we found that asking for the memory at fixed address 3777 would return the value stored at relative address 1,3777 which was a surprise given that bank 0 also exists, yet the offset for bank 1 is 0. The last piece of the puzzle was bank 37 corresponding to address 76000, which indicated the bank numbers are in octal (this probably should’ve been obvious given everything else is also octal).
With this information, we input the fixed address (27-1)*2000+3355 = 57355, which corresponds to 27,3355, the location of PI/16, into our own AGC running Comanche055 and got the correct value. (or, the first word of the correct value; the second was simply obtained by incrementing the address by 1) However, connecting to the AGC on the server, we did not obtain a value anywhere close to pi at this address. The problem stated that there was a “tangle” and the number of constants in that memory region had changed over time, so we decided to investigate close by memory addresses. Decrementing the address to 27,3353 gave the value 24775 30424, which matches the assembly listing, so we instead tried incrementing the address. The next few values did not match the assembly listing, and we found that the value stored at 27,3361 was close to PI/16 and also had a different value for team members connected to different instances of the challenge, a strong indication that we had the right address.
With this, we were able to figure out the exact command to enter:
27 01 57361 - To get the high bits
27 01 57362 - To get the lower bits
## Example Calculation
Normally, the PI/16 constant value is 06220 37553, which is PI/16 in octal. To convert this value to PI in decimal, we do:
0622000000 octal = 105381888 decimal
37553 octal = 16235 decimal
(105381888/2 + 16235) / 2^28 * 16 = 3.14159…
Typing the calculated PI value into the netcat interface would print out the flag.