More anticheat exceptions

This commit is contained in:
momo5502 2016-08-07 16:50:04 +02:00
parent f6b0ffc9df
commit 2aee48bffa
8 changed files with 188 additions and 131 deletions

View File

@ -5,7 +5,6 @@ namespace Components
int AntiCheat::LastCheck; int AntiCheat::LastCheck;
std::string AntiCheat::Hash; std::string AntiCheat::Hash;
Utils::Hook AntiCheat::LoadLibHook[4]; Utils::Hook AntiCheat::LoadLibHook[4];
Utils::Hook AntiCheat::VirtualProtectHook;
// This function does nothing, it only adds the two passed variables and returns the value // This function does nothing, it only adds the two passed variables and returns the value
// The only important thing it does is to clean the first parameter, and then return // The only important thing it does is to clean the first parameter, and then return
@ -105,8 +104,13 @@ namespace Components
FARPROC loadLibA = GetProcAddress(kernel32, Utils::String::XOR(std::string(reinterpret_cast<char*>(loadLibAStr), sizeof loadLibAStr), -1).data()); FARPROC loadLibA = GetProcAddress(kernel32, Utils::String::XOR(std::string(reinterpret_cast<char*>(loadLibAStr), sizeof loadLibAStr), -1).data());
FARPROC loadLibW = GetProcAddress(kernel32, Utils::String::XOR(std::string(reinterpret_cast<char*>(loadLibWStr), sizeof loadLibWStr), -1).data()); FARPROC loadLibW = GetProcAddress(kernel32, Utils::String::XOR(std::string(reinterpret_cast<char*>(loadLibWStr), sizeof loadLibWStr), -1).data());
#ifdef DEBUG_LOAD_LIBRARY
AntiCheat::LoadLibHook[0].Initialize(loadLibA, LoadLibaryAStub, HOOK_JUMP);
AntiCheat::LoadLibHook[1].Initialize(loadLibW, LoadLibaryWStub, HOOK_JUMP);
#else
AntiCheat::LoadLibHook[0].Initialize(loadLibA, loadLibStub, HOOK_JUMP); AntiCheat::LoadLibHook[0].Initialize(loadLibA, loadLibStub, HOOK_JUMP);
AntiCheat::LoadLibHook[1].Initialize(loadLibW, loadLibStub, HOOK_JUMP); AntiCheat::LoadLibHook[1].Initialize(loadLibW, loadLibStub, HOOK_JUMP);
#endif
//AntiCheat::LoadLibHook[2].Initialize(LoadLibraryExA, loadLibExStub, HOOK_JUMP); //AntiCheat::LoadLibHook[2].Initialize(LoadLibraryExA, loadLibExStub, HOOK_JUMP);
//AntiCheat::LoadLibHook[3].Initialize(LoadLibraryExW, loadLibExStub, HOOK_JUMP); //AntiCheat::LoadLibHook[3].Initialize(LoadLibraryExW, loadLibExStub, HOOK_JUMP);
} }
@ -140,6 +144,32 @@ namespace Components
AntiCheat::PerformCheck(); AntiCheat::PerformCheck();
} }
#ifdef DEBUG_LOAD_LIBRARY
HANDLE AntiCheat::LoadLibary(std::wstring library, void* callee)
{
HMODULE module;
char buffer[MAX_PATH] = { 0 };
GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, reinterpret_cast<char*>(callee), &module);
GetModuleFileNameA(module, buffer, sizeof buffer);
MessageBoxA(0, fmt::sprintf("Loading library %s via %s %X", std::string(library.begin(), library.end()).data(), buffer, reinterpret_cast<uint32_t>(callee)).data(), 0, 0);
return LoadLibraryExW(library.data(), NULL, 0);
}
HANDLE WINAPI AntiCheat::LoadLibaryAStub(const char* library)
{
std::string lib(library);
return AntiCheat::LoadLibary(std::wstring(lib.begin(), lib.end()), _ReturnAddress());
}
HANDLE WINAPI AntiCheat::LoadLibaryWStub(const wchar_t* library)
{
return AntiCheat::LoadLibary(library, _ReturnAddress());
}
#endif
void AntiCheat::UninstallLibHook() void AntiCheat::UninstallLibHook()
{ {
for (int i = 0; i < ARRAYSIZE(AntiCheat::LoadLibHook); ++i) for (int i = 0; i < ARRAYSIZE(AntiCheat::LoadLibHook); ++i)
@ -175,33 +205,37 @@ namespace Components
AntiCheat::InstallLibHook(); AntiCheat::InstallLibHook();
} }
// BOOL WINAPI AntiCheat::VirtualProtectStub(LPVOID lpAddress, SIZE_T dwSize, DWORD flNewProtect, PDWORD lpflOldProtect) void __declspec(naked) AntiCheat::CinematicStub()
// { {
// AntiCheat::VirtualProtectHook.Uninstall(false); __asm
// {
// if (flNewProtect == PAGE_WRITECOPY || flNewProtect == PAGE_READWRITE || flNewProtect == PAGE_EXECUTE_READWRITE || flNewProtect == PAGE_WRITECOMBINE) pushad
// { call AntiCheat::UninstallLibHook
// DWORD addr = (DWORD)lpAddress; popad
// DWORD start = 0x401000;
// DWORD end = start + 0x2D6000; call Game::R_Cinematic_StartPlayback_Now
//
// if (addr > start && addr < end) pushad
// { call AntiCheat::InstallLibHook
// OutputDebugStringA(Utils::VA("Write access to address %X", lpAddress)); popad
// }
// } retn
// }
// BOOL retVal = VirtualProtect(lpAddress, dwSize, flNewProtect, lpflOldProtect); }
// AntiCheat::VirtualProtectHook.Install(false);
// return retVal; bool AntiCheat::EncodeInitStub(const char* param)
// } {
AntiCheat::UninstallLibHook();
bool result = Game::Encode_Init(param);
AntiCheat::InstallLibHook();
return result;
}
AntiCheat::AntiCheat() AntiCheat::AntiCheat()
{ {
// This is required for debugging...in release mode :P
//AntiCheat::VirtualProtectHook.Initialize(VirtualProtect, VirtualProtectStub, HOOK_JUMP);
//AntiCheat::VirtualProtectHook.Install(true, true);
AntiCheat::EmptyHash(); AntiCheat::EmptyHash();
#ifdef DEBUG #ifdef DEBUG
@ -210,9 +244,12 @@ namespace Components
AntiCheat::CrashClient(); AntiCheat::CrashClient();
}); });
#else #else
Utils::Hook(0x507BD5, AntiCheat::PatchWinAPI, HOOK_CALL).Install()->Quick();
Utils::Hook(0x60BE8E, AntiCheat::SoundInitStub, HOOK_CALL).Install()->Quick(); Utils::Hook(0x60BE8E, AntiCheat::SoundInitStub, HOOK_CALL).Install()->Quick();
Utils::Hook(0x418204, AntiCheat::SoundInitStub, HOOK_CALL).Install()->Quick(); Utils::Hook(0x418204, AntiCheat::SoundInitStub, HOOK_CALL).Install()->Quick();
Utils::Hook(0x507BD5, AntiCheat::PatchWinAPI, HOOK_CALL).Install()->Quick(); Utils::Hook(0x51C76C, AntiCheat::CinematicStub, HOOK_CALL).Install()->Quick();
Utils::Hook(0x4A22E5, AntiCheat::EncodeInitStub, HOOK_CALL).Install()->Quick();
QuickPatch::OnFrame(AntiCheat::Frame); QuickPatch::OnFrame(AntiCheat::Frame);
// TODO: Probably move that :P // TODO: Probably move that :P
@ -224,7 +261,6 @@ namespace Components
{ {
AntiCheat::EmptyHash(); AntiCheat::EmptyHash();
AntiCheat::VirtualProtectHook.Uninstall(false);
for (int i = 0; i < ARRAYSIZE(AntiCheat::LoadLibHook); ++i) for (int i = 0; i < ARRAYSIZE(AntiCheat::LoadLibHook); ++i)
{ {
AntiCheat::LoadLibHook[i].Uninstall(); AntiCheat::LoadLibHook[i].Uninstall();

View File

@ -1,3 +1,6 @@
// Uncomment that to see if we are preventing necessary libraries from being loaded
//#define DEBUG_LOAD_LIBRARY
namespace Components namespace Components
{ {
class AntiCheat : public Component class AntiCheat : public Component
@ -25,10 +28,16 @@ namespace Components
static void UninstallLibHook(); static void UninstallLibHook();
static void InstallLibHook(); static void InstallLibHook();
#ifdef DEBUG_LOAD_LIBRARY
static HANDLE LoadLibary(std::wstring library, void* callee);
static HANDLE WINAPI LoadLibaryAStub(const char* library);
static HANDLE WINAPI LoadLibaryWStub(const wchar_t* library);
#endif
static void CinematicStub();
static void SoundInitStub(); static void SoundInitStub();
static BOOL WINAPI VirtualProtectStub(LPVOID lpAddress, SIZE_T dwSize, DWORD flNewProtect, PDWORD lpflOldProtect); static bool EncodeInitStub(const char* param);
static Utils::Hook LoadLibHook[4]; static Utils::Hook LoadLibHook[4];
static Utils::Hook VirtualProtectHook;
}; };
} }

View File

@ -21,7 +21,7 @@ namespace Components
std::string connectString(format, len); std::string connectString(format, len);
Game::SV_Cmd_TokenizeString(connectString.data()); Game::SV_Cmd_TokenizeString(connectString.data());
Command::Params params(true, *Game::cmd_id_sv); Command::Params params(true);
if (params.Length() < 3) if (params.Length() < 3)
{ {
@ -88,7 +88,7 @@ namespace Components
Game::SV_Cmd_TokenizeString(connectData.infostring().data()); Game::SV_Cmd_TokenizeString(connectData.infostring().data());
// Access the params // Access the params
Command::Params params(true, *Game::cmd_id_sv); Command::Params params(true);
// Ensure there are enough params // Ensure there are enough params
if (params.Length() < 3) if (params.Length() < 3)

View File

@ -7,6 +7,7 @@ namespace Components
{ {
public: public:
Params(bool sv, DWORD id) : CommandId(id), IsSV(sv) {}; Params(bool sv, DWORD id) : CommandId(id), IsSV(sv) {};
Params(bool sv) : Params(sv, (sv ? *Game::cmd_id_sv : *Game::cmd_id)) {};
Params(const Params &obj) : CommandId(obj.CommandId), IsSV(obj.IsSV) {}; Params(const Params &obj) : CommandId(obj.CommandId), IsSV(obj.IsSV) {};
Params() : Params(false, *Game::cmd_id) {}; Params() : Params(false, *Game::cmd_id) {};

View File

@ -14,6 +14,8 @@ namespace Components
Dvar::Register<int>("net_discoveryPortRangeMin", 25000, 0, 65535, Game::dvar_flag::DVAR_FLAG_SAVED, "Minimum scan range port for local server discovery"); Dvar::Register<int>("net_discoveryPortRangeMin", 25000, 0, 65535, Game::dvar_flag::DVAR_FLAG_SAVED, "Minimum scan range port for local server discovery");
Dvar::Register<int>("net_discoveryPortRangeMax", 35000, 1, 65536, Game::dvar_flag::DVAR_FLAG_SAVED, "Maximum scan range port for local server discovery"); Dvar::Register<int>("net_discoveryPortRangeMax", 35000, 1, 65536, Game::dvar_flag::DVAR_FLAG_SAVED, "Maximum scan range port for local server discovery");
// An additional thread prevents lags
// Not sure if that's the best way though
Discovery::DiscoveryContainer.Perform = false; Discovery::DiscoveryContainer.Perform = false;
Discovery::DiscoveryContainer.Terminate = false; Discovery::DiscoveryContainer.Terminate = false;
Discovery::DiscoveryContainer.Thread = std::thread([] () Discovery::DiscoveryContainer.Thread = std::thread([] ()

View File

@ -53,6 +53,8 @@ namespace Game
Dvar_InfoString_Big_t Dvar_InfoString_Big = (Dvar_InfoString_Big_t)0x4D98A0; Dvar_InfoString_Big_t Dvar_InfoString_Big = (Dvar_InfoString_Big_t)0x4D98A0;
Dvar_SetCommand_t Dvar_SetCommand = (Dvar_SetCommand_t)0x4EE430; Dvar_SetCommand_t Dvar_SetCommand = (Dvar_SetCommand_t)0x4EE430;
Encode_Init_t Encode_Init = (Encode_Init_t)0x462AB0;
Field_Clear_t Field_Clear = (Field_Clear_t)0x437EB0; Field_Clear_t Field_Clear = (Field_Clear_t)0x437EB0;
FreeMemory_t FreeMemory = (FreeMemory_t)0x4D6640; FreeMemory_t FreeMemory = (FreeMemory_t)0x4D6640;
@ -129,6 +131,7 @@ namespace Game
PartyHost_GetMemberName_t PartyHost_GetMemberName = (PartyHost_GetMemberName_t)0x44BE90; PartyHost_GetMemberName_t PartyHost_GetMemberName = (PartyHost_GetMemberName_t)0x44BE90;
R_AddCmdDrawStretchPic_t R_AddCmdDrawStretchPic = (R_AddCmdDrawStretchPic_t)0x509770; R_AddCmdDrawStretchPic_t R_AddCmdDrawStretchPic = (R_AddCmdDrawStretchPic_t)0x509770;
R_Cinematic_StartPlayback_Now_t R_Cinematic_StartPlayback_Now = (R_Cinematic_StartPlayback_Now_t)0x51C5B0;
R_RegisterFont_t R_RegisterFont = (R_RegisterFont_t)0x505670; R_RegisterFont_t R_RegisterFont = (R_RegisterFont_t)0x505670;
R_AddCmdDrawText_t R_AddCmdDrawText = (R_AddCmdDrawText_t)0x509D80; R_AddCmdDrawText_t R_AddCmdDrawText = (R_AddCmdDrawText_t)0x509D80;
R_LoadGraphicsAssets_t R_LoadGraphicsAssets = (R_LoadGraphicsAssets_t)0x506AC0; R_LoadGraphicsAssets_t R_LoadGraphicsAssets = (R_LoadGraphicsAssets_t)0x506AC0;

View File

@ -123,6 +123,9 @@ namespace Game
typedef dvar_t* (__cdecl * Dvar_SetCommand_t)(const char* name, const char* value); typedef dvar_t* (__cdecl * Dvar_SetCommand_t)(const char* name, const char* value);
extern Dvar_SetCommand_t Dvar_SetCommand; extern Dvar_SetCommand_t Dvar_SetCommand;
typedef bool(__cdecl * Encode_Init_t)(const char* );
extern Encode_Init_t Encode_Init;
typedef void(__cdecl * Field_Clear_t)(void* field); typedef void(__cdecl * Field_Clear_t)(void* field);
extern Field_Clear_t Field_Clear; extern Field_Clear_t Field_Clear;
@ -311,6 +314,9 @@ namespace Game
typedef void(_cdecl * R_AddCmdDrawStretchPic_t)(float x, float y, float w, float h, float xScale, float yScale, float xay, float yay, const float *color, Game::Material* material); typedef void(_cdecl * R_AddCmdDrawStretchPic_t)(float x, float y, float w, float h, float xScale, float yScale, float xay, float yay, const float *color, Game::Material* material);
extern R_AddCmdDrawStretchPic_t R_AddCmdDrawStretchPic; extern R_AddCmdDrawStretchPic_t R_AddCmdDrawStretchPic;
typedef bool(__cdecl * R_Cinematic_StartPlayback_Now_t)();
extern R_Cinematic_StartPlayback_Now_t R_Cinematic_StartPlayback_Now;
typedef void(__cdecl * R_LoadGraphicsAssets_t)(); typedef void(__cdecl * R_LoadGraphicsAssets_t)();
extern R_LoadGraphicsAssets_t R_LoadGraphicsAssets; extern R_LoadGraphicsAssets_t R_LoadGraphicsAssets;