Legendary Code
The real code, our re-runs and every source behind the series. From @mygearhut.
Pac-Man Level 256: One Byte Breaks Half the Screen
The real code, our re-runs and every source: https://code.mygearhut.com
Real Pac-Man arcade Z80, fruit-drawing routine
2BF0 3A134E LD A,(#4E13) ; load the level counter
2BF3 3C INC A ; 255 + 1 = 0, carry never checked
2BFC 47 LD B,A ; B = loop count
2C17 10E9 DJNZ #2C02 ; B-1, repeat until zero: 0 -> 255 firstRun it yourself: our Python re-run (37 lines)
#!/usr/bin/env python3
"""ILLUSTRATION - our re-run of the 8-bit arithmetic in the Pac-Man fruit-drawing routine (Z80, 0x2BF0..0x2C17).
Not the game. Mirrors only: level counter (one byte) -> INC A -> B -> DJNZ loop, 2 screen bytes per pass.
Usage: python3 repro.py -> writes repro.json next to this file (deterministic)."""
import json
from pathlib import Path
def u8(x): return x & 0xFF
def fruit_passes(level_counter):
"""level_counter = byte stored at 0x4E13 (0 = first level). Returns (A after INC, passes of the draw loop)."""
a = u8(level_counter + 1) # 2BF3 INC A (8-bit: 255 + 1 -> 0, carry dropped)
b = a if a < 8 else 7 # 2BF4/2BF6 CP #08 ; levels with A>=8 take the other branch and draw 7
passes = 0
while True: # 2C02..2C17 ... DJNZ #2C02
passes += 1
b = u8(b - 1) # DJNZ: B = B - 1, loop while B != 0
if b == 0:
break
return a, passes
rows = []
for lvl in (1, 2, 7, 8, 19, 21, 100, 255, 256):
ctr = lvl - 1 # the game counts from zero
a, p = fruit_passes(ctr)
rows.append({"level": lvl, "counter_byte": ctr if ctr < 256 else ctr, "A_after_inc": a, "draw_passes": p, "screen_bytes_advanced": 2 * p})
# level 256 is counter 255, the only value whose INC wraps; level 257 would be counter 256, which does not fit in a byte
rows = [r for r in rows if r["counter_byte"] <= 255]
out = {
"label": "ILLUSTRATION - our re-run, not the game",
"wrap": {"before": 255, "after_inc": u8(255 + 1)},
"rows": rows,
"max_counter_byte": 255,
"note": "screen_bytes_advanced = 2 per pass (INC HL twice, 2C14/2C15). Hodges: up to 512 bytes of memory are drawn.",
}
Path(__file__).with_name("repro.json").write_text(json.dumps(out, indent=1) + "\n")
print(json.dumps(out))
Sources
One Command Started Deleting Toy Story 2 in 1998
The real code, our re-runs and every source: https://code.mygearhut.com
The command (reported by Oren Jacob)
/bin/rm -r -f *Sources
- https://en.wikipedia.org/wiki/Toy_Story_2
- https://thenextweb.com/media/2012/05/21/how-pixars-toy-story-2-was-deleted-twice-once-by-technology-and-again-for-its-own-good/
- https://www.gnu.org/software/coreutils/manual/html_node/rm-invocation.html
- https://www.independent.co.uk/arts-entertainment/films/news/pixars-billiondollar-delete-button-nearly-lost-toy-story-2-animation-7758083.html
- https://www.newsweek.com/lightyear-producer-credited-saving-toy-story-2-after-deletion-1680072
Doom's Shift-by-16 Trick: 3D Without Floating Point
The real code, our re-runs and every source: https://code.mygearhut.com
id Software's own source, linuxdoom-1.10/m_fixed.h + m_fixed.c
#define FRACBITS 16
#define FRACUNIT (1<<FRACBITS)
typedef int fixed_t;
fixed_t FixedMul (fixed_t a, fixed_t b);
fixed_t
FixedMul
( fixed_t a,
fixed_t b )
{
return ((long long) a * (long long) b) >> FRACBITS;
}Run it yourself: our Python re-run (32 lines)
#!/usr/bin/env python3
"""ILLUSTRATION (our re-run): 16.16 fixed-point multiply as in id's m_fixed.c vs ordinary float math.
FRACBITS 16; FRACUNIT 1<<16; FixedMul(a,b) = ((long long)a * (long long)b) >> FRACBITS
Deterministic; writes repro.json next to this file. Run: python3 repro.py"""
import json
from pathlib import Path
FRACBITS = 16
FRACUNIT = 1 << FRACBITS
def to_fixed(x): # exact for numbers with at most 16 fractional bits
return int(round(x * FRACUNIT))
def fixed_mul(a, b): # Python ints are unbounded (the C uses long long); >> floors like C's arithmetic shift
return (a * b) >> FRACBITS
CASES = [(1.5, 2.25), (0.1, 0.1), (100.0, 0.75), (-3.5, 2.0)]
out = {"FRACBITS": FRACBITS, "FRACUNIT": FRACUNIT, "cases": []}
for x, y in CASES:
a, b = to_fixed(x), to_fixed(y)
p = fixed_mul(a, b)
out["cases"].append({"x": x, "y": y, "a": a, "b": b, "product_raw": a * b, "fixed_result": p,
"as_float": p / FRACUNIT, "float_result": x * y, "abs_error": abs(p / FRACUNIT - x * y)})
c = out["cases"][0]
assert (c["a"], c["b"], c["product_raw"], c["fixed_result"]) == (98304, 147456, 14495514624, 221184)
assert c["as_float"] == c["float_result"] == 3.375 and FRACUNIT == 65536
assert all(k["abs_error"] < 1 / FRACUNIT for k in out["cases"])
(Path(__file__).resolve().parent / "repro.json").write_text(json.dumps(out, indent=1) + "\n")
print(json.dumps(out["cases"], indent=1))
Sources
Heartbleed: One Missing Check Leaked 64 KB of Memory
The real code, our re-runs and every source: https://code.mygearhut.com
The real OpenSSL fix
// ssl/d1_both.c (added by commit 96db9023, 2014-04-07)
+ /* Read type and payload length first */
+ if (1 + 2 + 16 > s->s3->rrec.length)
+ return 0; /* silently discard */
+ hbtype = *p++;
+ n2s(p, payload);
+ if (1 + 2 + payload + 16 > s->s3->rrec.length)
+ return 0; /* silently discard per RFC 6520 sec. 4 */
+ pl = p;
+
+ unsigned int write_length = 1 /* heartbeat type */ +
+ 2 /* heartbeat length */ +
+ payload + padding;
+ if (write_length > SSL3_RT_MAX_PLAIN_LENGTH)
+ return 0;
+
+ buffer = OPENSSL_malloc(write_length);
+ r = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, write_length);
+ buffer, write_length,
// ssl/t1_lib.c (added by commit 96db9023, 2014-04-07)
+ /* Read type and payload length first */
+ if (1 + 2 + 16 > s->s3->rrec.length)
+ return 0; /* silently discard */
+ hbtype = *p++;
+ n2s(p, payload);
+ if (1 + 2 + payload + 16 > s->s3->rrec.length)
+ return 0; /* silently discard per RFC 6520 sec. 4 */
+ pl = p;
+ Run it yourself: our Python re-run (38 lines)
#!/usr/bin/env python3
"""ILLUSTRATION (our re-run, not OpenSSL): a heartbeat echo that trusts the length field. python3 -I data/repro.py -> repro.json
Memory is a fake byte array: the request record sits in front of fake secrets we made up."""
import json, struct
from pathlib import Path
H = Path(__file__).resolve().parent
MEM = bytearray(b"\x00" * 64)
REQ_AT = 16
SECRET = b"user=admin&pass=hunter2; session=9f3a77c1; KEY=-----BEGIN FAKE KEY-----"
def build_memory(payload: bytes, claimed: int) -> bytearray:
mem = bytearray(MEM)
rec = b"\x01" + struct.pack(">H", claimed) + payload + b"P" * 16 # type, 16-bit length, payload, 16 padding
mem[REQ_AT:REQ_AT + len(rec)] = rec
tail = REQ_AT + len(rec)
mem[tail:tail + len(SECRET)] = SECRET # whatever sat next to it on the heap
return mem
def echo(mem: bytearray, rec_len: int, checked: bool):
p = REQ_AT
claimed = struct.unpack(">H", mem[p + 1:p + 3])[0]
if checked and 1 + 2 + claimed + 16 > rec_len: # same shape as the fix: claimed vs real length
return None
return bytes(mem[p + 3:p + 3 + claimed]) # memcpy(bp, pl, payload)
payload = b"hello"
rec_len = 1 + 2 + len(payload) + 16
mem = build_memory(payload, 60)
vuln = echo(mem, rec_len, checked=False)
fixed = echo(mem, rec_len, checked=True)
honest = echo(build_memory(payload, 5), rec_len, checked=False)
res = {"label": "ILLUSTRATION: our re-run, fake memory, fake secrets",
"payload": payload.decode(), "payload_bytes": len(payload), "claimed": 60,
"echo_vulnerable": vuln.decode("latin1"), "echo_vulnerable_bytes": len(vuln),
"echo_fixed": fixed, "echo_honest": honest.decode(),
"max_claim_16bit": 2 ** 16 - 1, "max_claim_kib": round((2 ** 16 - 1) / 1024, 3)}
(H / "repro.json").write_text(json.dumps(res, indent=1))
print(json.dumps(res, indent=1))
Sources
- https://github.com/openssl/openssl/commit/96db9023b881d7cd9f379b0c154650d6c108e9a3.patch
- https://heartbleed.com/
- https://nvd.nist.gov/vuln/detail/CVE-2014-0160
- https://raw.githubusercontent.com/openssl/openssl/OpenSSL_1_0_1f/ssl/t1_lib.c
- https://www.openssl.org/news/secadv/20140407.txt
- https://www.rfc-editor.org/rfc/rfc6520.txt
Crash Bandicoot Levels Were Up to 8x Bigger Than Its RAM
The real code, our re-runs and every source: https://code.mygearhut.com
Andy Gavin, in his own words
"the even crazier – way crazier – virtual memory system required to shoehorn the 8-16 meg levels the artists created into the Playstation's little 2megs of RAM."
"Dave meanwhile had to invent insane bidirectional 10x compressors to help get the 128meg levels down into 12"
"As long as you could never SEE more than a set number of polygons (800 for Crash 1, 1300 for Crash 2 or 3) from any given position we could have perfect occlusion and sort, with no runtime cost."
"the machine had two megabytes or RAM and one megabyte of VRAM"Run it yourself: our Python re-run (34 lines)
#!/usr/bin/env python3
"""ILLUSTRATION (our re-run): paging a big level through a small page pool, with the numbers Andy Gavin states.
Inputs stated by Gavin (data/quotes.json): RAM 2 MB, levels 8-16 MB, 64 KB pages, never more than 16 pages needed at once.
Everything else here (the walk, the step size) is our own deterministic toy, not Naughty Dog's data.
python3 repro.py -> repro.json"""
import json
from pathlib import Path
RAM_KB, LEVEL_MB, PAGE_KB, POOL = 2 * 1024, 16, 64, 16 # Gavin: 2 MB RAM; "8-16 meg levels" (we take the top, 16); "64k pages"; "16 pages"
STEP, NSTEPS = 3, 8 # our walk: the camera needs 3 new pages per step
pages = LEVEL_MB * 1024 // PAGE_KB # 256
pool_kb = POOL * PAGE_KB # 1024 KB = 1 MB
resident, loads, evictions, max_res, steps = set(range(POOL)), POOL, 0, POOL, []
start = 0
for _ in range(NSTEPS):
new_start = start + STEP
want = set(range(new_start, new_start + POOL))
out = sorted(resident - want)
inn = sorted(want - resident)
resident = want
loads += len(inn)
evictions += len(out)
max_res = max(max_res, len(resident))
steps.append(dict(start=new_start, evicted=out, loaded=inn))
start = new_start
R = dict(
ram_kb=RAM_KB, level_mb=LEVEL_MB, level_to_ram_ratio=LEVEL_MB * 1024 / RAM_KB, # 8.0
page_kb=PAGE_KB, pages_in_level=pages, pool_pages=POOL, pool_kb=pool_kb, rest_of_ram_kb=RAM_KB - pool_kb,
max_resident_pages=max_res, steps=steps, loads_after_start=loads - POOL, evictions=evictions,
initial_pages=list(range(POOL)),
note="ILLUSTRATION / our re-run. Page size, pool size and RAM are Gavin's stated numbers; the walk is ours.")
Path(__file__).with_name("repro.json").write_text(json.dumps(R, indent=1) + "\n")
print(json.dumps({k: v for k, v in R.items() if k != "steps"}, indent=1))
Sources
- https://all-things-andy-gavin.com/2011/02/04/making-crash-bandicoot-part-3/
- https://all-things-andy-gavin.com/2011/02/16/crash-bandicoot-an-outsiders-perspective-part-8/
- https://arstechnica.com/gaming/2020/02/war-stories-how-crash-bandicoot-hacked-the-original-playstation
- https://cdn.arstechnica.net/wp-content/uploads/2020/02/crash_tscript.txt
Ariane 5 Died on One Number Over 32,767
The real code, our re-runs and every source: https://code.mygearhut.com
Run it yourself: our Python re-run (42 lines)
#!/usr/bin/env python3
"""ILLUSTRATION: our re-run of the arithmetic behind Ariane 501 (not the flight code, not the real BH values).
A 64-bit float converted to a signed 16-bit integer. The flight code was Ada, where an out-of-range conversion raised an
Operand Error; Python shows the same limit with struct (refuses) and ctypes (silently wraps).
python3 -I data/repro.py -> data/repro.json (deterministic)."""
import ctypes, json, struct
from pathlib import Path
INT16_MIN, INT16_MAX = -32768, 32767
class OperandError(Exception):
"""stand-in for the Ada exception the Inquiry Board report names"""
def to_int16_checked(x: float) -> int:
"""the Ada-style idea: convert, raise if it does not fit"""
n = int(x)
if not INT16_MIN <= n <= INT16_MAX:
raise OperandError(f"{x!r} does not fit in 16 bits")
return n
rows = []
for x in (1000.0, 32767.0, 32768.0, 40000.5, 65536.0):
try:
out, ok = to_int16_checked(x), True
except OperandError:
out, ok = None, False
try:
struct.pack("<h", int(x)); packs = True
except struct.error:
packs = False
rows.append(dict(value=x, fits_int16=ok, checked_result=out, struct_h_accepts=packs, ctypes_wrapped=ctypes.c_int16(int(x)).value,
bits16=format(ctypes.c_uint16(int(x)).value, "016b")))
res = dict(label="ILLUSTRATION: our re-run, not flight data", int16_min=INT16_MIN, int16_max=INT16_MAX, hex_max="0x7FFF",
bits_max=format(INT16_MAX, "016b"), bits_over=format(32768, "016b"), float_bits=64, int_bits=16, rows=rows)
assert INT16_MAX == 2 ** 15 - 1 == 0x7FFF
assert [r["fits_int16"] for r in rows] == [True, True, False, False, False]
assert rows[2]["ctypes_wrapped"] == -32768 and rows[3]["ctypes_wrapped"] == -25536 and rows[4]["ctypes_wrapped"] == 0
Path(__file__).with_name("repro.json").write_text(json.dumps(res, indent=1) + "\n")
print(json.dumps(res["rows"]))