Skip to main content

Specification

voidHere’s parse_r5ac_string(EngineContext*your ctx,text, u64typed offset,out std::vectorverbatim vec_data,from std::vectorthe vec_key,image:

size_t
length)
{

Specification

RSAC is the name of an in-house cheat detection software. It seems to be made by a team at respawn entertainment, although there is no public information about it anywhere on the internet.

Where is it?

It is located in the main game executable, r5apex_dx12.exe. Sometimes you will encounter entire functions that will be related to it, other times it'll be some inlined code in some important game/engine functions. It uses a basic xor transform on it's c-strings, which makes it so that it will only be decrypted on the stack. However, it's quite easy to statically analyze a runtime dump of Apex Legends, and figure out a way to:

  1. Find all instances of encrypted RSAC C-String's, preferably automated.

  2. Figure out the following parameters for (size_tthis itransformation:

    =
      0ull;
    • i

      Location <of length;the i++)encrypted {data.

      vec_data[i]
    • ^=
    • vec_key[i];

      Location }of printf("r5apex_dx12.exethe +encryption 0x%llx,key.

      '%s'\n",
    • offset,
    • reinterpret_cast(vec_data.data()));

      Length }of //printf("[+]the instructionencrypted patterndata.

      has
    • been
    validated,
  3. decoding...\n");
  4. u64

    In off_datacase =of get_operand_addressor_offset(this instructions[0]cheat );detection u64software, off_keythe =length get_operand_addressor_offset(of instructions[2]an );encrypted ifC-String's (off_dataencoded <data 1equals ||it's off_keyencryption <key's 1)size. {This //printf("[!]might failedbe done to obtainprevent DATArepeating andkeys KEYduring offsets.the (0x%llx)\n",XOR load_addresstransform, -which ctx->base);can return;weaken }the //printf("overall off_data:effectiveness 0x%llx,of off_key:encryption.

    0x%llx\n",
  5. off_data,
off_key);
u64
addrof_data
=
ctx->base

+
off_data;
u64
addrof_key
=

ctx->base
+
off_key;
size_t operation_length = get_encryption_length( instructions[3] ); if (operation_length < 1) { //printf("[!] failed to obtain proper operation length. (0x%llx)\n", load_address - ctx->base); return; } if (operation_length > 0x10000) return; //printf("LENGTH: 0x%llx\n", operation_length); std::vector vec_data( operation_length ); std::vector vec_key( operation_length ); memcpy(vec_data.data(), POINTER_OF(addrof_data), operation_length); memcpy(vec_key.data(), POINTER_OF(addrof_key), operation_length); parse_r5ac_string( ctx, load_address - ctx->base, vec_data, vec_key, operation_length ); }