Thursday, November 15, 2012

Reverse Engineering With Ponies

While it is quite apparent that I don't use this blog with any frequency or regularity, every so often I take on a technical project which I feel is worth documenting, and this is one such case.


TL;DR? Watch the video demo:




About one week ago, Gameloft released a My Little Pony game on iOS and Android devices, and if my Twitter feed is any indication, it has been wildly popular. According to the Google Play page, it already has hundreds of thousands of downloads.


Wanting to see what all the fuss is about, I downloaded the game as well, but only poked around at it for about 15 minutes before deciding it wasn't quite my cup of tea. But not wanting to feel completely left out, I decided it would be a good exercise to see if I could keep up with my friends by way of cheating. 0:)

There are quite a few types of resources in the game, in particular coins and gems. Like many mobile games today, it seems like the game producer's revenue stream (since the game is free to download) is in offering players to option of purchasing more of these resources using real money. So it will come as no surprise that the game has applied some safeguards to naive methods of manipulating the game state. However, since the game can be played completely offline, the entire game state is saved on our device, so we know going into it that this may prove difficult, but not impossible.



Initial Observations

The primary goal was to find a way to manipulate the resources available, i.e. give myself more coins and gems. So my first step was to try running a memory trainer on the process. Here's a quick description of a memory trainer for those unfamiliar:
In general, variables relevant to a video game (heath, money, experience) are stored in the process's memory. A memory trainer attempts to isolate the addresses of these variables in memory, and the manipulate them as desired.
So put another way, I wanted to figure out where the amount of coins I have is kept in memory, and then change it to a significantly larger value. So I dug up a generic memory trainer I'd written previously, and fired it up. I told it to find places in memory that contained a value equal to my current number of coins, but to my surprise, there were no locations in memory containing that value!

Very strange. It looks like the developers over at Gameloft have applied some obfuscation of data in memory to avoid such naive attacks. Kudos for making this a challenge. :D


