Echo of Soul File Encryption Information

Programming related discussions related to game research
atom0s
Posts: 250
Joined: Sat Dec 27, 2014 8:49 pm

Echo of Soul File Encryption Information

Post by atom0s »

Echo of Soul is an online MMORPG that makes use of some custom encryption mixed with Microsoft's Cryptography library.

Code: Select all

http://echoofsoul.aeriagames.com/


Protected files can be seen having a header like this:
Image

The first four bytes are used as a signature to determine if the file is protected or not. Inside of the game, we can see a check for this like this:

Code: Select all

  v2 = (const CHAR *)sub_E2DF80(lpFileName);
  v3 = CreateFileA(v2, 0x80000000, 1u, 0, 3u, 0x80u, 0);
  if ( v3 == (HANDLE)-1
    || (NumberOfBytesRead = 0,
        v9 = 0xD0B7A0CC,
        ReadFile(v3, Buffer, 4u, &NumberOfBytesRead, 0),
        CloseHandle(v3),
        NumberOfBytesRead != 4) )
  {
LABEL_8:
    result = 0;
  }
  else
  {
    for ( i = 0; ; ++i )
    {
      v7 = i;
      if ( i >= 4 )
        break;
      if ( Buffer[i] != *((_BYTE *)&v9 + i) )
        goto LABEL_8;
    }
    result = 1;
  }
  return result;


Here the file is loaded and the first 4 bytes are read. Afterward, the code checks byte by byte against the value of v9 (or 0xD0B7A0CC). If it matches its considered protected; otherwise it is not.

Next the game makes use of the Crypto library functions provided by Microsoft. The game creates an MD5 hash object by using the following:

Code: Select all

  if ( !CryptAcquireContextW((HCRYPTPROV *)(a2 + 1140), L"SBENCRYPTIONKEYCONTAINER10", L"Microsoft Enhanced Cryptographic Provider v1.0", 1u, 0) && GetLastError() == -2146893802 )
    CryptAcquireContextW((HCRYPTPROV *)(a2 + 1140), L"SBENCRYPTIONKEYCONTAINER10", 0, 1u, 8u);
  if ( !*(_DWORD *)(a2 + 1140) )
  {
    v6 = GetLastError();
    sub_E4B130(L"CryptAcquireContext failed. (%d)(0x%08x)", v6);
  }
  v7 = (HCRYPTHASH *)(a2 + 1148);
  if ( CryptCreateHash(*(_DWORD *)(a2 + 1140), 0x8003u, 0, 0, (HCRYPTHASH *)(a2 + 1148))
    && CryptHashData(*v7, &pbData, 8u, 0)
    && CryptDeriveKey(*(_DWORD *)(a2 + 1140), 0x6801u, *v7, (DWORD)&loc_800000, (HCRYPTKEY *)(a2 + 1144)) )
    v11 = 0;
  else
    LOBYTE(v11) = 0;


Here the game is creating a hash provider context to use an MD5 crypto object. The pbData is added to the has object as a key for the encryption / decryption which in this case is:
Image

Once initialized, the game makes use of the crypto provider with its encryption and decryption by the following two functions:

Code: Select all

int __usercall sub_409810@<eax>(HCRYPTKEY hKey@<ecx>, int a2@<esi>)
{
  signed int v2; // ecx@1
  int v3; // eax@2
  int result; // eax@3
  int v5; // [sp+0h] [bp-4h]@1
 
  v5 = 8;
  CryptDecrypt(hKey, 0, 1, 0, (BYTE *)a2, (DWORD *)&v5);
  v2 = 0;
  do
  {
    LOBYTE(v3) = *(_BYTE *)(v2 + a2);
    if ( (_BYTE)v3 == 127 )
    {
      result = 0;
    }
    else if ( (_BYTE)v3 == -128 )
    {
      result = 255;
    }
    else
    {
      v3 = (unsigned __int8)v3;
      if ( (unsigned __int8)v3 >= 0x80u )
        result = v3 - 1;
      else
        result = v3 + 1;
    }
    *(_BYTE *)(v2++ + a2) = result;
  }
  while ( v2 < 8 );
  *(_DWORD *)a2 ^= 0xA4A7FF88;
  *(_DWORD *)(a2 + 4) ^= 0xA0447823;
  return result;
}

