Jump to content
  • 0

Metadata is dumpable, but there's no difference between the dumped one and the one in the apk


Enfusia
 Share

Question

A new major update of the game 'Night of the Full Moon' is coming out soon, which kinda caught my attention.

I was able to mod an older version of the game (1.5.1.37), but that approach doesn't work for the newest version anymore (1.5.1.50).

Here's my analysis:
  -The developers use their own anti-tamper solution called 'HProtect'. It (was?) responsible for decrypting the metadata, and it also force closed the game if any changes were detected.
  -They updated HProtect, and I wasn't able to figure out what it does now.
  -The metadata in the old version of the game was obviously obfuscated, but the one in the new version is not, since the 4 magic bytes are valid (I uploaded some screenshots).
  -The il2cpp.so binary seems to be valid and not encrypted at all.

 

Things that I tried so far:
  -Using the zygisk il2cppdumper didn't work (dump.cs hasn't been created), but it did work with the old version of the game though.
  -Dumping via GameGuardian worked, but the output was identical to the file you get from the apk.
  -il2cppdumper gives me the "System.IO.EndOfStreamException: Unable to read beyond the end of the stream" error when trying to dump.
  -il2cppInspector says "could not verify the integrity of the metadata file or accurately identify the metadata sub-version" when selecting the metadata file.
  -Libdumper didn't work (also produced the identical output).

 

I'm kinda lost at this point, it would be great if someone could help me out with this. Also, please let me know if I forgot to include something.

 

Thanks in advance

Hex-View new metadata.png

Hex-View of old metadata.png

Metadata from the newest version.rar Metadata from the older version.rar Newest version of HProtect.rar Older version of HProtect.rar

Link to comment
Share on other sites

12 answers to this question

Recommended Posts

  • 0
39 minutes ago, HorridModz said:

I don't have the time to analyze this, but here are some notes:

