Follow MyGearHutYouTubeInstagramFacebookmygearhut.com

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 first
Run 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

Watch the video

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

Watch the video

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

Watch the video

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

Watch the video

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

Watch the video

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"]))

Sources

Watch the video

Follow MyGearHutYouTubeInstagramFacebookmygearhut.com