How To Cheat Ren'py Games 2017

Learn how to hack facebook games for unlimited coins, cheats, lifes, etc. Using Google Chrome, Cheat Engine, and a calculator. Expanded Mod is a collection of mods for the game Rogue-Like: Evolution, which is being developed by Oni. It has several contributors and aims to add several new things to the game, such as clothes, characters, events/locations and new features. How to play the Github version: Download Ren'Py 6.99.13 here and extract it somewhere.

How To Cheat Ren'py Games 2017 Pc

Some time ago (September 3, 2013, apparently), I had just finished readingAnalogue: A Hate Story (which I highly recommend, bythe way) and was particularly taken with the art. At that point it seems myengineer’s instincts kicked in and it seemed reasonable to reverse-engineer theresource archives to extract the art for my own nefarious purposes.

A little examination of the game files revealed a convenient truth: it was builtwith Ren’Py, a (open-source) visualnovel engine written in Python.Python is a language I’m quite familiar with, so the actual task promised to bewell within my expertise.

Code

Long story short, I’ve build some rudimentary tools for working with compiledRen’py data. You can get it from my repository onBitBucket. Technically-inclined readersmight also want to follow along in the code while reading.

Background

How to cheat ren

There are a large number of games designed with Ren’py. It’s an easy tool to getstarted with and hack on, since the script language is fairly simple and becauseit’s open-source, more sophisticated users are free to bend it to their will. Afew examples of (in my opinion) high-quality things built with the engine:

Ren'py

  • Analogue: A Hate Story and Hate Plus
  • Dysfunctional Systems: Learning to Manage Chaos (and the planned sequels)

Since visual novels tend to live or die on the combination of art and writing,the ability to examine the assets outside the game environment offersinteresting possibilities.

Since it was handy, I started my experimentation with Analogue.

RPA resource archives

The largest files distributed with the game were .rpa files, so I investigatedthose first for finding art. As it turned out, this was exactly the place Ineeded to look. Start by examining the raw data:

How

There’s an obvious file identifier (RPA-3.0), followed by a couple numbers anda lot of compressed-looking data. The first number turns out to be very close tothe total file size, so it’s probably some size or offset field, while the otherone looks like some kind of signature.

At this point I simply referred to the Ren’Py source code, rather than wastetime experimenting on the data itself. Turns out the first number is the fileoffset of the index, and the second one is a key used for simple obfuscation ofelements of the index (numbers are bitwise exclusive-or’d with the key). Thearchive index itself is aDEFLATE-compressed block ofpickled Python objects. Theindex maps file names to tuples of offset and block length specifying wherewithin the archive file the data can be found.

With that knowledge in hand, it’s short work to build a decoder for the indexdata and dump it all to files. This is rpa.py in my tools. Extracting thearchives pulls out plenty of images and other media, as well as a number ofinteresting-looking .rpyb files, which we’ll discuss shortly.

Cosplay

For a bit of amusement, I exercised my web-programming chops a little and builta standalone web page for playing with the extracted costumes and expressions of*Hyun-ae and *Mute, which I’ve included below. Here’s alink to the bare page for standaloneamusement as well.

Script guts

The basic format of compiled scripts (.rpyb files) is similar to that ofresource packages. The entire thing is a tuple of (data, statements), wheredata is a dictionary of basic metadata and statements is a list of objectsrepresenting the script’s code.

The statements in this are just the Ren’py abstract syntax tree, so all theobjects come from the renpy.ast module. Unfortunately and as I’ll discusslater, the pickle format makes this representation hard to work with.

The structure of AST members is designed such that each object can have attachedbytecode. In practice this appears to never happen in archives. In myinvestigations of the source, it appears that Ren’py only writes Python bytecodeas a performance enhancement, and most of it ends up in bytecode.rpyb. Thatfile appears to provide some sort of bytecode cache that overrides script filesin certain situations. For the purposes of reverse-engineering this isfortunate– Python bytecode is documented, but rather more difficult totranslate into something human-readable than the source code that is actuallypresent in RPYB archives.

Here’s some of the Act 1 script from Analogue run through the current version ofmy script decompiler:

Clearly there are a few things my decompiler needs to learn about. It does,however, handle the more common block elements such as If statements. In anycase, the Python code embedded in these scripts tends to be more interestingthan the rest (which are mostly just dialogue and display manipulation) for thepurposes of reverse-engineering. If you’re more interested in spoiling the gamefor yourself, it’s not as useful.

A few telling bits of logic from options.rpy:

The spacing here is interesting; I suspect (but haven’t attempted to verify)that the Ren’py script compiler strips comments since there haven’t been any inall of the scripts I’ve examined, so it’s likely that the unusual empty blocksin the code were comment blocks in a former life.

I’ve yet to dig much into what determines when demo_mode is set, but I doubtit would be difficult to forcibly set (or clear) if one were so inclined. Notthat I condone such an action..

A little bit of interesting game-critical logic, also from Analogue (caution:minor spoilers)

You can get some idea of how specialized Ren’py’s execution environment is fromthis code. Particularly, store is a magic value injected into the locals ofPython script blocks which maps to the RPY persistent variable store, whichstores most of the game state. config is a similar magic value providing ahandle to the engine configuration.

In this instance, radiation refers to a sort of hidden timer which forces theplayer to solve a puzzle on expiration (assuming the preconditions have beenmet), then make a decision which causes the plot to fork depending on thatdecision. Elsewhere in the code, I found a few developer switches which allowone to display the value of this countdown and reset or force it.

Conclusions

2017

As the officialdocumentation notes, theprocess of resource compilation is not very secure but is enough to deter casualcopying. I’ve shown here that such a claim is entirely correct, though scriptdecompilation may be somewhat harder than the developers envisioned due to thechoice of pickle as a serialization format.

It’s nothing particularly new to me, but a reminder to designers of software: ifit runs on your attacker’s system, it can be hacked. It’s not a question of“if”, but instead “how fast”. I was mostly interested in extracting resourceswith this project, which was quite easy. In that matter, I think the designersof Ren’Py made a good design decision. The compiled archives and scripts aremuch more robust against accidental modification in the face of curious usersthan not compiling anything, but the developers do not expend undue effortbuilding something harder to break which would eventually be broken anyway by asufficiently determined attacker.

Portability

As I alluded to earlier, the pickle representation makes the Ren’Py AST hard towork with. This is because many of the objects contain references to the enginestate, which in turn implies most of the engine needs to be initialized whenunpickling the AST. To say the least, this is not easy- engine initialization isnot easily separated from game startup.

To illustrate the problem, observe that the Ren’Py developer kit is simply theengine itself packaged with a game of sorts that provides help in getting a newproject set up by modifying the included scripts. There simply seems to be nopart of the engine that is designed to run without the rest of it running aswell.

In experimenting with different products built with Ren’Py, I’ve had to makechanges to some combination of the engine itself and my code in order tobootstrap the engine state to a point where the AST can be successfullyunpickled. Suffice to say, this has hampered my progress somewhat, and led me toconsider slightly different avenues of attack.

The most promising of these would involve a semi-custom unpickler which avoidsinstantiating actual Ren’Py objects; the only data that need be preserved is thestructural information, rather than the many hooks into engine state that arealso included in the pickle serialization. Further continuation of this projectis likely to take this approach to deserialization.