-Just because the 4 magic bytes are there does not mean the metadata is not encrypted (like in this game: https://katyscode.wordpress.com/2021/01/15/reverse-engineering-adventures-league-of-legends-wild-rift-il2cpp/)

-You can try using Il2cppInspector to dump the game

-You can try opening the game in ida pro and comparing with the old versions to see what has been changed

-You can try forcing the il2cpp version in the config.json file for il2cpp dumper - maybe this game switched the version of il2cpp to an older one for some reason

 

However, I do think the problem is that there is some protection in the libil2cpp.so file - this seems to be the most likely explanation.

Yeah my bad, you're right about the 4 magic bytes, I just wanted to point out that the developers changed the encryption method.

I didn't bother with ida because the actual decryption / encryption (probably) takes place in the HProtect java class, so ida wouldn't help that much, I assume.

Forcing the il2cpp version also didn't work, unfortunately.

I thought that the metadata file is the only encrypted file here, but you may be right. I'll try to investigate a little bit further, but I'm kinda running out of options.

 

Thank you anyways though, I appreciate it.

Link to comment
Share on other sites

  • 0

The game refused to launch and straight up crashed, even when just decompiling and compiling without making any changes.

I checked out the UnityPlayer class and compared it with the old version, the developers almost completely rewrote it.

The new UnityPlayer class also contains many suspicious variables and functions (which the old one didn't have), like 'bix2hex, hash_sha256, logLoadLibMainError, mProcessKillRequested:Z, mQuitting:Z, mKillingIsMyBusiness:Landroid/content/BroadcastReceiver', and so on.

I got the game to stop crashing on startup after making some changes to the UnityPlayer, but now it's just an endless blackscreen. Still a step in the right direction, though.

By the way, the game doesn't initialize HProtect through the UnityPlayerActivity.smali class like it used to, but it still gets loaded.

UnityPlayer.smali

Link to comment
Share on other sites

  • 0
23 hours ago, Enfusia said:

A new major update of the game 'Night of the Full Moon' is coming out soon, which kinda caught my attention.

I was able to mod an older version of the game (1.5.1.37), but that approach doesn't work for the newest version anymore (1.5.1.50).

Here's my analysis:
  -The developers use their own anti-tamper solution called 'HProtect'. It (was?) responsible for decrypting the metadata, and it also force closed the game if any changes were detected.
  -They updated HProtect, and I wasn't able to figure out what it does now.
  -The metadata in the old version of the game was obviously obfuscated, but the one in the new version is not, since the 4 magic bytes are valid (I uploaded some screenshots).
  -The il2cpp.so binary seems to be valid and not encrypted at all.

 

Things that I tried so far:
  -Using the zygisk il2cppdumper didn't work (dump.cs hasn't been created), but it did work with the old version of the game though.
  -Dumping via GameGuardian worked, but the output was identical to the file you get from the apk.
  -il2cppdumper gives me the "System.IO.EndOfStreamException: Unable to read beyond the end of the stream" error when trying to dump.
  -il2cppInspector says "could not verify the integrity of the metadata file or accurately identify the metadata sub-version" when selecting the metadata file.
  -Libdumper didn't work (also produced the identical output).

 

I'm kinda lost at this point, it would be great if someone could help me out with this. Also, please let me know if I forgot to include something.

 

Thanks in advance

Hex-View new metadata.png

Hex-View of old metadata.png

Metadata from the newest version.rar 2.77 MB · 0 downloads Metadata from the older version.rar 2.97 MB · 0 downloads Newest version of HProtect.rar 18.05 kB · 1 download Older version of HProtect.rar 10.96 kB · 0 downloads

Did some quick checking and its a first for me to, to see the names are scattered around in different locations in memory. I can't give you a solution.

Schermafbeelding_2022-09-06_201626-1.thumb.png.d5db0fdfb34e681566d989bd54a5b080.png

There are also two global metadata headers i believe.

unknown-17.thumb.png.c70c034c15bc2294ab831267bb616ac7.png

Can't spectate it because lost access to 010 Editor but you can search the magical bytes in Ca and copy. I believe header size is 272 bytes. But this could be 264 bytes as well i believe.

If you would replace the header from the meta in Others with that of Ca il2cppdumper would recognize it as a valid metadata. But then the values in the header don't correspond with the rest of the metadata. So if the metadata is encrypted the meta in Ca is the one that has no encryption. But im just assuming here. You would need to look deeper in to it.

Both meta headers point to different code/meta registration. 

I'm not sure if its realistic to say that you could try to fix the values in the Others metadata so that it corresponds to the data of the Ca  meta header? This was just some idea. Further then that i can't help you. But perhaps people more suitable for the issue can help you.

Edited by Platonic
Link to comment
Share on other sites

  • 0
19 hours ago, Enfusia said:

Yeah my bad, you're right about the 4 magic bytes, I just wanted to point out that the developers changed the encryption method.

I didn't bother with ida because the actual decryption / encryption (probably) takes place in the HProtect java class, so ida wouldn't help that much, I assume.

Forcing the il2cpp version also didn't work, unfortunately.

I thought that the metadata file is the only encrypted file here, but you may be right. I'll try to investigate a little bit further, but I'm kinda running out of options.

 

Thank you anyways though, I appreciate it.

Hi! From previous behaviour that "Dumped Metadata is identical to Obfuscated/Encrypted one", I assume that; it is because of Metadata is still on loading stage.

  • 1) Since Metadata is got flushed from memory so quickly, here we going to suffer from trial and error to make sure we got the right timing. Highly recommend to do it on PC with some Android Emulator because of milisecond is really important. On PC, you need to prepare Cheat Engine and some script for Auto Suspend/Freeze emulator. Prepare everything, by the time you launch the game; run the script (Highly suggest to use Custom Hotkey to execute the script) and search the Metadata Header on Cheat Engine. If not found, do Unfreeze-Freeze and scan again on CE, do this until you got some interesting bytes. You can try to use PsSuspend and make a script to automate that.
  • 2) You might need the game sandboxed, although you can try it using emulator but it has whole Android emulated, too big for us to debug it. The reason for this is;  we can use Ghidra and attach it directly into the game. This will make read things more easily.
  • 3) If you're sure that the Decryption thing is happen on HProtect Java Class, probably you can try some external hooking. Frida seems the right choice but I'm not sure if it's able to read what the function are currently doing, since it's just read class? I'm not an expert, so I didn't know the full ability of Frida. You can try to create custom hooks from scratch and make it access the data that's currently handled by HProtect. This yet a big effort to just looking for Metadata, not recommend since it's wasting of time.

From Platonic, it's more likely that Metadata will exist in bare form for doing step #1, since there's multiple Metadata co-exist? At this point, the only option is to Reverse Engineering the game; since every current tools aren't able to do the job.

Edited by MainC
word
Link to comment
Share on other sites

  • 0
11 minutes ago, MainC said:

