You’re the sheriff of a small town, investigating news about a gangster squad passing by. Rumor has it they’re easy to outsmart, so you have just followed one to their encampment by the river. You know you can easily take them out one by one, if you would just know their secret handshake..
$file gunpoint_2daf5fe3fb236b398ff9e5705a058a7f.dat gunpoint_2daf5fe3fb236b398ff9e5705a058a7f.dat: Gameboy ROM: "FLUX", [ROM ONLY], ROM: 256Kbit
Nice, a gameboy ROM. Searching for
gameboy emulator gets us
Visual Boy Advance as the first result. We need to
change the extension to
gbc to be able to open the file in the emulator.
After running the game for some time or doing
toggle, we get:
So probably we need to guess the secret key combination. Fortunately emulator has also dissasembler and IDA is also able to dissaseble the code. Here is some thorough description of Gameboy hardware. The most interesting part is here:
FF00 Name - P1 Contents - Register for reading joy pad info and determining system type. (R/W) Bit 7 - Not used Bit 6 - Not used Bit 5 - P15 out port Bit 4 - P14 out port Bit 3 - P13 in port Bit 2 - P12 in port Bit 1 - P11 in port Bit 0 - P10 in port This is the matrix layout for register $FF00: P14 P15 | | P10-------O-Right----O-A | | P11-------O-Left-----O-B | | P12-------O-Up-------O-Select | | P13-------O-Down-----O-Start | | Example code: Game: Ms. Pacman Address: $3b1 LD A,$20 <- bit 5 = $20 LD ($FF00),A <- select P14 by setting it low LD A,($FF00) LD A,($FF00) <- wait a few cycles CPL <- complement A AND $0F <- get only first 4 bits SWAP A <- swap it LD B,A <- store A in B LD A,$10 LD ($FF00),A <- select P15 by setting it low LD A,($FF00) LD A,($FF00) LD A,($FF00) LD A,($FF00) LD A,($FF00) LD A,($FF00) <- Wait a few MORE cycles CPL <- complement (invert) AND $0F <- get first 4 bits OR B <- put A and B together LD B,A <- store A in D LD A,($FF8B) <- read old joy data from ram XOR B <- toggle w/current button bit AND B <- get current button bit back LD ($FF8C),A <- save in new Joydata storage LD A,B <- put original value in A LD ($FF8B),A <- store it as old joy data LD A,$30 <- deselect P14 and P15 LD ($FF00),A <- RESET Joypad RET <- Return from Subroutine The button values using the above method are such: $80 - Start $8 - Down $40 - Select $4 - Up $20 - B $2 - Left $10 - A $1 - Right Let's say we held down A, Start, and Up. The value returned in accumulator A would be $94
If we go to
Tools->Dissasemble then we have a fairly good chance we land up in
the code that is almost the same. (If not press
Next few times) We can see
that the result of the key presses are stored in addresses
Counter at address
C0A0 is increased each time we press the correct key. Using
Tools->Memory viewer we can see when we press the correct key. The sequence is
up, left, down, right, up, left, down, right, B, B A, A.
Flag is tkCXDJheQDNRN
###Other write-ups and resources