Patch Tuesday

Runtime opcode patch (`jz` → `jnz`)

2026.09.30 NNS CTF 2026 113 pts Reversing
FLAG NNS{1_h0p3_y0u_p47ch3d_7h3_0pc0d3_dur1ng_run71m3_jnz_15_much_b3773r_7h4n_jz}

This challenge is part of a set written up together in ctf/writeup.txt. Shared context for that set:

All 6 “beginner” tier Reverse Engineering challenges were solved via pure static analysis (radare2 / objdump / Python), no interactive debugging required. Each binary encodes/XOR-obfuscates the flag with a small pseudo-random-number-generator (LCG) keystream, seeded and iterated with constants recovered from the disassembly. Recovering the flag is simply a matter of re-implementing the same PRNG in Python and applying it to the encoded bytes pulled straight out of the binary. Binary: PE32+ (Windows) console EXE.

entry0 reads a password, calls fcn.140001160 to validate it, then does test eax,eax; je <sorry> — i.e. only reaches the “print the flag” branch if the check function returns non-zero. The intended solve is to patch the conditional jump in a debugger (as the description suggests). However, the flag-printing branch is completely static: it XORs a 76-byte blob at 0x140003000 with the constant byte 0x5a and writes the result to stdout, regardless of what the password check actually computed. So we don’t need to patch anything at runtime — just XOR the embedded blob with 0x5a in Python.

Flag: NNS{1_h0p3_y0u_p47ch3d_7h3_0pc0d3_dur1ng_run71m3_jnz_15_much_b3773r_7h4n_jz}