Challenge author: m0ezk
Heyo stranger, I really need ur help! My PC hasn't been working for the past few days and the only thing I'm left with are my savefiles (I always have them on my USB-Stick, just in case). I need to know what's next in my favorite video game, could you please load these savefiles and tell me the following dialogue, please, I can't wait any longer!
Here's a link to the game, you can even run it easily on Linux: https://teamsalvato.itch.io/ddlc
I don't know how to contact you, so just text me the dialogue as a flag, ok? So if the dialogue says:"Sayori, what is up with you.." Then just send
flag{Sayori,_what_is_up_with_you..}
I'd be really REALLY thankful if you'd do that!
The challenge features the game Doki Doki Literature Club. The task is simple. Load up the save game and paste the content of the next dialog.
We have never touched Doki Doki before. I in particular have no even seen it on YouTube or Twitch. What you get in this writeup is the full experience of starting a challenge with zero knowledge.
A quick online search reveals that the save games live in our user home folder. For linux
that's ~/.renpy/DDLC-1454445547
(where DDLC-1454445547
like a unique id of the game).
When we just run the game, it will create the folder for us, and place a persistent
file in it. So that seems to be
like a game config file of some kind.
When we save the game, it will create a .save file.
Placing the challenge files in this folder brings up the save game in the Load Game screen.
However loading the save game brings up the message "The save file could not be loaded. Are you trying to cheat?", followed by a monologue of a girl named "Monika" mocking us.
Fair enough. The game seems rather well known. There surely is a community for it and the anti cheat is should already been defeated, right?
A quick search for Doki Doki Anticheat brings up a couple of results. Even some people that got this screen, but no solution. And no in-depth details, which was astounding. The closest we could find was:
https://icecrownserver.fandom.com/wiki/DDLC_Anticheat
This describes the anti cheat as following:
The game stores a save-irrespective persistent anticheat value, and a save stores a separate anticheat variable. These are compared to check for cheating. To ensure that a player doesn't accidentally trigger the anti-cheat event, save files are deleted whenever the anticheat variable is updated.
Dissecting the savegame
We concluded that this means one value is in the save game and one is in the persistent file. Not knowing any of the formats, we started looking for a save game editor. Doki Doki Savegame Editor resulted in nothing, but Renpy Savegame Editor gave a couple of online editors. Great! We used:
https://saveeditor.online/
The save game has a lot of values. Searching for anticheat will give two results:
At this point we assume that one anticheat value 420
.
From reading other writeups, we now know that we could have unticked the box and anticheat would have been disabled. We did not have that idea. Probably due to a mixture of anime school girl overflow and lack of sleep.
Dissecting persistence data
We read through the Persistent Data documentation of RenPy, but it did not reveal anything about the format of that file.
We found hints to a UnRen.bat
, but we were lacking the Windows environment to run it and did not feel like messing
with wine.
In some gist I am now unable to find again, we found this snippet:
python -c "import zlib; open('persistent.pickle', 'wb').write(zlib.decompress(open('persistent', 'rb').read()))"
This lead to us believing that it might be just a zlib compressed pickle file. And sure enough, it was. Using pickletools on the decompressed file was a success.
python3 -m pickletools persistent.pickle | less
The other anticheat value seems to be 1337
.
Fixing the savegame
According to the Wiki Entry we found, these values need to be the same. We already have the save game open in a savegame editor. Patching the save game sounds like the easiest way right now.
That's it. The flag is flag{...There_is_no_way_I'm_going_to_your_club.}
.