good-girl — Solving a Lookup-Table Validation CrackMe
Translating decompiled integer-validation logic into a mathematical constraint and finding valid command-line arguments.
Objective
The good-girl CrackMe prints either good girl! or bad girl!. The challenge was to determine the accepted argument format and find inputs that trigger the positive result.
Reconstructing the input model
Ghidra analysis showed that the executable requires exactly eight integer arguments (so argc == 9 when counting the program name). The eight numbers form four pairs of coordinates. Each coordinate is within the range 0 through 3 and selects an integer from a 4×4 lookup table.
for each (x, y) pair:
sum += table[x * 4 + y]
if sum == 0:
print("good girl!")
else:
print("bad girl!")
Recovered lookup table
| x \ y | 0 | 1 | 2 | 3 |
|---|---|---|---|---|
| 0 | 11 | 13 | 23 | -7 |
| 1 | -27 | 107 | -53 | 41 |
| 2 | 67 | -51 | 253 | -143 |
| 3 | -119 | 101 | 401 | -391 |
Manual solution
I selected four coordinate pairs whose table entries sum to zero: (0,0), (0,2), (0,3), and (1,0). Their values satisfy:
11 + 23 - 7 - 27 = 0
The command-line test documented in the report was:
chmod +x good-girl
./good-girl 0 0 0 2 0 3 1 0
# good girl!
Automating solution discovery
With the constraint reconstructed, I wrote a Python utility to enumerate coordinate combinations, calculate the four selected table values, and report inputs for which the total equals zero. Its command-line interface supported checking a candidate and printing multiple valid solutions. The report documents a run displaying twenty example solutions.
from itertools import product
table = [11, 13, 23, -7,
-27, 107, -53, 41,
67, -51, 253, -143,
-119, 101, 401, -391]
for coords in product(range(4), repeat=8):
total = sum(table[coords[i] * 4 + coords[i+1]]
for i in range(0, 8, 2))
if total == 0:
print(*coords)
break
Outcome and takeaways
The binary's acceptance rule was a deterministic zero-sum check over a fixed lookup table; no cryptographic key or remote dependency was involved. Reconstructing the validation algorithm made it possible to derive correct inputs manually and automate further searches without patching the executable.
Scope: standalone CrackMe analysis. This is a constraint-solving exercise, not evidence of a vulnerability in an unrelated product.