Hi! From previous behaviour that "Dumped Metadata is identical to Obfuscated/Encrypted one", I assume that; it is because of Metadata is still on loading stage.

  • 1) Since Metadata is got flushed from memory so quickly, here we going to suffer from trial and error to make sure we got the right timing. Highly recommend to do it on PC with some Android Emulator because of milisecond is really important. On PC, you need to prepare Cheat Engine and some script for Auto Suspend/Freeze emulator. Prepare everything, by the time you launch the game; run the script (Highly suggest to use Custom Hotkey to execute the script) and search the Metadata Header on Cheat Engine. If not found, do Unfreeze-Freeze and scan again on CE, do this until you got some interesting bytes. You can try to use PsSuspend and make a script to automate that.
  • 2) You might need the game sandboxed, although you can try it using emulator but it has whole Android emulated, too big for us to debug it. The reason for this is;  we can use Ghidra and attach it directly into the game. This will make read things more easily.
  • 3) If you're sure that the Decryption thing is happen on HProtect Java Class, probably you can try some external hooking. Frida seems the right choice but I'm not sure if it's able to read what the function are currently doing, since it's just read class? I'm not an expert, so I didn't know the full ability of Frida. You can try to create custom hooks from scratch and make it access the data that's currently handled by HProtect. This yet a big effort to just looking for Metadata, not recommend since it's wasting of time.

From Platonic, it's more likely that Metadata will exist in bare form for doing step #1, since there's multiple Metadata co-exist? At this point, the only option is to Reverse Engineering the game; since every current tools aren't able to do the job.

You can try running the pc version of the game, using ProcMon to find where the metadata is accessed, then setting a breakpoint. This will make sure you dump the metadata at the correct time (referencing this tutorial).

 

There is also the possibility that the dumped metadata is a decoy.

 

Link to comment
Share on other sites

  • 0
47 minutes ago, HorridModz said:

You can try running the pc version of the game, using ProcMon to find where the metadata is accessed, then setting a breakpoint. This will make sure you dump the metadata at the correct time (referencing this tutorial).

 

There is also the possibility that the dumped metadata is a decoy.

 

The pc version of the game doesn't have any protection whatsoever though (besides il2cpp, ofc).

Link to comment
Share on other sites

  • 0
43 minutes ago, HorridModz said:

You can try running the pc version of the game, using ProcMon to find where the metadata is accessed, then setting a breakpoint. This will make sure you dump the metadata at the correct time (referencing this tutorial).

 

There is also the possibility that the dumped metadata is a decoy.

 

Yep this is good alternative, although I don't really familiar with procmon; this is can also be done with Ghidra at previous step #2. But taking PC version of the game is more better than trying to sandbox the game. Is there a chance of Metadata being differs between PC and Android?

Link to comment
Share on other sites

  • 0
On 9/6/2022 at 10:42 PM, MainC said:

Hi! From previous behaviour that "Dumped Metadata is identical to Obfuscated/Encrypted one", I assume that; it is because of Metadata is still on loading stage.

  • 1) Since Metadata is got flushed from memory so quickly, here we going to suffer from trial and error to make sure we got the right timing. Highly recommend to do it on PC with some Android Emulator because of milisecond is really important. On PC, you need to prepare Cheat Engine and some script for Auto Suspend/Freeze emulator. Prepare everything, by the time you launch the game; run the script (Highly suggest to use Custom Hotkey to execute the script) and search the Metadata Header on Cheat Engine. If not found, do Unfreeze-Freeze and scan again on CE, do this until you got some interesting bytes. You can try to use PsSuspend and make a script to automate that.

I used Nox to emulate the game and Cheat Engine's memory viewer to look for the metadata header. I also made a script which uses PsSuspend, just like you recommended, so I can toggle between a halted and running state via a hotkey. I attached Cheat Engine to "NoxVMHandle.exe", and while I eventually found the metadata header, it wasn't what I was looking for. Maybe my timings were off, but I'm not sure.

 

Quote

2) You might need the game sandboxed, although you can try it using emulator but it has whole Android emulated, too big for us to debug it. The reason for this is;  we can use Ghidra and attach it directly into the game. This will make read things more easily.

I didn't quite understand what you meant by this. How do I sandbox the game? And you also mentioned that I shouldn't use an Android emulator, did you mean that I should run the game on my phone and attach the debugger remotely?

 

Quote

3) If you're sure that the Decryption thing is happen on HProtect Java Class, probably you can try some external hooking. Frida seems the right choice but I'm not sure if it's able to read what the function are currently doing, since it's just read class? I'm not an expert, so I didn't know the full ability of Frida. You can try to create custom hooks from scratch and make it access the data that's currently handled by HProtect. This yet a big effort to just looking for Metadata, not recommend since it's wasting of time.

