The Challenge
revme is an x86-64 ELF binary for reverse engineering. It contains a global symbol target holding 36 bytes of transformed data. The binary applies a series of transforms to a flag string and stores the result; your job is to invert those transforms and read the original.
Approach
Opening the binary in a decompiler, the transformation on each byte at index i is:
- XOR with
0x37 - Left-rotate by
(i % 8)bits - Add
i(mod 256)
Then the entire array is reversed before being stored as target.
To recover the flag, apply the inverse operations in reverse order:
- Reverse the array back to original ordering
- Subtract
i(mod 256) from each byte - Right-rotate by
(i % 8)bits (invert the left-rotate) - XOR with
0x37(XOR is its own inverse)
pwntools’ ELF parser makes reading named symbols from a binary trivial, so I didn’t need to manually extract bytes from the binary in a hex editor.
Solution
|
|
exe.symbols['target'] gives the virtual address of the symbol; exe.read(addr, 36) reads the 36 bytes from that offset in the binary file. The transforms are then applied in inverse order: first reverse the array (undoing the final storage reversal), then subtract i, then right-rotate by i % 8, then XOR with 0x37.
The ror helper computes an 8-bit right-rotation: shift right by n, shift left by 8-n, mask to 8 bits. Standard trick.
Running the script prints flag{reverse_me_if_you_can_5c0e9b38}.
What I Learned
When the transforms are applied in sequence and then the array is reversed, you have to be careful about the order of inversion — you undo the reversal first, then apply the per-byte inverses in the same positional order the forward transforms used. Getting that wrong shifts all the indices by one and produces garbage.