globals
struct globals {
inline static constexpr uintptr_t timestamp = 0x6A6D4AEF;
inline static constexpr uintptr_t ref_def = 0xEB841A0;
inline static constexpr uintptr_t name_array = 0xED1C710;
inline static constexpr uintptr_t camera_base = 0xE7764E0;
inline static constexpr uintptr_t game_mode = 0xDD44278;
inline static constexpr uintptr_t weapon_definitions = 0xE96ABF0;
inline static constexpr uintptr_t loot_ptr = 0xFD342C8;
inline static constexpr uintptr_t distribute = 0xB1D3E88;
inline static constexpr uintptr_t lobby_data = 0xE0D8CE8;
inline static constexpr uintptr_t ms_compassSystemArray = 0xEB51B18;
};
decrypt_rva
struct decrypt_rva {
inline static constexpr uintptr_t client_info_enc = 0xEB72B98;
inline static constexpr uintptr_t client_info_key = 0xD92F779;
inline static constexpr uintptr_t client_base_enc = 0x23CDA8;
inline static constexpr uintptr_t client_base_key = 0xD92F7AA;
inline static constexpr uintptr_t bone_enc = 0x12EC3488;
inline static constexpr uintptr_t bone_key = 0xD92F89D;
inline static constexpr uintptr_t stub_client_info = 0x3DBE51D;
inline static constexpr uintptr_t stub_client_base = 0x3BF9F27;
inline static constexpr uintptr_t stub_bone_base = 0x75A19DE;
};
camera
struct camera {
inline static constexpr uintptr_t base = 0xE7764E0;
inline static constexpr uintptr_t pos = 0x1F4;
inline static constexpr uintptr_t pos_enc = 0x160;
inline static constexpr uintptr_t pos_key = 0x16C;
inline static constexpr uintptr_t angles_a = 0x1E8;
inline static constexpr uintptr_t angles_b = 0x200;
inline static constexpr uintptr_t angles_c = 0x208;
};
local
struct local {
inline static constexpr uintptr_t index = 0xB03F0;
inline static constexpr uintptr_t index_pos = 0x418;
inline static constexpr uintptr_t visible_client_bits = 0x225FC4;
inline static constexpr uintptr_t recoil = 0xFD11C;
inline static constexpr uintptr_t scoreboard = 0x1F0F8;
inline static constexpr uintptr_t scoreboard_size = 0x80;
};
player
struct player {
inline static constexpr uintptr_t size = 0x2808;
inline static constexpr uintptr_t valid = 0x13FC;
inline static constexpr uintptr_t pos = 0xEB0;
inline static constexpr uintptr_t pos_data = 0x80;
inline static constexpr uintptr_t team = 0xB0;
inline static constexpr uintptr_t stance = 0x19D0;
inline static constexpr uintptr_t weapon_index = 0x208;
inline static constexpr uintptr_t weapon_obj = 0x200;
inline static constexpr uintptr_t usercmd = 0x308;
inline static constexpr uintptr_t health = 0x600;
};
bone
struct bone {
inline static constexpr uintptr_t base_pos = 0x1E86A0;
inline static constexpr uintptr_t size = 0x1D8;
inline static constexpr uintptr_t offset = 0xE0;
inline static constexpr uintptr_t head = 0x7;
inline static constexpr uintptr_t neck = 0x6;
inline static constexpr uintptr_t chest = 0x5;
inline static constexpr uintptr_t pelvis = 0x0;
};
entity
struct entity {
inline static constexpr uintptr_t predictedPlayerEntity = 0x35930;
inline static constexpr uintptr_t size = 0x720;
inline static constexpr uintptr_t nextState_number = 0x1D8;
inline static constexpr uintptr_t nextState_eType = 0x1E0;
inline static constexpr uintptr_t local_pos = 0x1FC;
inline static constexpr uintptr_t local_valid = 0x1F0;
inline static constexpr uintptr_t local_size = 0x648;
};
name_array
struct name_array {
inline static constexpr uintptr_t ptr = 0xED1C710;
inline static constexpr uintptr_t pos = 0x3038;
inline static constexpr uintptr_t size = 0xD0;
inline static constexpr uintptr_t entry_name = 0x10;
inline static constexpr uintptr_t entry_health = 0x90;
inline static constexpr uintptr_t entry_alive = 0x78;
};
loot
struct loot {
inline static constexpr uintptr_t ptr = 0xFD342C8;
inline static constexpr uintptr_t size = 0x850;
inline static constexpr uintptr_t pos = 0x178;
inline static constexpr uintptr_t valid1 = 0x83C;
inline static constexpr uintptr_t valid2 = 0x848;
inline static constexpr uintptr_t valid_supply = 0x849;
};
More
lobby
struct lobby {
inline static constexpr uintptr_t data = 0xE0D8CE8;
inline static constexpr uintptr_t Party_GetMemberPlatform = 0x30D3460;
inline static constexpr uintptr_t members = 0x20E8;
inline static constexpr uintptr_t member_size = 0x160;
inline static constexpr uintptr_t platform_offset = 0x15C;
inline static constexpr uintptr_t getName = 0x30D33C0;
};
compass
struct compass {
inline static constexpr uintptr_t ms_compassSystemArray = 0xEB51B18;
inline static constexpr uintptr_t CG_CompassFullToWorld = 0x49A7F00;
inline static constexpr uintptr_t mapWorldSize = 0xEA5E8;
inline static constexpr uintptr_t mapUpperLeft = 0x3188C;
inline static constexpr uintptr_t north = 0x3FC;
inline static constexpr uintptr_t GetMapSizeData = 0x8B3B0A1;
inline static constexpr uintptr_t currentZoomLevel = 0x79C4;
inline static constexpr uintptr_t tacmapMapCenter = 0x5E4;
inline static constexpr uintptr_t Minimap_Render = 0x8E593DA;
inline static constexpr uintptr_t GetCommonParams = 0x8D44E70;
};
code
struct code {
inline static constexpr uintptr_t GetBonePosition = 0x3560840;
inline static constexpr uintptr_t GetBoneIndex = 0x3BDA826;
inline static constexpr uintptr_t CG_Entity_GetPlayerViewOrigin = 0x4BA8530;
inline static constexpr uintptr_t SightTrace = 0x4068D10;
inline static constexpr uintptr_t ThirdPerson = 0x42777B0;
inline static constexpr uintptr_t CL_IsPlayerTalking = 0x6FC2D50;
inline static constexpr uintptr_t BG_GetWeaponClass = 0x437D2A0;
inline static constexpr uintptr_t UI_SafeTranslateString = 0xA4FCE80;
inline static constexpr uintptr_t CG_GetEntityPose_Math = 0x7E1C730;
inline static constexpr uintptr_t g_SnapshotQueue = 0xF42D330;
inline static constexpr uintptr_t ClientActive = 0x306070C;
inline static constexpr uintptr_t PlayerValid = 0x3077E24;
inline static constexpr uintptr_t Scoreboard = 0x915D9D5;
};
Decrypt (Steam 0x6A6D4AEF)
Live probe (2026-08-15): PEB mode 0 (~peb) → client_info=0x1CBE6826040 → client_base=0x1CBE7D12700 (case 7) → bone_base=0x1A0AAB43B00 (case 13) → refdef=0x1CBE6A0E650. Camera raw +0x1F4 and Key3 +0x160 both valid.
struct Vec2 { float x, y; };
struct Vec3 { float x, y, z; };
struct Key3 { std::int32_t ref0, ref1, ref2; };
struct RefDef {
std::int32_t x, y, width, height;
Vec2 fov;
char pad1[8];
char pad2[4];
Vec3 axis[3];
};
using ReadFn = bool(*)(void* ctx, std::uint64_t addr, void* dst, std::size_t size);
template <typename T>
inline T rd(ReadFn fn, void* ctx, std::uint64_t a) {
T v{};
if (fn && a) fn(ctx, a, &v, sizeof(T));
return v;
}
inline bool is_heap(std::uint64_t p) {
return p >= 0x10000ull && p <= 0x00007FFFFFFFFFFFull;
}
inline std::uint64_t get_refdef_ptr(ReadFn fn, void* ctx, std::uint64_t base) {
if (!base) return 0;
const std::uint64_t addr = base + globals::ref_def;
const Key3 enc = rd<Key3>(fn, ctx, addr);
const std::uint64_t a0 = enc.ref2 ^ addr;
const std::uint64_t a4 = enc.ref2 ^ (addr + 4);
const std::uint32_t lower = static_cast<std::uint32_t>(
static_cast<std::uint32_t>(enc.ref0) ^ static_cast<std::uint32_t>(a0 * (a0 + 2)));
const std::uint32_t upper = static_cast<std::uint32_t>(
static_cast<std::uint32_t>(enc.ref1) ^ static_cast<std::uint32_t>(a4 * (a4 + 2)));
const std::uint64_t p = (static_cast<std::uint64_t>(upper) << 32) | lower;
return is_heap(p) ? p : 0;
}
// ---- Live STEAM decrypts (0x6A6D4AEF) ----
// Blonde94 / UC steam 0x6A6D4AEF — MUST use rdx = ~peb (not base).
// mode: 0=~peb 1=peb 2=base 3=0 (0 is correct; others for probe only)
inline std::uint64_t decrypt_client_info_mode(ReadFn fn, void* ctx, std::uint64_t base, std::uint64_t peb, int mode)
{
if (!base) return 0;
const std::uint64_t mb = base;
std::uint64_t rax = mb, rbx = mb, rcx = mb, rdx = mb, r9 = mb;
rbx = rd<std::uint64_t>(fn, ctx, base + decrypt_rva::client_info_enc);
if (!rbx)
return 0;
r9 = base;
rax = rbx;
rax >>= 0x18;
rcx = 0;
rax ^= rbx;
rcx = _rotl64(rcx, 0x10);
rcx ^= rd<std::uint64_t>(fn, ctx, base + decrypt_rva::client_info_key);
rbx = rax;
rbx >>= 0x30;
rcx = ~rcx;
rbx ^= rax;
rax = 0x233F5F4AE79533B1ull;
rbx *= rax;
rax = 0x4FF2ED27F19D575Dull;
if (mode == 0) rdx = ~peb;
else if (mode == 1) rdx = peb;
else if (mode == 2) rdx = base;
else rdx = 0;
rbx -= rdx;
rbx += rax;
rbx ^= r9;
// Multiplier table: *(~key + 0x19) — must be readable
const std::uint64_t mul = rd<std::uint64_t>(fn, ctx, rcx + 0x19);
if (!mul) return 0;
rbx *= mul;
return rbx;
}
inline std::uint64_t decrypt_client_info(ReadFn fn, void* ctx, std::uint64_t base, std::uint64_t peb)
{
if (!peb) return 0;
// Correct path first
{
const std::uint64_t p = decrypt_client_info_mode(fn, ctx, base, peb, 0);
if (is_heap(p)) return p;
}
// Fallbacks only if ~peb failed (wrong PEB?)
for (int mode = 1; mode < 4; ++mode) {
const std::uint64_t p = decrypt_client_info_mode(fn, ctx, base, peb, mode);
if (is_heap(p)) return p;
}
return decrypt_client_info_mode(fn, ctx, base, peb, 0);
}
// Which PEB mode produced a heap client_info (-1 = none)
inline int probe_client_info_mode(ReadFn fn, void* ctx, std::uint64_t base, std::uint64_t peb)
{
for (int mode = 0; mode < 4; ++mode) {
if (is_heap(decrypt_client_info_mode(fn, ctx, base, peb, mode)))
return mode;
}
return -1;
}
inline std::uint64_t decrypt_client_base(ReadFn fn, void* ctx, std::uint64_t base, std::uint64_t peb, std::uint64_t client_info)
{
const std::uint64_t mb = base;
std::uint64_t rax = mb, rbx = mb, rcx = mb, rdx = mb, rdi = mb, rsi = mb, r8 = mb, r9 = mb, r10 = mb, r11 = mb, r12 = mb, r13 = mb, r14 = mb, r15 = mb;
r8 = rd<std::uint64_t>(fn, ctx, client_info + decrypt_rva::client_base_enc);
if(!r8)
return r8;
rbx = peb; //mov rbx, gs:[rax]
rax = rbx; //mov rax, rbx
rax <<= 0x23; //shl rax, 0x23
rax = _byteswap_uint64(rax); //bswap rax
rax &= 0xF;
switch(rax) {
case 0:
{
r10 = rd<std::uint64_t>(fn, ctx, base + decrypt_rva::client_base_key); //mov r10, [0x0000000009D35834]
rax = base; //lea rax, [0xFFFFFFFFFC405EDA]
r8 -= rax; //sub r8, rax
rax = r8; //mov rax, r8
rax >>= 0x1E; //shr rax, 0x1E
rax ^= r8; //xor rax, r8
r8 = rax; //mov r8, rax
r8 >>= 0x3C; //shr r8, 0x3C
r8 ^= rax; //xor r8, rax
rax = base; //lea rax, [0xFFFFFFFFFC405CBE]
r8 -= rax; //sub r8, rax
rax = r8; //mov rax, r8
rax >>= 0x28; //shr rax, 0x28
r8 ^= rax; //xor r8, rax
rax = 0; //and rax, 0xFFFFFFFFC0000000
rax = _rotl64(rax, 0x10); //rol rax, 0x10
rax ^= r10; //xor rax, r10
rax = ~rax; //not rax
r8 *= rd<std::uint64_t>(fn, ctx, rax + 0x9); //imul r8, [rax+0x09]
rax = 0x9CC8E0420ADA280D; //mov rax, 0x9CC8E0420ADA280D
rax *= r8; //imul rax, r8
rax += rbx; //add rax, rbx
r8 = rax; //mov r8, rax
r8 >>= 0x11; //shr r8, 0x11
r8 ^= rax; //xor r8, rax
rax = r8; //mov rax, r8
rax >>= 0x22; //shr rax, 0x22
r8 ^= rax; //xor r8, rax
return r8;
}
case 1:
{
r10 = rd<std::uint64_t>(fn, ctx, base + decrypt_rva::client_base_key); //mov r10, [0x0000000009D3539D]
r15 = base + 0x755F7BDD; //lea r15, [0x00000000719FD7B8]
rax = r8; //mov rax, r8
rax >>= 0x9; //shr rax, 0x09
rax ^= r8; //xor rax, r8
r8 = rax; //mov r8, rax
r8 >>= 0x12; //shr r8, 0x12
r8 ^= rax; //xor r8, rax
rax = r8; //mov rax, r8
rax >>= 0x24; //shr rax, 0x24
r8 ^= rax; //xor r8, rax
r8 ^= rbx; //xor r8, rbx
rcx = 0; //and rcx, 0xFFFFFFFFC0000000
rcx = _rotl64(rcx, 0x10); //rol rcx, 0x10
rcx ^= r10; //xor rcx, r10
rcx = ~rcx; //not rcx
r8 *= rd<std::uint64_t>(fn, ctx, rcx + 0x9); //imul r8, [rcx+0x09]
rcx = base; //lea rcx, [0xFFFFFFFFFC405841]
rax = rbx; //mov rax, rbx
rax -= rcx; //sub rax, rcx
rax += 0xFFFFFFFF9F0CFAED; //add rax, 0xFFFFFFFF9F0CFAED
r8 += rax; //add r8, rax
rax = 0x40ED86BABDEA8F5B; //mov rax, 0x40ED86BABDEA8F5B
r8 *= rax; //imul r8, rax
rax = 0xA7798517B7F399EA; //mov rax, 0xA7798517B7F399EA
r8 ^= rax; //xor r8, rax
rax = r15; //mov rax, r15
rax = ~rax; //not rax
rax ^= rbx; //xor rax, rbx
r8 += rax; //add r8, rax
rax = 0x459093E765583ADB; //mov rax, 0x459093E765583ADB
r8 *= rax; //imul r8, rax
return r8;
}
case 2:
{
r10 = rd<std::uint64_t>(fn, ctx, base + decrypt_rva::client_base_key); //mov r10, [0x0000000009D34F4F]
r14 = base + 0xAC81; //lea r14, [0xFFFFFFFFFC410413]
rax = 0xE03443781C6DB26D; //mov rax, 0xE03443781C6DB26D
r8 *= rax; //imul r8, rax
rax = 0x26676A6627BAC50C; //mov rax, 0x26676A6627BAC50C
r8 -= rax; //sub r8, rax
rax = 0x541ECC7788F37ADE; //mov rax, 0x541ECC7788F37ADE
r8 += rax; //add r8, rax
r8 += r14; //add r8, r14
rax = base + 0x142; //lea rax, [0xFFFFFFFFFC405492]
rax = ~rax; //not rax
rcx = rbx; //mov rcx, rbx
rcx = ~rcx; //not rcx
rcx -= rbx; //sub rcx, rbx
rcx += rax; //add rcx, rax
r8 += rcx; //add r8, rcx
rax = r8; //mov rax, r8
rax >>= 0x15; //shr rax, 0x15
r8 ^= rax; //xor r8, rax
rax = r8; //mov rax, r8
rax >>= 0x2A; //shr rax, 0x2A
r8 ^= rax; //xor r8, rax
rax = base; //lea rax, [0xFFFFFFFFFC4052F1]
r8 -= rax; //sub r8, rax
rax = 0; //and rax, 0xFFFFFFFFC0000000
rax = _rotl64(rax, 0x10); //rol rax, 0x10
rax ^= r10; //xor rax, r10
rax = ~rax; //not rax
r8 *= rd<std::uint64_t>(fn, ctx, rax + 0x9); //imul r8, [rax+0x09]
return r8;
}
case 3:
{
r10 = rd<std::uint64_t>(fn, ctx, base + decrypt_rva::client_base_key); //mov r10, [0x0000000009D34A72]
r13 = base + 0xF26D; //lea r13, [0xFFFFFFFFFC414522]
r8 ^= rbx; //xor r8, rbx
rcx = 0; //and rcx, 0xFFFFFFFFC0000000
rcx = _rotl64(rcx, 0x10); //rol rcx, 0x10
rcx ^= r10; //xor rcx, r10
rcx = ~rcx; //not rcx
r8 *= rd<std::uint64_t>(fn, ctx, rcx + 0x9); //imul r8, [rcx+0x09]
rax = 0x6C5618A3BE4C414; //mov rax, 0x6C5618A3BE4C414
r8 -= rax; //sub r8, rax
rax = 0xE98709096AD185CC; //mov rax, 0xE98709096AD185CC
r8 ^= rax; //xor r8, rax
rax = r8; //mov rax, r8
rax >>= 0xB; //shr rax, 0x0B
rax ^= r8; //xor rax, r8
r8 = base + 0x5ED318FB; //lea r8, [0x000000005B136A8B]
rcx = rax; //mov rcx, rax
r8 = ~r8; //not r8
r8 *= rbx; //imul r8, rbx
rcx >>= 0x16; //shr rcx, 0x16
rcx ^= rax; //xor rcx, rax
rax = rcx; //mov rax, rcx
rax >>= 0x2C; //shr rax, 0x2C
r8 ^= rax; //xor r8, rax
r8 ^= rcx; //xor r8, rcx
rax = 0x22A1571E2E749CB; //mov rax, 0x22A1571E2E749CB
r8 *= rax; //imul r8, rax
rax = rbx; //mov rax, rbx
rax *= r13; //imul rax, r13
r8 += rax; //add r8, rax
return r8;
}
case 4:
{
r10 = rd<std::uint64_t>(fn, ctx, base + decrypt_rva::client_base_key); //mov r10, [0x0000000009D345F4]
r15 = base + 0x72D0A311; //lea r15, [0x000000006F10F143]
rax = 0x54EE9012A77B3C0E; //mov rax, 0x54EE9012A77B3C0E
r8 ^= rax; //xor r8, rax
rax = base; //lea rax, [0xFFFFFFFFFC4049E1]
rax += 0x432D; //add rax, 0x432D
rax += rbx; //add rax, rbx
r8 += rax; //add r8, rax
rax = 0xBE6A84FFF3304C3D; //mov rax, 0xBE6A84FFF3304C3D
r8 *= rax; //imul r8, rax
rax = r8; //mov rax, r8
r8 >>= 0x12; //shr r8, 0x12
r8 ^= rax; //xor r8, rax
rax = r8; //mov rax, r8
rax >>= 0x24; //shr rax, 0x24
rax ^= r8; //xor rax, r8
r8 = rax; //mov r8, rax
r8 >>= 0x7; //shr r8, 0x07
r8 ^= rax; //xor r8, rax
rax = r8; //mov rax, r8
rax >>= 0xE; //shr rax, 0x0E
r8 ^= rax; //xor r8, rax
rax = r8; //mov rax, r8
rax >>= 0x1C; //shr rax, 0x1C
rax ^= r8; //xor rax, r8
r8 = rax; //mov r8, rax
r8 >>= 0x38; //shr r8, 0x38
r8 ^= rax; //xor r8, rax
rax = 0; //and rax, 0xFFFFFFFFC0000000
rax = _rotl64(rax, 0x10); //rol rax, 0x10
rax ^= r10; //xor rax, r10
rax = ~rax; //not rax
r8 *= rd<std::uint64_t>(fn, ctx, rax + 0x9); //imul r8, [rax+0x09]
rax = rbx; //mov rax, rbx
rax *= r15; //imul rax, r15
r8 -= rax; //sub r8, rax
rax = 0x598660DAA37ACC99; //mov rax, 0x598660DAA37ACC99
r8 ^= rax; //xor r8, rax
return r8;
}
case 5:
{
r10 = rd<std::uint64_t>(fn, ctx, base + decrypt_rva::client_base_key); //mov r10, [0x0000000009D34159]
rax = 0; //and rax, 0xFFFFFFFFC0000000
rax = _rotl64(rax, 0x10); //rol rax, 0x10
rax ^= r10; //xor rax, r10
rax = ~rax; //not rax
r8 *= rd<std::uint64_t>(fn, ctx, rax + 0x9); //imul r8, [rax+0x09]
rax = 0xC088FB236BE68165; //mov rax, 0xC088FB236BE68165
r8 *= rax; //imul r8, rax
rax = r8; //mov rax, r8
r8 >>= 0x5; //shr r8, 0x05
r8 ^= rax; //xor r8, rax
rax = r8; //mov rax, r8
rax >>= 0xA; //shr rax, 0x0A
rax ^= r8; //xor rax, r8
r8 = rax; //mov r8, rax
r8 >>= 0x14; //shr r8, 0x14
r8 ^= rax; //xor r8, rax
rax = r8; //mov rax, r8
rax >>= 0x28; //shr rax, 0x28
r8 ^= rax; //xor r8, rax
rax = r8; //mov rax, r8
rax >>= 0xB; //shr rax, 0x0B
r8 ^= rax; //xor r8, rax
rax = r8; //mov rax, r8
rax >>= 0x16; //shr rax, 0x16
r8 ^= rax; //xor r8, rax
rax = r8; //mov rax, r8
rax >>= 0x2C; //shr rax, 0x2C
r8 ^= rax; //xor r8, rax
rax = 0xF87FD44152069748; //mov rax, 0xF87FD44152069748
r8 ^= rax; //xor r8, rax
rax = base; //lea rax, [0xFFFFFFFFFC404676]
rax += 0x1079; //add rax, 0x1079
rax += rbx; //add rax, rbx
r8 ^= rax; //xor r8, rax
rcx = base; //lea rcx, [0xFFFFFFFFFC404857]
rax = rbx; //mov rax, rbx
rax = ~rax; //not rax
rax -= rcx; //sub rax, rcx
rax += 0xFFFFFFFF968271AB; //add rax, 0xFFFFFFFF968271AB
r8 += rax; //add r8, rax
return r8;
}
case 6:
{
r10 = rd<std::uint64_t>(fn, ctx, base + decrypt_rva::client_base_key); //mov r10, [0x0000000009D33CDB]
r15 = base + 0x1EE2; //lea r15, [0xFFFFFFFFFC406400]
rax = 0; //and rax, 0xFFFFFFFFC0000000
rax = _rotl64(rax, 0x10); //rol rax, 0x10
rax ^= r10; //xor rax, r10
rax = ~rax; //not rax
r8 *= rd<std::uint64_t>(fn, ctx, rax + 0x9); //imul r8, [rax+0x09]
rcx = 0x30DABF93D6E4FB5; //mov rcx, 0x30DABF93D6E4FB5
r8 ^= rcx; //xor r8, rcx
rax = rbx; //mov rax, rbx
rax ^= r15; //xor rax, r15
r8 -= rax; //sub r8, rax
rax = 0xDB8B0AAFA542904; //mov rax, 0xDB8B0AAFA542904
r8 -= rbx; //sub r8, rbx
r8 -= rax; //sub r8, rax
rax = r8; //mov rax, r8
rax >>= 0x22; //shr rax, 0x22
r8 ^= rax; //xor r8, rax
rax = 0xDF170407BBE28DB5; //mov rax, 0xDF170407BBE28DB5
r8 *= rax; //imul r8, rax
rax = r8; //mov rax, r8
r8 >>= 0x8; //shr r8, 0x08
r8 ^= rax; //xor r8, rax
rax = r8; //mov rax, r8
rax >>= 0x10; //shr rax, 0x10
r8 ^= rax; //xor r8, rax
rax = r8; //mov rax, r8
rax >>= 0x20; //shr rax, 0x20
r8 ^= rax; //xor r8, rax
return r8;
}
case 7:
{
r10 = rd<std::uint64_t>(fn, ctx, base + decrypt_rva::client_base_key); //mov r10, [0x0000000009D3389A]
r15 = base + 0xC177; //lea r15, [0xFFFFFFFFFC410254]
rax = 0; //and rax, 0xFFFFFFFFC0000000
rax = _rotl64(rax, 0x10); //rol rax, 0x10
rax ^= r10; //xor rax, r10
rax = ~rax; //not rax
r8 *= rd<std::uint64_t>(fn, ctx, rax + 0x9); //imul r8, [rax+0x09]
rax = 0x1C4A7DE2E2F8F68F; //mov rax, 0x1C4A7DE2E2F8F68F
rcx = 0x378CE09B287B2D41; //mov rcx, 0x378CE09B287B2D41
rcx ^= r8; //xor rcx, r8
rcx += rax; //add rcx, rax
r8 = rcx; //mov r8, rcx
r8 >>= 0x23; //shr r8, 0x23
r8 ^= rcx; //xor r8, rcx
rax = rbx + 0x1; //lea rax, [rbx+0x01]
rax *= r15; //imul rax, r15
rax += rbx; //add rax, rbx
r8 += rax; //add r8, rax
rax = 0xEBEA9B8B5714671D; //mov rax, 0xEBEA9B8B5714671D
r8 *= rax; //imul r8, rax
rax = r8; //mov rax, r8
rax >>= 0xE; //shr rax, 0x0E
rax ^= r8; //xor rax, r8
r8 = rax; //mov r8, rax
r8 >>= 0x1C; //shr r8, 0x1C
r8 ^= rax; //xor r8, rax
rax = r8; //mov rax, r8
rax >>= 0x38; //shr rax, 0x38
r8 ^= rax; //xor r8, rax
return r8;
}
case 8:
{
r10 = rd<std::uint64_t>(fn, ctx, base + decrypt_rva::client_base_key); //mov r10, [0x0000000009D33359]
r13 = base + 0x553; //lea r13, [0xFFFFFFFFFC4040EA]
r15 = base + 0x88B9; //lea r15, [0xFFFFFFFFFC40C43F]
rax = base; //lea rax, [0xFFFFFFFFFC4039B0]
r8 ^= rax; //xor r8, rax
rax = 0x3169FBDB3B875224; //mov rax, 0x3169FBDB3B875224
r8 += rax; //add r8, rax
rax = r15; //mov rax, r15
rax = ~rax; //not rax
rax *= rbx; //imul rax, rbx
r8 ^= rax; //xor r8, rax
r8 ^= rbx; //xor r8, rbx
r8 ^= r13; //xor r8, r13
rax = r8; //mov rax, r8
rax >>= 0x13; //shr rax, 0x13
r8 ^= rax; //xor r8, rax
rax = r8; //mov rax, r8
rax >>= 0x26; //shr rax, 0x26
r8 ^= rax; //xor r8, rax
rcx = 0; //and rcx, 0xFFFFFFFFC0000000
rcx = _rotl64(rcx, 0x10); //rol rcx, 0x10
rax = 0x49665D7F2AFA3F6B; //mov rax, 0x49665D7F2AFA3F6B
r8 *= rax; //imul r8, rax
rcx ^= r10; //xor rcx, r10
rax = base + 0x11D125F7; //lea rax, [0x000000000E115EE0]
rax = ~rax; //not rax
rcx = ~rcx; //not rcx
rax *= rbx; //imul rax, rbx
r8 += rax; //add r8, rax
r8 *= rd<std::uint64_t>(fn, ctx, rcx + 0x9); //imul r8, [rcx+0x09]
return r8;
}
case 9:
{
r9 = rd<std::uint64_t>(fn, ctx, base + decrypt_rva::client_base_key); //mov r9, [0x0000000009D32F1C]
r11 = base + 0x7C81; //lea r11, [0xFFFFFFFFFC40B3E0]
rax = rbx; //mov rax, rbx
rax *= r11; //imul rax, r11
r8 -= rax; //sub r8, rax
rax = base; //lea rax, [0xFFFFFFFFFC403485]
r8 -= rax; //sub r8, rax
rax = rbx; //mov rax, rbx
rax -= base; //sub rax, [rsp+0x70] -- didn't find trace -> use base
rax += 0xFFFFFFFFFFFF4D38; //add rax, 0xFFFFFFFFFFFF4D38
r8 += rax; //add r8, rax
rax = 0xB294869EA09D48AA; //mov rax, 0xB294869EA09D48AA
r8 ^= rax; //xor r8, rax
rax = 0xDA6A9700AB4D27FD; //mov rax, 0xDA6A9700AB4D27FD
r8 *= rax; //imul r8, rax
rax = 0; //and rax, 0xFFFFFFFFC0000000
rax = _rotl64(rax, 0x10); //rol rax, 0x10
rax ^= r9; //xor rax, r9
rax = ~rax; //not rax
r8 *= rd<std::uint64_t>(fn, ctx, rax + 0x9); //imul r8, [rax+0x09]
rax = 0x38632CDC13FD78A5; //mov rax, 0x38632CDC13FD78A5
r8 += rax; //add r8, rax
rax = r8; //mov rax, r8
rax >>= 0x1D; //shr rax, 0x1D
rax ^= r8; //xor rax, r8
r8 = rax; //mov r8, rax
r8 >>= 0x3A; //shr r8, 0x3A
r8 ^= rax; //xor r8, rax
return r8;
}
case 10:
{
r10 = rd<std::uint64_t>(fn, ctx, base + decrypt_rva::client_base_key); //mov r10, [0x0000000009D32A01]
r8 += rbx; //add r8, rbx
rax = 0x36164EFD786890C1; //mov rax, 0x36164EFD786890C1
r8 *= rax; //imul r8, rax
rax = 0x6F993F33D7A49418; //mov rax, 0x6F993F33D7A49418
rax += r8; //add rax, r8
r8 = rax; //mov r8, rax
r8 >>= 0x8; //shr r8, 0x08
r8 ^= rax; //xor r8, rax
rcx = r8; //mov rcx, r8
rcx >>= 0x10; //shr rcx, 0x10
rcx ^= r8; //xor rcx, r8
rax = 0; //and rax, 0xFFFFFFFFC0000000
rax = _rotl64(rax, 0x10); //rol rax, 0x10
r8 = rcx; //mov r8, rcx
rax ^= r10; //xor rax, r10
r8 >>= 0x20; //shr r8, 0x20
r8 ^= rcx; //xor r8, rcx
rax = ~rax; //not rax
r8 *= rd<std::uint64_t>(fn, ctx, rax + 0x9); //imul r8, [rax+0x09]
rax = 0xE88B55E25B8B057C; //mov rax, 0xE88B55E25B8B057C
r8 ^= rax; //xor r8, rax
rax = r8; //mov rax, r8
rax >>= 0x1A; //shr rax, 0x1A
rax ^= r8; //xor rax, r8
rcx = rax; //mov rcx, rax
rcx >>= 0x34; //shr rcx, 0x34
rcx ^= rax; //xor rcx, rax
rax = rcx; //mov rax, rcx
rax >>= 0x4; //shr rax, 0x04
rax ^= rcx; //xor rax, rcx
rcx = rax; //mov rcx, rax
rcx >>= 0x8; //shr rcx, 0x08
rcx ^= rax; //xor rcx, rax
r8 = rcx; //mov r8, rcx
r8 >>= 0x10; //shr r8, 0x10
r8 ^= rcx; //xor r8, rcx
rax = r8; //mov rax, r8
rax >>= 0x20; //shr rax, 0x20
r8 ^= rax; //xor r8, rax
return r8;
}
case 11:
{
r10 = rd<std::uint64_t>(fn, ctx, base + decrypt_rva::client_base_key); //mov r10, [0x0000000009D325D4]
rax = 0; //and rax, 0xFFFFFFFFC0000000
rax = _rotl64(rax, 0x10); //rol rax, 0x10
rax ^= r10; //xor rax, r10
rax = ~rax; //not rax
r8 *= rd<std::uint64_t>(fn, ctx, rax + 0x9); //imul r8, [rax+0x09]
rax = rbx; //mov rax, rbx
std::uint64_t RBP_0xFFFFFFFFFFFFFFB8;
RBP_0xFFFFFFFFFFFFFFB8 = base + 0xA1FD; //lea rax, [0xFFFFFFFFFC40D020]
rax *= RBP_0xFFFFFFFFFFFFFFB8; //imul rax, [rbp-0x48]
r8 += rax; //add r8, rax
rax = r8; //mov rax, r8
rax >>= 0x26; //shr rax, 0x26
r8 ^= rax; //xor r8, rax
rax = r8; //mov rax, r8
rax >>= 0xA; //shr rax, 0x0A
r8 ^= rax; //xor r8, rax
rax = r8; //mov rax, r8
rax >>= 0x14; //shr rax, 0x14
rax ^= r8; //xor rax, r8
r8 = rax; //mov r8, rax
r8 >>= 0x28; //shr r8, 0x28
r8 ^= rax; //xor r8, rax
rax = 0xC6A8E21F37CF3675; //mov rax, 0xC6A8E21F37CF3675
r8 *= rax; //imul r8, rax
rax = base; //lea rax, [0xFFFFFFFFFC402916]
rax += rbx; //add rax, rbx
r8 -= rax; //sub r8, rax
rax = base; //lea rax, [0xFFFFFFFFFC402A43]
r8 ^= rax; //xor r8, rax
return r8;
}
case 12:
{
r9 = rd<std::uint64_t>(fn, ctx, base + decrypt_rva::client_base_key); //mov r9, [0x0000000009D3209F]
rax = 0x5D2901AC55739352; //mov rax, 0x5D2901AC55739352
r8 -= rax; //sub r8, rax
rax = 0; //and rax, 0xFFFFFFFFC0000000
rax = _rotl64(rax, 0x10); //rol rax, 0x10
rax ^= r9; //xor rax, r9
rax = ~rax; //not rax
r8 *= rd<std::uint64_t>(fn, ctx, rax + 0x9); //imul r8, [rax+0x09]
rax = base; //lea rax, [0xFFFFFFFFFC402441]
r8 += rax; //add r8, rax
rax = 0x156D71AB28FBFAFF; //mov rax, 0x156D71AB28FBFAFF
r8 *= rax; //imul r8, rax
rax = r8; //mov rax, r8
r8 >>= 0x27; //shr r8, 0x27
r8 ^= rax; //xor r8, rax
r8 -= rbx; //sub r8, rbx
rax = r8; //mov rax, r8
rax >>= 0x17; //shr rax, 0x17
r8 ^= rax; //xor r8, rax
rax = r8; //mov rax, r8
rax >>= 0x2E; //shr rax, 0x2E
r8 ^= rax; //xor r8, rax
rax = base; //lea rax, [0xFFFFFFFFFC4024C3]
r8 ^= rax; //xor r8, rax
return r8;
}
case 13:
{
r11 = rd<std::uint64_t>(fn, ctx, base + decrypt_rva::client_base_key); //mov r11, [0x0000000009D31B56]
rax = r8; //mov rax, r8
rax >>= 0x1F; //shr rax, 0x1F
r8 ^= rax; //xor r8, rax
rcx = r8; //mov rcx, r8
rax = base; //lea rax, [0xFFFFFFFFFC401FAF]
rcx >>= 0x3E; //shr rcx, 0x3E
rcx ^= r8; //xor rcx, r8
rdx = 0; //and rdx, 0xFFFFFFFFC0000000
rdx = _rotl64(rdx, 0x10); //rol rdx, 0x10
r8 = rbx; //mov r8, rbx
r8 = ~r8; //not r8
rdx ^= r11; //xor rdx, r11
r8 += rcx; //add r8, rcx
rdx = ~rdx; //not rdx
r8 -= rax; //sub r8, rax
r8 -= 0x6929AFAC; //sub r8, 0x6929AFAC
r8 *= rd<std::uint64_t>(fn, ctx, rdx + 0x9); //imul r8, [rdx+0x09]
rax = r8; //mov rax, r8
rax >>= 0x18; //shr rax, 0x18
r8 ^= rax; //xor r8, rax
rax = r8; //mov rax, r8
rax >>= 0x30; //shr rax, 0x30
r8 ^= rax; //xor r8, rax
rax = 0x69651B1AF033619B; //mov rax, 0x69651B1AF033619B
r8 += rbx; //add r8, rbx
r8 *= rax; //imul r8, rax
rax = 0x29BBD1B30DFD9417; //mov rax, 0x29BBD1B30DFD9417
r8 *= rax; //imul r8, rax
rax = 0xA7B8F15C4FABBB6C; //mov rax, 0xA7B8F15C4FABBB6C
r8 ^= rax; //xor r8, rax
return r8;
}
case 14:
{
r10 = rd<std::uint64_t>(fn, ctx, base + decrypt_rva::client_base_key); //mov r10, [0x0000000009D316DA]
r8 += rbx; //add r8, rbx
rax = base + 0x8D0; //lea rax, [0xFFFFFFFFFC402661]
rax -= rbx; //sub rax, rbx
r8 += rax; //add r8, rax
rax = 0xBC0AAA7E98B1663A; //mov rax, 0xBC0AAA7E98B1663A
r8 ^= rax; //xor r8, rax
rax = 0x54D1F9305B205B45; //mov rax, 0x54D1F9305B205B45
r8 *= rax; //imul r8, rax
rcx = r8; //mov rcx, r8
rcx >>= 0xA; //shr rcx, 0x0A
rcx ^= r8; //xor rcx, r8
rax = rcx; //mov rax, rcx
rax >>= 0x14; //shr rax, 0x14
rax ^= rcx; //xor rax, rcx
r8 = rax; //mov r8, rax
r8 >>= 0x28; //shr r8, 0x28
r8 ^= rax; //xor r8, rax
rax = r8; //mov rax, r8
rax >>= 0x12; //shr rax, 0x12
rax ^= r8; //xor rax, r8
r8 = rax; //mov r8, rax
r8 >>= 0x24; //shr r8, 0x24
r8 ^= rax; //xor r8, rax
rax = 0xFFFFFFFFDE23E20A; //mov rax, 0xFFFFFFFFDE23E20A
rax -= rbx; //sub rax, rbx
rax -= base; //sub rax, [rsp+0x70] -- didn't find trace -> use base
r8 += rax; //add r8, rax
rax = 0; //and rax, 0xFFFFFFFFC0000000
rax = _rotl64(rax, 0x10); //rol rax, 0x10
rax ^= r10; //xor rax, r10
rax = ~rax; //not rax
r8 *= rd<std::uint64_t>(fn, ctx, rax + 0x9); //imul r8, [rax+0x09]
return r8;
}
case 15:
{
r10 = rd<std::uint64_t>(fn, ctx, base + decrypt_rva::client_base_key); //mov r10, [0x0000000009D31256]
r15 = base + 0x76BB; //lea r15, [0xFFFFFFFFFC409154]
rax = 0; //and rax, 0xFFFFFFFFC0000000
rax = _rotl64(rax, 0x10); //rol rax, 0x10
rax ^= r10; //xor rax, r10
rax = ~rax; //not rax
rax = rd<std::uint64_t>(fn, ctx, rax + 0x9); //mov rax, [rax+0x09]
std::uint64_t RBP_0xFFFFFFFFFFFFFFB0;
RBP_0xFFFFFFFFFFFFFFB0 = 0x3A27415DA31CA989; //mov rax, 0x3A27415DA31CA989
rax *= RBP_0xFFFFFFFFFFFFFFB0; //imul rax, [rbp-0x50]
r8 *= rax; //imul r8, rax
rax = 0x6F6A3BE0CADE4A54; //mov rax, 0x6F6A3BE0CADE4A54
r8 -= rax; //sub r8, rax
r8 -= rbx; //sub r8, rbx
rcx = r8; //mov rcx, r8
rcx >>= 0x13; //shr rcx, 0x13
rcx ^= r8; //xor rcx, r8
r8 = rbx; //mov r8, rbx
r8 = ~r8; //not r8
rax = r15; //mov rax, r15
rax = ~rax; //not rax
r8 *= rax; //imul r8, rax
rax = rcx; //mov rax, rcx
rax >>= 0x26; //shr rax, 0x26
rax ^= rcx; //xor rax, rcx
r8 += rax; //add r8, rax
rax = r8; //mov rax, r8
rax >>= 0x28; //shr rax, 0x28
r8 ^= rax; //xor r8, rax
rax = 0x3224CE0A9BEB6A6E; //mov rax, 0x3224CE0A9BEB6A6E
r8 -= rax; //sub r8, rax
return r8;
}
}
return 0;
}
inline std::uint64_t decrypt_bone_base(ReadFn fn, void* ctx, std::uint64_t base, std::uint64_t peb)
{
const std::uint64_t mb = base;
std::uint64_t rax = mb, rbx = mb, rcx = mb, rdx = mb, rdi = mb, rsi = mb, r8 = mb, r9 = mb, r10 = mb, r11 = mb, r12 = mb, r13 = mb, r14 = mb, r15 = mb;
rdx = rd<std::uint64_t>(fn, ctx, base + decrypt_rva::bone_enc);
if(!rdx)
return rdx;
r8 = peb; //mov r8, gs:[rax]
rax = r8; //mov rax, r8
rax >>= 0x13; //shr rax, 0x13
rax &= 0xF;
switch(rax) {
case 0:
{
r9 = rd<std::uint64_t>(fn, ctx, base + decrypt_rva::bone_key); //mov r9, [0x000000000638DE60]
rax = base + 0x8C93; //lea rax, [0xFFFFFFFFF8A671DC]
rax -= r8; //sub rax, r8
rdx ^= rax; //xor rdx, rax
rax = rdx; //mov rax, rdx
rax >>= 0x15; //shr rax, 0x15
rax ^= rdx; //xor rax, rdx
rdx = rax; //mov rdx, rax
rdx >>= 0x2A; //shr rdx, 0x2A
rdx ^= rax; //xor rdx, rax
rdx += r8; //add rdx, r8
rax = 0; //and rax, 0xFFFFFFFFC0000000
rax = _rotl64(rax, 0x10); //rol rax, 0x10
rax ^= r9; //xor rax, r9
rax = ~rax; //not rax
rdx *= rd<std::uint64_t>(fn, ctx, rax + 0x17); //imul rdx, [rax+0x17]
rax = base; //lea rax, [0xFFFFFFFFF8A5E22C]
rdx ^= rax; //xor rdx, rax
rax = 0x860534C8C01FEA7B; //mov rax, 0x860534C8C01FEA7B
rdx *= rax; //imul rdx, rax
rax = 0xEE334BF3EC572D68; //mov rax, 0xEE334BF3EC572D68
rdx ^= rax; //xor rdx, rax
return rdx;
}
case 1:
{
// Steam 0x6A6D4AEF — previous body was a stub (return rdx). Live PEB hits this case.
r10 = rd<std::uint64_t>(fn, ctx, base + decrypt_rva::bone_key);
r15 = base + 0xDF5D;
rax = 0;
rax = _rotl64(rax, 0x10);
rax ^= r10;
rax = ~rax;
rdx *= rd<std::uint64_t>(fn, ctx, rax + 0x17);
rax = 0x8A4B98169395E686ull;
rdx ^= rax;
rax = 0xC3957EB9F84EC5AFull;
rdx *= rax;
rax = rdx;
rax >>= 0xE;
rax ^= rdx;
rdx = rax;
rdx >>= 0x1C;
rdx ^= rax;
rax = rdx;
rax >>= 0x38;
rdx ^= rax;
rax = base + 0x31CB;
rax -= r8;
rdx += rax;
rax = rdx;
rax >>= 0xD;
rax ^= rdx;
rcx = rax;
rcx >>= 0x1A;
rcx ^= rax;
rdx = rcx;
rdx >>= 0x34;
rdx ^= rcx;
rax = r15;
rax = ~rax;
rdx ^= rax;
rdx ^= r8;
return rdx;
}
case 2:
{
r9 = rd<std::uint64_t>(fn, ctx, base + decrypt_rva::bone_key); //mov r9, [0x000000000638D526]
rax = 0; //and rax, 0xFFFFFFFFC0000000
rax = _rotl64(rax, 0x10); //rol rax, 0x10
rax ^= r9; //xor rax, r9
rax = ~rax; //not rax
rdx *= rd<std::uint64_t>(fn, ctx, rax + 0x17); //imul rdx, [rax+0x17]
rax = base + 0x47C2AE1B; //lea rax, [0x00000000406889E9]
rax = ~rax; //not rax
rax ^= r8; //xor rax, r8
rax += r8; //add rax, r8
rdx += rax; //add rdx, rax
rax = 0x94073D91C803188D; //mov rax, 0x94073D91C803188D
rdx ^= rax; //xor rdx, rax
rax = 0x2EEA8A0831CE333B; //mov rax, 0x2EEA8A0831CE333B
rdx *= rax; //imul rdx, rax
rdx += r8; //add rdx, r8
rax = rdx; //mov rax, rdx
rax >>= 0x13; //shr rax, 0x13
rdx ^= rax; //xor rdx, rax
rax = rdx; //mov rax, rdx
rax >>= 0x26; //shr rax, 0x26
rdx ^= rax; //xor rdx, rax
rax = 0xD4E2CCE5B7959CA0; //mov rax, 0xD4E2CCE5B7959CA0
rdx ^= rax; //xor rdx, rax
return rdx;
}
case 3:
{
r9 = rd<std::uint64_t>(fn, ctx, base + decrypt_rva::bone_key);
r12 = base + 0x114B;
rax = rdx;
rax >>= 0x13;
rax ^= rdx;
rdx = rax;
rdx >>= 0x26;
rdx ^= rax;
rax = rdx;
rax >>= 0x24;
rdx ^= rax;
rax = 0x764F15DD269101D3ull;
rdx *= rax;
rax = 0x34E81942B113C230ull;
rdx -= rax;
rax = 0x13805FC46F4FC36Aull;
rdx += rax;
rax = r8;
rax -= base;
rax += 0xFFFFFFFFFFFF85F3ull;
rdx += rax;
rax = 0;
rax = _rotl64(rax, 0x10);
rax ^= r9;
rax = ~rax;
rdx *= rd<std::uint64_t>(fn, ctx, rax + 0x17);
rdx ^= r12;
rdx ^= r8;
return rdx;
}
case 4:
{
r9 = rd<std::uint64_t>(fn, ctx, base + decrypt_rva::bone_key);
rax = rdx;
rax >>= 0x11;
rdx ^= rax;
rax = rdx;
rax >>= 0x22;
rdx ^= rax;
rax = 0x2CFB6FB2F3BAD3Cull;
rdx -= rax;
rax = 0;
rax = _rotl64(rax, 0x10);
rax ^= r9;
rax = ~rax;
rdx *= rd<std::uint64_t>(fn, ctx, rax + 0x17);
rax = 0xEED0F28134CE8447ull;
rdx *= rax;
rax = 0x52D4170A67BFFCB2ull;
rdx ^= rax;
rax = rdx + r8 * 1;
rdx = rax;
rdx >>= 0x16;
rdx ^= rax;
rax = rdx;
rax >>= 0x2C;
rdx ^= rax;
rdx ^= r8;
return rdx;
}
case 5:
{
r10 = rd<std::uint64_t>(fn, ctx, base + decrypt_rva::bone_key);
r15 = base + 0x19B7DBCB;
r12 = base + 0x654BDD13;
rax = r12;
rax = ~rax;
++rax;
rdx += rax;
rax = 0x4A2AFA53025C5181ull;
rdx += r8;
rdx *= rax;
rax = rdx;
rax >>= 0x28;
rdx ^= rax;
rax = r8 + r15 * 1;
rcx = base + 0xA045;
rcx += r8;
rcx ^= rax;
rdx ^= rcx;
rax = 0x574A3A5B7408079Bull;
rdx *= rax;
rax = 0;
rax = _rotl64(rax, 0x10);
rax ^= r10;
rax = ~rax;
rdx *= rd<std::uint64_t>(fn, ctx, rax + 0x17);
return rdx;
}
case 6:
{
r9 = rd<std::uint64_t>(fn, ctx, base + decrypt_rva::bone_key); //mov r9, [0x000000000638C315]
rax = 0; //and rax, 0xFFFFFFFFC0000000
rax = _rotl64(rax, 0x10); //rol rax, 0x10
rax ^= r9; //xor rax, r9
rax = ~rax; //not rax
rdx *= rd<std::uint64_t>(fn, ctx, rax + 0x17); //imul rdx, [rax+0x17]
rdx += r8; //add rdx, r8
rcx = base + 0x4951; //lea rcx, [0xFFFFFFFFF8A610AE]
rax = r8; //mov rax, r8
rax *= rcx; //imul rax, rcx
rdx += rax; //add rdx, rax
rax = r8 + rdx * 1; //lea rax, [r8+rdx*1]
r10 = base; //lea r10, [0xFFFFFFFFF8A5C8BA]
rcx = r10 + 0x1d37b933; //lea rcx, [r10+0x1D37B933]
rcx += rax; //add rcx, rax
rdx = rcx; //mov rdx, rcx
rdx >>= 0x9; //shr rdx, 0x09
rdx ^= rcx; //xor rdx, rcx
rax = rdx; //mov rax, rdx
rax >>= 0x12; //shr rax, 0x12
rax ^= rdx; //xor rax, rdx
rcx = rax; //mov rcx, rax
rcx >>= 0x24; //shr rcx, 0x24
rcx ^= rax; //xor rcx, rax
rax = 0x6C2A29044A40E4C7; //mov rax, 0x6C2A29044A40E4C7
rcx *= rax; //imul rcx, rax
rcx ^= r10; //xor rcx, r10
rax = rcx; //mov rax, rcx
rax >>= 0x3; //shr rax, 0x03
rax ^= rcx; //xor rax, rcx
rcx = rax; //mov rcx, rax
rcx >>= 0x6; //shr rcx, 0x06
rcx ^= rax; //xor rcx, rax
rax = rcx; //mov rax, rcx
rax >>= 0xC; //shr rax, 0x0C
rax ^= rcx; //xor rax, rcx
rdx = rax; //mov rdx, rax
rdx >>= 0x18; //shr rdx, 0x18
rdx ^= rax; //xor rdx, rax
rax = rdx; //mov rax, rdx
rax >>= 0x30; //shr rax, 0x30
rdx ^= rax; //xor rdx, rax
return rdx;
}
case 7:
{
r9 = rd<std::uint64_t>(fn, ctx, base + decrypt_rva::bone_key); //mov r9, [0x000000000638BF07]
rax = base; //lea rax, [0xFFFFFFFFF8A5C51C]
rdx += rax; //add rdx, rax
rax = 0x5F80490A38DB3901; //mov rax, 0x5F80490A38DB3901
rdx ^= rax; //xor rdx, rax
rax = 0x4EC9DC6A5902297D; //mov rax, 0x4EC9DC6A5902297D
rdx -= rax; //sub rdx, rax
rax = rdx; //mov rax, rdx
rax >>= 0x25; //shr rax, 0x25
rdx ^= rax; //xor rdx, rax
rcx = base + 0xCEFB; //lea rcx, [0xFFFFFFFFF8A693A6]
rax = r8; //mov rax, r8
rax ^= rcx; //xor rax, rcx
rdx += rax; //add rdx, rax
rax = 0x92B34BC27C367071; //mov rax, 0x92B34BC27C367071
rdx *= rax; //imul rdx, rax
rdx -= r8; //sub rdx, r8
rax = 0; //and rax, 0xFFFFFFFFC0000000
rax = _rotl64(rax, 0x10); //rol rax, 0x10
rax ^= r9; //xor rax, r9
rax = ~rax; //not rax
rdx *= rd<std::uint64_t>(fn, ctx, rax + 0x17); //imul rdx, [rax+0x17]
return rdx;
}
case 8:
{
r10 = rd<std::uint64_t>(fn, ctx, base + decrypt_rva::bone_key);
r13 = base + 0x5723;
r12 = base + 0xFAB2;
rax = 0xE62DA6375F493113ull;
rdx *= rax;
rax = base;
rdx -= rax;
rax = 0;
rax = _rotl64(rax, 0x10);
rax ^= r10;
rax = ~rax;
rdx *= rd<std::uint64_t>(fn, ctx, rax + 0x17);
rdx -= r8;
rax = rdx;
rax >>= 0xF;
rdx ^= rax;
rax = rdx;
rax >>= 0x1E;
rdx ^= rax;
rax = rdx;
rax >>= 0x3C;
rdx ^= rax;
rax = rdx;
rax >>= 0x3;
rax ^= rdx;
rdx = rax;
rdx >>= 0x6;
rdx ^= rax;
rax = rdx;
rax >>= 0xC;
rdx ^= rax;
rax = rdx;
rax >>= 0x18;
rax ^= rdx;
rdx = rax;
rdx >>= 0x30;
rdx ^= rax;
rax = r8 + r12 * 1;
rdx ^= rax;
rdx ^= r13;
rdx ^= r8;
return rdx;
}
case 9:
{
r10 = rd<std::uint64_t>(fn, ctx, base + decrypt_rva::bone_key); //mov r10, [0x000000000638B5AA]
r11 = base + 0x429D; //lea r11, [0xFFFFFFFFF8A5FFA3]
r9 = base + 0xF1EC; //lea r9, [0xFFFFFFFFF8A6AEEB]
rax = 0; //and rax, 0xFFFFFFFFC0000000
rax = _rotl64(rax, 0x10); //rol rax, 0x10
rax ^= r10; //xor rax, r10
rax = ~rax; //not rax
rdx *= rd<std::uint64_t>(fn, ctx, rax + 0x17); //imul rdx, [rax+0x17]
rax = r8 + r9 * 1; //lea rax, [r8+r9*1]
rcx = r8 + r11 * 1; //lea rcx, [r8+r11*1]
rcx += rdx; //add rcx, rdx
rcx ^= rax; //xor rcx, rax
rax = base + 0x5304B0E6; //lea rax, [0x000000004BAA6D41]
rcx ^= rax; //xor rcx, rax
rcx ^= r8; //xor rcx, r8
rdx = rcx; //mov rdx, rcx
rdx >>= 0x22; //shr rdx, 0x22
rdx ^= rcx; //xor rdx, rcx
rax = 0xEE899EDDAF56550; //mov rax, 0xEE899EDDAF56550
rdx ^= rax; //xor rdx, rax
rax = rdx; //mov rax, rdx
rax >>= 0xE; //shr rax, 0x0E
rdx ^= rax; //xor rdx, rax
rax = rdx; //mov rax, rdx
rax >>= 0x1C; //shr rax, 0x1C
rdx ^= rax; //xor rdx, rax
rax = rdx; //mov rax, rdx
rax >>= 0x38; //shr rax, 0x38
rdx ^= rax; //xor rdx, rax
rax = 0x39D515C223A57391; //mov rax, 0x39D515C223A57391
rdx *= rax; //imul rdx, rax
return rdx;
}
case 10:
{
rax = rdx; //mov rax, rdx
rax >>= 0xF; //shr rax, 0x0F
rax ^= rdx; //xor rax, rdx
rdx = rax; //mov rdx, rax
rdx >>= 0x1E; //shr rdx, 0x1E
rdx ^= rax; //xor rdx, rax
rax = rdx; //mov rax, rdx
rax >>= 0x3C; //shr rax, 0x3C
rax ^= rdx; //xor rax, rdx
rdx = rax; //mov rdx, rax
rdx >>= 0x13; //shr rdx, 0x13
rdx ^= rax; //xor rdx, rax
rax = rdx; //mov rax, rdx
rax >>= 0x26; //shr rax, 0x26
rdx ^= rax; //xor rdx, rax
return rdx;
}
case 11:
{
r9 = rd<std::uint64_t>(fn, ctx, base + decrypt_rva::bone_key); //mov r9, [0x000000000638ACBD]
rax = rdx; //mov rax, rdx
rax >>= 0x22; //shr rax, 0x22
rdx ^= rax; //xor rdx, rax
rax = base + 0x67B591A2; //lea rax, [0x00000000605B437B]
rax = ~rax; //not rax
rax ^= r8; //xor rax, r8
rax += r8; //add rax, r8
rdx -= rax; //sub rdx, rax
rax = 0; //and rax, 0xFFFFFFFFC0000000
rax = _rotl64(rax, 0x10); //rol rax, 0x10
rax ^= r9; //xor rax, r9
rax = ~rax; //not rax
rdx *= rd<std::uint64_t>(fn, ctx, rax + 0x17); //imul rdx, [rax+0x17]
rdx ^= r8; //xor rdx, r8
rax = 0x112AEF7CBA9BEDF1; //mov rax, 0x112AEF7CBA9BEDF1
rdx *= rax; //imul rdx, rax
rax = 0x792205E77EAA6797; //mov rax, 0x792205E77EAA6797
rdx ^= rax; //xor rdx, rax
return rdx;
}
case 12:
{
r9 = rd<std::uint64_t>(fn, ctx, base + decrypt_rva::bone_key); //mov r9, [0x000000000638A90C]
rax = 0; //and rax, 0xFFFFFFFFC0000000
rax = _rotl64(rax, 0x10); //rol rax, 0x10
rax ^= r9; //xor rax, r9
rax = ~rax; //not rax
rdx *= rd<std::uint64_t>(fn, ctx, rax + 0x17); //imul rdx, [rax+0x17]
rax = 0x33BF00DD8A073650; //mov rax, 0x33BF00DD8A073650
rdx -= rax; //sub rdx, rax
rax = rdx; //mov rax, rdx
rax >>= 0xA; //shr rax, 0x0A
rdx ^= rax; //xor rdx, rax
rax = rdx; //mov rax, rdx
rax >>= 0x14; //shr rax, 0x14
rax ^= rdx; //xor rax, rdx
rdx = rax; //mov rdx, rax
rdx >>= 0x28; //shr rdx, 0x28
rdx ^= rax; //xor rdx, rax
rax = base; //lea rax, [0xFFFFFFFFF8A5AE09]
rdx ^= rax; //xor rdx, rax
rax = base + 0x70E4B3E1; //lea rax, [0x00000000698A60D2]
rax = ~rax; //not rax
rdx += rax; //add rdx, rax
rax = 0x37300D9E69A77B2F; //mov rax, 0x37300D9E69A77B2F
rdx *= rax; //imul rdx, rax
rdx -= r8; //sub rdx, r8
return rdx;
}
case 13:
{
r9 = rd<std::uint64_t>(fn, ctx, base + decrypt_rva::bone_key); //mov r9, [0x000000000638A53C]
rax = base + 0x666C9DA0; //lea rax, [0x000000005F1248CC]
rax ^= r8; //xor rax, r8
rdx -= rax; //sub rdx, rax
rax = 0x124569EA4125D98; //mov rax, 0x124569EA4125D98
rdx ^= rax; //xor rdx, rax
rax = rdx; //mov rax, rdx
rax >>= 0x5; //shr rax, 0x05
rax ^= rdx; //xor rax, rdx
rcx = rax; //mov rcx, rax
rcx >>= 0xA; //shr rcx, 0x0A
rcx ^= rax; //xor rcx, rax
rdx = rcx; //mov rdx, rcx
rdx >>= 0x14; //shr rdx, 0x14
rdx ^= rcx; //xor rdx, rcx
rax = rdx; //mov rax, rdx
rax >>= 0x28; //shr rax, 0x28
rax ^= rdx; //xor rax, rdx
rdx = rax; //mov rdx, rax
rdx >>= 0x1A; //shr rdx, 0x1A
rdx ^= rax; //xor rdx, rax
rax = rdx; //mov rax, rdx
rcx = 0; //and rcx, 0xFFFFFFFFC0000000
rax >>= 0x34; //shr rax, 0x34
rcx = _rotl64(rcx, 0x10); //rol rcx, 0x10
rdx ^= rax; //xor rdx, rax
rcx ^= r9; //xor rcx, r9
rcx = ~rcx; //not rcx
rdx *= rd<std::uint64_t>(fn, ctx, rcx + 0x17); //imul rdx, [rcx+0x17]
rdx ^= r8; //xor rdx, r8
rax = 0xD83F30F92C64DF4F; //mov rax, 0xD83F30F92C64DF4F
rdx ^= rax; //xor rdx, rax
rax = 0xB69AFD2628432A9D; //mov rax, 0xB69AFD2628432A9D
rdx *= rax; //imul rdx, rax
return rdx;
}
case 14:
{
r9 = rd<std::uint64_t>(fn, ctx, base + decrypt_rva::bone_key); //mov r9, [0x000000000638A10A]
r10 = base + 0xD03A; //lea r10, [0xFFFFFFFFF8A678A0]
rax = rdx; //mov rax, rdx
rax >>= 0x1B; //shr rax, 0x1B
rdx ^= rax; //xor rdx, rax
rax = rdx; //mov rax, rdx
rcx = 0; //and rcx, 0xFFFFFFFFC0000000
rax >>= 0x36; //shr rax, 0x36
rcx = _rotl64(rcx, 0x10); //rol rcx, 0x10
rdx ^= rax; //xor rdx, rax
rcx ^= r9; //xor rcx, r9
rcx = ~rcx; //not rcx
rdx *= rd<std::uint64_t>(fn, ctx, rcx + 0x17); //imul rdx, [rcx+0x17]
rax = 0xDC4274449EFE767B; //mov rax, 0xDC4274449EFE767B
rdx ^= rax; //xor rdx, rax
rax = rdx; //mov rax, rdx
rax >>= 0x6; //shr rax, 0x06
rax ^= rdx; //xor rax, rdx
rcx = rax; //mov rcx, rax
rcx >>= 0xC; //shr rcx, 0x0C
rcx ^= rax; //xor rcx, rax
rdx = rcx; //mov rdx, rcx
rdx >>= 0x18; //shr rdx, 0x18
rdx ^= rcx; //xor rdx, rcx
rax = rdx; //mov rax, rdx
rax >>= 0x30; //shr rax, 0x30
rdx ^= rax; //xor rdx, rax
rax = base + 0x5113; //lea rax, [0xFFFFFFFFF8A5F6BD]
rax ^= r8; //xor rax, r8
rdx -= rax; //sub rdx, rax
rax = 0x4480AA60A21867F9; //mov rax, 0x4480AA60A21867F9
rdx *= rax; //imul rdx, rax
rax = r8 + r10 * 1; //lea rax, [r8+r10*1]
rdx += rax; //add rdx, rax
return rdx;
}
case 15:
{
r10 = rd<std::uint64_t>(fn, ctx, base + decrypt_rva::bone_key);
r13 = base + 0x642A39AC;
r12 = base + 0x6744783A;
rdx += r8;
rax = r8;
rax = ~rax;
rax ^= r13;
rdx -= rax;
rdx ^= r12;
rdx ^= r8;
rax = 0;
rax = _rotl64(rax, 0x10);
rax ^= r10;
rax = ~rax;
rdx *= rd<std::uint64_t>(fn, ctx, rax + 0x17);
rax = 0x54750E0E4638841Aull;
rdx += rax;
rax = 0x17257FE07A931EB4ull;
rdx ^= rax;
rax = rdx;
rax >>= 0x4;
rdx ^= rax;
rax = rdx;
rax >>= 0x8;
rdx ^= rax;
rax = rdx;
rax >>= 0x10;
rdx ^= rax;
rax = rdx;
rax >>= 0x20;
rdx ^= rax;
rax = 0x7493CCED6314B08Bull;
rdx *= rax;
return rdx;
}
}
return 0;
}
inline std::uint16_t get_bone_index(ReadFn fn, void* ctx, std::uint64_t base, std::uint32_t bone_index)
{
const std::uint64_t mb = base;
std::uint64_t rax = mb, rbx = mb, rcx = mb, rdx = mb, rdi = mb, rsi = mb, r8 = mb, r9 = mb, r10 = mb, r11 = mb, r12 = mb, r13 = mb, r14 = mb, r15 = mb;
rbx = bone_index;
rcx = rbx * 0x13C8;
rax = 0xCB182C584BD5193; //mov rax, 0xCB182C584BD5193
r11 = base; //lea r11, [0xFFFFFFFFFC4257C1]
rax = _umul128(rax, rcx, (std::uint64_t*)&rdx); //mul rcx
rax = rcx; //mov rax, rcx
r10 = 0xD6FB75C08B670E5B; //mov r10, 0xD6FB75C08B670E5B
rax -= rdx; //sub rax, rdx
rax >>= 0x1; //shr rax, 0x01
rax += rdx; //add rax, rdx
rax >>= 0xC; //shr rax, 0x0C
rax = rax * 0x1E7D; //imul rax, rax, 0x1E7D
rcx -= rax; //sub rcx, rax
rax = 0x4078E2A8FCDA18EF; //mov rax, 0x4078E2A8FCDA18EF
r8 = rcx * 0x1E7D; //imul r8, rcx, 0x1E7D
rax = _umul128(rax, r8, (std::uint64_t*)&rdx); //mul r8
rdx >>= 0xB; //shr rdx, 0x0B
rax = rdx * 0x1FC4; //imul rax, rdx, 0x1FC4
r8 -= rax; //sub r8, rax
rax = 0xF0F0F0F0F0F0F0F1; //mov rax, 0xF0F0F0F0F0F0F0F1
rax = _umul128(rax, r8, (std::uint64_t*)&rdx); //mul r8
rax = 0x624DD2F1A9FBE77; //mov rax, 0x624DD2F1A9FBE77
rdx >>= 0x6; //shr rdx, 0x06
rcx = rdx * 0x44; //imul rcx, rdx, 0x44
rax = _umul128(rax, r8, (std::uint64_t*)&rdx); //mul r8
rax = r8; //mov rax, r8
rax -= rdx; //sub rax, rdx
rax >>= 0x1; //shr rax, 0x01
rax += rdx; //add rax, rdx
rax >>= 0x6; //shr rax, 0x06
rcx += rax; //add rcx, rax
rax = rcx * 0xFA; //imul rax, rcx, 0xFA
rcx = r8 * 0xFC; //imul rcx, r8, 0xFC
rcx -= rax; //sub rcx, rax
rax = rd<std::uint16_t>(fn, ctx, rcx + r11 * 1 + 0xC51BD00); //movzx eax, word ptr [rcx+r11*1+0xC51BD00]
r8 = rax * 0x13C8; //imul r8, rax, 0x13C8
rax = r10; //mov rax, r10
rax = _umul128(rax, r8, (std::uint64_t*)&rdx); //mul r8
rax = r10; //mov rax, r10
rdx >>= 0xD; //shr rdx, 0x0D
rcx = rdx * 0x261B; //imul rcx, rdx, 0x261B
r8 -= rcx; //sub r8, rcx
r9 = r8 * 0x2F75; //imul r9, r8, 0x2F75
rax = _umul128(rax, r9, (std::uint64_t*)&rdx); //mul r9
rdx >>= 0xD; //shr rdx, 0x0D
rax = rdx * 0x261B; //imul rax, rdx, 0x261B
r9 -= rax; //sub r9, rax
rax = 0x8FB823EE08FB823F; //mov rax, 0x8FB823EE08FB823F
rax = _umul128(rax, r9, (std::uint64_t*)&rdx); //mul r9
rax = 0x579D6EE340579D6F; //mov rax, 0x579D6EE340579D6F
rdx >>= 0x5; //shr rdx, 0x05
rcx = rdx * 0x39; //imul rcx, rdx, 0x39
rax = _umul128(rax, r9, (std::uint64_t*)&rdx); //mul r9
rdx >>= 0x6; //shr rdx, 0x06
rcx += rdx; //add rcx, rdx
rax = rcx * 0x176; //imul rax, rcx, 0x176
rcx = r9 * 0x178; //imul rcx, r9, 0x178
rcx -= rax; //sub rcx, rax
r14 = rd<std::uint16_t>(fn, ctx, rcx + r11 * 1 + 0xC51FF70); //movsx r14d, word ptr [rcx+r11*1+0xC51FF70]
return static_cast<std::uint16_t>(r14);
}
// Camera origin: same Key3-style per-float xor as refdef (Usermode DecryptCameraOrigin).
// Fallback in callers is the raw float3 at camera_pos (+0x1F4).
inline Vec3 decrypt_camera_origin(ReadFn fn, void* ctx, std::uint64_t camera_base)
{
Vec3 origin{};
if (!fn || !camera_base) return origin;
std::uint32_t enc[3]{};
if (!fn(ctx, camera_base + camera::pos_enc, enc, sizeof(enc)))
return origin;
const std::uint32_t key = rd<std::uint32_t>(fn, ctx, camera_base + camera::pos_key);
float* c = &origin.x;
for (int j = 0; j < 3; ++j) {
const std::uint32_t t = static_cast<std::uint32_t>(
camera_base + camera::pos_enc + 4u * static_cast<std::uint32_t>(j)) ^ key;
const std::uint32_t d = enc[j] ^ (t * (t + 2u));
std::memcpy(&c[j], &d, sizeof(float));
}
return origin;
}