1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
|
#include "main.h"
#include <iostream>
#include <array>
#include <fstream>
#include <iterator>
#include <windows.h>
#include <wincrypt.h>
void init_memory();
void main_loop();
#undef main
bool exists_and_is_of_size( std::string path, unsigned long size )
{
const auto file = ::CreateFileA( path.c_str(), GENERIC_READ, 0, nullptr, OPEN_EXISTING, 0, 0 ) ;
if( file == INVALID_HANDLE_VALUE ) return false ;
const auto sz = ::GetFileSize( file, nullptr ) ;
::CloseHandle(file) ;
return sz == size ;
}
HANDLE create_process( std::string path )
{
::STARTUPINFO si {} ;
::PROCESS_INFORMATION pi {} ;
std::vector<char> vec( path.begin(), path.end() ) ;
vec.resize( path.size() + 100 ) ;
if( ::CreateProcessA( nullptr, vec.data(), nullptr, nullptr, false, 0, nullptr, nullptr,
std::addressof(si), std::addressof(pi) ) )
::CloseHandle( pi.hThread ) ;
return pi.hProcess ;
}
constexpr std::size_t MD5_SIZE = 16 ;
using md5_digest = std::array< BYTE, MD5_SIZE > ;
std::vector<BYTE> get_bytes( std::string path )
{
std::ifstream file( path, std::ios_base::binary ) ;
return { std::istream_iterator<BYTE>{file}, std::istream_iterator<BYTE>{} } ;
}
md5_digest md5( std::string path ) // MinGW: link with libadvapi32.a
{
md5_digest digest {} ;
//const auto bytes = get_bytes(path) ;
auto bytes = get_bytes(path) ;
if( !bytes.empty() )
{
HCRYPTPROV provider = 0 ;
if( ::CryptAcquireContext( std::addressof(provider), nullptr, nullptr, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT ) )
{
HCRYPTHASH hash = 0 ;
if( ::CryptCreateHash( provider, CALG_MD5, 0, 0, std::addressof(hash) ) )
{
::CryptHashData( hash, bytes.data(), bytes.size(), 0 ) ;
DWORD nbytes = bytes.size() ;
::CryptGetHashParam( hash, HP_HASHVAL, digest.data(), std::addressof(nbytes), 0 ) ;
::CryptDestroyHash(hash) ;
}
::CryptReleaseContext( provider, 0 ) ;
}
}
return digest ;
}
int main(int argc, char *argv[])
{
const std::string anti_cheat_path = "AntiCheat.exe" ;
// const std::uintmax_t anti_cheat_size = 40 ; //file is 40kb
const std::uintmax_t anti_cheat_size = 40960 ; // 40,960 bytes
// initialise with the actual md5 digest for anti_cheat.exe
const md5_digest expected_anti_cheat_md5 = { 0x75, 0xa8, 0x2f, 0xaf, 0xa3, 0xb8, 0x92, 0xa3,
0x49, 0xf8, 0x0c, 0xe4, 0x5c, 0x7e, 0x7a, 0x15 } ;
// if anti_cheat is in the current directory and has the expected size
if( exists_and_is_of_size( anti_cheat_path, anti_cheat_size ) )
{
const auto anti_cheat = create_process( anti_cheat_path ) ;
if( !anti_cheat ) return 1 ; // return if the anti_cheat process could not be launched
if( md5(anti_cheat_path) == expected_anti_cheat_md5 ) // if the md5 digest matches
{
if (!init_sdl()) return 0;
init_memory();
init_audio();
load_splash_screen();
load_login();
read_host_info();
read_config_info();
load_ignore();
load_sos();
//connect_to_hub();
init_sockets();
main_loop();
return 0;
}
// main_loop() should execute this while loop, once every 'check_interval_millisecs' milliseconds
while( WaitForSingleObject( anti_cheat, 0 ) == WAIT_TIMEOUT ) // if anti_cheat is still running
{
const unsigned int check_interval_millisecs = 5000 ; // check every five seconds
// run game loop for check_interval_millisecs milliseconds
// go back to while and check if anti_cheat is still running
}
}
else return 1 ; // anti cheat not found
}
|