BOOL __usercall sub_4097B0@<eax>(int a1@<edx>, DWORD a2@<ecx>, HCRYPTKEY hKey)
{
  signed int v3; // ecx@1
  unsigned __int8 v4; // al@2
  char v5; // al@3
  DWORD pdwDataLen; // [sp+0h] [bp-4h]@1

  pdwDataLen = a2;
  *(_DWORD *)a1 ^= 0xA4A7FF88;
  *(_DWORD *)(a1 + 4) ^= 0xA0447823;
  v3 = 0;
  do
  {
    v4 = *(_BYTE *)(v3 + a1);
    if ( v4 )
    {
      if ( v4 == -1 )
      {
        v5 = -128;
      }
      else if ( v4 >= 0x80u )
      {
        v5 = v4 + 1;
      }
      else
      {
        v5 = v4 - 1;
      }
    }
    else
    {
      v5 = 127;
    }
    *(_BYTE *)(v3++ + a1) = v5;
  }
  while ( v3 < 8 );
  pdwDataLen = 8;
  return CryptEncrypt(hKey, 0, 1, 0, (BYTE *)a1, &pdwDataLen, 8u);
}


Not going to go into much detail on these, but we see that the data is processed in 8 byte chunks. Those 8 bytes are broken into 4 byte parts and xor'd with the keys: 0xA4A7FF88 and 0xA0447823
Some minor adjustments are made based on the byte data and the crypto provider is called to encrypt or decrypt the data.

I created two tools to deal with both of these functions.
eosdec - A tool to decrypt Echo of Souls files.
eosenc - A tool to encrypt Echo of Souls files.

A simple test to validate the encryption is being handled properly is to:
eosdec the EoS.ini file. Then to eosenc the resulting decrypted file.
The new encrypted file will match the original EoS.ini perfectly.

You can check out this project (and possibly other future tools for this game) here:
https://gitlab.com/atom0s/EoSTools
atom0s
Posts: 250
Joined: Sat Dec 27, 2014 8:49 pm

Re: Echo of Soul File Encryption Information

Post by atom0s »

I have moved this project to Gitlab as Github has been bought over by corporate greed.
https://gitlab.com/atom0s/EoSTools
Dezert
Posts: 3
Joined: Sat Apr 02, 2016 1:46 pm

Re: Echo of Soul File Encryption Information

Post by Dezert »

atom0s wrote:I have moved this project to Gitlab as Github has been bought over by corporate greed.
https://gitlab.com/atom0s/EoSTools


There should be exe files? or without them to do to make it work?
atom0s
Posts: 250
Joined: Sat Dec 27, 2014 8:49 pm

Re: Echo of Soul File Encryption Information

Post by atom0s »

Dezert wrote:
atom0s wrote:I have moved this project to Gitlab as Github has been bought over by corporate greed.
https://gitlab.com/atom0s/EoSTools


There should be exe files? or without them to do to make it work?


You need to compile them yourself. I do not release binaries for things like this for legal reasons. Download Visual Studio 2015 (there is a free version that will work just fine). And use it to compile the projects to exe's.
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: Echo of Soul File Encryption Information

Post by aluigi »

Regarding the binaries, if for you it's ok I have attached them (compiled yesterday as x86 release static) to this post so you will have no legal annoyances :)
AnonBaiter
Posts: 1125
Joined: Tue Feb 02, 2016 2:35 am

Re: Echo of Soul File Encryption Information

Post by AnonBaiter »

atom0s wrote:I do not release binaries for things like this for legal reasons.
Why? Do you think that compiling programs are now encouraging piracy?
atom0s
Posts: 250
Joined: Sat Dec 27, 2014 8:49 pm

Re: Echo of Soul File Encryption Information

Post by atom0s »

AnonBaiter wrote:
atom0s wrote:I do not release binaries for things like this for legal reasons.
Why? Do you think that compiling programs are now encouraging piracy?


Releasing binaries that allow the access to assets and copyright material has gotten me DMCA's in the past, so yes I avoid them. Do I think/care that encourages piracy? No.
But I enjoy not fighting with game companies over legal garbage so I just don't bother releasing binaries.

. no worries, I just choose not to release binaries for these kinds of things due to legal reasons.