summaryrefslogtreecommitdiff
path: root/csgo-loader/csgo-client/Security
diff options
context:
space:
mode:
authorboris <wzn@moneybot.cc>2018-12-20 21:38:04 +1300
committerboris <wzn@moneybot.cc>2018-12-20 21:38:04 +1300
commita5acd4c9a3b24c9d5af3a8f504e5af053fa7fa09 (patch)
tree27bc30d3f35e5daaaa15ee6de066119df8d352c7 /csgo-loader/csgo-client/Security
parent77b52da44b263df4884be2f35f885d8edccbb6fa (diff)
yo is this loss
Diffstat (limited to 'csgo-loader/csgo-client/Security')
-rw-r--r--csgo-loader/csgo-client/Security/Encryption.cpp174
-rw-r--r--csgo-loader/csgo-client/Security/Encryption.hpp12
-rw-r--r--csgo-loader/csgo-client/Security/FnvHash.hpp24
-rw-r--r--csgo-loader/csgo-client/Security/SyscallManager.cpp40
-rw-r--r--csgo-loader/csgo-client/Security/SyscallManager.hpp15
5 files changed, 175 insertions, 90 deletions
diff --git a/csgo-loader/csgo-client/Security/Encryption.cpp b/csgo-loader/csgo-client/Security/Encryption.cpp
index 7d4fd05..4d42ee7 100644
--- a/csgo-loader/csgo-client/Security/Encryption.cpp
+++ b/csgo-loader/csgo-client/Security/Encryption.cpp
@@ -6,7 +6,8 @@
#define KEY_SIZE 32
#define NUM_ROUNDS 14
-namespace Wrapper {
+namespace Wrapper
+{
// Constants used for the AES256 algorithm.
uint8_t sbox[256] = {
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
@@ -87,15 +88,18 @@ namespace Wrapper {
, m_rkey(ByteArray(KEY_SIZE, 0))
, m_buffer_pos(0)
, m_remainingLength(0)
- , m_decryptInitialized(false) {
+ , m_decryptInitialized(false)
+ {
for(ByteArray::size_type i = 0; i < m_key.size(); ++i)
m_key[i] = key[i];
}
- Aes256::~Aes256() {
+ Aes256::~Aes256()
+ {
}
- ByteArray::size_type Aes256::encrypt(const ByteArray& key, const ByteArray& plain, ByteArray& encrypted) {
+ ByteArray::size_type Aes256::encrypt(const ByteArray& key, const ByteArray& plain, ByteArray& encrypted)
+ {
Aes256 aes(key);
aes.encrypt_start(plain.size(), encrypted);
@@ -105,7 +109,8 @@ namespace Wrapper {
return encrypted.size();
}
- ByteArray::size_type Aes256::encrypt(const ByteArray& key, const unsigned char* plain, const ByteArray::size_type plain_length, ByteArray& encrypted) {
+ ByteArray::size_type Aes256::encrypt(const ByteArray& key, const unsigned char* plain, const ByteArray::size_type plain_length, ByteArray& encrypted)
+ {
Aes256 aes(key);
aes.encrypt_start(plain_length, encrypted);
@@ -115,7 +120,8 @@ namespace Wrapper {
return encrypted.size();
}
- ByteArray::size_type Aes256::decrypt(const ByteArray& key, const ByteArray& encrypted, ByteArray& plain) {
+ ByteArray::size_type Aes256::decrypt(const ByteArray& key, const ByteArray& encrypted, ByteArray& plain)
+ {
Aes256 aes(key);
aes.decrypt_start(encrypted.size());
@@ -125,7 +131,8 @@ namespace Wrapper {
return plain.size();
}
- ByteArray::size_type Aes256::decrypt(const ByteArray& key, const unsigned char* encrypted, const ByteArray::size_type encrypted_length, ByteArray& plain) {
+ ByteArray::size_type Aes256::decrypt(const ByteArray& key, const unsigned char* encrypted, const ByteArray::size_type encrypted_length, ByteArray& plain)
+ {
Aes256 aes(key);
aes.decrypt_start(encrypted_length);
@@ -135,7 +142,8 @@ namespace Wrapper {
return plain.size();
}
- ByteArray::size_type Aes256::encrypt_start(const ByteArray::size_type plain_length, ByteArray& encrypted) {
+ ByteArray::size_type Aes256::encrypt_start(const ByteArray::size_type plain_length, ByteArray& encrypted)
+ {
m_remainingLength = plain_length;
// Generate salt
@@ -163,10 +171,12 @@ namespace Wrapper {
return encrypted.size();
}
- ByteArray::size_type Aes256::encrypt_continue(const ByteArray& plain, ByteArray& encrypted) {
+ ByteArray::size_type Aes256::encrypt_continue(const ByteArray& plain, ByteArray& encrypted)
+ {
ByteArray::const_iterator it = plain.begin(), itEnd = plain.end();
- while(it != itEnd) {
+ while(it != itEnd)
+ {
m_buffer[m_buffer_pos++] = *(it++);
check_and_encrypt_buffer(encrypted);
@@ -175,10 +185,12 @@ namespace Wrapper {
return encrypted.size();
}
- ByteArray::size_type Aes256::encrypt_continue(const unsigned char* plain, const ByteArray::size_type plain_length, ByteArray& encrypted) {
+ ByteArray::size_type Aes256::encrypt_continue(const unsigned char* plain, const ByteArray::size_type plain_length, ByteArray& encrypted)
+ {
ByteArray::size_type i = 0;
- while(i < plain_length) {
+ while(i < plain_length)
+ {
m_buffer[m_buffer_pos++] = plain[i++];
check_and_encrypt_buffer(encrypted);
@@ -187,11 +199,14 @@ namespace Wrapper {
return encrypted.size();
}
- void Aes256::check_and_encrypt_buffer(ByteArray& encrypted) {
- if(m_buffer_pos == BLOCK_SIZE) {
+ void Aes256::check_and_encrypt_buffer(ByteArray& encrypted)
+ {
+ if(m_buffer_pos == BLOCK_SIZE)
+ {
encrypt(m_buffer);
- for(m_buffer_pos = 0; m_buffer_pos < BLOCK_SIZE; ++m_buffer_pos) {
+ for(m_buffer_pos = 0; m_buffer_pos < BLOCK_SIZE; ++m_buffer_pos)
+ {
encrypted.push_back(m_buffer[m_buffer_pos]);
--m_remainingLength;
}
@@ -200,14 +215,17 @@ namespace Wrapper {
}
}
- ByteArray::size_type Aes256::encrypt_end(ByteArray& encrypted) {
- if(m_buffer_pos > 0) {
+ ByteArray::size_type Aes256::encrypt_end(ByteArray& encrypted)
+ {
+ if(m_buffer_pos > 0)
+ {
while(m_buffer_pos < BLOCK_SIZE)
m_buffer[m_buffer_pos++] = 0;
encrypt(m_buffer);
- for(m_buffer_pos = 0; m_buffer_pos < BLOCK_SIZE; ++m_buffer_pos) {
+ for(m_buffer_pos = 0; m_buffer_pos < BLOCK_SIZE; ++m_buffer_pos)
+ {
encrypted.push_back(m_buffer[m_buffer_pos]);
--m_remainingLength;
}
@@ -218,12 +236,14 @@ namespace Wrapper {
return encrypted.size();
}
- void Aes256::encrypt(unsigned char* buffer) {
+ void Aes256::encrypt(unsigned char* buffer)
+ {
unsigned char i, rcon;
copy_key();
add_round_key(buffer, 0);
- for(i = 1, rcon = 1; i < NUM_ROUNDS; ++i) {
+ for(i = 1, rcon = 1; i < NUM_ROUNDS; ++i)
+ {
sub_bytes(buffer);
shift_rows(buffer);
mix_columns(buffer);
@@ -237,7 +257,8 @@ namespace Wrapper {
add_round_key(buffer, i);
}
- ByteArray::size_type Aes256::decrypt_start(const ByteArray::size_type encrypted_length) {
+ ByteArray::size_type Aes256::decrypt_start(const ByteArray::size_type encrypted_length)
+ {
unsigned char j;
m_remainingLength = encrypted_length;
@@ -255,10 +276,12 @@ namespace Wrapper {
return m_remainingLength;
}
- ByteArray::size_type Aes256::decrypt_continue(const ByteArray& encrypted, ByteArray& plain) {
+ ByteArray::size_type Aes256::decrypt_continue(const ByteArray& encrypted, ByteArray& plain)
+ {
ByteArray::const_iterator it = encrypted.begin(), itEnd = encrypted.end();
- while(it != itEnd) {
+ while(it != itEnd)
+ {
m_buffer[m_buffer_pos++] = *(it++);
check_and_decrypt_buffer(plain);
@@ -267,10 +290,12 @@ namespace Wrapper {
return plain.size();
}
- ByteArray::size_type Aes256::decrypt_continue(const unsigned char* encrypted, const ByteArray::size_type encrypted_length, ByteArray& plain) {
+ ByteArray::size_type Aes256::decrypt_continue(const unsigned char* encrypted, const ByteArray::size_type encrypted_length, ByteArray& plain)
+ {
ByteArray::size_type i = 0;
- while(i < encrypted_length) {
+ while(i < encrypted_length)
+ {
m_buffer[m_buffer_pos++] = encrypted[i++];
check_and_decrypt_buffer(plain);
@@ -279,8 +304,10 @@ namespace Wrapper {
return plain.size();
}
- void Aes256::check_and_decrypt_buffer(ByteArray& plain) {
- if(!m_decryptInitialized && m_buffer_pos == m_salt.size() + 1) {
+ void Aes256::check_and_decrypt_buffer(ByteArray& plain)
+ {
+ if(!m_decryptInitialized && m_buffer_pos == m_salt.size() + 1)
+ {
unsigned char j;
ByteArray::size_type padding;
@@ -297,11 +324,13 @@ namespace Wrapper {
m_decryptInitialized = true;
}
- else if(m_decryptInitialized && m_buffer_pos == BLOCK_SIZE) {
+ else if(m_decryptInitialized && m_buffer_pos == BLOCK_SIZE)
+ {
decrypt(m_buffer);
for(m_buffer_pos = 0; m_buffer_pos < BLOCK_SIZE; ++m_buffer_pos)
- if(m_remainingLength > 0) {
+ if(m_remainingLength > 0)
+ {
plain.push_back(m_buffer[m_buffer_pos]);
--m_remainingLength;
}
@@ -310,11 +339,13 @@ namespace Wrapper {
}
}
- ByteArray::size_type Aes256::decrypt_end(ByteArray& plain) {
+ ByteArray::size_type Aes256::decrypt_end(ByteArray& plain)
+ {
return plain.size();
}
- void Aes256::decrypt(unsigned char* buffer) {
+ void Aes256::decrypt(unsigned char* buffer)
+ {
unsigned char i, rcon = 1;
copy_key();
@@ -325,7 +356,8 @@ namespace Wrapper {
shift_rows_inv(buffer);
sub_bytes_inv(buffer);
- for(i = NUM_ROUNDS, rcon = 0x80; --i;) {
+ for(i = NUM_ROUNDS, rcon = 0x80; --i;)
+ {
if((i & 1))
expand_dec_key(&rcon);
add_round_key(buffer, i);
@@ -336,7 +368,8 @@ namespace Wrapper {
add_round_key(buffer, i);
}
- void Aes256::expand_enc_key(unsigned char* rc) {
+ void Aes256::expand_enc_key(unsigned char* rc)
+ {
unsigned char i;
m_rkey[0] = m_rkey[0] ^ sbox[m_rkey[29]] ^ (*rc);
@@ -345,7 +378,8 @@ namespace Wrapper {
m_rkey[3] = m_rkey[3] ^ sbox[m_rkey[28]];
*rc = FE(*rc);
- for(i = 4; i < 16; i += 4) {
+ for(i = 4; i < 16; i += 4)
+ {
m_rkey[i] = m_rkey[i] ^ m_rkey[i - 4];
m_rkey[i + 1] = m_rkey[i + 1] ^ m_rkey[i - 3];
m_rkey[i + 2] = m_rkey[i + 2] ^ m_rkey[i - 2];
@@ -356,7 +390,8 @@ namespace Wrapper {
m_rkey[18] = m_rkey[18] ^ sbox[m_rkey[14]];
m_rkey[19] = m_rkey[19] ^ sbox[m_rkey[15]];
- for(i = 20; i < 32; i += 4) {
+ for(i = 20; i < 32; i += 4)
+ {
m_rkey[i] = m_rkey[i] ^ m_rkey[i - 4];
m_rkey[i + 1] = m_rkey[i + 1] ^ m_rkey[i - 3];
m_rkey[i + 2] = m_rkey[i + 2] ^ m_rkey[i - 2];
@@ -364,10 +399,12 @@ namespace Wrapper {
}
}
- void Aes256::expand_dec_key(unsigned char* rc) {
+ void Aes256::expand_dec_key(unsigned char* rc)
+ {
unsigned char i;
- for(i = 28; i > 16; i -= 4) {
+ for(i = 28; i > 16; i -= 4)
+ {
m_rkey[i + 0] = m_rkey[i + 0] ^ m_rkey[i - 4];
m_rkey[i + 1] = m_rkey[i + 1] ^ m_rkey[i - 3];
m_rkey[i + 2] = m_rkey[i + 2] ^ m_rkey[i - 2];
@@ -379,7 +416,8 @@ namespace Wrapper {
m_rkey[18] = m_rkey[18] ^ sbox[m_rkey[14]];
m_rkey[19] = m_rkey[19] ^ sbox[m_rkey[15]];
- for(i = 12; i > 0; i -= 4) {
+ for(i = 12; i > 0; i -= 4)
+ {
m_rkey[i + 0] = m_rkey[i + 0] ^ m_rkey[i - 4];
m_rkey[i + 1] = m_rkey[i + 1] ^ m_rkey[i - 3];
m_rkey[i + 2] = m_rkey[i + 2] ^ m_rkey[i - 2];
@@ -393,21 +431,24 @@ namespace Wrapper {
m_rkey[3] = m_rkey[3] ^ sbox[m_rkey[28]];
}
- void Aes256::sub_bytes(unsigned char* buffer) {
+ void Aes256::sub_bytes(unsigned char* buffer)
+ {
unsigned char i = KEY_SIZE / 2;
while(i--)
buffer[i] = sbox[buffer[i]];
}
- void Aes256::sub_bytes_inv(unsigned char* buffer) {
+ void Aes256::sub_bytes_inv(unsigned char* buffer)
+ {
unsigned char i = KEY_SIZE / 2;
while(i--)
buffer[i] = sboxinv[buffer[i]];
}
- void Aes256::copy_key() {
+ void Aes256::copy_key()
+ {
ByteArray::size_type i;
for(i = 0; i < m_key.size(); ++i)
@@ -416,14 +457,16 @@ namespace Wrapper {
m_rkey[i + m_key.size()] = m_salt[i];
}
- void Aes256::add_round_key(unsigned char* buffer, const unsigned char round) {
+ void Aes256::add_round_key(unsigned char* buffer, const unsigned char round)
+ {
unsigned char i = KEY_SIZE / 2;
while(i--)
buffer[i] ^= m_rkey[(round & 1) ? i + 16 : i];
}
- void Aes256::shift_rows(unsigned char* buffer) {
+ void Aes256::shift_rows(unsigned char* buffer)
+ {
unsigned char i, j, k, l; /* to make it potentially parallelable :) */
i = buffer[1];
@@ -447,7 +490,8 @@ namespace Wrapper {
buffer[6] = l;
}
- void Aes256::shift_rows_inv(unsigned char* buffer) {
+ void Aes256::shift_rows_inv(unsigned char* buffer)
+ {
unsigned char i, j, k, l; /* same as above :) */
i = buffer[1];
@@ -471,10 +515,12 @@ namespace Wrapper {
buffer[14] = l;
}
- void Aes256::mix_columns(unsigned char* buffer) {
+ void Aes256::mix_columns(unsigned char* buffer)
+ {
unsigned char i, a, b, c, d, e;
- for(i = 0; i < 16; i += 4) {
+ for(i = 0; i < 16; i += 4)
+ {
a = buffer[i];
b = buffer[i + 1];
c = buffer[i + 2];
@@ -489,10 +535,12 @@ namespace Wrapper {
}
}
- void Aes256::mix_columns_inv(unsigned char* buffer) {
+ void Aes256::mix_columns_inv(unsigned char* buffer)
+ {
unsigned char i, a, b, c, d, e, x, y, z;
- for(i = 0; i < 16; i += 4) {
+ for(i = 0; i < 16; i += 4)
+ {
a = buffer[i];
b = buffer[i + 1];
c = buffer[i + 2];
@@ -509,15 +557,19 @@ namespace Wrapper {
}
}
- inline unsigned char rj_xtime(unsigned char x) {
+ inline unsigned char rj_xtime(unsigned char x)
+ {
return (x & 0x80) ? ((x << 1) ^ 0x1b) : (x << 1);
}
// Wrapper for the AES256 encryption algorithm.
- void Encryption::Start() {
+ void Encryption::Start()
+ {
// Create cryptographic context.
- if(!CryptAcquireContextA(&m_CryptProvider, nullptr, nullptr, PROV_RSA_AES, 0)) {
- if(!CryptAcquireContextA(&m_CryptProvider, nullptr, nullptr, PROV_RSA_AES, CRYPT_NEWKEYSET)) {
+ if(!CryptAcquireContextA(&m_CryptProvider, nullptr, nullptr, PROV_RSA_AES, 0))
+ {
+ if(!CryptAcquireContextA(&m_CryptProvider, nullptr, nullptr, PROV_RSA_AES, CRYPT_NEWKEYSET))
+ {
printf("Failed to initialise encryption provider.\n");
return;
}
@@ -527,7 +579,8 @@ namespace Wrapper {
uint32_t RandomBytesCount = sizeof RandomBytes;
// Generate random bytes to use as encryption key.
- if(CryptGenRandom(m_CryptProvider, RandomBytesCount, RandomBytes)) {
+ if(CryptGenRandom(m_CryptProvider, RandomBytesCount, RandomBytes))
+ {
m_EncryptionKey.reserve(RandomBytesCount);
m_EncryptionKey.insert(
m_EncryptionKey.begin(),
@@ -541,19 +594,23 @@ namespace Wrapper {
CryptReleaseContext(m_CryptProvider, 0);
}
- void Encryption::Start(ByteArray &EncryptionKey) {
+ void Encryption::Start(ByteArray &EncryptionKey)
+ {
// If an encryption key is provided, initialise the wrapper with
// the passed parameter.
- if(!EncryptionKey.empty()) {
+ if(!EncryptionKey.empty())
+ {
m_EncryptionKey.reserve(EncryptionKey.size());
std::copy(EncryptionKey.begin(), EncryptionKey.end(), m_EncryptionKey.begin());
}
- else {
+ else
+ {
Start();
}
}
- ByteArray Encryption::Encrypt(ByteArray &Data) {
+ ByteArray Encryption::Encrypt(ByteArray &Data)
+ {
// Encrypt outgoing data.
ByteArray Encrypted;
@@ -566,7 +623,8 @@ namespace Wrapper {
return Encrypted;
}
- ByteArray Encryption::Decrypt(ByteArray &Data) {
+ ByteArray Encryption::Decrypt(ByteArray &Data)
+ {
// Decrypt incoming data.
ByteArray Decrypted;
diff --git a/csgo-loader/csgo-client/Security/Encryption.hpp b/csgo-loader/csgo-client/Security/Encryption.hpp
index d55608f..b1c49dc 100644
--- a/csgo-loader/csgo-client/Security/Encryption.hpp
+++ b/csgo-loader/csgo-client/Security/Encryption.hpp
@@ -9,9 +9,11 @@ using ByteArray = std::vector<uint8_t>;
#define BLOCK_SIZE 16
-namespace Wrapper {
+namespace Wrapper
+{
// AES256 implementation.
- class Aes256 {
+ class Aes256
+ {
public:
Aes256(const ByteArray& key);
@@ -67,7 +69,8 @@ namespace Wrapper {
};
// Encryption wrapper.
- class Encryption {
+ class Encryption
+ {
ByteArray m_EncryptionKey;
HCRYPTPROV m_CryptProvider;
@@ -82,7 +85,8 @@ namespace Wrapper {
ByteArray Decrypt(ByteArray &Data);
// Exposes the encryption key.
- ByteArray GetKey() {
+ ByteArray GetKey()
+ {
return m_EncryptionKey;
}
};
diff --git a/csgo-loader/csgo-client/Security/FnvHash.hpp b/csgo-loader/csgo-client/Security/FnvHash.hpp
index da7e80d..35c9ad0 100644
--- a/csgo-loader/csgo-client/Security/FnvHash.hpp
+++ b/csgo-loader/csgo-client/Security/FnvHash.hpp
@@ -4,9 +4,11 @@
// Credits: namazso
// Implements FNV-1a hash algorithm
-namespace detail {
+namespace detail
+{
template <typename Type, Type OffsetBasis, Type Prime>
- struct SizeDependantData {
+ struct SizeDependantData
+ {
using type = Type;
constexpr static auto k_offset_basis = OffsetBasis;
@@ -23,7 +25,8 @@ namespace detail {
struct SizeSelector<64> : SizeDependantData<std::uint64_t, 0xcbf29ce484222325ull, 1099511628211ull> {};
template <std::size_t Size>
- class FnvHash {
+ class FnvHash
+ {
private:
using data_t = SizeSelector<Size>;
@@ -36,14 +39,16 @@ namespace detail {
public:
static __forceinline constexpr auto hash_init(
- ) -> hash {
+ ) -> hash
+ {
return k_offset_basis;
}
static __forceinline constexpr auto hash_byte(
hash current,
std::uint8_t byte
- ) -> hash {
+ ) -> hash
+ {
return (current ^ byte) * k_prime;
}
@@ -51,7 +56,8 @@ namespace detail {
static __forceinline constexpr auto hash_constexpr(
const char(&str)[N],
const std::size_t size = N - 1 /* do not hash the null */
- ) -> hash {
+ ) -> hash
+ {
const auto prev_hash = size == 1 ? hash_init() : hash_constexpr(str, size - 1);
const auto cur_hash = hash_byte(prev_hash, str[size - 1]);
return cur_hash;
@@ -60,7 +66,8 @@ namespace detail {
static auto __forceinline hash_runtime_data(
const void* data,
const std::size_t sz
- ) -> hash {
+ ) -> hash
+ {
const auto bytes = static_cast<const uint8_t*>(data);
const auto end = bytes + sz;
auto result = hash_init();
@@ -72,7 +79,8 @@ namespace detail {
static auto __forceinline hash_runtime(
const char* str
- ) -> hash {
+ ) -> hash
+ {
auto result = hash_init();
do
result = hash_byte(result, *str++);
diff --git a/csgo-loader/csgo-client/Security/SyscallManager.cpp b/csgo-loader/csgo-client/Security/SyscallManager.cpp
index 55d68a3..9de2459 100644
--- a/csgo-loader/csgo-client/Security/SyscallManager.cpp
+++ b/csgo-loader/csgo-client/Security/SyscallManager.cpp
@@ -4,17 +4,21 @@
// Global accessor for SyscallManager.
Wrapper::SyscallManagerPtr Syscalls = std::make_unique<Wrapper::SyscallManager>();
-namespace Wrapper {
- void SyscallStub::SetIndex(uint32_t Index) {
+namespace Wrapper
+{
+ void SyscallStub::SetIndex(uint32_t Index)
+ {
unsigned long OldProtection{};
-
+
// Make the code executable and set the index.
- if(VirtualProtect(m_Shellcode, sizeof m_Shellcode, PAGE_EXECUTE_READWRITE, &OldProtection)) {
+ if(VirtualProtect(m_Shellcode, sizeof m_Shellcode, PAGE_EXECUTE_READWRITE, &OldProtection))
+ {
*(uint32_t *)(&m_Shellcode[4]) = Index;
}
}
- ByteArray SyscallManager::GetNtdllFromDisk() {
+ ByteArray SyscallManager::GetNtdllFromDisk()
+ {
char SystemPath[MAX_PATH];
GetSystemDirectoryA(SystemPath, MAX_PATH);
@@ -42,7 +46,8 @@ namespace Wrapper {
}
// Stolen :-)
- uint64_t SyscallManager::GetRawOffsetByRva(IMAGE_SECTION_HEADER *SectionHeader, uint64_t Sections, uint64_t FileSize, uint64_t Rva) {
+ uint64_t SyscallManager::GetRawOffsetByRva(IMAGE_SECTION_HEADER *SectionHeader, uint64_t Sections, uint64_t FileSize, uint64_t Rva)
+ {
IMAGE_SECTION_HEADER *Header = GetSectionByRva(SectionHeader, Sections, Rva);
if(!Header)
@@ -59,10 +64,12 @@ namespace Wrapper {
return Offset;
}
- IMAGE_SECTION_HEADER *SyscallManager::GetSectionByRva(IMAGE_SECTION_HEADER *SectionHeader, uint64_t Sections, uint64_t Rva) {
+ IMAGE_SECTION_HEADER *SyscallManager::GetSectionByRva(IMAGE_SECTION_HEADER *SectionHeader, uint64_t Sections, uint64_t Rva)
+ {
IMAGE_SECTION_HEADER *Header = SectionHeader;
- for(size_t i{}; i < Sections; ++i, ++Header) {
+ for(size_t i{}; i < Sections; ++i, ++Header)
+ {
uint64_t VirtualAddress = Header->VirtualAddress;
uint64_t AddressBounds = VirtualAddress + Header->SizeOfRawData;
@@ -74,9 +81,10 @@ namespace Wrapper {
}
// Sick macros, retard.
- #define GetRvaPointer(Rva) (Buffer + GetRawOffsetByRva(SectionHeader, SectionCount, FileSize, Rva))
+#define GetRvaPointer(Rva) (Buffer + GetRawOffsetByRva(SectionHeader, SectionCount, FileSize, Rva))
- bool SyscallManager::Start() {
+ bool SyscallManager::Start()
+ {
// Read contents of NTDLL.
ByteArray Ntdll = GetNtdllFromDisk();
@@ -101,7 +109,7 @@ namespace Wrapper {
if(!SectionHeader)
return false;
-
+
uint64_t ExportRva = NtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
uint64_t ExportSize = NtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
uint64_t ExportRaw = GetRawOffsetByRva(SectionHeader, SectionCount, FileSize, ExportRva);
@@ -120,7 +128,8 @@ namespace Wrapper {
return false;
// Loop each exported symbol.
- for(uint32_t n{}; n < ExportDirectory->NumberOfNames; ++n) {
+ for(uint32_t n{}; n < ExportDirectory->NumberOfNames; ++n)
+ {
uint32_t NameRva = Names[n];
uint32_t FunctionRva = Functions[Ordinals[n]];
@@ -129,10 +138,11 @@ namespace Wrapper {
// We've found a syscall.
uint8_t *Opcodes = (uint8_t *)(Buffer + FunctionRawOffset);
-
- if(!memcmp(Opcodes, "\x4C\x8B\xD1\xB8", 4)) {
+
+ if(!memcmp(Opcodes, "\x4C\x8B\xD1\xB8", 4))
+ {
uint32_t SyscallIndex = *(uint32_t *)(Buffer + FunctionRawOffset + 4);
-
+
char *SyscallName = (char *)(Buffer + NameRawOffset);
uint64_t SyscallNameHash = fnv::hash_runtime(SyscallName);
diff --git a/csgo-loader/csgo-client/Security/SyscallManager.hpp b/csgo-loader/csgo-client/Security/SyscallManager.hpp
index e154625..a9c67aa 100644
--- a/csgo-loader/csgo-client/Security/SyscallManager.hpp
+++ b/csgo-loader/csgo-client/Security/SyscallManager.hpp
@@ -11,9 +11,11 @@
using ByteArray = std::vector<uint8_t>;
-namespace Wrapper {
+namespace Wrapper
+{
// A stub used for our syscalls.
- class SyscallStub {
+ class SyscallStub
+ {
// The shellcode which executes a low latency system call.
uint8_t m_Shellcode[11] = {
0x4C, 0x8B, 0xD1, // mov r10, rcx
@@ -28,14 +30,16 @@ namespace Wrapper {
// Sets the syscall index.
void SetIndex(uint32_t Index);
- __forceinline uintptr_t Get() {
+ __forceinline uintptr_t Get()
+ {
return (uintptr_t)m_Shellcode;
}
};
// Manager for system calls. Used to iterate NTDLL for all syscall indices.
// Read: https://www.evilsocket.net/2014/02/11/on-windows-syscall-mechanism-and-syscall-numbers-extraction-methods/
- class SyscallManager {
+ class SyscallManager
+ {
// Reading NTDLL from disk because it cannot be modified
// due to restrictions put in place by PatchGuard.
ByteArray GetNtdllFromDisk();
@@ -54,7 +58,8 @@ namespace Wrapper {
// Finds a syscall by hash.
template < typename T >
- T Find(uint64_t Hash) {
+ T Find(uint64_t Hash)
+ {
return (T)m_Syscalls[Hash].Get();
}
};