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
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:
-
Find all instances of encrypted RSAC C-String's, preferably automated.
-
Figure out the following parameters for (size_tthis itransformation:
=
0ull;-
iLocation <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,
decoding...\n");-
u64In 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",
off_data,
off_key);
u64
addrof_data
=
ctx->base
+
off_data;
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 ); }