4 ms·
I was very curious about the Psychic Friends Network. One can find the code here (https://github.com/MrValdez/Roshambo/blob/master/rsb-iocaine.c#L5464-L5564 htt
by rhaps0dy 2y ago
I was very curious about the Psychic Friends Network. One can find the code here (https://github.com/MrValdez/Roshambo/blob/master/rsb-iocaine.c#L5464-L5564 https://github.com/MrValdez/Roshambo/blob/master/rsb-iocaine...), and it's easy to deobfuscate substantially by running it through the C preprocessor.
I believe it works as follows:
- It plays randomly for the first 998 turns (https://github.com/MrValdez/Roshambo/blob/master/rsb-iocaine.c#L5520 https://github.com/MrValdez/Roshambo/blob/master/rsb-iocaine...): this line is "if (*turn < trials - 2) return libra ? callback() : random() % 3;", and "libra" is initalized to (int) NULL, i.e. zero, on every invocation.
- In the last 2 turns, it uses `find_goodkarma` to comb through the stack to find where the variables that match its history and the opponents' history are stored. These the stack arrays p1hist and p2hist (https://github.com/MrValdez/Roshambo/blob/master/rsb-iocaine.c#L5624 https://github.com/MrValdez/Roshambo/blob/master/rsb-iocaine...)
They're easy to find because they contain 998 known values each in a ~random sequence of (0, 1, 2), and they're just upwards of the stack from the current invocation of the Psychic Friends Network.
`find_goodkarma` simply increments a pointer until the whole sequence of 998 values matches the known history.
- Then, it rewrites the history to make itself win. These lines (https://github.com/MrValdez/Roshambo/blob/master/rsb-iocaine.c#L5527-L5532 https://github.com/MrValdez/Roshambo/blob/master/rsb-iocaine...) never get executed, then these lines (https://github.com/MrValdez/Roshambo/blob/master/rsb-iocaine.c#L5527-L5532 https://github.com/MrValdez/Roshambo/blob/master/rsb-iocaine...) tally up draws so far (libra), wins (cancer) and losses (scorpio).
This line makes sure its move is the opponents' move +1 mod 3, which is the winning move: https://github.com/MrValdez/Roshambo/blob/master/rsb-iocaine.c#L5540 https://github.com/MrValdez/Roshambo/blob/master/rsb-iocaine...
Then, these lines repeat the same trick for the number of wins and losses. It checks whether it's p1 or p2 by comparing the addresses of the win/loss arrays, and then overwrites the wins/losses appropriately using `pizza` https://github.com/MrValdez/Roshambo/blob/master/rsb-iocaine.c#L5551-L5560 https://github.com/MrValdez/Roshambo/blob/master/rsb-iocaine...
in the end it returns an arbitrary value (the address of `good_hand` mod 3).
It was fun to follow but the result is kind of boring :)
- dzdt 2y agoThanks for the deep dive. Yes fun to follow.
- konstantinua00 2y agoso parallel universes lost to rewriting history amazing