Description
Now you must occasionally beat the Imp. Modify the warrior to something more aggressive, such as the documented "Imp Ex" example.
Setup
Replace the original Imp with a more capable warrior (Imp Ex is the canonical example).
Submit the modified file via nc saturn.picoctf.net 63042 and win at least one round.
cat <<'RED' > imp.red
;redcode-94
;name Imp Ex
add #4, 3
mov 2, @2
jmp -2
dat #0, #0
end
REDnc saturn.picoctf.net 63042 < imp.redSolution
Want to try it yourself first?
The guided walkthrough reveals hints one step at a time.
Step 1
Adopt a published warriorObservationI noticed the challenge description explicitly called out the documented 'Imp Ex' example and that the original Imp (a simple MOV loop) never writes DAT kill instructions, which suggested replacing it entirely with a published bomber-class warrior rather than trying to patch the Imp.Imp Ex from the Core War docs beats a stock Imp close to 100 percent of the time. One copy is enough for at least one round win.What didn't work first
Tried: Trying to modify the original Imp by making it move faster or duplicate itself.
Tweaking the Imp's single MOV instruction (changing the stride or adding copies) rarely turns it into a winner because the Imp's inherent weakness is that it never writes DAT kill instructions. No matter how many copies run, they can't kill the opponent. The correct approach is to switch to a completely different warrior class - a bomber - that actively plants fatal DAT traps across memory.
Tried: Writing a warrior from scratch without referencing the Core War documentation, guessing at Redcode syntax.
Redcode has specific addressing modes and opcode rules that are easy to get wrong from intuition alone (for example, confusing immediate '#' with direct addressing, or forgetting that offsets are relative to the current instruction). A hand-crafted warrior with syntax errors will be silently rejected or fail to compile on the server. Using a documented working warrior like Imp Ex guarantees a valid baseline.
Learn more
Imp Ex (Imp Exterminator) is the textbook anti-Imp warrior. It is a tiny bomber that writes
DATinstructions across memory faster than the Imp can run, killing the Imp's process when execution lands on a bombed cell. Empirically, Imp Ex (or any tuned 4-stride bomber against a 1-stride Imp) wins close to 100 percent of stock-Imp matches when offsets are randomised.The server runs ICWS-94 Redcode (the modern standard). The header line
;redcode-94tells the parser which dialect to use; without it some servers fall back to the 1988 standard, which lacks the instruction modifiers (.ab, .i, etc.) that newer warriors rely on. Sticking with the trio of unmodified opcodesadd,mov,jmpin the snippet above keeps it portable across both dialects.Quick addressing-mode reference for reading other warriors:
# immediate -> the literal value (e.g. add #4, 3 adds 4) direct -> offset from current instruction (no prefix) @ indirect -> follow the B-field of the target cell, then dereference < pre-decrement -> decrement target's B-field, then use it indirectly > post-increment-> use indirectly, then increment target's B-field * A-indirect -> like @ but follow A-field (ICWS-94 only) { A-pre-decr -> ICWS-94 } A-post-incr -> ICWS-94 $ direct (94) -> explicit form of no-prefix directWalking through Imp Ex line by line.
add #4, 3adds the literal 4 to the B-field of instruction at offset +3 (thedat #0, #0bomb pointer), so the bomb's target advances by 4 each iteration.mov 2, @2copies the instruction at offset +2 (thedatbomb itself) to the address pointed to indirectly by instruction +2's B-field, dropping a death trap.jmp -2loops back to theadd. Theaddmutates the bomb pointer in place, so each cycle bombs a fresh cell on a stride of 4 covering the entire Imp's sweep path.Other warriors worth keeping in your back pocket: Dwarf is the original 4-stride bomber and is even shorter than Imp Ex; Tiger is a faster bomber with a 5-cell stride that historically scored well on the Hill. Cross-checking your result against multiple warriors helps confirm the server is not silently rejecting one of them on parse error.
Step 2
Collect the rewardObservationI noticed the server runs 100 rounds and only prints the flag in the final summary, which meant the connection had to be kept open for the full run rather than closed after the first visible win.Once 100 matches finish, the service prints the flag in the summary. Anything north of 1 win clears the threshold.What didn't work first
Tried: Disconnecting from nc after the first win result appears, before the 100-round summary is printed.
The flag is only printed in the final summary after all 100 rounds complete. Closing the connection early (Ctrl+C) or piping the input without letting the server finish terminates the session before the flag appears. Let the server run all 100 rounds and read the full output.
Learn more
"At least one round" is the lenient bar. A bomber that wins close to 100 of 100 makes the test pass on the first connect. The 100-round format is statistical: random starting offsets vary how the warriors meet, so partial-win warriors prove they are genuinely capable rather than getting one lucky pairing.
The progression across the three Ready Gladiator challenges (lose all, win some, win all) mirrors strategy work in CTFs more broadly: understand the game, achieve partial success, then turn the corner to consistent wins.
Flag
Reveal flag
picoCTF{1mp_1n...5_...}
Any warrior capable of beating the Imp at least once will work; Imp Ex is a handy template.