Atari 2600
- Challenge: Atari 2600
- Category: Misc
- Flag:
V1T{O_O}
My initial read / first impressions
We are given a single file:
At first, the .bas.bin filename made it look like it could be some weird BASIC program or maybe a compiled game. Running normal checks on it did not show any obvious text or strings that looked like a flag.
The file is exactly 4096 bytes, which is a big hint. A 4KB binary with this kind of structure is very likely an Atari 2600 ROM.
So instead of treating it like a normal executable, I started looking at it as a 6502 program mapped into Atari 2600 cartridge memory.
For Atari 2600 4KB ROMs, the ROM usually gets mapped at:
So file offset 0x000 corresponds to address $F000.
Looking through the ROM
Since this is a game challenge and the prompt says:
I assumed the flag would probably appear after triggering some in-game condition, like touching a prize or reaching a certain state.
But instead of playing the game manually, I looked for suspicious code paths in the ROM. One thing that stood out was this code around $F50A:
The important instruction is:
That means the game calls a subroutine at $F562.
This looked very suspicious because it was guarded by a variable at $D7, almost like the game only wants to run this routine once. That already made it feel like a “you got the prize” or “show the reward” routine.
The suspicious drawing routine
At $F562, the code turns into a giant list of repeated instructions like this:
And then again:
This pattern repeats a ton of times.
Translated into assembly, each block is basically:
The values change each time, but the structure stays the same.
That made the routine pretty easy to understand. It is calling $F278 over and over with different A and Y values.
Looking at $F278, it behaves like a pixel / playfield plotting function. The value in A acts like an x-coordinate, and Y acts like a row. So the routine at $F562 is not doing complex logic. It is literally drawing pixels.
That was the big giveaway.
Decoding the pixels
Instead of trying to emulate the Atari 2600, I extracted every repeated call from $F562.
The format was:
So each block gives one plotted pixel:
XXis the x-coordinateYYis the y-coordinate
After extracting all the (x, y) pairs and printing them as a grid, the first few rows looked like this:
At first it looks kind of ugly, but if you split it into 3-wide characters with a 1-column gap, it becomes readable:
Reading the tiny 3x3 font gives:
So the hidden prize was literally drawn into the Atari playfield.
Solution Script
Here is the final script I used to extract the plotted pixels and decode the message.
from pathlib import Path
rom = Path("v1t.bas.bin").read_bytes()
base = 0xF000
start = 0xF562 - base
pixels = set()
i = start
while rom[i] != 0x60:
block = rom[i:i+9]
if block[0] != 0xA2 or block[1] != 0x00:
raise Exception("bad block")
if block[2] != 0xA0:
raise Exception("bad block")
if block[4] != 0xA9:
raise Exception("bad block")
if block[6:9] != bytes([0x20, 0x78, 0xF2]):
raise Exception("bad block")
y = block[3]
x = block[5]
pixels.add((x, y))
i += 9
for y in range(1, 4):
print("".join("#" if (x, y) in pixels else "." for x in range(31)))
font = {
("#.#", "#.#", ".#."): "V",
(".#.", "##.", ".#."): "1",
("###", ".#.", ".#."): "T",
(".##", "##.", ".##"): "{",
("###", "#.#", "###"): "O",
("...", "...", "###"): "_",
("##.", ".##", "##."): "}"
}
flag = ""
for start_x in range(0, 31, 4):
glyph = tuple(
"".join("#" if (x, y) in pixels else "." for x in range(start_x, start_x + 3))
for y in range(1, 4)
)
flag += font[glyph]
print(flag)
Running it prints:
#.#..#..###..##.###.....###.##.
#.#.##...#..##..#.#.....#.#..##
.#...#...#...##.###.###.###.##.
V1T{O_O}