init
This commit is contained in:
218
src/detail/rage.hpp
Normal file
218
src/detail/rage.hpp
Normal file
@@ -0,0 +1,218 @@
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
|
||||
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<typename T, bool TMutate = true>
|
||||
class sysObfuscated
|
||||
{
|
||||
public:
|
||||
sysObfuscated() { CompileTimeAssert((sizeof(T) & 3) == 0); Init(); }
|
||||
sysObfuscated(const sysObfuscated<T, TMutate>& rhs) { Init(); Set(rhs.Get()); }
|
||||
template<bool TMutateOther> sysObfuscated(const sysObfuscated<T, TMutateOther>& 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 TMutateOther> bool operator==(const sysObfuscated<T, TMutateOther>& rhs) const { return Get() == rhs.Get(); }
|
||||
template<bool TMutateOther> bool operator!=(const sysObfuscated<T, TMutateOther>& rhs) const { return Get() != rhs.Get(); }
|
||||
template<bool TMutateOther> bool operator<(const sysObfuscated<T, TMutateOther>& rhs) const { return Get() < rhs.Get(); }
|
||||
template<bool TMutateOther> bool operator<=(const sysObfuscated<T, TMutateOther>& rhs) const { return Get() <= rhs.Get(); }
|
||||
template<bool TMutateOther> bool operator>(const sysObfuscated<T, TMutateOther>& rhs) const { return Get() > rhs.Get(); }
|
||||
template<bool TMutateOther> bool operator>=(const sysObfuscated<T, TMutateOther>& rhs) const { return Get() >= rhs.Get(); }
|
||||
|
||||
public:
|
||||
template<bool TMutateOther> sysObfuscated<T, TMutate>& operator=(const sysObfuscated<T, TMutateOther>& rhs) { Set(rhs.Get()); return *this; }
|
||||
sysObfuscated<T, TMutate>& operator=(const T& data) { Set(data); return *this; }
|
||||
|
||||
public:
|
||||
template<bool TMutateOther> sysObfuscated<T, TMutate>& operator+=(const sysObfuscated<T, TMutateOther>& rhs) { Set(Get()+rhs.Get()); return *this; }
|
||||
sysObfuscated<T, TMutate>& operator+=(const T& data) { Set(Get()+data); return *this; }
|
||||
template<bool TMutateOther> sysObfuscated<T, TMutate>& operator-=(const sysObfuscated<T, TMutateOther>& rhs) { Set(Get()-rhs.Get()); return *this; }
|
||||
sysObfuscated<T, TMutate>& operator-=(const T& data) { Set(Get()-data); return *this; }
|
||||
template<bool TMutateOther> sysObfuscated<T, TMutate>& operator*=(const sysObfuscated<T, TMutateOther>& rhs) { Set(Get()*rhs.Get()); return *this; }
|
||||
sysObfuscated<T, TMutate>& operator*=(const T& data) { Set(Get()*data); return *this; }
|
||||
template<bool TMutateOther> sysObfuscated<T, TMutate>& operator/=(const sysObfuscated<T, TMutateOther>& rhs) { Set(Get()/rhs.Get()); return *this; }
|
||||
sysObfuscated<T, TMutate>& 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<class T, bool TMutate> __forceinline void sysObfuscated<T, TMutate>::Init()
|
||||
{
|
||||
m_xor = sysObfuscatedTypes::obfRand();
|
||||
if(TMutate)
|
||||
{
|
||||
m_mutate = sysObfuscatedTypes::obfRand();
|
||||
}
|
||||
}
|
||||
|
||||
template<class T, bool TMutate> __forceinline T sysObfuscated<T, TMutate>::Get() const
|
||||
{
|
||||
u32 xorVal = m_xor ^ (u32)(size_t)this;
|
||||
u32 ret[sizeof(T)/sizeof(u32)];
|
||||
u32* src = const_cast<u32*>(&m_data[0]);
|
||||
u32* dest = (u32*)&ret;
|
||||
for(size_t i=0; i<sizeof(T)/4; ++i)
|
||||
{
|
||||
if(TMutate)
|
||||
{
|
||||
// Extract valid data from two words of storage
|
||||
u32 a = *src & m_mutate;
|
||||
u32 b = src[sizeof(T)/4] & (~m_mutate);
|
||||
|
||||
// Apply entropy in the unused bits: Just flip the two u16's in the u32. We can't do a
|
||||
// huge amount more without knowledge of the mutation mask.
|
||||
u32 entropyA = ((*src & (~m_mutate)) << 16) | ((*src & (~m_mutate)) >> 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<sysObfuscated<T, TMutate>*>(this)->Set(*(T*)&ret);
|
||||
}
|
||||
|
||||
return *(T*)&ret;
|
||||
}
|
||||
|
||||
template<class T, bool TMutate> __forceinline void sysObfuscated<T, TMutate>::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<sizeof(T)/4; ++i)
|
||||
{
|
||||
if(TMutate)
|
||||
{
|
||||
u32 a = *src & m_mutate;
|
||||
u32 b = *src & (~m_mutate);
|
||||
++src;
|
||||
|
||||
*dest = a;
|
||||
dest[sizeof(T)/4] = b;
|
||||
++dest;
|
||||
}
|
||||
else
|
||||
{
|
||||
*dest++ = *src++ ^ xorVal;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename _T>
|
||||
class scrCommandHash
|
||||
{
|
||||
private:
|
||||
static const int ToplevelSize = 256;
|
||||
static const int PerBucket = 7;
|
||||
|
||||
struct Bucket
|
||||
{
|
||||
sysObfuscated<Bucket *, false> obf_Next;
|
||||
_T Data[PerBucket];
|
||||
sysObfuscated<u32, false> obf_Count;
|
||||
sysObfuscated<u64, false> 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; i<ToplevelSize; i++)
|
||||
m_Buckets[i] = NULL;
|
||||
}
|
||||
|
||||
void Kill()
|
||||
{
|
||||
for (int i=0; i<ToplevelSize; i++) {
|
||||
Bucket *b = m_Buckets[i];
|
||||
while (b) {
|
||||
char *old = (char*) b;
|
||||
b = b->obf_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; i<b->obf_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;
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user