lucia's profile picture

Published by

published

Category: Web, HTML, Tech

shenanigans in creating a deterministic patch of TIQ2

introduction

most of my time spent reverse engineering has been for the impossible quiz series, namely the first game. however, a few weeks ago, i was asked to create a deterministic edition, a version of the game where all randomness is removed, for the second game, which id never even played!! id never dealt with PRNG (pseudo-random number generation) in flash before so naturally, i had to start learning!!


naive approach

my first approach was similar to my level chooser for the original game, where it would patch the code of flash player directly, in this case, making the random number generator always return the same value. looking back,,, this is an INSANE idea, and no one in their right mind would ever do this as their first choice but......... hindsight is 20/20 aint it?

BUT! i started first with a simple google search about the PRNG, and found this insanely helpful paper! with these constants in hand (mainly using 789221/0xC0AE5), i could find the offset of the function in the source code, which is the first step!

disassembled PRNG code

looking at this, its quite clear that all of this is ultimately going to get stored in the eax register at the end (see sub eax, ecx at the end), so itd be real easy to modify this to give any number we want! we could just do mov eax, 0x3 to move 3 into the register, for example.

bad news though. the assembled code for mov eax, 0x3 is 0xB803000000, and the assembled code for sub eax, ecx is 0x2bc1! now, it doesnt take an expert to see that we have too many bytes to insert!! simple solution though, the previous lines assembled code is 0xc1f915, which combined with the next line, is the exact same length as the code we need to insert!

one last hurdle here! we need to find out what the values actually need to be when we randomize them, being able to set numbers without knowing what it has to be aint too useful!!

soooo, lets bust open JPEXS to see how the random numbers are actually used! heres an example for q5

well nice! we now know that if n = 0, itll play frame 2 of the sprite (here, would make the player type "ARSE"), if n = 1, itll play frame 3 of the sprite (theyd have to type "CARROT"), and if n = 2, itll play frame (theyd have to type "UDDER"). so, now we get to set the random number to whatever we want when injecting!

well. actually, fuck. if we have this code here, couldn't we just change it here, and not have to deal with the complicated assembly injection, and forcing the user to install a sketchy program that literally modifies the running code of a program doesnt.. look great... so! this is the end of the naive attempt! now for the actual solution that i ended up using.


final approach

well, given the new obvious approach, its easy to make it! we just gotta set n to whatever the correct number is for our desired "random" choice, and boom! deterministic.

so, for example, for q5 as we discussed before, the best option is n = 0, since "ARSE" is the quickest for the user to type. so, all thats left was to consult the discord for which answers were optimal!

so, here are the following deterministic questions:

q5 - ARSE

q17 - the brown balloon shows up at the very far left

q45 - the answer is tom cruise (not optimal, any question is abt the same speed?)

q49 - 43?9⏎

q70 - chris takes 3 punches

q87 - the egg is at 1:00 (again, just randomly chosen, nothing has an advantage)

q91 - you can click after ~1 sec

q107 - pick the bottom left

q110 - the sequence where the red square starts in the bottom left

q117 - psychedelic boogie child

q120 - 43


now, one final issue. cheating! how can we make sure people don't use this to pass off as a legitimate run!!

well it aint that big of an issue, theres about a 1 in 60 million chance of getting the same randomization as the deterministic edition, so there really isnt a way to get the same in any reasonable amount of time. but, the mods wanted it, so i implemented a watermark (not saying here for obvious reason!!)


release

well, now that we got all of that done, were able to release it! it took 4 tries to get it right, first few times i literally forgot certain questions?? whatever, after that got ironed out, i was finally able to release it, and deterministic any% became the newest category on speedrun.com!

thanks for reading my rambling! if youre interested, you can get the file here!


2 Kudos

Comments

Displaying 0 of 0 comments ( View all | Add Comment )