#pragma once #include using u32 = std::uint32_t; using u64 = std::uint64_t; namespace fxn::detail::rage { namespace sysObfuscatedTypes { __forceinline u32 obfRand() { static u32 next = 0xCB536E6A; next = next * 214013 + 2531011; return next; } } template class sysObfuscated { public: sysObfuscated() { CompileTimeAssert((sizeof(T) & 3) == 0); Init(); } sysObfuscated(const sysObfuscated& rhs) { Init(); Set(rhs.Get()); } template sysObfuscated(const sysObfuscated& rhs) { Init(); Set(rhs.Get()); } explicit sysObfuscated(const T& data) { Init(); Set(data); } ~sysObfuscated() {} public: __forceinline T Get() const; __forceinline void Set(const T& data); __forceinline operator T() const { return Get(); } public: template bool operator==(const sysObfuscated& rhs) const { return Get() == rhs.Get(); } template bool operator!=(const sysObfuscated& rhs) const { return Get() != rhs.Get(); } template bool operator<(const sysObfuscated& rhs) const { return Get() < rhs.Get(); } template bool operator<=(const sysObfuscated& rhs) const { return Get() <= rhs.Get(); } template bool operator>(const sysObfuscated& rhs) const { return Get() > rhs.Get(); } template bool operator>=(const sysObfuscated& rhs) const { return Get() >= rhs.Get(); } public: template sysObfuscated& operator=(const sysObfuscated& rhs) { Set(rhs.Get()); return *this; } sysObfuscated& operator=(const T& data) { Set(data); return *this; } public: template sysObfuscated& operator+=(const sysObfuscated& rhs) { Set(Get()+rhs.Get()); return *this; } sysObfuscated& operator+=(const T& data) { Set(Get()+data); return *this; } template sysObfuscated& operator-=(const sysObfuscated& rhs) { Set(Get()-rhs.Get()); return *this; } sysObfuscated& operator-=(const T& data) { Set(Get()-data); return *this; } template sysObfuscated& operator*=(const sysObfuscated& rhs) { Set(Get()*rhs.Get()); return *this; } sysObfuscated& operator*=(const T& data) { Set(Get()*data); return *this; } template sysObfuscated& operator/=(const sysObfuscated& rhs) { Set(Get()/rhs.Get()); return *this; } sysObfuscated& operator/=(const T& data) { Set(Get()/data); return *this; } private: void Init(); mutable u32 m_data[(TMutate ? sizeof(T)*2 : sizeof(T)) / sizeof(u32)]; mutable u32 m_xor; mutable u32 m_mutate; }; template __forceinline void sysObfuscated::Init() { m_xor = sysObfuscatedTypes::obfRand(); if(TMutate) { m_mutate = sysObfuscatedTypes::obfRand(); } } template __forceinline T sysObfuscated::Get() const { u32 xorVal = m_xor ^ (u32)(size_t)this; u32 ret[sizeof(T)/sizeof(u32)]; u32* src = const_cast(&m_data[0]); u32* dest = (u32*)&ret; for(size_t i=0; i> 16); u32 entropyB = ((src[sizeof(T)/4] & m_mutate) << 16) | ((src[sizeof(T)/4] & m_mutate) >> 16); *src = (*src & m_mutate) | entropyA; src[sizeof(T)/4] = (src[sizeof(T)/4] & (~m_mutate)) | entropyB; *dest++ = a | b; ++src; } else { *dest++ = *src++ ^ xorVal; } } // Call Set() to reset the xor and mutate keys on every call to Get() if(TMutate) { const_cast*>(this)->Set(*(T*)&ret); } return *(T*)&ret; } template __forceinline void sysObfuscated::Set(const T& data) { // Reset xor and mutate keys Init(); u32 xorVal = m_xor ^ (u32)(size_t)this; u32* src = (u32*)&data; u32* dest = &m_data[0]; for(size_t i=0; i class scrCommandHash { private: static const int ToplevelSize = 256; static const int PerBucket = 7; struct Bucket { sysObfuscated obf_Next; _T Data[PerBucket]; sysObfuscated obf_Count; sysObfuscated obf_Hashes[PerBucket]; u64 plainText_Hashes[PerBucket]; }; public: void RegistrationComplete(bool val) { m_bRegistrationComplete = val; } void Init() { m_Occupancy = 0; m_bRegistrationComplete = false; for (int i=0; iobf_Next.Get(); delete[] old; } m_Buckets[i] = NULL; } m_Occupancy = 0; } void Insert(u64 hashcode,_T cmd) { Bucket * b = m_Buckets[hashcode & (ToplevelSize-1)]; // If this chain is empty, or the first bucket is full, allocate and patch in a new bucket if (!b || b->obf_Count.Get() == PerBucket) { Bucket *nb = (Bucket*) new char[sizeof(Bucket)]; nb->obf_Next.Set(m_Buckets[hashcode & (ToplevelSize-1)]); nb->obf_Count.Set(0); b = m_Buckets[hashcode & (ToplevelSize-1)] = nb; } b->obf_Hashes[b->obf_Count.Get()].Set(hashcode); b->plainText_Hashes[b->obf_Count.Get()] = 0; //hashcode; b->Data[b->obf_Count] = cmd; b->obf_Count.Set(b->obf_Count.Get()+1); //inc count } _T Lookup(u64 hashcode) { Bucket *b = m_Buckets[hashcode & (ToplevelSize-1)]; while (b) { for (u32 i=0; iobf_Count.Get(); i++) if (b->obf_Hashes[i].Get() == hashcode) return b->Data[i]; b = b->obf_Next.Get(); } return 0; } private: Bucket* m_Buckets[ToplevelSize]; int m_Occupancy; bool m_bRegistrationComplete; }; }