To be honest, I'm not even sure what HProtect does anymore. I compared the old and new version of the game with WinMerge, and they basically overhauled everything. I guess I'll just use Android Studio and debug some suspicious looking classes, maybe that will guide me to the correct path.

Link to comment
Share on other sites

  • 0
Quote

I used Nox to emulate the game and Cheat Engine's memory viewer to look for the metadata header. I also made a script which uses PsSuspend, just like you recommended, so I can toggle between a halted and running state via a hotkey. I attached Cheat Engine to "NoxVMHandle.exe", and while I eventually found the metadata header, it wasn't what I was looking for. Maybe my timings were off, but I'm not sure.

Yeah that's the tricky part; that's why i suggest step #2 using Ghidra and using breakpoint.
 

Quote

I didn't quite understand what you meant by this. How do I sandbox the game? And you also mentioned that I shouldn't use an Android emulator, did you mean that I should run the game on my phone and attach the debugger remotely?

  • - The purpose of this is to make read things easily as Ghidra will offer current task that process are doing. Also you can set breakpoint to pause the task momentarily, although you can do it with CE but you need to find the right address first; unlike Ghidra.
  • - Sandboxing the game allows it to only the game that's running; if you have Android Emulator, you probably got background system apps/service that running and that's the challange when attaching a debugger to an Android Emulator. Although you can just do it remotely that really slow or using an Android Debugger app (If it's exist and I'm not sure if the features will equal to current standards)
Quote

To be honest, I'm not even sure what HProtect does anymore. I compared the old and new version of the game with WinMerge, and they basically overhauled everything. I guess I'll just use Android Studio and debug some suspicious looking classes, maybe that will guide me to the correct path.

That's a challange for Reversing the game; it's good to assume but you had to find another when it's not. Honestly, you can keep experimenting everyday; notes on the progress; and eventually you will get somewhere. Good Luck on your findings!

Edited by MainC
I have no idea for duplicated comment
Link to comment
Share on other sites

  • 0

I guess I'll drop the modding attempt (for now), since nothing I tried seems to be working.

I tried the PsSuspend way again, there were 4 (!) metadata headers in the initial dump, which slowly merge into 2 headers in total (and I have absolutely no idea what the deal with that is).

Making the apk debuggable also didn't work for some reason. I set the debuggable string in the manifest.xml to true, but I wasn't able to find the app in the developer settings. Even the LSPosed module didn't work. So I guess no debugging for me, then.

Trying to analyze the smali code is also quite tough, but the fact that I'm not able to debug it makes it even harder.

Maybe someday I'll return to the project, but that seems to be it. Kudos to the developers though, they REALLY don't want people to mod their game.

Also, thank you guys for your time.

Link to comment
Share on other sites

  • -1

I don't have the time to analyze this, but here are some notes:

-Just because the 4 magic bytes are there does not mean the metadata is not encrypted (like in this game: https://katyscode.wordpress.com/2021/01/15/reverse-engineering-adventures-league-of-legends-wild-rift-il2cpp/)

-You can try using Il2cppInspector to dump the game

-You can try opening the game in ida pro and comparing with the old versions to see what has been changed

-You can try forcing the il2cpp version in the config.json file for il2cpp dumper - maybe this game switched the version of il2cpp to an older one for some reason

 

However, I do think the problem is that there is some protection in the libil2cpp.so file - this seems to be the most likely explanation.

Edited by HorridModz
Link to comment
Share on other sites

  • -1
4 hours ago, Enfusia said:

The game refused to launch and straight up crashed, even when just decompiling and compiling without making any changes.

I checked out the UnityPlayer class and compared it with the old version, the developers almost completely rewrote it.

The new UnityPlayer class also contains many suspicious variables and functions (which the old one didn't have), like 'bix2hex, hash_sha256, logLoadLibMainError, mProcessKillRequested:Z, mQuitting:Z, mKillingIsMyBusiness:Landroid/content/BroadcastReceiver', and so on.

I got the game to stop crashing on startup after making some changes to the UnityPlayer, but now it's just an endless blackscreen. Still a step in the right direction, though.

By the way, the game doesn't initialize HProtect through the UnityPlayerActivity.smali class like it used to, but it still gets loaded.

UnityPlayer.smali 128.9 kB · 0 downloads

If no tools are working, I think the only option is (of course) to manually reverse engineer it. Good luck!

Edited by HorridModz
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.