1. masagrator

    OP masagrator The developper
    Member

    Joined:
    Oct 14, 2018
    Messages:
    3,385
    Country:
    Poland
    So lately we got two games that are using index encryption which hides informations about file names, compressed and decompressed sizes + offsets where they are. Assets are not encrypted.

    Here I will provide a method how to get 32 bytes hex decryption key from main file. This tutorial is based on Ninjala 2.1 version.
    Don't share here keys as this is violation of rules. Provided key in this tutorial has been faked.

    Method was checked only on two games: Ninjala 2.1 and Five Nights at Freddy's: Help Wanted 1.22. Both are using Unreal Engine 4.24.x, other versions may have different function for using it so if this tutorial won't work for some game, write comment in this thread.

    Requirements:
    - IDA or Ghidra (you don't need decompilers) with support for ARM64/AArch64
    - Knowledge how to extract main from exefs (you can use nxdumptool) and how to use IDA or Ghidra (I won't explain how to load properly main to them)
    - Some time


    1. Load "main" from exefs to IDA or Ghidra
    2. Analyze them so they will be disassembled as much as possible (we don't need any types, demangled symbols, etc. Only assembler)
    3. Now next points will depend on what you are using
    • 3.1 After finishing analyzing go to Search -> sequence of bytes...
      upload_2020-10-3_19-38-4.png
      3.2. to showed window paste this:
      Code:
      00 04 00 AD C0 03 5F D6
      check "Find all occurences" and press OK
      upload_2020-10-3_19-39-11.png

      3.3. After a short while we will get window with all results (in case of Ninjala we have only 2 results)
      upload_2020-10-3_19-41-0.png

      3.4. Jump to result by pressing on it, we need to find function that will look like this
      upload_2020-10-3_19-42-58.png

      By this I mean short function that includes four lines with "xmmword" text.
      If function looks different, then this is wrong function and check other results.

      3.5. Press on first xmmword so it will jump to different address (in this case 7106753E30 which you can see after "xmmword_". This way we are at first 16 bytes of our decryption key.
      Go to Hex View tab and copy 16 bytes starting from address where xmmword provides (which means 7106753E30).
      upload_2020-10-3_19-49-16.png

      So in this case we are copying:
      Code:
      12 11 34 56 78 90 12 34  43 21 09 87 65 43 21 00
      And paste it somewhere, for example to text file and save it.

      Go back to last function where xmmwords were. Now go to second xmmword (in this case xmmword_710675B580).
      Go to Hex View tab and copy 16 bytes starting from address where xmmword provides (which means 710675B580).
      upload_2020-10-3_19-52-6.png
      So in this case we are copying:
      Code:
      36 36 36 36 36 36 36 36  36 36 36 36 36 36 36 21
      and paste it at the end of file where you have pasted previous 16 bytes. Delete all spaces that are in this file.

      Now our decryption key is ready:
      Code:
      1211345678901234432109876543210036363636363636363636363636363621
    • 3.1. After finishing analyzing go to Search -> Memory
      upload_2020-10-3_19-57-33.png

      3.2. Paste to "Search value" window this code:
      Code:
      00 04 00 AD C0 03 5F D6
      Be sure format is checked as "Hex" and press "Search All".
      upload_2020-10-3_19-58-51.png

      3.3. 3.3. After a short while we will get window with all results (in case of Ninjala we have only 2 results)
      upload_2020-10-3_19-59-42.png

      3.4. Jump to result by pressing on it, we need to find function that will look like this
      upload_2020-10-3_20-0-18.png

      In Ghidra case we have little trouble because on how advanced analyze you had you will get different output in disassembler window. Maybe the best solution will be to check if function you have has 6 instructions. If not, it's wrong and you should check other results.

      DAT_ can be named differently dependent on quality of analyze. Have that in mind.

      3.5. Press on first "offset DAT_" (in this case "offset DAT_7106753e30") so you will jump to different offset. You are now at the beginning of first 16 bytes of decryption key. Go to "Bytes: " window and copy 16 bytes starting from offset where DAT pointed us (in this case 7106753e30)
      upload_2020-10-3_20-4-30.png

      So in this case we are copying:
      Code:
      12 11 34 56 78 90 12 34 43 21 09 87 65 43 21 00
      Paste it somewhere, for example to text file, and save it.

      Go back to last function where "offset DAT_" were. Now go to second "offset DAT_" (in this case DAT_710675b580) and now we are at last 16 bytes of decryption key.
      Again go to "Bytes: " window and copy 16 bytes starting from offset where DAT pointed us (in this case 710675b580)

      upload_2020-10-3_20-7-15.png

      So in this case we are copying:
      Code:
      36 36 36 36 36 36 36 36 36 36 36 36 36 36 36 21
      and paste it at the end of file where you have pasted previous 16 bytes. Delete all spaces that are in this file.

      Now our decryption key is ready:
      Code:
      1211345678901234432109876543210036363636363636363636363636363621
     
    Last edited by masagrator, Oct 7, 2020
Draft saved Draft deleted
Loading...

Hide similar threads Similar threads with keywords - decryption, extract, Unreal