Having failed at that, the next attack surface I analyzed was the game's save file. It wasn't hard to find (the file is named mlp_save.dat in the game's data directory), but on opening it up in a hex editor, I didn't see any obvious layout to it. But this isn't too surprising since many games just employ a binary data format. So the usual trick is to spot the difference in save files with only minor changes.

So I exported a save file from when I had 3000 coins, and then a second save file from when I had 3300 coins, hoping to spot only a few bytes of difference so that I could identify where this value was being saved. However, to my surprise (once again), the entire file had changed. There were literally only a few dozen (out of ten thousand) bytes that had remained the same. Such a small difference leading to a high variation suggests encryption is in play. Although once again, this game can be played entirely offline, so the encryption and decryption is done locally, which means that the cipher is likely symmetric with a key saved somewhere nearby.

I should say that it's possible that the encryption of the save files could be incidental to some other purpose such as simply to preventing sharing of save files online, but regardless it's certainly a roadblock.


Disassembling and Decompiling

Given that both memory and save files are obfuscated, breaking into this game necessarily requires reverse engineering of the code. Expanding the APK for the game, we can see that it comes with the usual Dalvik classes (in the classes.dex file), but also utilizes a very large JNI library (libPonyWorld.so, which is a surprising 10MB of compiled code). So I grabbed JD-GUI and IDA and went to town on it.


Before even looking at the code, I noticed that the string for the save file name "mlp_save.dat" only appears in the native binary libPonyWorld.so and not in the Java classes, suggesting that the interesting things are going to be happening there. Indeed, after opening up a bunch of the Java classes (which have useful names like aa and ba; I suppose their app was obfuscated with ProGuard or something similar) I found out that the Java code is mostly just graphics/hardware handling. All the interesting game logic looks like it's in the native binary.

I spent about two days coming up with everything in this post, so I won't go through the analysis step-by-step, but here are some of the things I figured out just casually walking around the disassembly.
  • The native code is mostly written in C++.
  • The save files, before they're written to disk, are in an XML format, so it is easy to tell if one has successfully decrypted the save files. Once decrypted, they'll be easy to manipulate as well.
  • Parsing of the XML appears to be done with the open source TinyXML library (which has been embedded in libPonyWorld.so).
  • The player data I originally wanted to manipulate is contained in the PlayerData class, which has GetCoins(void) and GetGems(void) methods: this is probably where I want to look to understand how the player data is obfuscated in memory.

Creating a New Memory Trainer

Since manipulating the save file requires a lot of steps (figuring out the encryption algorithm, figuring out the encryption key, reverse engineering the file structure, etc.), I decided to first see if I could understand why my memory trainer was failing. As mentioned above, the place to look seemed to be the PlayerData::GetGems(void) method. Here's what it looks like in IDA.



An ordinary field getter would just LDR a memory address into R0 and return, so obviously there's something much more interesting going on here. Here's a quick MS-PAINT style mock-up of how I interpret this code.

In words, four integers are loaded from consecutive addresses in memory (specifically addressed relative to the PlayerData structure). As labeled in the picture, I call these integers A, B, C, D.
A and C and XOR'd together, as are B and D. Those two values then have a ROR4 (rotate right by 4 bits) operation applied to them. If those two values aren't equal, exit. (And I don't just mean exit the function, I mean exit the whole program; apparently these guys are serious about not wanting you to poke around in their memory). If they are equal, then return that value.

So in other words, the game keeps two copies of the variable in memory so that if you try to manipulate one, the whole game will crash on you. Further, each copy is obfuscated with a ROR4 operation and then XOR'd with whatever is saved as integers C and D. I immediately suspected that these were integers were random values just there to hide data. And indeed if you find your way to the PlayerData constructor, these memory addresses are given a random value from the lrand48 function.



Given this knowledge, I made a new memory trainer specifically for this game (based on the old memory trainer I dug up) that searches for memory, taking into account the above obfuscation techniques. After a wee bit of trial and error, I met with success!



Reverse Engineering Save Files

With that success under my belt, I wanted to go back to manipulating save files. Based on my observations, the game has an entire SaveManager class dedicated to this task. Again, going through all the steps would take awhile, so here's what I was able to figure out.
  • As mentioned above, the raw save files are in an XML format.
  • The XML is compressed using the zlib library. (version 1.2.3 based on strings I found in the binary).
  • This output is then encrypted using the XXTEA algorithm, and using your GLUID as the encryption key.
  • The GLUID (Gameloft Unique/User Identifier, I think), is unique per device, so no sharing of save files between devices. (Well, at least not until I'm done).
  • The GLUID isn't saved on disk, but it is printed in the logs if you just want to use ADB logcat.
  • Alternatively, the GLUID derivation is actually done in the Java code which is much more readable, so I was able to pretty quickly discern that the GLUID is just an MD5 hash of the phone's IMEI concatenated with the string "com.gameloft.android.ANMP.GloftPOHM". If the device doesn't have an IMEI (i.e. if it's a tablet), then the device's ANDROID_ID is used instead.
  • The output of this MD5 hash is passed around as 4 4-byte signed integers, but there's a bit of funny business that goes on with it. First of all, the bytes from the MD5 hash are turned into integers under big-endian encoding, despite the fact that everything else in our world is little-endian. Why did they code it that way? Because they could.
  • Further, there's some funny mangling that goes on if those integers are negative. More on that below.

Once all that was determined (which was the majority of the time spent on this), I spent a little while staring at the code which actually reads in the raw save file, and determined it has the following format.

+++++++++++++++++++++++++++++++++++++++++++++++++++++++
+   4 Bytes    +   4 Bytes   +  4 Bytes    +          +
+ Uncomp. Size + Compr. Size + Encry. Size +          +
++++++++++++++++++++++++++++++++++++++++++++          +
+                                                     +
+                                                     +
+                                                     +
+               (Arbitrary Size)                      +
+             XXTEA Encrypted Data                    +
+                                                     +
+                                                     +
+                                         +++++++++++++
+                                         +  4 Bytes  +
+                                         + Reserved  +
+++++++++++++++++++++++++++++++++++++++++++++++++++++++

The first 4-byte integer is the size in bytes of the uncompressed save file (i.e. the XML). The next 4-byte integer is the size in bytes of the decrypted data, and the final 4-byte integer in the header is the size in bytes of the encrypted data.

The final 4 bytes appended after the encrypted data (which I labeled as reserved) always have the value 1 (as a four-byte little-endian integer); I suspect this is meant to be a save file format version, but as far as I could see the save file loader doesn't even bother reading those four bytes in.

As a side-note, the code which reads in save files appears to blindly trust the file sizes in the header and then reads in the file to heap space malloc'd accordingly. As such, this seems like an ideal target for a classical buffer overflow attack. I could easily see a crafted save file that triggers arbitrary code execution. But I'll leave that to someone else as a separate project.


As I mentioned, the encrypted data is decrypted with the XXTEA algorithm using the GLUID as the key. The only particular issue I ran in to is the way the game mangles integers in the GLUID that are negative. It took a bit a trial-and-error, but I finally figured out that if an integer X is negative, the game replaces X by 0x7FFFFFFF - X. It's in no way apparent to me why they do this. *shrug*

Furthermore, whether it is a bug or by design, the last of the four integers is mangled in an even more confusing manner. The above operation is only applied to it if the first integer was negative. Why would they do this?! It doesn't even feel like effective obfuscation.

Once the data portion in the middle is decrypted, the output has the following format:

+++++++++++++++++++++++++++++++++++++++++++++++++++++++
+                                                     +
+                                                     +
+                                                     +
+               (Arbitrary Size)                      +
+             zlib Compressed Data                    +
+                                                     +
+                                                     +
+                                       +++++++++++++++
+                                       +   4 Bytes   +
+                                       +   Checksum  +
+++++++++++++++++++++++++++++++++++++++++++++++++++++++


The checksum is a CRC32 hash of the uncompressed data. Incidentally, I discovered that there are quite a few algorithms that call themselves CRC32, so it was some more trial-and-error before I found an open-source implementation that matched the checksums I was looking for.

Finally, after passing the compressed data through zlib, we have the raw XML of the save file. I've uploaded an example here.
There's lots of things you can toy with in the save file. One thing in particular that jumped out at me though:
<Timers TrashTimer="86400" DerpyTimer="25"/>
There's a "DerpyTimer" in the game. Apparently the Gameloft developers have no compunction about calling her by name. ;)


After using an ordinary text editor to change the save file, I just inverted the process to create a new save file and put it back on my phone. Success!




Conclusions

Games that are played offline are inherently hackable. All the game state is local and there's no opportunity for asymmetric encryption since all the keys have to be kept locally. Gameloft has implemented several blockades which made it a non-trivial matter of getting to the save files and applying memory hacking. However, as an amateur reverse engineer it only took me two days to break through all those barriers, so I would hardly describe the game as impenetrable.

As I mentioned in the beginning, I wasn't really that into the game to begin with, but I did really enjoy the challenge to breaking into it. Intentional or not, they provided me with many hours of entertainment. So kudos to Gameloft for supplying me with a challenge that was neither trivial nor intractable.



Tools

I'm releasing both the memory trainer and scripts to pack/unpack save files. Note that the former requires using ADB on a rooted Android device while the game is running. The latter are perl scripts run on your computer, so you don't strictly need a rooted phone (in fact, it will probably work for iPhone saves as well, but I haven't tried it), but you still need a method for getting the save files in and out of your phone (the save files are saved to internal flash, not the SD card). Personally, I use ADB, although there may be other solutions.


mlp_mem_trainer
Usage: Start the game, upload the memory trainer your device, and then run it in a shell. It will prompt you for your current coin value, and then it will scan memory (this make take up to 5 minutes).

Example:
./adb push mlp_mem_trainer /data/local/
./adb shell
# /data/local/mlp_mem_trainer
Enter current coin quantity: 3795
Scanning range: a000-376e000
Player data address found: 1a24f7c


unpack_savefile.pl / pack_savefile.pl (You'll also need this modified XXTEA.pm library)
Usage: ./unpack_savefile.pl mlp_save.dat #IMEI# > save.xml
./pack_savefile.pl save.xml #IMEI# >mlp_save.dat

Example:

./adb pull /data/data/com.gameloft.android.ANMP.GloftPOHM/files/mlp_save.dat ./mlp_save.dat

./unpack_savefile.pl mlp_save.dat 001122334455667 > save.xml

xmllint --format save.xml > new_save.xml

gedit new_save.xml

./pack_savefile.pl new_save.xml 001122334455667 > mlp_save.dat

./adb push mlp_save.dat /data/data/com.gameloft.android.ANMP.GloftPOHM/files/mlp_save.dat


Android App

Here's a working proof-of-concept contained in an easy-to-use Android app. It works on my two devices (both of which run Cyanogenmod) without needing root access, but your mileage may vary.
MlpHacker-v1.03.apk

CHANGELOG
- v1.03
 * App now attempts to use root access if save-file is not read/writable. See my follow-up post for more details.
- v1.02
 * Added ability to edit number of hearts.
- v1.01
 * Updated to allow user-editable values for coins/gems/level.
 * Added ability to edit number of shards.
- v1.00
 * Initial release


162 comments:

  1. Hey, thanks for this post. I have an iPad 2 and I feel that the string that is concatenated with my UDID isn't "com.gameloft.android.ANMP.GloftPOHM", but I can't find the Java file that you determined this at to know what it might be instead. I can send you my files if you like, or if you have any info on this I'd love to hear back from you. I unfortunately am a Brony who enjoys this game too much but doesn't want to pay hundreds on IAP =/

    ReplyDelete
    Replies
    1. Yea, you're right that it probably uses a different string in the iOS version. The Java file in the Android version was com.gameloft.android.ANMP.GloftPOHM.SendInfo, and to be slightly more precise it uses the package name (and not a hard-coded string).

      In Android the internal app name is "com.gameloft.android.ANMP.GloftPOHM", so if iOS apps have a similar naming convention you could try just dropping in whatever the formal app is.

      Delete
    2. could you add me on skype : fuzzywuffyaffle

      i haven't touched anything, and now the xml produce 0KB
      would be easier to check with you in real time

      Delete
    3. I went in and looked on my Jailbroken device and see that the application is stored under some really long title starting with a "B23". I uninstalled it and reinstalled it and it now has a new long title, but perhaps this long title is the Package Name that it somehow dynamically assigns. I did manage to find this referenced in a .plist, so it still should be determineable without jailbreaking because I know this particular plist is in the application folder that I had gotten from my unjailbroken iPad.

      I'd try your script now with replacing the long identifier, but I'm at work. I'll let you know later when I get back.

      Delete
    4. Let me know if you have any success. Anything I could suggest would just be pure guessing at this. (Until I get a copy of the iPhone app to disassemble, my only frame of reference is the Android version, and apparently they don't operate identically in this regard).

      Hopefully I'll be able to convince my friend to lend me her phone for a little while so I can get a copy of the iPhone version and start working on it.

      Delete
    5. The hackfile isnt not available. do you have any backup?

      Delete
    6. Veho, if you're talking about melknin's hacks, they are NOT working anymore because of updates. If you have new version you should consider reading recent comments down below.
      If you have old version of the game, then I have an html save file editor compatible with it.

      Delete
  2. This comment has been removed by the author.

    ReplyDelete
  3. I have unpacked the savefile, and packed it back without doing any edit, the file change from 17KB to 18KB, once i push it back on the phone, the game start from new like if there were no save.
    Am I doing something wrong ?

    ReplyDelete
    Replies
    1. Assuming the unpacked version actually produced XML, it sounds like the scripts are working. (And don't mind the difference in file sizes; the data is compressed and since the compression libraries aren't 100% identical you're likely to get differently sized output).

      One problem that I ran into when I was fiddling with it was file permissions. Double-check that the new file is chmod 666 on your phone after you've uploaded it.

      (I just spotted that you made a similar comment below; perhaps you've already figured this out. :P )

      Delete
    2. When i pull the dat, then delete it from the phone, and push the dat back in place, everything work fine.

      Now when i pull the dat, extract it as a readable xml, recompile it as a dat, and push it back, the game just restart from zero like a new game with a new user. regardless of the owner:group and permission.

      when i push back the original .dat, the save return to where i left it before.

      so, I am not sure what is wrong on this part at all

      Delete
    3. I'm having the same problem...

      Any ideas?

      Delete
  4. This comment has been removed by the author.

    ReplyDelete
  5. It wont work for me. no matter what I change on the save file it just loads the normal save I had befor...

    ReplyDelete
    Replies
    1. Because your "files" folder is read only, check the command and you will see an error.

      You have to chmod it so you can replace the file.You can do it with X-plore, or any file browser as long as you have root.

      Delete
    2. Well, I did figure the read only problem soon after I posted ... only problem I dont know how to fix it. Can you even do that on a NOT rooted phone?
      I tried to do the chmod with ADB but all I got was a "operation not permitted".

      Delete
    3. depending of the device, you can or cannot, most likely not. by default for sure, I don't know if there is a way to chmod your folder, same goes for the trainer, the sdcard is mounted as noexec and there is not much you can do about it.

      if you have more trouble, let me know and i can add you on skype or something

      Delete
    4. Yeah, I would really appreciate some help.

      Delete
  6. seem like the mlp_mem_trainer could not find player data in memory on galaxy s2 as well.

    I wonder if the files have been updated or something to make it so hard

    ReplyDelete
  7. A side question, is it possible that the "Unable to inflate" error is related to something else other than that portion of the decryption? I understand the concepts of decryption, but don't exactly know how that relates to your Perl script. Never had to use Perl before.

    ReplyDelete
    Replies
    1. Yes and no. If the iPhone version uses a completely different scheme for storing the save files, then that could be the reason for the error. However, I suspect it's just that the key derivation for the encryption that's different.

      However, the way the key is derived could be more different than we're so far guessing. For example, it might not use the phone's IMEI (perhaps there's some other identifier they prefer on iOS). So my best advice until I get the chance to look at it properly is to just guess-and-check different strings.

      Delete
    2. Alright, shall do, thanks! There are some values floating around in one of the lists that I'll run through tonight. I did actually find

      "GAMELOFT_GLUID
      <775be2d7 bd0a90fd f8b5188d 7139dc47 ac8d46d4 2dcb4e99 706c7c42 9d2cf7e0 74a2d8c5>"

      in there somewhere, maybe that's actually the key? Dunno. I'll let you know if I make any progress.

      Delete
    3. Yep, it turns out that's the key. I didn't disassemble the app, so I have no idea how they derive it on iOS (could be randomly generated for all I know...), but that's easy enough to grab. If you want to modify the pack/unpack scripts, replace the whole key derivation section with something like this:

      my $gluid = "775be2d7 bd0a90fd f8b5188d 7139dc47 ac8d46d4 2dcb4e99 706c7c42 9d2cf7e0 74a2d8c5";
      $gluid =~ s/ //g;
      my $key = pack("H*", $gluid);


      With that figured out, I'll post a tool / howto in the next couple of days. The iOS solution won't be quite as easy as just installing an app, but it'll at least be easier than fiddling around with perl scripts. ;)

      Delete
    4. Sounds wonderful!
      Nice work, I'll try if the savegames are usable after doing this.

      Now I just need to know where Damian found the GLUID, thanks for your efforts!

      Delete
    5. Oops I found the GLUID but I don't understand a single word of Perl scripts, so I can't get the script working.

      Would be totally nice to have a working script :D

      Delete
    6. Yeah, I was a bit surprised that the GLUID was in plain text in the plists. I don't understand exactly what the script does but modifying a variable should be simple enough, haha. I'll try it and see! Thanks!

      Delete
    7. Bingo, that worked! Beautiful XML save file. I did exactly what you said and just removed the middle part of the code that set the $key. Now to try to modify it and re-encrypt it!

      Delete
    8. Whatever I do, I get compiler errors or "Unable to inflate" error. I just don't know what went wrong :(

      Delete
    9. So I could unpack into an XML and pack the XML into the mlp_save.dat, but it seems to not have encrypted right as my game can't read it, and I can't unpack it again. Is there anything you can think of that I'd need to modify in the Pack script other than replacing the $key definitions the same way I did the Unpack one?

      Delete
    10. DevinXXL, I replaced the middle part of the code, Lines 21 - 32, with:

      my $gluid = "775be2d7 bd0a90fd f8b5188d 7139dc47 ac8d46d4 2dcb4e99 706c7c42 9d2cf7e0 74a2d8c5";
      $gluid =~ s/ //g;
      my $key = pack("H*", $gluid);

      You would need to swap that out for your GLUID.

      Delete
    11. Guess what I did... "Global symbol "@keyasints" requires explicit package name at ./unpack_savefile.pl line 24."

      I also get the "Unable to inflate" error when packing a .xml as .dat and then try unpacking it again...

      Delete
    12. Haha, yeah, I did that first and when I looked at what that actually does I realized that I don't need it since I have the key defined itself.

      Yeah, Unpack (Successful), Pack (Doesn't throw an error), Unpack (Unable to inflate line 32) for me. There's probably an easy fix to this, I just don't know exactly what is going on with the encrypt function or why it would fail.

      Delete
    13. After some tinkering, I found out that I can remove part of the end of the GLUID key and it still works to unpack the original .dat. I don't think it should work that way, so it might only be using a portion of it. I'll continue playing around with it and see if anything comes up.

      Delete
    14. Just determined I can Unpack / Decrypt the mlp_save.dat with a key of just the first 32 bits of my GLUID (775be2d7 bd0a90fd f8b5188d 7139dc47). Sadly, re-encrypting / packing this does not file the corrupt .dat file =/

      Delete
    15. The encryption algorithm (XXTEA) only has a 32-byte key which is why you can discard the rest of the GLUID at it will work regardless.

      As for why the repacking would fail (or rather, why it would produce corrupt output), there's no obvious reason that comes to mind. I'd suggest double-checking that the key derivation you've put into unpack is identical in the pack script.

      (And if it helps, I'm planning on releasing a tool and instructions for iOS later tonight; I've just got to get everything recorded and written up).

      Delete
    16. That makes sense with XXTEA. Is there any chance it could be like... a Public Key encryption with a different key for encrypting? Because certainly the decryption key is correct as I can see the XML file. I'm having a hard time just understanding why the reverse isn't working, hah. Even if it's not readable by the game, I would have thought that I could have Unpacked, Packed, and Unpacked without a problem if using the same key.

      I'll wait until your tool / instructions to see if I'm missing anything, haha. Thanks for all the help!

      Delete
  8. This comment has been removed by the author.

    ReplyDelete
  9. On iOS, the game is stored as "com.gameloft.mylittlepony", in a directory named "D8D59DCB-4749-..." (this is a dynamically created code, every iOS app has a name like this). I could send you the files if it helps.
    I also tried to create an IPA file, I could upload that too (I don't know if it actually works).
    For testing, you could add me in Skype: "dickes-devin"
    We'd all love to see an iOS version soon!
    Thanks for your great work!

    ReplyDelete
    Replies
    1. I had tried to replace the script with the "com.gameloft.mylittlepony", that directory ID (different than yours due to the dynamic generation), the GLUID, and some other value that I have no idea what it was that looked like an ID of sorts in one of the plists, but the decryption seems to fail. I'm starting to wonder if the encryption is different on iOS, but completely honestly, it's probably me doing something wrong.

      Also, as with what DevinXXL said, if you need to gather more data, I offer my files to you as well.

      And I never said it before, but as someone who went to undergrad for CS, I found your post enjoyable to read as well.

      Delete
  10. So would the Android app you created work on nonrooted smartphones?
    Also, could you maybe keep an updatelog with what crucial changes you do to that app?

    ReplyDelete
    Replies
    1. Yes, the Android app should work even on non-rooted phones. I also updated the blogpost with a changelog so you can see what updates I've made to the app.

      Delete
  11. Will this work on any Android phones or do they have to be jailbroken first?

    ReplyDelete
  12. The app cant load the save on my unrooted v2.3 Sony Ericsson R800x. i get the error java.io.IOexception: unknown compression method. what do?

    ReplyDelete
  13. Hi! I loved your explanation of how the memory is being obfuscated (And I already thanked for this memory save editor for my wife).
    I have been fiddling with another game "Slot Galaxy" and so far I believe it holds similar obfuscation of the "coins" while in memory, it would help me a great deal if I could see the code of the mlp_mem_trainer (or would you recommend I simply decompile it with some tool directly)... I have more experience with C# and only little with Java so I'm still a little bit lost here :P

    Anyway thank you for anything you throw over here.

    ReplyDelete
    Replies
    1. It's pretty poorly/lazily written, but feel free to look it over if you think it'll help. :)

      http://pastebin.com/iFPp0vsQ

      Delete
  14. Guy, you are a pure GENIUS! I tried retro game hex editing (like bytes, words and integers). WELL DONE ;]!

    ReplyDelete
  15. I tried the app, it couldn't find my save file, should a setup a directory to put it in where I can expect it to find my file

    ReplyDelete
  16. Is it just me or are most of the download links down?

    ReplyDelete
    Replies
    1. For me as well. Found a download link on a Spanish-language tutorial here:

      http://www.taringa.net/posts/juegos/15955923/_Juego_-Monedas-y-Gemas-Ilimitados-en-el-juego-oficial-MLP.html

      I had my doubts as to its legitimacy, but it worked on my game, so.

      Delete
  17. This comment has been removed by the author.

    ReplyDelete
  18. Hi, really great work! A shame that gameloft took down the links, however I got hold of the apk! ;)
    It works on my ICS-Tablet like a charm, but not on the Kindle Fire HD of my gf, I think, because the path name of the Kindle version is "com.gameloft.android.AMAZ.GloftPOAS".

    Any chance to get a version of the app with support for the Kindle Fire?

    ReplyDelete
    Replies
    1. Ok, I guess the real problem the unpacking runs into is, that the KFHD does not have a IMEI or Android ID.
      So the encryption seems to work different.

      Damned...

      Delete
    2. And me again, I got it. In fact fairly simple.

      1. Pulled the "GLDID" from adb logcat or other log display tool after running MLP on the KFHD.
      2. Changed the string "com.gameloft.android.ANMP.GloftPOHM"
      to
      "com.gameloft.android.AMAZ.GloftPOAS"
      in your HTML De/Encrypter
      3. Inserted the GLDID in the IMEI field and Bäng! ;)

      Delete
  19. hi. that is a great work, thank you. i could not success when i tried the ANDROID_ID on my tablet but
    the GLUID in the log worked to decrypt the save file. i wonder whether (and pretty sure that) this may be
    applied to LPS 'littlest pet shop' game too with some miner changes ? i tried a few hours with PEHM (LPS)
    and figured out that the save file is something like /data/data/com.gameloft.android.ANMP.GloftPEHM/files/save.xml
    but the GLUID in the log for LPS (which is different than the one for MLP, even on the same machine) does not work.
    may be i did something wrong on the way but maybe they did some little additional (changinge word order etc.)
    trick in the key ? do you have any hint ? thanks in advance

    ReplyDelete
  20. This comment has been removed by the author.

    ReplyDelete
  21. Unable to load save for MLP 1.2.1 on Embryo 6.0 for SGH-T989. Root enabled and root granted to MLP Hacker 1.03

    Attempting to restore coins after reinstalling due to ROM change.

    ReplyDelete
  22. and I confused because I don't understand about coding :s why don't you upload the file so I can put it on my phone :p

    well however, whatta smart guy you are. you did the research and found the goal. congratz!

    ReplyDelete
  23. it looks like another layer of encryption has been added in recent updates. the mlp_save.dat successfully decodes, but, it decodes into gibberish.

    ReplyDelete
  24. I've looked through libmyponyworld.so
    Now instead of .obb file there are some .ark files, that contain other files compressed with zlib (1.2.3) and encrypted with XXTEA (may not be compressed/encrypted, it's defined in txt files), but I don't know the key to decrypt. (disassembling dumb :) )
    Save file changed too, AFAIK now xml data is XXTEA encrypted before compressing by zlib.
    It means, save file now is something like that: 12 bytes+XXTEA.Encrypt(Zlib.compress(XXTEA.Encrypt(xml))+CRC)+4 bytes.
    But, it seems like the key for xml encryption is different (or maybe something else is done to encrypted xml before compressing, i don't know).

    Here are some parts of disassembly. One is from saving subroutine, another one from loading. Maybe someone knows, how to get the key out of there.
    http://pastebin.com/84aS876g
    (LoadBuffer and SaveBuffer subroutines do compress and encrypt input with GLUID the way they did before)

    I'm almost out of gems, I need help :D

    P.S. Sorry for my english :)

    ReplyDelete
    Replies
    1. Since you have some knowledge on how to do instruction-level hacking, I can show you the way of cracking libMyPonyWorld.so file itself to ADD instead of SUBSTRACTING gems/coins/hearts to your account each time you make a transaction.
      I settled for it because my skills are to low to hack the key the game uses to encrypt the save data buffer before compressing it with zlib (like you correctly pointed out ;) ).

      I will be brief:
      1. If you want GEMS to be added each time you make a transaction, you have to binary-edit the libMyPonyWorld.so file and change byte 0x00239B72. It should be 0x65 and you have to change it to 0x85.
      2. If you want coins, you have to change byte 0x00239936 (also, from 0x65 to 0x85).
      3. If you want hearts (this one I haven't tested, but the code block looked nearly identical), you have to change byte 0x00239D6E, this time from 0x64 to 0x84.

      If you want to understand what the change does (or if the library is different in size for some reason in your case), the instructions that get changed are the RSB commands (reverse substract) in SpendCoins/SpendGems/SpendSocial command blocks. Changing the bytes that I mentioned changes those commands to ADD instructions. You can guess what happens then. ;) Of course, there is nothing stopping you from changing all three of those bytes at once and make the game add goodies to your account instead of taking them away. ;)
      Do note: this crack will not stop the game from telling you that you're missing coins. So if you want to let the game add 25 gems each time you play the balloon game (for example), you firstly have to have the said 25 gems (only the final subtracting gets changed, not all the checks along the way).

      If your so library is of different size/structure, the only thing you have to look for with IDA Pro (or any other disassembler that you use) are the command blocks for SpendCoins/SpendGems/SpendSocial methods. Once there, you have to find the position of the RSB instruction and change the byte at the given position from 64 or 65 to 84 or 85 respectively (you musnt change the second nibble of the byte, i.e. the '4' has to remain '4' and '5' has to remain '5') because it indicates which registers the command uses. And you don't want to change those. :D

      Also, always remember to make a backup of your library. ;)

      I wish you luck in cracking the library. :) Right now, I have 977 gems in my pony world, and 10 minutes ago I started with 40. :D If I bought Celestia right now, the game would add another 950 gems to my account. That would last for a while. ;)

      Delete
    2. Thanks for such useful post, but I've just succesfully done some memory editing by hand a minute ago (really), and now I have about 95M coins and 68M gems ^_^ (but I've forgot about hearts T_T, it'll take time to do that again).
      I guess someone else will find your post useful ;)
      I just don't want to edit game files, only saves or memory :)
      BTW, still interested in XXTEA key, just because it could help to increase new Flashy Pony drop rate

      Delete
    3. And I can post kind of guide how to earn gems/hearts/coins (maybe smth else) like i did, if needed. Just ask, and I'll explain. (requires root and Game Guardian app, maybe there are easier ways...)

      Delete
    4. This comment has been removed by the author.

      Delete
    5. Sorry for the deleted comment, it is uploaded 2 posts below for some reason...

      Delete
  25. And the memory trainer doesn't work cuz it's now ROR #5 instead of ROR #4

    ReplyDelete
  26. Actually, why not? If you could share what you found, I would gladly listen. :)
    Especially since the game checks md5 (or some other hash signature) of the lib file and changes it back after a while. :D
    Didn't take that into account, but still cheated a lot of gems during that time.

    So yeah, if you could share your discovery with gameguardian I'm very much interested to hear. ;)
    Also, I guess that the same trick (to change those instruction based on the byte values in the memory) could also be applied after the program has been loaded into the memory. I will have to check it some time.

    ReplyDelete
  27. Yeah, now I've got 627k hearts :)
    Ok, I will share, but not now, cuz it's about 5 AM in my city and I want to sleep :)
    But the idea is easy, you should first find the offset in memory where coins stored, by doing (a lot of) fuzzy searches (equal/inequal depending on amount of coins not changed/changed). You should find two offsets (let first be X, then second should be X+4). X+8 and X+C are offsets where random numbers are being stored (see Creating a New Memory Trainer, in melknin's post).
    If Y is amount of coins you want to have, then you have to set memory at offset X to (Y ROR 27) XOR [X+8] ([X+8] is the random number stored at X+8 offset), and at offset X+4 to (Y ROR 27) XOR [X+C]. THen, return to game. If it doesn't close, then you've done everyting right. For the displayed ammount to update, spend or get some coins.
    Gems stored at X+10 (X+10,X+14 - you should change, X+18 and X+1C - random numbers)
    Hearts at X+40 (X+40,X+44,X+48,X+4C)

    I think that's enough, for now at least :)

    ReplyDelete
    Replies
    1. Cool, thanks.

      I'm quite familiar with the general process of memory editing, although not on Android. And without disassembling the code it would be nearly impossible to find those addresses, much less change them. ;) So kudos to melknin and you for figuring it all out.

      I will give it a try tomorrow. It's quite late where I'm at too. ;)

      Delete
    2. Well, I tried your method, but gameguardian doesn't seem to find the correct addresses (even if it lands with only one or two after some crazy fuzzy searches).
      I tried to change the values without following the rules and it didn't even crash the game. :P

      Ah, well. I'm back to duping gems with my cracked .so file. :D

      Delete
    3. Maybe setting search range to "More regions" will do the trick.
      My offset was something like 0x61XXXXXX, just in case.
      As I remember I failed at searching with "default regions", I'm sorry for being late with that.
      I just want to help anyway :)

      Delete
  28. I admit I haven't ventured beyond the default region. ;) I will be sure to give it a try. Out of sheer curiosity, as I'm in no particular need for any currency right now. ;) I used my cracked library yesterday, and after a few balloon games and a pony shopping-spree, I amassed around 6k of gems.

    That feeling when the game gives you 950 gems for buying Princess Celestia! :D

    Thanks for yet another tip. :)

    ReplyDelete
  29. My goal is quite simple I want to find the game data to save so I can transfer to new device. I have looked for mlp_save.dat to copy and I cannot find it anywhere. I have used Astro file explorer my nexus 7 device is not rooted. I can only find the game file under sdcard/android/data/com.gameloft.android.ANMP.GloftPOHM. If you can give me the path that would be great. If not cool work anyway.

    ReplyDelete
    Replies
    1. Your goal is indeed simple, but the means to achieve it are currently beyond anybody's reach. You see, the save file is encrypted (twice!) with the key, part of which is your device's unique ID (you can read all about it in melknin's blog above). Simply put, the save file created on your nexus will be decrypted to garbage on the other device.

      If you, however, still want to try copying the save file, take a look here: https://docs.google.com/document/d/1LCwissTFnI-fWAZ2FSD5My906BQuP60ZO3YvW5vGmyY/edit. The article details two ways in which you can back up the save file and lists its path somewhere.

      Anyway, the path to the savefile is: /data/data/com.gameloft.android.ANMP.GloftPOHM/files/mlp_save.dat. However, to even be able to access /data file system on my device, I had to root my tablet. Otherwise it threw permission denied error.

      Good luck!

      Delete
    2. Ahh, thank you kindly. Yes this is indeed beyond my reach. Currently the rooted software does not work with 4.2.2, otherwise I could have rooted, backed up and then reinstalled on new device. Thanks for spelling it out for me.

      Delete
  30. Would there be a way to transfer saves from one phone to another?

    ReplyDelete
    Replies
    1. Using the info on this page, I wrote a Python program that let me move my save from one iPod touch to another. Looks like the XML may be obfuscated after the Hearts & Hooves update, so I didn't do any modifying to the file.

      I'll post info here in the comments soon after I clean it up and upload to GitHub.

      Delete
    2. Do you mean to say that only the 'outer' encryption is device-dependant (encrypted with the GLUID melknin mentioned in his blog)? Does that perhaps mean that the inner (after the zlib part) encryption doesn't use the GLUID but rather device-independent key?

      It would at least make us able to backup saves and restore them on other devices. ;)

      Delete
    3. It doesn't seem like the inner enc. key is GLUID.
      Code responsible for that is obfuscated somehow in libmyponyworld.so, but it seems like the key is static and device-independent.
      But I'm not sure because of obfuscation.
      It would be great for someone to try to copy save to another device and tell us the results.
      Maybe it will help me to get the key)

      Delete
    4. Ok, just uploaded to https://github.com/scott-walker/My-Stuff/blob/master/Python/2.6/src/MLP_SaveTransfer.py. It's just one file, so probably easiest to just cut and paste instead of pulling from the Git repository.

      Makes sense the inner key would not be the GLUID, otherwise I would not have been able to transfer my saves. I wonder if it uses some static key and xxtea, or is just something lame like XORing with some value.

      I'd like to give the source code a look, but I don't have an Android phone to get the APK with. I've seen you can do this with an Android simulator, but anyone know an easier way to get the latest APK w/o a phone?

      Delete
    5. Forgot to put in the code comments that the XXTEA library I used was from https://pypi.python.org/pypi/xxtea

      Delete
    6. It is definitely XXTEA encryption (but maybe not only it).

      Try to Google "download apk from play market" (sorry i can't give you exact link right now)

      Delete
  31. Looking around the memory, I found a very easy way to find the memory locations that need to be edited. It turns out that the Elements of Harmony values are not obfuscated like the bits/gems/hearts values.

    All that needs to be done is search for one of the current values of an Element (I used Laughter due to it being so readily available from the first shops you get), then use it (again, easy to "feed" the Laughter Element since it's the first one uncovered), and search for the new value. The times I've done this, I've ended up with three possible locations, so then it's just trial and error, checking each one of them to see where the memory map works out like this:

    X+00 | Coins A
    X+04 | Coins B
    X+08 | Coins Random A
    X+0C | Coins Random B
    X+10 | Gems A
    X+14 | Gems B
    X+18 | Gems Random A
    X+1C | Gems Random B
    X+20 | Unknown 1 A
    X+24 | Unknown 1 B
    X+28 | Unknown 1 Random A
    X+2C | Unknown 1 Random B
    X+30 | Unknown 2 A
    X+34 | Unknown 2 B
    X+38 | Unknown 2 Random A
    X+3C | Unknown 2 Random B
    X+40 | Hearts A
    X+44 | Hearts B
    X+48 | Hearts Random A
    X+4C | Hearts Random B
    X+50 | Unknown 3
    X+54 | Unknown 4
    X+58 | Element - Loyalty
    X+5C | Element - Kindness
    X+60 | Element - Honesty
    X+64 | Element - Generosity
    X+68 | Element - Laughter
    X+6C | Element - Magic

    Everything is 4 bytes. Unknown values 2 and 4 both appear to be 0 (zero) at all times. The Elements' values are soft-limited to 999 (0x3E7), but can be edited to be higher (the game will reset them back down to 999 anytime the Element is gained, such as from shops or the Balloon Pop game).

    This is using v1.2.2 of the game on Android. There is an update (v1.2.3) on Google Play that I haven't tested yet.

    I ended up setting Game Guardian's search range to "All Regions" to be able to find things.

    Special thanks to melknin and gafusss for leading the way!

    ReplyDelete
    Replies
    1. Wow, good job) Should be really much easier now, thanks!
      I can check your offsets guesses through the code, if needed, but I think you are right.

      Delete
    2. It appears that the Unknown 1 value is your current high score in the "Clear the Sky" mini-game. I guess Gameloft thought it needed to be protected for some reason (crazy scores?).

      Delete
    3. Just updated to v1.2.5 (released 2013-02-26) and confirmed that the memory locations haven't been messed with (yet). So the Element search still works fine and the ROR is still 5 for the obfuscated values.

      Delete
  32. AHAHAHAHAHAHA
    YAY!
    AT LAST I FOUND THE KEY TO DECRYPT THE SAVE FILE!
    OH MY GOSH, IT WAS SO HARD!
    I can't keep calm, I thought I'll never be able to do that!
    Seems like I'm better in reverse engeneering than I thought :)
    (But I spent about 2$ for memory viewing/editing app in play market :) )
    Gameloft hid it in ResetRiverShaders and ParseIcons functions (part of the key is 'PNG' ascii) ;)
    Here it is:
    302a75507acbd72f89504e4712901cf0

    But I'm afraid Gameloft staff watch us, so they will change something again :)

    ReplyDelete
    Replies
    1. Wow, congratulations on finding that. :)
      Hidden in PNG as ASCII? Those crazy bastards... :D

      Well, ultimately you can't really hide a key because it needs to be used to encrypt the data as you play, so with right amount of time and patience success has to come sooner or later.

      Congrats on your perseverance. ;)

      Delete
    2. Ditto, nice job there. Stupid question, but you use this key to decrypt the uncompressed zlib data using XXTEA, right? I tried that and got gibberish. I hope the iOS version doesn't use a different key.

      Delete
    3. Never mind, I was dumb and didn't convert it properly for the python xxtea method to deal with.

      Delete
    4. Karach Mlpfics, I mean, 0x50, 0x4e, 0x47 is ASCII 'P', 'N', G'. :)

      volvox, so it works?

      Delete
    5. Hehe, and I thought they hidden it in a PNG graphics. :D Especially since you mentioned ResetRiverShaders and ParseIcons functions.

      Delete
    6. Maybe they did, I don't know actually how these functions work :)

      Delete
    7. This comment has been removed by the author.

      Delete
    8. I try to reproduce JS script in C# with your key.
      here my code : http://pastie.org/private/hdljwivwuoy826hgkfovq

      I don't know where the problem is, but inflate throw an exception, I think the key is not valid.

      Delete
    9. If I correctly interpreted your code...
      You use the wrong key, but this doesn't mean key is not valid. Take a look at the savefile structure:
      12 bytes + XXTEA.Encrypt(Zlib.compress(XXTEA.Encrypt(xml)) + CRC) + 4 bytes.
      THe key I posted above is used only in inner encryption (XML), outer encryption still uses GLUID as key.

      Delete
  33. And it seems like the key for ark files is:
    4F943201A15B02004F943201B5889900
    But I can't check it right now.

    ReplyDelete
    Replies
    1. Yes, it is. And I was able to determine .ark file structure.
      4 bytes - number of files in archive.
      4 bytes - metadata offset
      4 bytes - seems to be always 01000000
      12-(metadata_offset-1) - compressed data (files compressed and/or encrypted one by one)
      Metadata_offset-endoffile - encrypted metadata
      _______
      Metadata structure:
      64 bytes - filename
      64 bytes - subfolder name (ex. 'folder/')
      4 bytes - offset in ark archive
      4 bytes - uncompressed file size
      4 bytes - compressed file size (if equals to uncompressed size then not compressed)
      4 bytes - encrypted file size (or zeroes if not encrypted)
      4 bytes - timestamp
      16 bytes - MD5 hash of the file
      4 bytes - extract the file? (01000000 or 00000000)
      =>168 bytes for every file in archive

      Delete
  34. This comment has been removed by the author.

    ReplyDelete
  35. I'm sorry for being "That guy" but I don't understand almost anything here. Can someone point me to a step-by-step instructions for decrypting, editing, then re-encrypting the save file and the programs required?

    ReplyDelete
    Replies
    1. Soon I'll modify html savefile editor. After that I'll help you.

      BTW, I've got a problem. jQuery doesn't want to parse new savefile xml somewhy (syntax is correct), so it should be edited by-hand... Could anyone help me?
      It might be hard for "those guys" to edit the file rather than values in boxes :)

      Delete
    2. Ah, my bad, I forgot to slice some zero bytes...

      Anyway, game fails to load repacked savefile (even with the same XML). Seems like compression algorithm is wrong (I was able to decompress original compression with some online tools, but failed with repacked one), and I don't know how to fix it :(

      Delete
    3. I'm sorry, I'm so much of a newb at this sort of thing and there are a lot of comments...

      Where is your save file editor? I see the memory scanner thing above, but that keeps failing cause of too much traffic.

      Delete
    4. gafusss: Yup, I got my python code to reencrypt everything, and it should be fine as far as I can tell. I'm trying to get it back on my iOS device right now.

      Once I get everything working, I'll upload a decrypt and an encrypt program to gitHub along with instructions. Probably another day or two.

      Delete
    5. Fevix Darkwatch, It's not due to traffic, see ***update in http://roundcube3.blogspot.ru/2012/11/save-file-hacking-mlp-for-idevices.html

      http://pastebin.com/pEYqjkz8 - this is save file editor (copy and save as .html, then open in your browser), but it DOESN'T work.

      volvox, waiting for the results :)

      Delete
    6. I found where the problem is.
      You need to add adler32 to zipped XML before encrypt.

      Delete
    7. Didn't I?

      var a = String.fromCharCode(120) + String.fromCharCode(156) + RawDeflate.deflate(ee) +
      intToBytesBigEndian(adler32(ee)) <---
      + intToBytes(crc32(ee));

      Delete
    8. sorry, you're right.
      The crc is altered, I have 00 00 XX XX for CRC, I keep looking

      Delete
    9. @Gafusss: Is that the one you update or do you need a new pastebin for each update?

      Delete
    10. Fevix Darkwatch, seems like I can update this one. I don't know how I should change the code, though.

      Delete
  36. it's working !
    I'll share you my c# project / exe

    ReplyDelete
    Replies
    1. Even though I don't need to change anything in my save file, I'm looking forward your program :)

      Delete
    2. here :

      https://www.dropbox.com/sh/e1nlcqp9t2x88av/rsvp8ozABC?m

      Delete
    3. Well, it doesn't work for me, 'an error occured, verify your GLUID' when I try to open my save file :(
      Maybe you should add more debug information (I just have no visual studio installed to see where exactly it fails), for example - 'Outer decryption failed', 'Decompression failed' etc.

      P.S. thanks for credits :)

      Delete
    4. Android, but I know my GLUID from adb logcat, and I used it with html editor, so it is definitely correct

      Delete
    5. may me the calculation for Android has changed.
      this line I think :
      rstr_md5(f + "com.gameloft.android.ANMP.GloftPOHM");

      For iPhone it's ok, because the GLUID is not computed, but write into a file.

      Delete
    6. lol, i've rebuilded your project with VS, and now it works :) I'm now going to test the save file

      Delete
  37. I am definitely not tech savvy, and I hope I don't sound like a total jackhole, but what is a GLUID and how do I find it?

    ReplyDelete
    Replies
    1. tutorial : http://roundcube3.blogspot.fr/2012/11/save-file-hacking-mlp-for-idevices.html

      Delete
    2. This comment has been removed by the author.

      Delete
    3. This comment has been removed by the author.

      Delete
  38. This comment has been removed by the author.

    ReplyDelete
  39. Ok, device transfer, full decrypt, and full encrypt Python versions on gitHub. Just copy to the clipboard and save instead of doing all the git fanciness:

    https://github.com/scott-walker/My-Stuff/blob/master/Python/2.6/src/MLP_SaveTransfer.py
    https://github.com/scott-walker/My-Stuff/blob/master/Python/2.6/src/MLP_Decrypt.py
    https://github.com/scott-walker/My-Stuff/blob/master/Python/2.6/src/MLP_Encrypt.py

    The comments have instructions and XML editing tips. For the non-technical, download python 2.7 first from python.org.

    ReplyDelete
  40. At last I've finished. I just had to use other compression scripts.
    But now it is not just one file :)

    So, here is the html save file editor:
    https://www.dropbox.com/sh/q7h556ycfdsce5p/Fiq-OkClgD?m
    Howto use:
    0.1)Download->Download as .zip
    0.2)Extract "html" folder anywhere
    0.3)Pull your save file from your device
    0.4)Find out your GLUID
    1)Open extracted html folder, then open "index.html" file in your browser
    4)Select your save file and enter your GLUID (I guess entering IMEI or Android ID may fail)
    5)Edit values in boxes
    6)Press "Generate new save file" file button
    7)Push the new save file back to your device (and don't forget to change it's owner and permissons)
    8)Enjoy ;)

    ReplyDelete
  41. Thank you guys - melknin, gafuss, volvox and Baptiste Massemin - for all your hard work. :)

    Personally, I went with Baptiste's code (thanks for sharing, though I realize it wasn't originally meant for me :) ), because C# is the language (from the choices you all went with) that I can understand on the spot. Thus, with a few minutes of coding, I was able to enhance Baptiste's editor to drop ponies' level by one star.

    See, my nephew came yesterday and was quite sad that ponies didn't want to play ball with him. For the love of Celestia, I can't understand why gameloft would disable the possibility to play with the pony after their level has been maxed out. Using the page-skip glitch one could still play with the ponies anyway. :P
    Anyway, yesterday I had a little talk with the ponies using Baptiste's modified editor, and now they will obediently play ball with my nephew. :D

    Thanks again for your hard work, guys.

    ReplyDelete
  42. I don't seem to have an mlp_save.dat file. Am I out of luck?

    I have a ton of files like this:
    "###_and_startup.ark"
    "###_and_startup_Index.txt"
    "###_and_startup_Metadata.txt"
    Is this my new save "file"? Should i not have updated?

    ReplyDelete
    Replies
    1. You're in wrong folder. For android it is /data/data/com.gameloft.android.ANMP.GloftPOHM/files/

      Delete
    2. I only have one /data folder. INside that is the com.gameloft.whatevers.

      Inside that is where I was, seeing the .ark files.

      Delete
    3. Correction: Inside the com.gameloft folder is a /files folder, and inside THAT is where everything above is.

      Delete
    4. As I said, this is the wrong folder.
      There MUST be another data folder, and save file path should be exactly as i mentioned.

      Maybe you just need root.

      Delete
    5. This device is funky, period. The android OS in it is engineered for this exact hardware, and updates have to come only from the manufacturer. I don't think I CAN root this device (If rooting is anything like jailbreaking iOS, I mean. If not, I'm an idiot and would very much like to know how to get root.) The device runs 4.0.4 of the Android platform.

      Additionally, I'm having trouble getting any sort of terminal or anything open for the "adk logcat" thing laid out in one of the tutorials linked here in this article.

      I do apologize for being an absolute and total newb at all of this, and also apologize for any frustration I bring to any of you.

      Delete
    6. Okay, I had that backwards, the hardware is optimized for the software. Either way, the updates must come from the manufacturer.

      For those wondering what sort of horrible android device I got saddled with, here, have a look.
      http://www.visual-land.com/mid.html
      http://www.visual-land.com/mid4faqs.html

      Delete
    7. I found no information about rooting your device, let's hope someone else here can help you.

      Delete
    8. This comment has been removed by the author.

      Delete
  43. I'm now working on .ark files repacking.
    I've written a program in C# (thanks to Baptiste Massemin :)) and successfuly repacked 000_and_startup.ark file with changed lotto xml files (just to check if it works), but I had to update file size and CRC32 in pack.info (/data/data/com.gameloft.android.ANMP.GloftPOHM/pack.info).
    I'll share my program later

    ReplyDelete
    Replies
    1. Just a quick note: remember my cracked .so library? It seems the game checks checksums or some other crap, and replaces the modified files on the go if your device is connected to the net.

      As long as I had wifi switched off the library remained cracked, once I switched the net on the library was re-downloaded somehow (after a few minutes, mind you, giving me some time to do gem-spending :P ).

      Of course, this observation is strictly about the so library. I have no idea whether ark files are checked for their integrity as well.

      Delete
  44. As for now, I almost everytime win 1337 bits in the gem lotto. I mean...
    Here is ARK archiver - a tool to extract, edit & repack .ark archives.
    Binary - https://www.dropbox.com/sh/0b1mne4z4tcdcr2/8YOVTjxP7P/Bin - download as .zip and extract somewhere, then run ARK archiver.exe. Tips available inside :)
    VS C# project - https://www.dropbox.com/sh/0b1mne4z4tcdcr2/gYvig4cVfk?m

    Note: you need not only ark files, but pack.info from /data/data/com.gameloft.android.ANMP.GloftPOHM/

    With repacked arks I played only offline. So I don't know what can happen while playing online.

    So please, try and tell us the results :)

    ReplyDelete
    Replies
    1. Okay, I'm really getting frustrated and am about to uninstall this overpriced app.

      I do not have a pack.info. Anywhere. I run Windows Search from the base folder of my entire device (Where the address is simply "K:\") and search for "pack.info" and there are 0 results. Same thing for "mlp_save.dat".

      I have all of the .apk files, but none of the files required by any tool here. Can I just put my entire MLP game directory into a zip folder and throw it to one of you for editing?

      Delete
    2. Aaaand somehow I completely ****ed it up and the game keeps closing with the message "AN SD card with at least 80MB free is required to download the additional data" when I have a nearly empty 4GB SD card in.

      Delete
    3. And then I go to reinstall it all and the download continuously fails. I am now ponyless and angry at this device once more.

      I found a thirdparty source for it, and have installed it and started it. It's currently downloading the data once again. I need to go pay the rent, so I'll give you all an update when I get back.

      Delete
    4. Okay, so the version I recieved was the one with the OBB file, and I have experience editing that one. I'm just not going to update until I have a nice large stock of gems, bits, and harmony shards.

      Delete
    5. You are my hero, gafusss. :D

      I was sick and tired of trying to win Magnum in the balloon pop game. After a slight... erm... improvement ;) of probability to get him (inside the ark file), I got him in the first try. :D

      So thanks again for your binary wizardry. :)

      Delete
    6. :D
      I'm glad to help y'all :)

      It fills my life with sense actually ;) Bringing free ponies :D

      On the topic: there might be some other interesting files in these archives ;)

      Delete
    7. Can you please help me understand why everytime i launch the app, it always asks me to turn on my network connection? if i dont then the app closes, and if i turn it on, then it re-downloads the *correct files from its server
      I have gone through and edited my .ark files, recompiled them
      I also put the new pack.info file where it belongs (I have Root)
      It is really frustrating me,
      Although i am quite impressed with everyone developing tools for liberating users of the game:)
      and the save editor worked to keep me from having to purchase gems, but i would really like to make a few other improvements of my own to the game.
      I would really appreciate your thoughts on the subject.

      Delete
    8. Make sure you set right file privileges and owner. Check inside pack.info if CRC32 and size are correct. Can you reopen your .ark after editing?
      Also, please tell which archives you edit and how exactly (somewhere in the tips I've mentioned, that file sizes (extracted ones) must not change significantly, because I'm still not sure about pack.info data about zip).

      Are you trying to replace textures or models or something like that?) Just in case, make sure they are correct. And, yeah, mind the XML syntax.

      Delete
    9. when i look at the owner and privileges of the original file, it looks like its just my computer?
      should i be using a specific program to change the privilege?
      and yes i can reopen the .ark
      for the time being im just trying to edit the 000_and_startup 001_and_startup And 004_and_startup
      if i can get those working, then i will try inputting my own graphics
      I see what your saying, that the files cant be changed drastically

      Delete
    10. File privileges and owner should be set on device, not on your PC.
      You can use root browser/root explorer etc, chmod.
      What about crc32 and file sizes in pack.info, are they correct?

      Well, maybe they can be changed drastically, I'm not sure yet, one has to check.

      Delete
    11. I have found out a few things,
      the privileges are a precaution, but not required
      The crc32 IS IMPORTANT file size is complicated, i havent figured out the limits of changeing it yet
      but if you make a few adjustments try to have the code about the same size
      but yes thank you for reminding me to check the crc32
      I think that was my problem

      ALSO: i found an xml for a cheatmenu??
      i dont kno how to implement it
      but there is an easy way to get a new pony!
      there is a pony hiding in the code that hasnt had its name approved by hasbro
      Cottoncloudy
      Thanks again!

      Delete
    12. Of course crc32 IS important, it's obvious) Was it incorrect? If so and if you used my program, I apologize, for me and for Karach Mlpfics it worked well. Should I fix the code?

      I've seen this XML, but didn't read it)

      Delete
    13. everything was fine with your program, it was a few problems on my end, anyways i got most of my changes finished.
      any thoughts on making derpy playable?

      Delete
  45. Could someone post up a guide or something on how to get to your pack.info file? Is the fact that I don't have my phone rooted preventing me from getting the pack.info file and repacking the Ark files after making edits to them?

    ReplyDelete
    Replies
    1. I'm sorry, but AFAIK you NEED root to pull pack.info

      Delete
  46. Every time i try to download anything i get "Error (509)
    This account's public links are generating too much traffic and have been temporarily disabled!" can you upload your files elsewhere and post a link? thanks.

    ReplyDelete
  47. Apparently, Android got a Canterlot update today which presumably adds yet another layer of security to the save game.

    It's getting ridiculous right now. :D The amount of encryption they protect this file with is hilarious.

    ReplyDelete
    Replies
    1. current extractor (surprisingly) still works

      there is now 3 files with the useful stuff being in 001_and_mlpdata.ark which is ~60MB
      it takes a long time to extract (~210MB extracted)

      Delete
    2. Yep, save changed a bit, now "MLP_SFV2" (My Little Pony save file version 2?) string is concatenated with encrypted xml. It looks like keys are the same, but something else is done with encrypted xml (not another layer of encryption or compression, just something with string, i guess), or maybe xml encryption key has changed. I'll try to figure it out

      Delete
  48. Is there a new hack for the Canterlot Update?

    ReplyDelete
  49. You can find a working savegame editor for the Canterlot Update (and older) here: http://redd.it/19tb3r

    ReplyDelete