← Back to Writeups
CUSTOMMediumReversing

Dog Simulator

XESXOR9/10/20263 min read
#reversing#custom#medium#fnv1a_preimage_z3#macho_arm64_reversing#state_machine_recovery#string_analysis

Dog Simulator

Platform: CUSTOM | Category: Reversing | Type: Challenge | Difficulty: Medium | OS: N/A | **Author: XESXOR Techniques: fnv1a_preimage_z3, macho_arm64_reversing, state_machine_recovery, string_analysis

Summary

Walkthrough of the CUSTOM Reversing Dog Simulator. Task: stripped ARM64 Mach-O 'Dog Simulator' game requiring a correct 6-day action routine. Solution: reverse the state machine, recover the fixed action order plus two Speak commands — a 12-letter FNV

Description

If you can survive 6 dog-days of walkies, tricks, and zoomies, you might uncover a secret (if you can stick to the right routine in the right order)!

A "Dog Simulator" game binary (stripped ARM64 Mach-O, PIE, dynamically linked to libSystem). Over 6 days you choose menu actions. State (Score, Bond, Energy, Mood) is tracked, and at the finale the owner either prints a garbled failure message or reveals the flag if the correct routine was followed in the correct order. Goal: recover the exact six-day routine.

Analysis

The whole program logic lives in a single stripped function (0x100000500). Actions deterministically update Score, Bond, Energy, and Mood (calm/hyped/overstimulated/sleepy), and advance a four-stage combo counter. The finale gates the flag on all of the following:

  • exactly one Bark, one Fetch, one Sit, one Eat; zero Zoomies; two Speak actions
  • final Score == 55, Bond > 24, Energy > 20, Mood != overstimulated
  • combo state reaches 4 (right actions in the right order)
  • total alphabetic Speak letters == 19
  • two FNV-1a hash constants must match (combo hash + transcript hash)

Speak normalizes input to lowercase alphabetic and hashes it with FNV-1a (offset basis 0x811c9dc5, prime 0x01000193):

  • The first Speak (at combo state 3) must hash to 0x9f58d866. Any 12-letter lowercase preimage works — this explains the "the words feel the wrong length" failure when a baseline (e.g. six barks) is used: the spoken letters never reach the expected total length of 19.
  • The second Speak must normalize exactly to gremlin — the name the owner calls the dog in the day-6 line "Last day of the week, little gremlin." This triggers "(He seems to fixate on what your owner called you.)" and adds the final 7 letters (12 + 7 = 19).

Key finale strings recovered:

  • Owner: awww he said "%s" — success path prints the flag
  • Owner: he tried to say it, but it came out garbled.
  • Owner: the routine felt right, but the timing was off.
  • Owner: he keeps trying to say something... but the words feel the wrong length.
  • (Good boy! combo completed!)

Solution

The correct six-day routine (menu sequence 2,3,1,6,4,6):

  1. Fetch
  2. Sit
  3. Bark
  4. Speak: naxxzpxhhzgk (12-letter FNV-1a preimage of 0x9f58d866)
  5. Eat
  6. Speak: gremlin (owner-name from day-6 dialogue)

Recover the 12-letter preimage with Z3:

python
#!/usr/bin/env python3
from z3 import *
c = [BitVec(f'c{i}', 32) for i in range(12)]
s = Solver()
for x in c:
    s.add(x >= ord('a'), x <= ord('z'))
h = BitVecVal(0x811c9dc5, 32)          # FNV-1a offset basis
for x in c:
    h = (h ^ x) * 0x01000193           # FNV-1a prime
s.add(h == 0x9f58d866)                 # target combo hash
print(s.check())
m = s.model()
print(''.join(chr(m[x].as_long()) for x in c))   # -> naxxzpxhhzgk

Drive the binary (press Enter to begin, then feed choices/commands):

bash
printf '\n2\n3\n1\n6\nnaxxzpxhhzgk\n4\n6\ngremlin\n' | ./dog-sim-mac

Final state on success: Score=55 Bond=30 Energy=36 Mood=calm, Speak total letters 19, and the finale prints:

Owner: awww he said "bronco{REDACTED}"

Key Takeaways / Lessons

  • Mastering fnv1a_preimage_z3, macho_arm64_reversing, state_machine_recovery, string_analysis was key to this challenge.
  • Always check for common misconfigurations and verify assumptions.

Crafted by XESXOR Research • 2026-07-11 • CUSTOM • Dog Simulator • Difficulty: Medium