Basic anticheat component

This commit is contained in:
momo5502 2016-02-29 14:47:21 +01:00
parent 60cd705153
commit 6fdf7f887a
6 changed files with 120 additions and 2 deletions

View File

@ -33,6 +33,7 @@ namespace Components
Loader::Register(new Renderer()); Loader::Register(new Renderer());
Loader::Register(new UIFeeder()); Loader::Register(new UIFeeder());
Loader::Register(new UIScript()); Loader::Register(new UIScript());
Loader::Register(new AntiCheat());
Loader::Register(new Dedicated()); Loader::Register(new Dedicated());
Loader::Register(new Discovery()); Loader::Register(new Discovery());
Loader::Register(new Exception()); Loader::Register(new Exception());

View File

@ -48,6 +48,7 @@ namespace Components
#include "Modules\Renderer.hpp" #include "Modules\Renderer.hpp"
#include "Modules\UIFeeder.hpp" #include "Modules\UIFeeder.hpp"
#include "Modules\UIScript.hpp" #include "Modules\UIScript.hpp"
#include "Modules\AntiCheat.hpp"
#include "Modules\Dedicated.hpp" #include "Modules\Dedicated.hpp"
#include "Modules\Discovery.hpp" #include "Modules\Discovery.hpp"
#include "Modules\Exception.hpp" #include "Modules\Exception.hpp"

View File

@ -0,0 +1,86 @@
#include "STDInclude.hpp"
namespace Components
{
std::string AntiCheat::Hash;
void __declspec(naked) AntiCheat::CrashClient()
{
static uint8_t crashProcedure[] =
{
// Uninstall minidump handler
0xB8, 0x63, 0xE7, 0x2F, 0x00, // mov eax, 2FE763h
0x05, 0xAD, 0xAD, 0x3C, 0x00, // add eax, 3CADADh
0x6A, 0x58, // push 88
0x8B, 0x80, 0xEA, 0x01, 0x00, 0x00, // mov eax, [eax + 1EAh]
0xFF, 0x10, // call dword ptr [eax]
// Crash me.
0xB8, 0x4F, 0x91, 0x27, 0x00, // mov eax, 27914Fh
0x05, 0xDD, 0x28, 0x1A, 0x00, // add eax, 1A28DDh
0x80, 0x00, 0x68, // add byte ptr [eax], 68h
0xC3, // retn
};
__asm
{
// This does absolutely nothing :P
// TODO: Obfuscate even more
xor eax, eax
mov ebx, [esp + 4h]
shl ebx, 4h
// Call our crash procedure
push offset crashProcedure
retn
}
}
// This has to be called when doing .text changes during runtime
void AntiCheat::EmptyHash()
{
AntiCheat::Hash.clear();
}
void AntiCheat::Frame()
{
static int lastCheck = 0;
// Perform check only every 20 seconds
if (lastCheck && (Game::Com_Milliseconds() - lastCheck) < 1000 * 20) return;
lastCheck = Game::Com_Milliseconds();
// Get base module
const uint8_t* module = reinterpret_cast<const uint8_t*>(GetModuleHandle(NULL));
std::string hash = Utils::Cryptography::SHA512::Compute(module + 0x1000, 0x2D6000, false);
// Set the hash, if none is set
if (AntiCheat::Hash.empty())
{
AntiCheat::Hash = hash;
}
// Crash if the hashes don't match
else if(AntiCheat::Hash != hash)
{
AntiCheat::CrashClient();
}
}
AntiCheat::AntiCheat()
{
Renderer::OnFrame(AntiCheat::Frame);
Dedicated::OnFrame(AntiCheat::Frame);
#ifdef DEBUG
Command::Add("penis", [] (Command::Params)
{
AntiCheat::CrashClient();
});
#endif
}
AntiCheat::~AntiCheat()
{
AntiCheat::EmptyHash();
}
}

View File

@ -0,0 +1,18 @@
namespace Components
{
class AntiCheat : public Component
{
public:
AntiCheat();
~AntiCheat();
const char* GetName() { return "Component"; }; // Wrong name :P
static void CrashClient();
static void EmptyHash();
private:
static std::string Hash;
static void Frame();
};
}

View File

@ -120,12 +120,17 @@ namespace Utils
#pragma region SHA256 #pragma region SHA256
std::string SHA256::Compute(std::string data, bool hex) std::string SHA256::Compute(std::string data, bool hex)
{
return SHA256::Compute(reinterpret_cast<const uint8_t*>(data.data()), data.size(), hex);
}
std::string SHA256::Compute(const uint8_t* data, size_t length, bool hex)
{ {
uint8_t buffer[32] = { 0 }; uint8_t buffer[32] = { 0 };
hash_state state; hash_state state;
sha256_init(&state); sha256_init(&state);
sha256_process(&state, reinterpret_cast<const uint8_t*>(data.data()), data.size()); sha256_process(&state, data, length);
sha256_done(&state, buffer); sha256_done(&state, buffer);
std::string hash(reinterpret_cast<char*>(buffer), sizeof(buffer)); std::string hash(reinterpret_cast<char*>(buffer), sizeof(buffer));
@ -139,12 +144,17 @@ namespace Utils
#pragma region SHA512 #pragma region SHA512
std::string SHA512::Compute(std::string data, bool hex) std::string SHA512::Compute(std::string data, bool hex)
{
return SHA512::Compute(reinterpret_cast<const uint8_t*>(data.data()), data.size(), hex);
}
std::string SHA512::Compute(const uint8_t* data, size_t length, bool hex)
{ {
uint8_t buffer[64] = { 0 }; uint8_t buffer[64] = { 0 };
hash_state state; hash_state state;
sha512_init(&state); sha512_init(&state);
sha512_process(&state, reinterpret_cast<const uint8_t*>(data.data()), data.size()); sha512_process(&state, data, length);
sha512_done(&state, buffer); sha512_done(&state, buffer);
std::string hash(reinterpret_cast<char*>(buffer), sizeof(buffer)); std::string hash(reinterpret_cast<char*>(buffer), sizeof(buffer));

View File

@ -226,12 +226,14 @@ namespace Utils
{ {
public: public:
static std::string Compute(std::string data, bool hex = false); static std::string Compute(std::string data, bool hex = false);
static std::string Compute(const uint8_t* data, size_t length, bool hex = false);
}; };
class SHA512 class SHA512
{ {
public: public:
static std::string Compute(std::string data, bool hex = false); static std::string Compute(std::string data, bool hex = false);
static std::string Compute(const uint8_t* data, size_t length, bool hex = false);
}; };
} }
} }