diff --git a/CMakeLists.txt b/CMakeLists.txt index a240a6b..a5357b9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,14 +1,9 @@ -cmake_minimum_required(VERSION 3.15) - -set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /O2") -project(BeamMP-Launcher) +cmake_minimum_required(VERSION 3.10) +project(Launcher) set(CMAKE_CXX_STANDARD 17) - -file(GLOB source_files - "src/*.cpp" "src/include/*.h" - "src/include/*.hpp" "src/curl/*.h" - "src/Network 2.0/*.cpp" "src/Network 2.0/*.h" - "src/Memory/*.hpp" "src/Memory/*.cpp") - -add_executable(BeamMP-Launcher ${source_files}) -target_link_libraries(BeamMP-Launcher ws2_32 urlmon discord-rpc libcurl_a zlibstatic) \ No newline at end of file +file(GLOB source_files "src/*.cpp" "src/*/*.cpp" "src/*/*.hpp" "include/*.h" "include/*/*.h") +add_executable(${PROJECT_NAME} ${source_files}) +set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME "BeamMP-Launcher") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj") +target_link_libraries(${PROJECT_NAME} ws2_32 urlmon rstrtmgr discord-rpc zlibstatic libcurl_a) +target_include_directories(${PROJECT_NAME} PUBLIC $) \ No newline at end of file diff --git a/cmake-build-debug/zlibstatic.lib b/cmake-build-debug/zlibstatic.lib index 7f8f1ce..6f06484 100644 Binary files a/cmake-build-debug/zlibstatic.lib and b/cmake-build-debug/zlibstatic.lib differ diff --git a/cmake-build-release/zlibstatic.lib b/cmake-build-release/zlibstatic.lib index 7f8f1ce..d76c0d3 100644 Binary files a/cmake-build-release/zlibstatic.lib and b/cmake-build-release/zlibstatic.lib differ diff --git a/src/curl/curl.h b/include/Curl/curl.h similarity index 100% rename from src/curl/curl.h rename to include/Curl/curl.h diff --git a/src/curl/curlbuild.h b/include/Curl/curlbuild.h similarity index 100% rename from src/curl/curlbuild.h rename to include/Curl/curlbuild.h diff --git a/src/curl/curlrules.h b/include/Curl/curlrules.h similarity index 100% rename from src/curl/curlrules.h rename to include/Curl/curlrules.h diff --git a/src/curl/curlver.h b/include/Curl/curlver.h similarity index 100% rename from src/curl/curlver.h rename to include/Curl/curlver.h diff --git a/src/curl/easy.h b/include/Curl/easy.h similarity index 100% rename from src/curl/easy.h rename to include/Curl/easy.h diff --git a/include/Curl/http.h b/include/Curl/http.h new file mode 100644 index 0000000..9a1438e --- /dev/null +++ b/include/Curl/http.h @@ -0,0 +1,6 @@ +/// +/// Created by Anonymous275 on 7/18/2020 +/// +#pragma once +int Download(const std::string& URL,const std::string& Path,bool close); +std::string HTTP_REQUEST(const std::string& IP,int port); \ No newline at end of file diff --git a/src/curl/mprintf.h b/include/Curl/mprintf.h similarity index 100% rename from src/curl/mprintf.h rename to include/Curl/mprintf.h diff --git a/src/curl/multi.h b/include/Curl/multi.h similarity index 100% rename from src/curl/multi.h rename to include/Curl/multi.h diff --git a/src/curl/stdcheaders.h b/include/Curl/stdcheaders.h similarity index 100% rename from src/curl/stdcheaders.h rename to include/Curl/stdcheaders.h diff --git a/src/curl/system.h b/include/Curl/system.h similarity index 100% rename from src/curl/system.h rename to include/Curl/system.h diff --git a/src/curl/typecheck-gcc.h b/include/Curl/typecheck-gcc.h similarity index 99% rename from src/curl/typecheck-gcc.h rename to include/Curl/typecheck-gcc.h index 6ec8bcf..315c264 100644 --- a/src/curl/typecheck-gcc.h +++ b/include/Curl/typecheck-gcc.h @@ -581,7 +581,7 @@ typedef CURLcode (_curl_ssl_ctx_callback2)(CURL *, void *, const void *); typedef CURLcode (_curl_ssl_ctx_callback3)(CURL *, const void *, void *); typedef CURLcode (_curl_ssl_ctx_callback4)(CURL *, const void *, const void *); #ifdef HEADER_SSL_H -/* hack: if we included OpenSSL's ssl.h, we know about SSL_CTX +/* hTRG: if we included OpenSSL's ssl.h, we know about SSL_CTX * this will of course break if we're included before OpenSSL headers... */ typedef CURLcode (_curl_ssl_ctx_callback5)(CURL *, SSL_CTX, void *); diff --git a/include/Discord/discord_info.h b/include/Discord/discord_info.h new file mode 100644 index 0000000..a1a2b01 --- /dev/null +++ b/include/Discord/discord_info.h @@ -0,0 +1,11 @@ +/// +/// Created by Anonymous275 on 7/16/2020 +/// +#pragma once +#include +void Discord_Main(); +std::string GetDName(); +std::string GetDTag(); +std::string GetDID(); +void DAboard(); + diff --git a/src/include/discord_register.h b/include/Discord/discord_register.h similarity index 100% rename from src/include/discord_register.h rename to include/Discord/discord_register.h diff --git a/src/include/discord_rpc.h b/include/Discord/discord_rpc.h similarity index 99% rename from src/include/discord_rpc.h rename to include/Discord/discord_rpc.h index 3e1441e..8609bf7 100644 --- a/src/include/discord_rpc.h +++ b/include/Discord/discord_rpc.h @@ -1,5 +1,5 @@ #pragma once -#include +#include // clang-format off diff --git a/include/Logger.h b/include/Logger.h new file mode 100644 index 0000000..5c3a52f --- /dev/null +++ b/include/Logger.h @@ -0,0 +1,12 @@ +/// +/// Created by Anonymous275 on 4/2/2020. +/// +#pragma once +#include +#include +void InitLog(); +void except(const std::string& toPrint); +void debug(const std::string& toPrint); +void error(const std::string& toPrint); +void info(const std::string& toPrint); +void warn(const std::string& toPrint); diff --git a/include/Memory.h b/include/Memory.h new file mode 100644 index 0000000..e6e3d42 --- /dev/null +++ b/include/Memory.h @@ -0,0 +1,5 @@ +/// +/// Created by Anonymous275 on 7/20/2020 +/// +#pragma once +void MemoryInit(); diff --git a/include/Network/network.h b/include/Network/network.h new file mode 100644 index 0000000..3869a6b --- /dev/null +++ b/include/Network/network.h @@ -0,0 +1,25 @@ +/// +/// Created by Anonymous275 on 7/18/2020 +/// +#pragma once +#include +void NetReset(); +extern long long ping; +extern bool Dev; +void ClearAll(); +extern int ClientID; +extern bool ModLoaded; +extern bool Terminate; +extern int DEFAULT_PORT; +extern bool TCPTerminate; +extern std::string MStatus; +extern std::string UlStatus; +extern std::string ListOfMods; +void UDPSend(std::string Data); +[[noreturn]] void CoreNetwork(); +void TCPSend(const std::string&Data); +void GameSend(const std::string&Data); +void SendLarge(const std::string&Data); +void TCPClientMain(const std::string& IP,int Port); +void UDPClientMain(const std::string& IP,int Port); +void TCPGameServer(const std::string& IP, int Port); diff --git a/include/Security/Enc.h b/include/Security/Enc.h new file mode 100644 index 0000000..3901895 --- /dev/null +++ b/include/Security/Enc.h @@ -0,0 +1,12 @@ +/// +/// Created by Anonymous275 on 7/16/2020 +/// +#pragma once +#include +#include "Xor.h" +std::string RSA_D(const std::string& Data,int d, int n); +std::string RSA_E(const std::string& Data,int e, int n); +std::string LocalEnc(const std::string& Data); +std::string LocalDec(const std::string& Data); +std::string Encrypt(std::string msg); +std::string Decrypt(std::string msg); \ No newline at end of file diff --git a/include/Security/Game.h b/include/Security/Game.h new file mode 100644 index 0000000..7eaa2e3 --- /dev/null +++ b/include/Security/Game.h @@ -0,0 +1,6 @@ +/// +/// Created by Anonymous275 on 7/19/2020 +/// +#pragma once +extern unsigned long GamePID; +void SecureMods(); diff --git a/include/Security/Init.h b/include/Security/Init.h new file mode 100644 index 0000000..4fae3cd --- /dev/null +++ b/include/Security/Init.h @@ -0,0 +1,11 @@ +/// +/// Created by Anonymous275 on 7/18/2020 +/// +#pragma once +#include +void PreGame(int argc, char* argv[],const std::string& GamePath); +void InitGame(const std::string& Dir,const std::string&Current); +std::string CheckVer(const std::string &path); +void SecurityCheck(char* argv[]); +std::string GetGameDir(); +void LegitimacyCheck(); \ No newline at end of file diff --git a/include/Security/Xor.h b/include/Security/Xor.h new file mode 100644 index 0000000..a7b2874 --- /dev/null +++ b/include/Security/Xor.h @@ -0,0 +1,130 @@ +/// +/// Created by Anonymous275 on 8/11/2020 +/// +#pragma once +#include +#include +#include + +#define BEGIN_NAMESPACE(x) namespace x { +#define END_NAMESPACE } + +BEGIN_NAMESPACE(XorCompileTime) + + constexpr auto time = __TIME__; + constexpr auto seed = static_cast(time[7]) + static_cast(time[6]) * 10 + static_cast(time[4]) * 60 + static_cast(time[3]) * 600 + static_cast< int >(time[1]) * 3600 + static_cast< int >(time[0]) * 36000; + +// 1988, Stephen Park and Keith Miller +// "Random Number Generators: Good Ones Are Hard To Find", considered as "minimal standard" +// Park-Miller 31 bit pseudo-random number generator, implemented with G. Carta's optimisation: +// with 32-bit math and without division + + template + struct RandomGenerator{ + private: + static constexpr unsigned a = 16807; // 7^5 + static constexpr unsigned m = 2147483647; // 2^31 - 1 + + static constexpr unsigned s = RandomGenerator< N - 1 >::value; + static constexpr unsigned lo = a * (s & 0xFFFFu); // Multiply lower 16 bits by 16807 + static constexpr unsigned hi = a * (s >> 16u); // Multiply higher 16 bits by 16807 + static constexpr unsigned lo2 = lo + ((hi & 0x7FFFu) << 16u); // Combine lower 15 bits of hi with lo's upper bits + static constexpr unsigned hi2 = hi >> 15u; // Discard lower 15 bits of hi + static constexpr unsigned lo3 = lo2 + hi; + + public: + static constexpr unsigned max = m; + static constexpr unsigned value = lo3 > m ? lo3 - m : lo3; + }; + + template <> + struct RandomGenerator< 0 >{ + static constexpr unsigned value = seed; + }; + + template + struct RandomInt{ + static constexpr auto value = RandomGenerator< N + 1 >::value % M; + }; + + template + struct RandomChar{ + static const char value = static_cast< char >(1 + RandomInt< N, 0x7F - 1 >::value); + }; + + template + struct XorString{ + private: + const char _key; + std::array< Char, N + 1 > _encrypted; + + constexpr Char enc(Char c) const{ + return c ^ _key; + } + + Char dec(Char c) const{ + return c ^ _key; + } + + public: + template + constexpr __forceinline XorString(const Char* str, std::index_sequence< Is... >) : _key(RandomChar< K >::value), _encrypted{ enc(str[Is])... } + {} + + __forceinline decltype(auto) decrypt(){ + for (size_t i = 0; i < N; ++i) { + _encrypted[i] = dec(_encrypted[i]); + } + _encrypted[N] = '\0'; + return _encrypted.data(); + } + }; + + static auto w_printf = [](const char* fmt, ...) { + va_list args; + va_start(args, fmt); + vprintf_s(fmt, args); + va_end(args); + }; + + static auto w_printf_s = [](const char* fmt, ...) { + va_list args; + va_start(args, fmt); + vprintf_s(fmt, args); + va_end(args); + }; + + /*static auto w_sprintf = [](char* buf, const char* fmt, ...) { + va_list args; + va_start(args, fmt); + vsprintf(buf, fmt, args); + va_end(args); + };*/ + + /*static auto w_sprintf_ret = [](char* buf, const char* fmt, ...) { + int ret; + va_list args; + va_start(args, fmt); + ret = vsprintf(buf, fmt, args); + va_end(args); + return ret; + };*/ + + static auto w_sprintf_s = [](char* buf, size_t buf_size, const char* fmt, ...) { + va_list args; + va_start(args, fmt); + vsprintf_s(buf, buf_size, fmt, args); + va_end(args); + }; + + static auto w_sprintf_s_ret = [](char* buf, size_t buf_size, const char* fmt, ...) { + int ret; + va_list args; + va_start(args, fmt); + ret = vsprintf_s(buf, buf_size, fmt, args); + va_end(args); + return ret; + }; +#define Sec( s ) []{ constexpr XorCompileTime::XorString< sizeof(s)/sizeof(char) - 1, __COUNTER__, char > expr( s, std::make_index_sequence< sizeof(s)/sizeof(char) - 1>() ); return expr; }().decrypt() +#define SecW( s ) []{ constexpr XorCompileTime::XorString< sizeof(s)/sizeof(wchar_t) - 1, __COUNTER__, wchar_t > expr( s, std::make_index_sequence< sizeof(s)/sizeof(wchar_t) - 1>() ); return expr; }().decrypt() +END_NAMESPACE diff --git a/include/Startup.h b/include/Startup.h new file mode 100644 index 0000000..0d219ad --- /dev/null +++ b/include/Startup.h @@ -0,0 +1,10 @@ +/// +/// Created by Anonymous275 on 7/18/2020 +/// +#pragma once +#include +void InitLauncher(int argc, char* argv[]); +void CheckDir(int argc,char* args[]); +std::string GetVer(); +std::string GetEN(); +extern bool Dev; \ No newline at end of file diff --git a/include/Zlib/Compressor.h b/include/Zlib/Compressor.h new file mode 100644 index 0000000..1947ef5 --- /dev/null +++ b/include/Zlib/Compressor.h @@ -0,0 +1,7 @@ +/// +/// Created by Anonymous275 on 7/24/2020 +/// +#pragma once +#include +std::string Comp(std::string Data); +std::string DeComp(std::string Compressed); diff --git a/src/include/zconf.h b/include/Zlib/zconf.h similarity index 97% rename from src/include/zconf.h rename to include/Zlib/zconf.h index 733b5eb..352f552 100644 --- a/src/include/zconf.h +++ b/include/Zlib/zconf.h @@ -3,10 +3,19 @@ * For conditions of distribution and use, see copyright notice in zlib.h */ +/* @(#) $Id$ */ #ifndef ZCONF_H #define ZCONF_H +/* #undef Z_PREFIX */ +/* #undef Z_HAVE_UNISTD_H */ +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + * Even better than compiling with -DZ_PREFIX would be to use configure to set + * this permanently in zconf.h using "./configure --zprefix". + */ #ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ # define Z_PREFIX_SET diff --git a/src/include/zlib.h b/include/Zlib/zlib.h similarity index 100% rename from src/include/zlib.h rename to include/Zlib/zlib.h diff --git a/include/Zlib/zutil.h b/include/Zlib/zutil.h new file mode 100644 index 0000000..b079ea6 --- /dev/null +++ b/include/Zlib/zutil.h @@ -0,0 +1,271 @@ +/* zutil.h -- internal interface and configuration of the compression library + * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id$ */ + +#ifndef ZUTIL_H +#define ZUTIL_H + +#ifdef HAVE_HIDDEN +# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) +#else +# define ZLIB_INTERNAL +#endif + +#include "zlib.h" + +#if defined(STDC) && !defined(Z_SOLO) +# if !(defined(_WIN32_WCE) && defined(_MSC_VER)) +# include +# endif +# include +# include +#endif + +#ifdef Z_SOLO + typedef long ptrdiff_t; /* guess -- will be caught if guess is wrong */ +#endif + +#ifndef local +# define local static +#endif +/* since "static" is used to mean two completely different things in C, we + define "local" for the non-static meaning of "static", for readability + (compile with -Dlocal if your debugger can't find static symbols) */ + +typedef unsigned char uch; +typedef uch FAR uchf; +typedef unsigned short ush; +typedef ush FAR ushf; +typedef unsigned long ulg; + +extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ +/* (size given to avoid silly warnings with Visual C++) */ + +#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] + +#define ERR_RETURN(strm,err) \ + return (strm->msg = ERR_MSG(err), (err)) +/* To be used only when the state is known to be valid */ + + /* common constants */ + +#ifndef DEF_WBITS +# define DEF_WBITS MAX_WBITS +#endif +/* default windowBits for decompression. MAX_WBITS is for compression only */ + +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif +/* default memLevel */ + +#define STORED_BLOCK 0 +#define STATIC_TREES 1 +#define DYN_TREES 2 +/* The three kinds of block type */ + +#define MIN_MATCH 3 +#define MAX_MATCH 258 +/* The minimum and maximum match lengths */ + +#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ + + /* target dependencies */ + +#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) +# define OS_CODE 0x00 +# ifndef Z_SOLO +# if defined(__TURBOC__) || defined(__BORLANDC__) +# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) + /* Allow compilation with ANSI keywords only enabled */ + void _Cdecl farfree( void *block ); + void *_Cdecl farmalloc( unsigned long nbytes ); +# else +# include +# endif +# else /* MSC or DJGPP */ +# include +# endif +# endif +#endif + +#ifdef AMIGA +# define OS_CODE 1 +#endif + +#if defined(VAXC) || defined(VMS) +# define OS_CODE 2 +# define F_OPEN(name, mode) \ + fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") +#endif + +#ifdef __370__ +# if __TARGET_LIB__ < 0x20000000 +# define OS_CODE 4 +# elif __TARGET_LIB__ < 0x40000000 +# define OS_CODE 11 +# else +# define OS_CODE 8 +# endif +#endif + +#if defined(ATARI) || defined(atarist) +# define OS_CODE 5 +#endif + +#ifdef OS2 +# define OS_CODE 6 +# if defined(M_I86) && !defined(Z_SOLO) +# include +# endif +#endif + +#if defined(MACOS) || defined(TARGET_OS_MAC) +# define OS_CODE 7 +# ifndef Z_SOLO +# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os +# include /* for fdopen */ +# else +# ifndef fdopen +# define fdopen(fd,mode) NULL /* No fdopen() */ +# endif +# endif +# endif +#endif + +#ifdef __acorn +# define OS_CODE 13 +#endif + +#if defined(WIN32) && !defined(__CYGWIN__) +# define OS_CODE 10 +#endif + +#ifdef _BEOS_ +# define OS_CODE 16 +#endif + +#ifdef __TOS_OS400__ +# define OS_CODE 18 +#endif + +#ifdef __APPLE__ +# define OS_CODE 19 +#endif + +#if defined(_BEOS_) || defined(RISCOS) +# define fdopen(fd,mode) NULL /* No fdopen() */ +#endif + +#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX +# if defined(_WIN32_WCE) +# define fdopen(fd,mode) NULL /* No fdopen() */ +# ifndef _PTRDIFF_T_DEFINED + typedef int ptrdiff_t; +# define _PTRDIFF_T_DEFINED +# endif +# else +# define fdopen(fd,type) _fdopen(fd,type) +# endif +#endif + +#if defined(__BORLANDC__) && !defined(MSDOS) + #pragma warn -8004 + #pragma warn -8008 + #pragma warn -8066 +#endif + +/* provide prototypes for these when building zlib without LFS */ +#if !defined(_WIN32) && \ + (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0) + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); +#endif + + /* common defaults */ + +#ifndef OS_CODE +# define OS_CODE 3 /* assume Unix */ +#endif + +#ifndef F_OPEN +# define F_OPEN(name, mode) fopen((name), (mode)) +#endif + + /* functions */ + +#if defined(pyr) || defined(Z_SOLO) +# define NO_MEMCPY +#endif +#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) + /* Use our own functions for small and medium model with MSC <= 5.0. + * You may have to use the same strategy for Borland C (untested). + * The __SC__ check is for Symantec. + */ +# define NO_MEMCPY +#endif +#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) +# define HAVE_MEMCPY +#endif +#ifdef HAVE_MEMCPY +# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ +# define zmemcpy _fmemcpy +# define zmemcmp _fmemcmp +# define zmemzero(dest, len) _fmemset(dest, 0, len) +# else +# define zmemcpy memcpy +# define zmemcmp memcmp +# define zmemzero(dest, len) memset(dest, 0, len) +# endif +#else + void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); + int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); + void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len)); +#endif + +/* Diagnostic functions */ +#ifdef ZLIB_DEBUG +# include + extern int ZLIB_INTERNAL z_verbose; + extern void ZLIB_INTERNAL z_error OF((char *m)); +# define Assert(cond,msg) {if(!(cond)) z_error(msg);} +# define Trace(x) {if (z_verbose>=0) fprintf x ;} +# define Tracev(x) {if (z_verbose>0) fprintf x ;} +# define Tracevv(x) {if (z_verbose>1) fprintf x ;} +# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} +# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} +#else +# define Assert(cond,msg) +# define Trace(x) +# define Tracev(x) +# define Tracevv(x) +# define Tracec(c,x) +# define Tracecv(c,x) +#endif + +#ifndef Z_SOLO + voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items, + unsigned size)); + void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr)); +#endif + +#define ZALLOC(strm, items, size) \ + (*((strm)->zalloc))((strm)->opaque, (items), (size)) +#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) +#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} + +/* Reverse the bytes in a 32-bit value */ +#define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ + (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) + +#endif /* ZUTIL_H */ diff --git a/src/Compressor.cpp b/src/Compressor.cpp index 42b68ec..9733650 100644 --- a/src/Compressor.cpp +++ b/src/Compressor.cpp @@ -1,59 +1,49 @@ /// -/// Created by Anonymous275 on 4/23/2020 +/// Created by Anonymous275 on 7/15/2020 /// - -#include +#include "Zlib/zlib.h" #include -#include "include/zlib.h" - -void Print(const std::string&MSG){ - //std::cout << MSG << std::endl; -} - -std::string Compress(const std::string&Data){ - std::string b; - b.resize(Data.length()); +#define Biggest 30000 +std::string Comp(std::string Data){ + char*C = new char[Biggest]; + memset(C, 0, Biggest); z_stream defstream; defstream.zalloc = Z_NULL; defstream.zfree = Z_NULL; defstream.opaque = Z_NULL; - defstream.avail_in = (uInt)Data.length()+1; + defstream.avail_in = (uInt)Data.length(); defstream.next_in = (Bytef *)&Data[0]; - defstream.avail_out = (uInt)b.size(); - defstream.next_out = (Bytef *)&b[0]; + defstream.avail_out = Biggest; + defstream.next_out = reinterpret_cast(C); deflateInit(&defstream, Z_BEST_COMPRESSION); + deflate(&defstream, Z_SYNC_FLUSH); deflate(&defstream, Z_FINISH); deflateEnd(&defstream); - for(int i = int(b.length())-1;i >= 0;i--){ - if(b.at(i) != '\0'){ - b.resize(i); - break; - } - } - return b; + int TO = defstream.total_out; + std::string Ret(TO,0); + memcpy_s(&Ret[0],TO,C,TO); + delete [] C; + return Ret; } - -std::string Decompress(const std::string&Data) -{ - std::string c; - c.resize(Data.size()*5); +std::string DeComp(std::string Compressed){ + char*C = new char[Biggest]; + memset(C, 0, Biggest); z_stream infstream; infstream.zalloc = Z_NULL; infstream.zfree = Z_NULL; infstream.opaque = Z_NULL; - infstream.avail_in = (uInt)(Data.c_str()); - infstream.next_in = (Bytef *)&Data[0]; - infstream.avail_out = (uInt)c.size(); - infstream.next_out = (Bytef *)&c[0]; + infstream.avail_in = Biggest; + infstream.next_in = (Bytef *)(&Compressed[0]); + infstream.avail_out = Biggest; + infstream.next_out = (Bytef *)(C); inflateInit(&infstream); - inflate(&infstream, Z_NO_FLUSH); + inflate(&infstream, Z_SYNC_FLUSH); + inflate(&infstream, Z_FINISH); inflateEnd(&infstream); - for(int i = int(c.length())-1;i >= 0;i--){ - if(c.at(i) != '\0'){ - c.resize(i+1); - break; - } - } - return c; + int TO = infstream.total_out; + std::string Ret(TO,0); + memcpy_s(&Ret[0],TO,C,TO); + delete [] C; + return Ret; } \ No newline at end of file diff --git a/src/CoreNetwork.cpp b/src/CoreNetwork.cpp deleted file mode 100644 index e9c54b7..0000000 --- a/src/CoreNetwork.cpp +++ /dev/null @@ -1,196 +0,0 @@ -/// -/// Created by Anonymous275 on 4/3/2020 -/// -#include -#include -#include -#include -#include -#include -#include -extern int DEFAULT_PORT; -std::string HTTP_REQUEST(const std::string&url,int port); -void ProxyThread(const std::string& IP, int port); -void Exit(const std::string& Msg); -extern std::string UlStatus; -extern std::string MStatus; -extern int ping; -extern bool Terminate; -extern bool TCPTerminate; -extern bool Dev; -extern std::string ListOfMods; -bool Confirm = false; -void Reset(); -std::set Conf; - -void StartSync(const std::string &Data){ - UlStatus = "UlLoading..."; - Terminate = false; - TCPTerminate = false; - Conf.clear(); - ping = -1; - std::thread t1(ProxyThread,Data.substr(1,Data.find(':')-1),std::stoi(Data.substr(Data.find(':')+1))); - //std::thread t1(ProxyThread,"127.0.0.1",30814); - t1.detach(); -} - -std::string Parse(const std::string& Data){ - char Code = Data.substr(0,1).at(0), SubCode = 0; - if(Data.length() > 1)SubCode = Data.substr(1,1).at(0); - switch (Code){ - case 'A': - return Data.substr(0,1); - case 'B': - Reset(); - Terminate = true; - TCPTerminate = true; - return Code + HTTP_REQUEST("s1.yourthought.co.uk/servers-info",3599); - case 'C': - ListOfMods.clear(); - StartSync(Data); - std::cout << "Connecting to server" << std::endl; - while(ListOfMods.empty() && !Terminate){ - std::this_thread::sleep_for(std::chrono::seconds(1)); - } - if(ListOfMods == "-")return "L"; - else return "L"+ListOfMods; - case 'U': - if(SubCode == 'l')return UlStatus; - if(SubCode == 'p')return "Up" + std::to_string(ping); - if(!SubCode)return UlStatus+ "\n" + "Up" + std::to_string(ping); - case 'M': - return MStatus; - case 'Q': - if(SubCode == 'S'){ - Reset(); - Terminate = true; - TCPTerminate = true; - ping = -1; - } - if(SubCode == 'G')exit(2); - return ""; - case 'R': //will send mod name - if(Conf.find(Data) == Conf.end()){ - Conf.insert(Data); - Confirm = true; - } - return ""; - default: - return ""; - } -} -bool once = false; -[[noreturn]] void MemoryInit(); -[[noreturn]] void CoreNetworkThread(){ - try { - std::cout << "Ready!" << std::endl; - do { - if (Dev)std::cout << "Core Network on start!" << std::endl; - WSADATA wsaData; - int iResult; - SOCKET ListenSocket; - SOCKET ClientSocket; - - struct addrinfo *result = nullptr; - struct addrinfo hints{}; - - int iSendResult; - char recvbuf[64000]; - int recvbuflen = 64000; - - // Initialize Winsock - iResult = WSAStartup(514, &wsaData); //2.2 - if (iResult != 0) { - if (Dev)std::cout << "WSAStartup failed with error: " << iResult << std::endl; - } - - ZeroMemory(&hints, sizeof(hints)); - hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - hints.ai_flags = AI_PASSIVE; - - // Resolve the server address and port - iResult = getaddrinfo(nullptr, std::to_string(DEFAULT_PORT).c_str(), &hints, &result); - if (iResult != 0) { - if (Dev)std::cout << "(Core) getaddrinfo failed with error: " << iResult << std::endl; - WSACleanup(); - } - - // Create a socket for connecting to server - ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol); - if (ListenSocket == -1) { - if (Dev)std::cout << "(Core) socket failed with error: " << WSAGetLastError() << std::endl; - freeaddrinfo(result); - WSACleanup(); - }else{ - iResult = bind(ListenSocket, result->ai_addr, (int) result->ai_addrlen); - if (iResult == SOCKET_ERROR) { - if (Dev)Exit("(Core) bind failed with error: " + std::to_string(WSAGetLastError())); - freeaddrinfo(result); - closesocket(ListenSocket); - WSACleanup(); - } - } - - - iResult = listen(ListenSocket, SOMAXCONN); - if (iResult == SOCKET_ERROR) { - if (Dev)std::cout << "(Core) listen failed with error: " << WSAGetLastError() << std::endl; - closesocket(ListenSocket); - WSACleanup(); - } - ClientSocket = accept(ListenSocket, nullptr, nullptr); - if (ClientSocket == -1) { - if (Dev)std::cout << "(Core) accept failed with error: " << WSAGetLastError() << std::endl; - closesocket(ListenSocket); - WSACleanup(); - } - closesocket(ListenSocket); - if (!once) { - std::thread Memory(MemoryInit); - Memory.detach(); - once = true; - } - do { - std::string Response; - iResult = recv(ClientSocket, recvbuf, recvbuflen, 0); - if (iResult > 0) { - std::string data = recvbuf; - data.resize(iResult); - Response = Parse(data); - } else if (iResult == 0) { - if (Dev)std::cout << "(Core) Connection closing...\n"; - } else { - if (Dev)std::cout << "(Core) recv failed with error: " << WSAGetLastError() << std::endl; - closesocket(ClientSocket); - WSACleanup(); - } - if (!Response.empty()) { - iSendResult = send(ClientSocket, (Response+"\n").c_str(), int(Response.length())+1, 0); - if (iSendResult == SOCKET_ERROR) { - if (Dev)std::cout << "send failed with error: " << WSAGetLastError() << std::endl; - closesocket(ClientSocket); - WSACleanup(); - } else { - ///std::cout << "Bytes sent: " << iSendResult << std::endl; - } - } - } while (iResult > 0); - - iResult = shutdown(ClientSocket, SD_SEND); - if (iResult == SOCKET_ERROR) { - if (Dev)std::cout << "(Core) shutdown failed with error: " << WSAGetLastError() << std::endl; - closesocket(ClientSocket); - WSACleanup(); - Sleep(500); - } - closesocket(ClientSocket); - WSACleanup(); - } while (true); - } catch (std::exception&e) { - std::cout << "Exception! : " << e.what() << std::endl; - system("pause"); - exit(1); - } -} \ No newline at end of file diff --git a/src/Discord.cpp b/src/Discord.cpp index f88cfdf..7ca0205 100644 --- a/src/Discord.cpp +++ b/src/Discord.cpp @@ -1,206 +1,126 @@ /// -/// Created by Anonymous275 on 3/25/2020 +/// Created by Anonymous275 on 7/16/2020 /// - -#define _CRT_SECURE_NO_WARNINGS -#include -#include -#include -#include -#include "include/discord_rpc.h" -#include +#include "Discord/discord_rpc.h" +#include "Security/Enc.h" +#include "Logger.h" +#include #include -#include -#include -#include -extern bool Dev; -extern char*EName; -static const char* APPLICATION_ID = "629743237988352010"; -static int64_t StartTime; -static int SendPresence = 1; -std::vector GlobalInfo; -std::string hta(const std::string& hex); -void SystemExec(const std::string& cmd); -static void updateDiscordPresence() -{ - if (SendPresence) { - char buffer[256]; - DiscordRichPresence discordPresence; - memset(&discordPresence, 0, sizeof(discordPresence)); - discordPresence.state = "Playing with friends!"; - //sprintf(buffer, "Frustration level: %d", FrustrationLevel); - //discordPresence.details = buffer; - discordPresence.startTimestamp = StartTime; - //discordPresence.endTimestamp = time(0) + 5 * 60; - discordPresence.largeImageKey = "mainlogo"; - //discordPresence.smallImageKey = "logo"; - //discordPresence.partyId = "party1234"; - //discordPresence.partySize = 1; - //discordPresence.partyMax = 6; - //discordPresence.matchSecret = "xyzzy"; - //discordPresence.joinSecret = "join"; - //discordPresence.spectateSecret = "look"; - //discordPresence.instance = 0; - Discord_UpdatePresence(&discordPresence); - } - else { - Discord_ClearPresence(); - } +#include +struct DInfo{ + std::string Name; + std::string Tag; + std::string DID; +}; +DInfo* DiscordInfo = nullptr; +void DASM(); +int64_t StartTime; +void updateDiscordPresence(){ + //if (SendPresence) { + //char buffer[256]; + DiscordRichPresence discordPresence; + memset(&discordPresence, 0, sizeof(discordPresence)); + std::string P = Sec("Playing with friends!"); + discordPresence.state = P.c_str(); + //sprintf(buffer, "Frustration level: %d", FrustrationLevel); + //discordPresence.details = buffer; + discordPresence.startTimestamp = StartTime; + //discordPresence.endTimestamp = time(0) + 5 * 60; + std::string L = Sec("mainlogo"); + discordPresence.largeImageKey = L.c_str(); + //discordPresence.smallImageKey = "logo"; + //discordPresence.partyId = "party1234"; + //discordPresence.partySize = 1; + //discordPresence.partyMax = 6; + //discordPresence.matchSecret = "xyzzy"; + //discordPresence.joinSecret = "join"; + //discordPresence.spectateSecret = "look"; + //discordPresence.instance = 0; + Discord_UpdatePresence(&discordPresence); + //} + //else { + // Discord_ClearPresence(); + //} } - -std::string ATH(const std::string& text){ - std::string hex; - for (const char&c : text) { - int des = (int)c; - char*C = new char[5]{0}; - _itoa_s(des,C,5,16); - hex += C; - delete[] C; - } - return hex; +void handleDiscordReady(const DiscordUser* User){ + DiscordInfo = new DInfo{ + LocalEnc(User->username), + LocalEnc(User->discriminator), + LocalEnc(User->userId) + }; } - -static void handleDiscordReady(const DiscordUser* connectedUser) -{ - /*printf("\nDiscord: connected to user %s#%s - %s\n", - connectedUser->username, - connectedUser->discriminator, - connectedUser->userId);*/ - GlobalInfo.emplace_back(connectedUser->username); - GlobalInfo.emplace_back(ATH(connectedUser->discriminator)); - GlobalInfo.emplace_back(ATH(connectedUser->userId)); - GlobalInfo.emplace_back(connectedUser->userId); -} - -static void handleDiscordDisconnected(int errcode, const char* message) -{ - if(Dev)printf("\nDiscord: disconnected (%d: %s)\n", errcode, message); -} - -static void handleDiscordError(int errcode, const char* message) -{ - if(Dev)printf("\nDiscord: error (%d: %s)\n", errcode, message); -} - -static void handleDiscordJoin(const char* secret) -{ - if(Dev)printf("\nDiscord: join (%s)\n", secret); -} - -static void handleDiscordSpectate(const char* secret) -{ - if(Dev)printf("\nDiscord: spectate (%s)\n", secret); -} - -static void handleDiscordJoinRequest(const DiscordUser* request) -{ - /* int response = -1; - char yn[4]; - printf("\nDiscord: join request from %s#%s - %s\n", - request->username, - request->discriminator, - request->userId); - do { - printf("Accept? (y/n)"); - if (!prompt(yn, sizeof(yn))) { - break; - } - - if (!yn[0]) { - continue; - } - - if (yn[0] == 'y') { - response = DISCORD_REPLY_YES; - break; - } - - if (yn[0] == 'n') { - response = DISCORD_REPLY_NO; - break; - } - } while (1); - if (response != -1) { - Discord_Respond(request->userId, response); - }*/ -} - - -static void discordInit() -{ +void discordInit(){ DiscordEventHandlers handlers; memset(&handlers, 0, sizeof(handlers)); handlers.ready = handleDiscordReady; - handlers.disconnected = handleDiscordDisconnected; + /*handlers.disconnected = handleDiscordDisconnected; handlers.errored = handleDiscordError; handlers.joinGame = handleDiscordJoin; handlers.spectateGame = handleDiscordSpectate; - handlers.joinRequest = handleDiscordJoinRequest; - Discord_Initialize(APPLICATION_ID, &handlers, 1,nullptr); + handlers.joinRequest = handleDiscordJoinRequest;*/ + std::string a = Sec("629743237988352010"); + Discord_Initialize(a.c_str(), &handlers, 1,nullptr); } - -[[noreturn]] static void Loop() -{ - char line[512]; - char* space; - - StartTime = time(0); - +[[noreturn]] void Loop(){ + StartTime = time(nullptr); while (true) { updateDiscordPresence(); - -#ifdef DISCORD_DISABLE_IO_THREAD - Discord_UpdateConnection(); -#endif + #ifdef DISCORD_DISABLE_IO_THREAD + Discord_UpdateConnection(); + #endif Discord_RunCallbacks(); - if(GlobalInfo.empty()){ + if(DiscordInfo == nullptr){ std::this_thread::sleep_for(std::chrono::milliseconds(250)); - }else std::this_thread::sleep_for(std::chrono::milliseconds(2000)); + }else std::this_thread::sleep_for(std::chrono::seconds(2)); } } - -void SecurityCheck2(){ - int i = 0; - std::ifstream f(hta(EName), std::ios::binary); - f.seekg(0, std::ios_base::end); - std::streampos fileSize = f.tellg(); - if(IsDebuggerPresent() || fileSize > 0x60B5F){ - i++; - GlobalInfo.clear(); - } - if(i)GlobalInfo.clear(); - f.close(); -} - [[noreturn]] void SecurityLoop(){ - static std::string t; - static std::string t1; - static std::string t2; - t.clear(); - t1.clear(); - t2.clear(); + std::string t,t1,t2; while(true){ - if(!GlobalInfo.empty() && GlobalInfo.size() == 4){ + if(DiscordInfo != nullptr){ if(t.empty()){ - t = GlobalInfo.at(0); - t1 = GlobalInfo.at(1); - t2 = GlobalInfo.at(2); - }else if(t2 != ATH(GlobalInfo.at(3)) || t != GlobalInfo.at(0) || - t1 != GlobalInfo.at(1) || t2 != GlobalInfo.at(2))exit(0); - } - SecurityCheck2(); - if(IsDebuggerPresent())GlobalInfo.clear(); + t = LocalDec(DiscordInfo->Name); + t1 = LocalDec(DiscordInfo->Tag); + t2 = LocalDec(DiscordInfo->DID); + }else if(t2 != LocalDec(DiscordInfo->DID) || + t != LocalDec(DiscordInfo->Name) || t1 != LocalDec(DiscordInfo->Tag))DiscordInfo = nullptr; + }else if(!t.empty())DiscordInfo->DID.clear(); + DASM(); std::this_thread::sleep_for(std::chrono::milliseconds(500)); } } - - -void Discord_Main(){ +void DMain(){ auto*S = new std::thread(SecurityLoop); S->detach(); delete S; discordInit(); Loop(); - Discord_Shutdown(); } - +std::string GetDName(){ + return LocalDec(DiscordInfo->Name); +} +std::string GetDTag(){ + return LocalDec(DiscordInfo->Tag); +} +std::string GetDID(){ + return LocalDec(DiscordInfo->DID); +} +void DAboard(){ + DiscordInfo = nullptr; +} +void ErrorAboard(){ + error(Sec("Discord timeout! please start the discord app and try again after 30 secs")); + std::this_thread::sleep_for(std::chrono::seconds(5)); + exit(6); +} +void Discord_Main(){ + std::thread t1(DMain); + t1.detach(); + info(Sec("Connecting to discord client...")); + int C = 0; + while(DiscordInfo == nullptr && C < 80){ + std::this_thread::sleep_for(std::chrono::milliseconds(300)); + C++; + } + if(DiscordInfo == nullptr)ErrorAboard(); +} diff --git a/src/GameStart.cpp b/src/GameStart.cpp index b31b5fd..fdc1554 100644 --- a/src/GameStart.cpp +++ b/src/GameStart.cpp @@ -1,55 +1,78 @@ /// -/// Created by Anonymous275 on 5/2/2020 +/// Created by Anonymous275 on 7/19/2020 /// +#include "Security/Enc.h" #include +#include "Startup.h" +#include "Logger.h" #include #include - +unsigned long GamePID = 0; std::string QueryKey(HKEY hKey,int ID); -void SystemExec(const std::string&cmd); -void Exit(const std::string& Msg); - +void DeleteKey(){ + HKEY hKey; + LPCTSTR sk = Sec("Software\\BeamNG\\BeamNG.drive"); + RegOpenKeyEx(HKEY_CURRENT_USER, sk, 0, KEY_ALL_ACCESS, &hKey); + RegDeleteValueA(hKey, Sec("userpath_override")); +} std::string Write(const std::string&Path){ HKEY hKey; - LPCTSTR sk = TEXT("Software\\BeamNG\\BeamNG.drive"); + LPCTSTR sk = Sec("Software\\BeamNG\\BeamNG.drive"); LONG openRes = RegOpenKeyEx(HKEY_CURRENT_USER, sk, 0, KEY_ALL_ACCESS, &hKey); - if (openRes != ERROR_SUCCESS)Exit("Error! Please launch the game at least once"); + if (openRes != ERROR_SUCCESS){ + error(Sec("Please launch the game at least once")); + std::this_thread::sleep_for(std::chrono::seconds(5)); + exit(5); + } std::string Query = QueryKey(hKey,4); - LONG setRes = RegSetValueEx(hKey, TEXT("userpath_override"), 0, REG_SZ, (LPBYTE)Path.c_str(), Path.size()); - if(setRes != ERROR_SUCCESS)Exit("Error! Failed to launch the game code 1"); + LONG setRes = RegSetValueEx(hKey, Sec("userpath_override"), 0, REG_SZ, (LPBYTE)Path.c_str(), DWORD(Path.size())); + if(setRes != ERROR_SUCCESS){ + error(Sec("Failed to launch the game")); + std::this_thread::sleep_for(std::chrono::seconds(5)); + exit(5); + } RegCloseKey(hKey); return Query; } -void DeleteKey(){ - HKEY hKey; - LPCTSTR sk = TEXT("Software\\BeamNG\\BeamNG.drive"); - RegOpenKeyEx(HKEY_CURRENT_USER, sk, 0, KEY_ALL_ACCESS, &hKey); - RegDeleteValueA(hKey, TEXT("userpath_override")); -} void RollBack(const std::string&Val,int T){ std::this_thread::sleep_for(std::chrono::seconds(T)); - if(!Val.empty())Write(Val); - else DeleteKey(); + if(!Val.empty()){ + if(Write(Val) == Val)DeleteKey(); + }else DeleteKey(); } - -void SetPID(DWORD PID); -void StartGame(const std::string&ExeDir,const std::string&Current){ +std::string Restore; +void OnExit(){ + RollBack(Restore,0); +} +void StartGame(std::string Dir,std::string Current){ + Current = Current.substr(0,Current.find_last_of('\\')) + Sec("\\BeamNG\\"); BOOL bSuccess = FALSE; PROCESS_INFORMATION pi; STARTUPINFO si = {0}; si.cb = sizeof(si); - std::string BaseDir = ExeDir.substr(0,ExeDir.find_last_of('\\')); - bSuccess = CreateProcessA(ExeDir.c_str(), nullptr, nullptr, nullptr, TRUE, 0, nullptr, BaseDir.c_str(), &si, &pi); - if (bSuccess) - { - std::cout << "Game Launched!\n"; - SetPID(pi.dwProcessId); - std::thread RB(RollBack,Write(Current),7); + std::string BaseDir = Dir + Sec("\\Bin64"); + Dir += Sec(R"(\Bin64\BeamNG.drive.x64.exe)"); + bSuccess = CreateProcessA(Dir.c_str(), nullptr, nullptr, nullptr, TRUE, 0, nullptr, BaseDir.c_str(), &si, &pi); + if (bSuccess){ + info(Sec("Game Launched!")); + GamePID = pi.dwProcessId; + Restore = Write(Current); + atexit(OnExit); + std::thread RB(RollBack,Restore,7); RB.detach(); WaitForSingleObject(pi.hProcess, INFINITE); - std::cout << "\nGame Closed! launcher closing in 5 secs\n"; - }else std::cout << "\nFailed to Launch the game! launcher closing in 5 secs\n"; - RollBack(Write(Current),0); + error(Sec("Game Closed! launcher closing soon")); + RollBack(Restore,0); + }else{ + error(Sec("Failed to Launch the game! launcher closing soon")); + RollBack(Write(Current),0); + } std::this_thread::sleep_for(std::chrono::seconds(5)); exit(2); -} \ No newline at end of file +} +void InitGame(const std::string& Dir,const std::string&Current){ + if(!Dev){ + std::thread Game(StartGame, Dir, Current); + Game.detach(); + } +} diff --git a/src/Logger.cpp b/src/Logger.cpp new file mode 100644 index 0000000..65b2020 --- /dev/null +++ b/src/Logger.cpp @@ -0,0 +1,80 @@ +/// +/// Created by Anonymous275 on 7/17/2020 +/// +#include "Security/Enc.h" +#include "Startup.h" +#include "Logger.h" +#include +#include +#include +std::string getDate() { + typedef std::chrono::duration>::type> days; + std::chrono::system_clock::time_point now = std::chrono::system_clock::now(); + std::chrono::system_clock::duration tp = now.time_since_epoch(); + days d = std::chrono::duration_cast(tp);tp -= d; + auto h = std::chrono::duration_cast(tp);tp -= h; + auto m = std::chrono::duration_cast(tp);tp -= m; + auto s = std::chrono::duration_cast(tp);tp -= s; + time_t tt = std::chrono::system_clock::to_time_t(now); + tm local_tm{}; + localtime_s(&local_tm,&tt); + std::stringstream date; + int S = local_tm.tm_sec; + int M = local_tm.tm_min; + int H = local_tm.tm_hour; + std::string Secs = (S > 9 ? std::to_string(S) : "0" + std::to_string(S)); + std::string Min = (M > 9 ? std::to_string(M) : "0" + std::to_string(M)); + std::string Hour = (H > 9 ? std::to_string(H) : "0" + std::to_string(H)); + date + << "[" + << local_tm.tm_mday << "/" + << local_tm.tm_mon + 1 << "/" + << local_tm.tm_year + 1900 << " " + << Hour << ":" + << Min << ":" + << Secs + << "] "; + return date.str(); +} +void InitLog(){ + std::ofstream LFS; + LFS.open (Sec("Launcher.log")); + if(!LFS.is_open()){ + error(Sec("logger file init failed!")); + }else LFS.close(); +} +void addToLog(const std::string& Line){ + std::ofstream LFS; + LFS.open (Sec("Launcher.log"), std::ios_base::app); + LFS << Line.c_str(); + LFS.close(); +} +void info(const std::string& toPrint) { + std::string Print = getDate() + Sec("[INFO] ") + toPrint + "\n"; + std::cout << Print; + addToLog(Print); +} +void debug(const std::string& toPrint) { + if(!Dev)return; + std::string Print = getDate() + Sec("[DEBUG] ") + toPrint + "\n"; + std::cout << Print; + addToLog(Print); +} +void warn(const std::string& toPrint){ + std::string Print = getDate() + Sec("[WARN] ") + toPrint + "\n"; + std::cout << Print; + addToLog(Print); +} +void error(const std::string& toPrint) { + static int ECounter = 0; + std::string Print = getDate() + Sec("[ERROR] ") + toPrint + "\n"; + std::cout << Print; + addToLog(Print); + if(ECounter > 10)exit(7); + ECounter++; +} +void except(const std::string& toPrint) { + std::string Print = getDate() + Sec("[EXCEP] ") + toPrint + "\n"; + std::cout << Print; + addToLog(Print); +} diff --git a/src/Memory/Memory.cpp b/src/Memory/Memory.cpp index 7194369..76c8b21 100644 --- a/src/Memory/Memory.cpp +++ b/src/Memory/Memory.cpp @@ -31,8 +31,7 @@ int Memory::GetProcessId(const std::string& processName) { return pe32.th32ProcessID; } -long long Memory::GetModuleBase(HANDLE processHandle, const std::string &sModuleName) -{ +long long Memory::GetModuleBase(HANDLE processHandle, const std::string &sModuleName){ HMODULE *hModules = nullptr; char szBuf[50]; DWORD cModules; @@ -74,8 +73,7 @@ void PrintAllBases(HANDLE processHandle){ delete[] hModules; } -BOOL Memory::SetPrivilege(HANDLE hToken, LPCTSTR lpszPrivilege, BOOL bEnablePrivilege) -{ +BOOL Memory::SetPrivilege(HANDLE hToken, LPCTSTR lpszPrivilege, BOOL bEnablePrivilege){ TOKEN_PRIVILEGES tp; LUID luid; @@ -215,7 +213,7 @@ double Memory::ReadPointerDouble(HANDLE processHandle, long long startAddress, i std::string Memory::ReadText(HANDLE processHandle, long long address) { if (address == -1) return "-1"; - char buffer = !0; + char buffer = 1; char* stringToRead = new char[128]; SIZE_T NumberOfBytesToRead = sizeof(buffer); SIZE_T NumberOfBytesActuallyRead; diff --git a/src/Memory/Memory.hpp b/src/Memory/Memory.hpp index d942a4c..e6e648e 100644 --- a/src/Memory/Memory.hpp +++ b/src/Memory/Memory.hpp @@ -9,8 +9,7 @@ #include #include -class Memory -{ +class Memory{ public: DWORD PID = 0; int GetProcessId(const std::string& processName); diff --git a/src/Memory/Reader.cpp b/src/Memory/Reader.cpp index 6635478..1916f14 100644 --- a/src/Memory/Reader.cpp +++ b/src/Memory/Reader.cpp @@ -1,11 +1,14 @@ /// /// Created by Anonymous275 on 6/17/2020 /// +#include "Network/network.h" +#include "Security/Game.h" +#include "Security/Enc.h" #include "Memory.hpp" +#include "Startup.h" #include #include -extern std::string MStatus; -extern bool Dev; + Memory Game; std::string GameVer(HANDLE processHandle, long long Address){ //lib_Beam @@ -15,15 +18,16 @@ std::string GameVer(HANDLE processHandle, long long Address){ } std::string LoadedMap(HANDLE processHandle, long long Address){ //lib_Beam - Address += 0x1B0688; - std::vector Off = {0x2F8,0x0}; + //History : 0x1B0688 + Address += 0x1A1668; + std::vector Off = {0x140,0x0}; return Game.ReadPointerText(processHandle,Address,Off); } -void SetPID(DWORD PID){ - Game.PID = PID; -} -[[noreturn]] void MemoryInit(){ - if(Game.PID == 0 && !Dev)exit(4); + +void MemoryInit(){ + if(Dev)return; + Game.PID = GamePID; + if(Game.PID == 0)exit(4); HANDLE processHandle; long long ExeBase; //BeamNG.drive.x64.exe long long Lib1 = 0x180000000; //libbeamng.x64.dll Contains Vehicle Data diff --git a/src/Network 2.0/GlobalHandler.cpp b/src/Network 2.0/GlobalHandler.cpp deleted file mode 100644 index 6cfe5d2..0000000 --- a/src/Network 2.0/GlobalHandler.cpp +++ /dev/null @@ -1,249 +0,0 @@ -//// -//// Created by Anonymous275 on 3/3/2020. -//// -#include -#include -#include -#include -#include -#include - -int ClientID = -1; -extern int DEFAULT_PORT; -std::chrono::time_point PingStart,PingEnd; -bool TCPTerminate = false; -bool Terminate = false; -bool CServer = true; -bool gameConected = false; -SOCKET ClientSocket; -extern bool Dev; -int ping = -1; - -void GameSend(const std::string&Data){ - if(TCPTerminate || !gameConected || ClientSocket == -1)return; - int iSendResult = send(ClientSocket, (Data + "\n").c_str(), int(Data.length()) + 1, 0); - if (iSendResult == SOCKET_ERROR) { - if (Dev)std::cout << "(Proxy) send failed with error: " << WSAGetLastError() << std::endl; - } else { - if (Dev && Data.length() > 1000) { - std::cout << "(Launcher->Game) Bytes sent: " << iSendResult << std::endl; - } - //std::cout << "(Launcher->Game) Bytes sent: " << iSendResult << " : " << Data << std::endl; - } -} -void SendLarge(const std::string&Data); -void TCPSend(const std::string&Data); -void UDPSend(const std::string&Data); -void ServerSend(const std::string&Data, bool Rel){ - if(Terminate || Data.empty())return; - char C = 0; - bool Ack = false; - if(Data.length() > 3)C = Data.at(0); - if (C == 'O' || C == 'T' || C == 'C')Ack = true; - if(Ack || Rel){ - if(Ack || Data.length() > 1000)SendLarge(Data); - else TCPSend(Data); - }else UDPSend(Data); - - if (Dev && Data.length() > 1000) { - std::cout << "(Launcher->Server) Bytes sent: " + std::to_string(Data.length()) + " : " - + Data.substr(0, 10) - + Data.substr(Data.length() - 10) + "\n"; - }else if(Dev && C == 'Z'){ - //std::cout << "(Game->Launcher) : " << Data << std::endl; - } -} - - -void AutoPing(){ - while(!Terminate){ - ServerSend("p",false); - PingStart = std::chrono::high_resolution_clock::now(); - std::this_thread::sleep_for(std::chrono::seconds (1)); - } -} - -std::string UlStatus = "Ulstart"; -std::string MStatus = " "; -void ServerParser(const std::string& Data){ - if(Data.empty())return; - char Code = Data.at(0),SubCode = 0; - if(Data.length() > 1)SubCode = Data.at(1); - switch (Code) { - case 'P': - ClientID = std::stoi(Data.substr(1)); - break; - case 'p': - PingEnd = std::chrono::high_resolution_clock::now(); - ping = std::chrono::duration_cast(PingEnd-PingStart).count(); - return; - case 'M': - MStatus = Data; - UlStatus = "Uldone"; - return; - } - GameSend(Data); -} - -void TCPClientMain(const std::string& IP,int Port); -void UDPClientMain(const std::string& IP,int Port); -void NetMain(const std::string& IP, int Port){ - std::thread Ping(AutoPing); - Ping.detach(); - UDPClientMain(IP,Port); - CServer = true; - Terminate = true; - std::cout << "Connection Terminated!" << std::endl; -} -extern SOCKET UDPSock; -extern SOCKET TCPSock; -void Reset(){ - TCPTerminate = false; - gameConected = false; - Terminate = false; - UlStatus = "Ulstart"; - MStatus = " "; - if(UDPSock != SOCKET_ERROR)closesocket(UDPSock); - UDPSock = -1; - if(TCPSock != SOCKET_ERROR)closesocket(TCPSock); - TCPSock = -1; -} -std::string Compress(const std::string&Data); -std::string Decompress(const std::string&Data); -void TCPGameServer(const std::string& IP, int Port){ - if(Dev)std::cout << "Game server Started! " << IP << ":" << Port << std::endl; - do { - Reset(); - if(CServer) { - std::thread Client(TCPClientMain, IP, Port); - Client.detach(); - } - if(Dev)std::cout << "Game server on Start" << std::endl; - WSADATA wsaData; - int iResult; - SOCKET ListenSocket = INVALID_SOCKET; - SOCKET Socket = INVALID_SOCKET; - - struct addrinfo *result = nullptr; - struct addrinfo hints{}; - char recvbuf[10000]; - int recvbuflen = 10000; - - // Initialize Winsock - iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); - if (iResult != 0) { - if(Dev)std::cout << "(Proxy) WSAStartup failed with error: " << iResult << std::endl; - exit(-1); - } - - ZeroMemory(&hints, sizeof(hints)); - hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - hints.ai_flags = AI_PASSIVE; - // Resolve the server address and port - iResult = getaddrinfo(nullptr, std::to_string(DEFAULT_PORT+1).c_str(), &hints, &result); - if (iResult != 0) { - if(Dev)std::cout << "(Proxy) getaddrinfo failed with error: " << iResult << std::endl; - WSACleanup(); - break; - } - - // Create a socket for connecting to server - ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol); - if (ListenSocket == INVALID_SOCKET) { - if(Dev)std::cout << "(Proxy) socket failed with error: " << WSAGetLastError() << std::endl; - freeaddrinfo(result); - WSACleanup(); - break; - } - - // Setup the TCP listening socket - iResult = bind(ListenSocket, result->ai_addr, (int) result->ai_addrlen); - if (iResult == SOCKET_ERROR) { - if(Dev)std::cout << "(Proxy) bind failed with error: " << WSAGetLastError() << std::endl; - freeaddrinfo(result); - closesocket(ListenSocket); - WSACleanup(); - break; - } - - freeaddrinfo(result); - - iResult = listen(ListenSocket, SOMAXCONN); - if (iResult == SOCKET_ERROR) { - if(Dev)std::cout << "(Proxy) listen failed with error: " << WSAGetLastError() << std::endl; - closesocket(ListenSocket); - WSACleanup(); - continue; - } - Socket = accept(ListenSocket, nullptr, nullptr); - if (Socket == INVALID_SOCKET) { - if(Dev)std::cout << "(Proxy) accept failed with error: " << WSAGetLastError() << std::endl; - closesocket(ListenSocket); - WSACleanup(); - continue; - } - closesocket(ListenSocket); - if(Dev)std::cout << "(Proxy) Game Connected!" << std::endl; - gameConected = true; - if(CServer){ - std::thread t1(NetMain, IP, Port); - t1.detach(); - CServer = false; - } - - ClientSocket = Socket; - do { - //std::cout << "(Proxy) Waiting for Game Data..." << std::endl; - iResult = recv(Socket, recvbuf, recvbuflen, 0); - if (iResult > 0) { - std::string buff; - buff.resize(iResult*2); - memcpy(&buff[0],recvbuf,iResult); - buff.resize(iResult); - - ServerSend(buff,false); - - } else if (iResult == 0) { - if(Dev)std::cout << "(Proxy) Connection closing...\n"; - closesocket(Socket); - WSACleanup(); - Terminate = true; - continue; - } else { - if(Dev)std::cout << "(Proxy) recv failed with error: " << WSAGetLastError() << std::endl; - closesocket(Socket); - WSACleanup(); - continue; - } - } while (iResult > 0); - - iResult = shutdown(Socket, SD_SEND); - if (iResult == SOCKET_ERROR) { - if(Dev)std::cout << "(Proxy) shutdown failed with error: " << WSAGetLastError() << std::endl; - TCPTerminate = true; - Terminate = true; - closesocket(Socket); - WSACleanup(); - continue; - } - closesocket(Socket); - WSACleanup(); - }while (!TCPTerminate); -} - -void VehicleNetworkStart(); -void CoreNetworkThread(); -void ProxyStart(){ - std::thread t1(CoreNetworkThread); - if(Dev)std::cout << "Core Network Started!\n"; - t1.join(); -} - -void ProxyThread(const std::string& IP, int Port){ - std::thread GameThread(TCPGameServer,IP,Port); - GameThread.detach(); - /*std::thread t2(VehicleNetworkStart); - t2.detach();*/ -} \ No newline at end of file diff --git a/src/Network/Core.cpp b/src/Network/Core.cpp new file mode 100644 index 0000000..44895a3 --- /dev/null +++ b/src/Network/Core.cpp @@ -0,0 +1,198 @@ +/// +/// Created by Anonymous275 on 7/20/2020 +/// +#include "Network/network.h" +#include "Security/Enc.h" +#include "Curl/http.h" +#include +#include +#include "Memory.h" +#include "Logger.h" +#include +#include +std::set* ConfList = nullptr; +bool TCPTerminate = false; +int DEFAULT_PORT = 4444; +bool Terminate = false; +std::string UlStatus; +std::string MStatus; +bool once = false; +bool ModLoaded; +long long ping = -1; +void StartSync(const std::string &Data){ + UlStatus = Sec("UlLoading..."); + TCPTerminate = false; + Terminate = false; + ConfList->clear(); + ping = -1; + std::thread GS(TCPGameServer,Data.substr(1,Data.find(':')-1),std::stoi(Data.substr(Data.find(':')+1))); + GS.detach(); +} +void Parse(std::string Data,SOCKET CSocket){ + char Code = Data.at(0), SubCode = 0; + if(Data.length() > 1)SubCode = Data.at(1); + switch (Code){ + case 'A': + Data = Data.substr(0,1); + break; + case 'B': + NetReset(); + Terminate = true; + TCPTerminate = true; + //if(!Dev){ + Data = Code + HTTP_REQUEST(Sec("s1.yourthought.co.uk/servers-info"),3599); + //}else Data.clear(); + break; + case 'C': + ListOfMods.clear(); + StartSync(Data); + info(Sec("Connecting to server")); + while(ListOfMods.empty() && !Terminate){ + std::this_thread::sleep_for(std::chrono::seconds(1)); + } + if(ListOfMods == "-")Data = "L"; + else Data = "L"+ListOfMods; + break; + case 'U': + if(SubCode == 'l')Data = UlStatus; + if(SubCode == 'p')Data = "Up" + std::to_string(ping); + if(!SubCode)Data = std::string(UlStatus) + "\n" + "Up" + std::to_string(ping); + break; + case 'M': + Data = MStatus; + break; + case 'Q': + if(SubCode == 'S'){ + NetReset(); + Terminate = true; + TCPTerminate = true; + ping = -1; + } + if(SubCode == 'G')exit(2); + Data.clear(); + break; + case 'R': //will send mod name + if(ConfList->find(Data) == ConfList->end()){ + ConfList->insert(Data); + ModLoaded = true; + } + Data.clear(); + break; + default: + Data.clear(); + break; + } + if(!Data.empty() && CSocket != -1){ + int res = send(CSocket, (Data+"\n").c_str(), int(Data.size())+1, 0); + if(res < 0){ + debug(Sec("(Core) send failed with error: ") + std::to_string(WSAGetLastError())); + } + } +} +void GameHandler(SOCKET Client){ + if (!once){ + std::thread Memory(MemoryInit); + Memory.detach(); + once = true; + } + char buf[64000]; + int res,len = 64000; + do{ + res = recv(Client, buf, len, 0); + if(res < 1)break; + std::string data(buf, res); + std::thread Respond(Parse, data, Client); + Respond.detach(); + }while(res > 0); + if (res == 0) { + debug(Sec("(Core) Connection closing")); + } else { + debug(Sec("(Core) recv failed with error: ") + std::to_string(WSAGetLastError())); + } + closesocket(Client); +} +void localRes(){ + MStatus = " "; + UlStatus = Sec("Ulstart"); + if(ConfList != nullptr){ + ConfList->clear(); + delete ConfList; + ConfList = nullptr; + } + ConfList = new std::set; +} +void CoreMain() { + debug(Sec("Core Network on start!")); + WSADATA wsaData; + SOCKET LSocket,CSocket; + struct addrinfo *res = nullptr; + struct addrinfo hints{}; + int iRes = WSAStartup(514, &wsaData); //2.2 + if (iRes)debug(Sec("WSAStartup failed with error: ") + std::to_string(iRes)); + ZeroMemory(&hints, sizeof(hints)); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + hints.ai_flags = AI_PASSIVE; + iRes = getaddrinfo(nullptr, std::to_string(DEFAULT_PORT).c_str(), &hints, &res); + if (iRes){ + debug(Sec("(Core) addr info failed with error: ") + std::to_string(iRes)); + WSACleanup(); + return; + } + LSocket = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + if (LSocket == -1){ + debug(Sec("(Core) socket failed with error: ") + std::to_string(WSAGetLastError())); + freeaddrinfo(res); + WSACleanup(); + return; + } + iRes = bind(LSocket, res->ai_addr, int(res->ai_addrlen)); + if (iRes == SOCKET_ERROR) { + error(Sec("(Core) bind failed with error: ") + std::to_string(WSAGetLastError())); + freeaddrinfo(res); + closesocket(LSocket); + WSACleanup(); + return; + } + iRes = listen(LSocket, SOMAXCONN); + if (iRes == SOCKET_ERROR) { + debug(Sec("(Core) listen failed with error: ") + std::to_string(WSAGetLastError())); + freeaddrinfo(res); + closesocket(LSocket); + WSACleanup(); + return; + } + do{ + CSocket = accept(LSocket, nullptr, nullptr); + if (CSocket == -1) { + error(Sec("(Core) accept failed with error: ") + std::to_string(WSAGetLastError())); + continue; + } + localRes(); + info(Sec("Game Connected!")); + GameHandler(CSocket); + warn(Sec("Game Reconnecting...")); + }while(CSocket); + closesocket(LSocket); + WSACleanup(); +} +int Handle(EXCEPTION_POINTERS *ep){ + char* hex = new char[100]; + sprintf_s(hex,100, "%lX", ep->ExceptionRecord->ExceptionCode); + except(Sec("(Core) Code : ") + std::string(hex)); + delete [] hex; + return 1; +} +[[noreturn]] void CoreNetwork(){ + while(true){ + __try{ + CoreMain(); + }__except(Handle(GetExceptionInformation())){} + std::this_thread::sleep_for(std::chrono::seconds(1)); + } +} + + + + diff --git a/src/Network/GlobalHandler.cpp b/src/Network/GlobalHandler.cpp new file mode 100644 index 0000000..88afdb2 --- /dev/null +++ b/src/Network/GlobalHandler.cpp @@ -0,0 +1,202 @@ +/// +/// Created by Anonymous275 on 7/25/2020 +/// +#include "Network/network.h" +#include "Security/Enc.h" +#include +#include +#include "Logger.h" +#include +#include +#include +std::chrono::time_point PingStart,PingEnd; +bool GConnected = false; +bool CServer = true; +extern SOCKET UDPSock; +extern SOCKET TCPSock; +SOCKET CSocket; +void GameSend(const std::string&Data){ + if(TCPTerminate || !GConnected || CSocket == -1)return; + int iSRes = send(CSocket, (Data + "\n").c_str(), int(Data.size()) + 1, 0); + if (iSRes == SOCKET_ERROR) { + debug(Sec("(Proxy) send failed with error: ") + std::to_string(WSAGetLastError())); + } else if (Data.length() > 1000){ + debug(Sec("(Launcher->Game) Bytes sent: ") + std::to_string(iSRes)); + } +} +void ServerSend(std::string Data, bool Rel){ + if(Terminate || Data.empty())return; + char C = 0; + bool Ack = false; + int DLen = int(Data.length()); + if(DLen > 3)C = Data.at(0); + if (C == 'O' || C == 'T')Ack = true; + if(Ack || Rel){ + if(Ack || DLen > 1000)SendLarge(Data); + else TCPSend(Data); + }else UDPSend(Data); + + if (DLen > 1000) { + debug(Sec("(Launcher->Server) Bytes sent: ") + std::to_string(Data.length()) + " : " + + Data.substr(0, 10) + + Data.substr(Data.length() - 10)); + }else if(C == 'Z'){ + //debug("(Game->Launcher) : " + Data); + } +} +void NetReset(){ + TCPTerminate = false; + GConnected = false; + Terminate = false; + UlStatus = Sec("Ulstart"); + MStatus = " "; + if(UDPSock != SOCKET_ERROR)closesocket(UDPSock); + UDPSock = -1; + if(TCPSock != SOCKET_ERROR)closesocket(TCPSock); + TCPSock = -1; + ClearAll(); +} + +SOCKET SetupListener(){ + static SOCKET LSocket = -1; + if(LSocket != -1)return LSocket; + struct addrinfo *result = nullptr; + struct addrinfo hints{}; + WSADATA wsaData; + int iRes = WSAStartup(514, &wsaData); //2.2 + if (iRes != 0) { + error(Sec("(Proxy) WSAStartup failed with error: ") + std::to_string(iRes)); + return -1; + } + ZeroMemory(&hints, sizeof(hints)); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + hints.ai_flags = AI_PASSIVE; + iRes = getaddrinfo(nullptr, std::to_string(DEFAULT_PORT+1).c_str(), &hints, &result); + if (iRes != 0) { + error(Sec("(Proxy) info failed with error: ") + std::to_string(iRes)); + WSACleanup(); + } + LSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol); + if (LSocket == -1) { + error(Sec("(Proxy) socket failed with error: ") + std::to_string(WSAGetLastError())); + freeaddrinfo(result); + WSACleanup(); + return -1; + } + iRes = bind(LSocket, result->ai_addr, (int) result->ai_addrlen); + if (iRes == SOCKET_ERROR) { + error(Sec("(Proxy) bind failed with error: ") + std::to_string(WSAGetLastError())); + freeaddrinfo(result); + closesocket(LSocket); + WSACleanup(); + return -1; + } + freeaddrinfo(result); + iRes = listen(LSocket, SOMAXCONN); + if (iRes == SOCKET_ERROR) { + error(Sec("(Proxy) listen failed with error: ") + std::to_string(WSAGetLastError())); + closesocket(LSocket); + WSACleanup(); + return -1; + } + return LSocket; +} +void AutoPing(){ + while(!Terminate){ + ServerSend(Sec("p"),false); + PingStart = std::chrono::high_resolution_clock::now(); + std::this_thread::sleep_for(std::chrono::seconds (1)); + } +} +int ClientID = -1; +void ParserAsync(const std::string& Data){ + if(Data.empty())return; + char Code = Data.at(0),SubCode = 0; + if(Data.length() > 1)SubCode = Data.at(1); + switch (Code) { + case 'P': + ClientID = std::stoi(Data.substr(1)); + break; + case 'p': + PingEnd = std::chrono::high_resolution_clock::now(); + if(PingStart > PingEnd)ping = 0; + else ping = std::chrono::duration_cast(PingEnd-PingStart).count(); + return; + case 'M': + MStatus = Data; + UlStatus = Sec("Uldone"); + return; + default: + break; + } + GameSend(Data); +} +void ServerParser(const std::string& Data){ + std::thread Async(ParserAsync,Data); + Async.detach(); +} +void NetMain(const std::string& IP, int Port){ + std::thread Ping(AutoPing); + Ping.detach(); + UDPClientMain(IP,Port); + CServer = true; + Terminate = true; + info(Sec("Connection Terminated!")); +} +void TCPGameServer(const std::string& IP, int Port){ + SOCKET LSocket = SetupListener(); + while (!TCPTerminate && LSocket != -1){ + GConnected = false; + if(!CServer){ + warn(Sec("Connection still alive terminating")); + NetReset(); + TCPTerminate = true; + Terminate = true; + break; + } + if(CServer) { + std::thread Client(TCPClientMain, IP, Port); + Client.detach(); + } + CSocket = accept(LSocket, nullptr, nullptr); + if (CSocket == -1) { + error(Sec("(Proxy) accept failed with error: ") + std::to_string(WSAGetLastError())); + break; + } + debug(Sec("(Proxy) Game Connected!")); + GConnected = true; + if(CServer){ + std::thread t1(NetMain, IP, Port); + t1.detach(); + CServer = false; + } + char buf[10000]; + int Res,len = 10000; + ZeroMemory(buf, len); + do{ + Res = recv(CSocket,buf,len,0); + if(Res < 1)break; + std::string t; + std::string buff(Res,0); + memcpy_s(&buff[0],Res,buf,Res); + std::stringstream ss(buff); + int S = 0; + while (std::getline(ss, t, '\n')) { + ServerSend(t,false); + S++; + } + if(S > 3)std::cout << S << std::endl; + }while(Res > 0); + if(Res == 0)debug(Sec("(Proxy) Connection closing")); + else debug(Sec("(Proxy) recv failed error : ") + std::to_string(WSAGetLastError())); + } + TCPTerminate = true; + GConnected = false; + Terminate = true; + if(LSocket == -1){ + UlStatus = Sec("Critical error! check the launcher logs"); + } + if(CSocket != SOCKET_ERROR)closesocket(CSocket); +} \ No newline at end of file diff --git a/src/http.cpp b/src/Network/Http.cpp similarity index 69% rename from src/http.cpp rename to src/Network/Http.cpp index 1002281..e77882a 100644 --- a/src/http.cpp +++ b/src/Network/Http.cpp @@ -1,29 +1,30 @@ /// -/// Created by Anonymous275 on 3/17/2020 +/// Created by Anonymous275 on 7/18/2020 /// - #define CURL_STATICLIB -#include "curl/curl.h" +#include "Security/Game.h" +#include "Security/Enc.h" +#include "Curl/curl.h" #include - -void Exit(const std::string& Msg); -static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp) -{ +static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp){ ((std::string*)userp)->append((char*)contents, size * nmemb); return size * nmemb; } std::string HTTP_REQUEST(const std::string& IP,int port){ CURL *curl; - //CURLcode res; + CURLcode res; std::string readBuffer; curl = curl_easy_init(); if(curl) { curl_easy_setopt(curl, CURLOPT_URL, IP.c_str()); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L); curl_easy_setopt(curl, CURLOPT_PORT, port); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer); - curl_easy_perform(curl); + res = curl_easy_perform(curl); curl_easy_cleanup(curl); + if(res != CURLE_OK)return "-1"; } curl_global_cleanup(); return readBuffer; @@ -31,14 +32,12 @@ std::string HTTP_REQUEST(const std::string& IP,int port){ int nb_bar; double last_progress, progress_bar_adv; -int progress_bar (void *bar, double t, double d) -{ - if(last_progress != round(d/t*100)) - { +int progress_bar (void *bar, double t, double d){ + if(last_progress != round(d/t*100)){ nb_bar = 25; progress_bar_adv = round(d/t*nb_bar); std::cout<<"\r"; - std::cout<<"Progress : [ "; + std::cout<stream) { - fopen_s(&out->stream,out->filename,"wb"); + fopen_s(&out->stream,out->filename,Sec("wb")); if(!out->stream)return -1; } return fwrite(buffer, size, nmemb, out->stream); } - -int Download(const std::string& URL,const std::string& Path) -{ +int Download(const std::string& URL,const std::string& Path,bool close){ CURL *curl; CURLcode res; - struct File file = { - Path.c_str(), - nullptr - }; - curl_global_init(CURL_GLOBAL_DEFAULT); + struct File file = {Path.c_str(),nullptr}; + //curl_global_init(CURL_GLOBAL_DEFAULT); curl = curl_easy_init(); - if(curl) { + if(curl){ curl_easy_setopt(curl, CURLOPT_URL,URL.c_str()); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &file); curl_easy_setopt(curl, CURLOPT_NOPROGRESS, FALSE); @@ -84,12 +77,11 @@ int Download(const std::string& URL,const std::string& Path) curl_easy_setopt(curl, CURLOPT_USE_SSL, CURLUSESSL_ALL); res = curl_easy_perform(curl); curl_easy_cleanup(curl); - if(CURLE_OK != res) { - return res; - } + if(res != CURLE_OK)return res; } if(file.stream)fclose(file.stream); + if(!close)SecureMods(); curl_global_cleanup(); std::cout << std::endl; return -1; -} \ No newline at end of file +} diff --git a/src/Resources.cpp b/src/Network/Resources.cpp similarity index 57% rename from src/Resources.cpp rename to src/Network/Resources.cpp index 89a9d42..e090d10 100644 --- a/src/Resources.cpp +++ b/src/Network/Resources.cpp @@ -1,26 +1,21 @@ /// /// Created by Anonymous275 on 4/11/2020 /// - +#include "Discord/discord_info.h" +#include "Network/network.h" +#include "Security/Enc.h" #include #include +#include "Startup.h" +#include "Logger.h" #include +#include #include #include #include #include -extern std::vector GlobalInfo; -void Exit(const std::string& Msg); namespace fs = std::experimental::filesystem; -std::string HTA(const std::string& hex); -std::string Encrypt(std::string msg); -std::string Decrypt(std::string msg); -extern std::string UlStatus; -extern bool TCPTerminate; -extern bool Terminate; -extern bool Confirm; -extern bool Dev; std::string ListOfMods; std::vector Split(const std::string& String,const std::string& delimiter){ std::vector Val; @@ -42,12 +37,12 @@ void STCPSend(SOCKET socket,const std::string&Data){ } int BytesSent = send(socket, Data.c_str(), int(Data.length())+1, 0); if (BytesSent == 0){ - if(Dev)std::cout << "(TCP) Connection closing..." << std::endl; + debug(Sec("(TCP) Connection closing...")); Terminate = true; return; } else if (BytesSent < 0) { - if(Dev)std::cout << "(TCP) send failed with error: " << WSAGetLastError() << std::endl; + debug(Sec("(TCP) send failed with error: ") + std::to_string(WSAGetLastError())); closesocket(socket); Terminate = true; return; @@ -60,12 +55,11 @@ std::pair STCPRecv(SOCKET socket){ ZeroMemory(buf, len); int BytesRcv = recv(socket, buf, len,0); if (BytesRcv == 0){ - std::cout << "(TCP) Connection closing..." << std::endl; + info(Sec("(TCP) Connection closing...")); Terminate = true; return std::make_pair((char*)"",0); - } - else if (BytesRcv < 0) { - std::cout << "(TCP) recv failed with error: " << WSAGetLastError() << std::endl; + }else if (BytesRcv < 0) { + info(Sec("(TCP) recv failed with error: ") + std::to_string(WSAGetLastError())); closesocket(socket); Terminate = true; return std::make_pair((char*)"",0); @@ -77,75 +71,105 @@ std::pair STCPRecv(SOCKET socket){ } void CheckForDir(){ struct stat info{}; - if(stat( "Resources", &info) != 0){ - _wmkdir(L"Resources"); + if(stat( Sec("Resources"), &info) != 0){ + _wmkdir(SecW(L"Resources")); } } void WaitForConfirm(){ - while(!Terminate && !Confirm){ + while(!Terminate && !ModLoaded){ std::this_thread::sleep_for(std::chrono::milliseconds(10)); } - Confirm = false; + ModLoaded = false; } -extern char* ver; -void SyncResources(SOCKET Sock){ - std::cout << "Checking Resources..." << std::endl; - CheckForDir(); - STCPSend(Sock,Encrypt(HTA("4e52") + GlobalInfo.at(0) + ":" + HTA(GlobalInfo.at(2)))); - STCPSend(Sock,Encrypt(HTA(std::string("5643")+ver))); +int N,E; +void Parse(const std::string& msg){ + std::stringstream ss(msg); + std::string t; + while (std::getline(ss, t, 'g')) { + if(t.find_first_not_of(Sec("0123456789abcdef")) != std::string::npos)return; + if(N == 0){ + N = std::stoi(t, nullptr, 16); + }else if(E == 0){ + E = std::stoi(t, nullptr, 16); + }else return; + } +} + +std::string HandShake(SOCKET Sock){ + N = 0;E = 0; auto Res = STCPRecv(Sock); - std::string msg = Res.first; - if(msg.size() < 2 || Decrypt(msg).substr(0,2) != "WS"){ + std::string msg(Res.first,Res.second); + Parse(msg); + if(N != 0 && E != 0) { + msg = RSA_E("NR" + GetDName() + ":" + GetDID(),E,N); + if(!msg.empty()) { + STCPSend(Sock,msg); + STCPSend(Sock, RSA_E("VC" + GetVer(),E,N)); + Res = STCPRecv(Sock); + msg = Res.first; + } + } + if(N == 0 || E == 0 || msg.size() < 2 || msg.substr(0,2) != "WS"){ Terminate = true; TCPTerminate = true; - UlStatus = "UlDisconnected: full or outdated server"; - std::cout << "Terminated!" << std::endl; - return; + UlStatus = Sec("UlDisconnected: full or outdated server"); + info(Sec("Terminated!")); + return ""; } - STCPSend(Sock,"SR"); + STCPSend(Sock,Sec("SR")); Res = STCPRecv(Sock); if(strlen(Res.first) == 0 || std::string(Res.first) == "-"){ - std::cout << "Didn't Receive any mods..." << std::endl; + info(Sec("Didn't Receive any mods...")); ListOfMods = "-"; - STCPSend(Sock,"Done"); - std::cout << "Done!" << std::endl; - return; + STCPSend(Sock,Sec("Done")); + info(Sec("Done!")); + return ""; } - std::vector list = Split(std::string(Res.first), ";"); + return Res.first; +} + +void SyncResources(SOCKET Sock){ + std::string Ret = HandShake(Sock); + if(Ret.empty())return; + + info(Sec("Checking Resources...")); + CheckForDir(); + + std::vector list = Split(Ret, ";"); std::vector FNames(list.begin(), list.begin() + (list.size() / 2)); std::vector FSizes(list.begin() + (list.size() / 2), list.end()); list.clear(); + Ret.clear(); int Amount = 0,Pos = 0; - struct stat info{}; std::string a,t; - for(const std::string&N : FNames){ - if(!N.empty()){ - t += N.substr(N.find_last_of('/')+1) + ";"; + for(const std::string&name : FNames){ + if(!name.empty()){ + t += name.substr(name.find_last_of('/') + 1) + ";"; } } if(t.empty())ListOfMods = "-"; else ListOfMods = t; t.clear(); for(auto FN = FNames.begin(),FS = FSizes.begin(); FN != FNames.end() && !Terminate; ++FN,++FS) { - int pos = FN->find_last_of('/'); + auto pos = FN->find_last_of('/'); if (pos == std::string::npos)continue; Amount++; } - if(!FNames.empty())std::cout << "Syncing..." << std::endl; + if(!FNames.empty())info(Sec("Syncing...")); for(auto FN = FNames.begin(),FS = FSizes.begin(); FN != FNames.end() && !Terminate; ++FN,++FS) { - int pos = FN->find_last_of('/'); + auto pos = FN->find_last_of('/'); if (pos != std::string::npos) { - a = "Resources" + FN->substr(pos); + a = Sec("Resources") + FN->substr(pos); } else continue; Pos++; - if (stat(a.c_str(), &info) == 0) { + if (fs::exists(a)) { if (FS->find_first_not_of("0123456789") != std::string::npos)continue; if (fs::file_size(a) == std::stoi(*FS)){ - UlStatus = "UlLoading Resource: (" + std::to_string(Pos) + "/" + std::to_string(Amount) + + UlStatus = Sec("UlLoading Resource: (") + std::to_string(Pos) + "/" + std::to_string(Amount) + "): " + a.substr(a.find_last_of('/')); std::this_thread::sleep_for(std::chrono::milliseconds(50)); - fs::copy_file(a, "BeamNG/mods"+a.substr(a.find_last_of('/')), fs::copy_options::overwrite_existing); + fs::copy_file(a, Sec("BeamNG/mods")+a.substr(a.find_last_of('/')), fs::copy_options::overwrite_existing); WaitForConfirm(); continue; }else remove(a.c_str()); @@ -160,42 +184,42 @@ void SyncResources(SOCKET Sock){ auto Pair = STCPRecv(Sock); char* Data = Pair.first; size_t BytesRcv = Pair.second; - if (strcmp(Data, "Cannot Open") == 0 || Terminate){ + if (strcmp(Data, Sec("Cannot Open")) == 0 || Terminate){ if(BytesRcv != 0)delete[] Data; break; } memcpy_s(File+Recv,BytesRcv,Data,BytesRcv); - Recv += BytesRcv; + Recv += int(BytesRcv); float per = float(Recv)/std::stof(*FS) * 100; std::string Percent = std::to_string(truncf(per * 10) / 10); - UlStatus = "UlDownloading Resource: (" + std::to_string(Pos) + "/" + std::to_string(Amount) + + UlStatus = Sec("UlDownloading Resource: (") + std::to_string(Pos) + "/" + std::to_string(Amount) + "): " + a.substr(a.find_last_of('/')) + " (" + Percent.substr(0, Percent.find('.') + 2) + "%)"; delete[] Data; } while (Recv != Size && Recv < Size && !Terminate); if(Terminate)break; - UlStatus = "UlLoading Resource: (" + std::to_string(Pos) + "/" + std::to_string(Amount) + + UlStatus = Sec("UlLoading Resource: (") + std::to_string(Pos) + "/" + std::to_string(Amount) + "): " + a.substr(a.find_last_of('/')); std::ofstream LFS; - if (!LFS.is_open()) { - LFS.open(a.c_str(), std::ios_base::app | std::ios::binary); + LFS.open(a.c_str(), std::ios_base::app | std::ios::binary); + if (LFS.is_open()) { + LFS.write(File, Recv); + LFS.close(); } - LFS.write(File,Recv); - LFS.close(); ZeroMemory(File,Size); delete[] File; }while(fs::file_size(a) != std::stoi(*FS) && !Terminate); - if(!Terminate)fs::copy_file(a, "BeamNG/mods"+a.substr(a.find_last_of('/')), fs::copy_options::overwrite_existing); + if(!Terminate)fs::copy_file(a,Sec("BeamNG/mods")+a.substr(a.find_last_of('/')), fs::copy_options::overwrite_existing); WaitForConfirm(); } FNames.clear(); FSizes.clear(); a.clear(); if(!Terminate){ - STCPSend(Sock,"Done"); - std::cout << "Done!" << std::endl; + STCPSend(Sock,Sec("Done")); + info(Sec("Done!")); }else{ - UlStatus = "Ulstart"; - std::cout << "Connection Terminated!" << std::endl; + UlStatus = Sec("Ulstart"); + info(Sec("Connection Terminated!")); } } \ No newline at end of file diff --git a/src/Network 2.0/VehicleData.cpp b/src/Network/VehicleData.cpp similarity index 66% rename from src/Network 2.0/VehicleData.cpp rename to src/Network/VehicleData.cpp index 3d51156..51f648e 100644 --- a/src/Network 2.0/VehicleData.cpp +++ b/src/Network/VehicleData.cpp @@ -1,18 +1,16 @@ /// /// Created by Anonymous275 on 5/8/2020 /// - - +#include "Zlib/Compressor.h" +#include "Network/network.h" +#include "Security/Enc.h" #include -#include +#include "Logger.h" #include #include #include #include -extern bool Terminate; -extern int ClientID; -extern bool Dev; SOCKET UDPSock; sockaddr_in ToServer{}; struct PacketData{ @@ -20,30 +18,52 @@ struct PacketData{ std::string Data; int Tries; }; - struct SplitData{ - int Total; - int ID; + int Total{}; + int ID{}; std::set> Fragments; }; - std::set SplitPackets; std::set BigDataAcks; -void UDPSend(const std::string&Data){ - if(ClientID == -1 || UDPSock == INVALID_SOCKET)return; +void ClearAll(){ + for(SplitData*S : SplitPackets){ + if(S != nullptr){ + delete S; + S = nullptr; + } + } + for(PacketData*S : BigDataAcks){ + if(S != nullptr){ + delete S; + S = nullptr; + } + } + SplitPackets.clear(); + BigDataAcks.clear(); +} +void UDPSend(std::string Data){ + if(ClientID == -1 || UDPSock == -1)return; + if(Data.length() > 400){ + std::string CMP(Comp(Data)); + Data = "ABG:" + CMP; + } std::string Packet = char(ClientID+1) + std::string(":") + Data; - int sendOk = sendto(UDPSock, Packet.c_str(), int(Packet.length()) + 1, 0, (sockaddr*)&ToServer, sizeof(ToServer)); - if (sendOk == SOCKET_ERROR)std::cout << "Error Code : " << WSAGetLastError() << std::endl; + int sendOk = sendto(UDPSock, Packet.c_str(), int(Packet.size()), 0, (sockaddr*)&ToServer, sizeof(ToServer)); + if (sendOk == SOCKET_ERROR)error(Sec("Error Code : ") + std::to_string(WSAGetLastError())); } void LOOP(){ while(UDPSock != -1) { for (PacketData* p : BigDataAcks) { - if(p->Tries < 20){ + if(p != nullptr && p->Tries < 20){ p->Tries++; UDPSend(p->Data); }else{ BigDataAcks.erase(p); + if(p != nullptr){ + delete p; + p = nullptr; + } break; } } @@ -53,13 +73,13 @@ void LOOP(){ void AckID(int ID){ for(PacketData* p : BigDataAcks){ - if(p->ID == ID){ + if(p != nullptr && p->ID == ID){ p->Tries = 25; break; } } } -int PacktID(){ +int PackID(){ static int ID = -1; if(ID > 999999)ID = 0; else ID++; @@ -72,11 +92,11 @@ int SplitID(){ return SID; } void SendLarge(const std::string&Data){ - int ID = PacktID(); + int ID = PackID(); std::string Packet; if(Data.length() > 1000){ std::string pckt = Data; - int S = 1,Split = ceil(float(pckt.length()) / 1000); + int S = 1,Split = int(ceil(float(pckt.length()) / 1000)); int SID = SplitID(); while(pckt.length() > 1000){ Packet = "SC"+std::to_string(S)+"/"+std::to_string(Split)+":"+std::to_string(ID)+"|"+ @@ -85,7 +105,7 @@ void SendLarge(const std::string&Data){ UDPSend(Packet); pckt = pckt.substr(1000); S++; - ID = PacktID(); + ID = PackID(); } Packet = "SC"+std::to_string(S)+"/"+std::to_string(Split)+":"+ std::to_string(ID)+"|"+std::to_string(SID)+":"+pckt; @@ -115,24 +135,25 @@ bool Handled(int ID){ } SplitData*GetSplit(int SplitID){ for(SplitData* a : SplitPackets){ - if(a->ID == SplitID)return a; + if(a != nullptr && a->ID == SplitID)return a; } - SplitData* a = new SplitData(); + auto* a = new SplitData(); SplitPackets.insert(a); return a; } void ServerParser(const std::string& Data); void HandleChunk(const std::string&Data){ - int pos1 = Data.find(':')+1,pos2 = Data.find(':',pos1),pos3 = Data.find('/'); - int pos4 = Data.find('|'); + int pos1 = int(Data.find(':'))+1,pos2 = int(Data.find(':',pos1)),pos3 = int(Data.find('/')); + int pos4 = int(Data.find('|')); int Max = stoi(Data.substr(pos3+1,pos1-pos3-2)); int Current = stoi(Data.substr(2,pos3-2)); int ID = stoi(Data.substr(pos1,pos4-pos1)); int SplitID = stoi(Data.substr(pos4+1,pos2-pos4-1)); - std::string ack = "ACK:" + Data.substr(pos1,pos4-pos1); + std::string ack = "TRG:" + Data.substr(pos1,pos4-pos1); UDPSend(ack); if(Handled(ID))return; + warn("Handeling Packet ID : " + std::to_string(ID)); SplitData* SData = GetSplit(SplitID); SData->Total = Max; SData->ID = SplitID; @@ -144,17 +165,22 @@ void HandleChunk(const std::string&Data){ } ServerParser(ToHandle); SplitPackets.erase(SData); + delete SData; + SData = nullptr; } } -void UDPParser(const std::string&Packet){ - if(Packet.substr(0,4) == "ACK:"){ +void UDPParser(std::string Packet){ + if(Packet.substr(0,4) == "ABG:"){ + Packet = DeComp(Packet.substr(4)); + } + if(Packet.substr(0,4) == "TRG:"){ AckID(stoi(Packet.substr(4))); - if(Dev)std::cout << "Got Ack for data" << std::endl; + debug(Sec("Got Ack for data")); return; }else if(Packet.substr(0,3) == "BD:"){ - int pos = Packet.find(':',4); + auto pos = Packet.find(':',4); int ID = stoi(Packet.substr(3,pos-3)); - std::string pckt = "ACK:" + std::to_string(ID); + std::string pckt = "TRG:" + std::to_string(ID); UDPSend(pckt); if(!Handled(ID)) { pckt = Packet.substr(pos + 1); @@ -174,33 +200,28 @@ void UDPRcv(){ int clientLength = sizeof(FromServer); ZeroMemory(&FromServer, clientLength); ZeroMemory(buf, len); - if(UDPSock == INVALID_SOCKET)return; - int bytesIn = recvfrom(UDPSock, buf, len, 0, (sockaddr*)&FromServer, &clientLength); - if (bytesIn == SOCKET_ERROR) - { - //std::cout << "Error receiving from Server " << WSAGetLastError() << std::endl; - return; - } - UDPParser(std::string(buf)); + if(UDPSock == -1)return; + int Rcv = recvfrom(UDPSock, buf, len, 0, (sockaddr*)&FromServer, &clientLength); + if (Rcv == SOCKET_ERROR)return; + std::string Ret(Rcv,0); + memcpy_s(&Ret[0],Rcv,buf,Rcv); + UDPParser(Ret); } -void TCPSend(const std::string&Data); void UDPClientMain(const std::string& IP,int Port){ WSADATA data; - if (WSAStartup(514, &data)) //2.2 - { - std::cout << "Can't start Winsock! " << std::endl; + if (WSAStartup(514, &data)){ + error(Sec("Can't start Winsock!")); return; } ToServer.sin_family = AF_INET; ToServer.sin_port = htons(Port); inet_pton(AF_INET, IP.c_str(), &ToServer.sin_addr); UDPSock = socket(AF_INET, SOCK_DGRAM, 0); - BigDataAcks.clear(); std::thread Ack(LOOP); Ack.detach(); IDReset(); - TCPSend("P"); - UDPSend("p"); + TCPSend(Sec("P")); + UDPSend(Sec("p")); while(!Terminate)UDPRcv(); closesocket(UDPSock); WSACleanup(); diff --git a/src/Network 2.0/VehicleEvent.cpp b/src/Network/VehicleEvent.cpp similarity index 60% rename from src/Network 2.0/VehicleEvent.cpp rename to src/Network/VehicleEvent.cpp index 1d45e6c..32a3da1 100644 --- a/src/Network 2.0/VehicleEvent.cpp +++ b/src/Network/VehicleEvent.cpp @@ -3,15 +3,13 @@ /// #include +#include "Logger.h" #include #include +#include "Security/Enc.h" +#include "Network/network.h" -extern std::string UlStatus; -extern bool Terminate; -extern bool Dev; SOCKET TCPSock; - - void TCPSend(const std::string&Data){ if(TCPSock == -1){ Terminate = true; @@ -19,12 +17,12 @@ void TCPSend(const std::string&Data){ } int BytesSent = send(TCPSock, Data.c_str(), int(Data.length())+1, 0); if (BytesSent == 0){ - if(Dev)std::cout << "(TCP) Connection closing..." << std::endl; + debug(Sec("(TCP) Connection closing...")); Terminate = true; return; } else if (BytesSent < 0) { - if(Dev)std::cout << "(TCP) send failed with error: " << WSAGetLastError() << std::endl; + debug(Sec("(TCP) send failed with error: ") + std::to_string(WSAGetLastError())); closesocket(TCPSock); Terminate = true; return; @@ -43,12 +41,12 @@ void TCPRcv(){ } int BytesRcv = recv(TCPSock, buf, len,0); if (BytesRcv == 0){ - if(Dev)std::cout << "(TCP) Connection closing..." << std::endl; + debug(Sec("(TCP) Connection closing...")); Terminate = true; return; } else if (BytesRcv < 0) { - if(Dev)std::cout << "(TCP) recv failed with error: " << WSAGetLastError() << std::endl; + debug(Sec("(TCP) recv failed with error: ") + std::to_string(WSAGetLastError())); closesocket(TCPSock); Terminate = true; return; @@ -56,31 +54,25 @@ void TCPRcv(){ ServerParser(std::string(buf)); } -void GameSend(const std::string&Data); void SyncResources(SOCKET TCPSock); void TCPClientMain(const std::string& IP,int Port){ WSADATA wsaData; SOCKADDR_IN ServerAddr; int RetCode; - WSAStartup(514, &wsaData); //2.2 TCPSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - if(TCPSock == -1) - { - printf("Client: socket failed! Error code: %d\n", WSAGetLastError()); + if(TCPSock == -1){ + printf(Sec("Client: socket failed! Error code: %d\n"), WSAGetLastError()); WSACleanup(); return; } - ServerAddr.sin_family = AF_INET; ServerAddr.sin_port = htons(Port); inet_pton(AF_INET, IP.c_str(), &ServerAddr.sin_addr); - RetCode = connect(TCPSock, (SOCKADDR *) &ServerAddr, sizeof(ServerAddr)); - if(RetCode != 0) - { - UlStatus = "UlConnection Failed!"; - std::cout << "Client: connect failed! Error code: " << WSAGetLastError() << std::endl; + if(RetCode != 0){ + UlStatus = Sec("UlConnection Failed!"); + std::cout << Sec("Client: connect failed! Error code: ") << WSAGetLastError() << std::endl; closesocket(TCPSock); WSACleanup(); Terminate = true; @@ -90,14 +82,11 @@ void TCPClientMain(const std::string& IP,int Port){ SyncResources(TCPSock); while(!Terminate)TCPRcv(); - GameSend("T"); + GameSend(Sec("T")); ////Game Send Terminate - if( shutdown(TCPSock, SD_SEND) != 0 && Dev) - std::cout << "(TCP) shutdown error code: " << WSAGetLastError() << std::endl; + if(closesocket(TCPSock) != 0) + debug(Sec("(TCP) Cannot close socket. Error code: ") + std::to_string(WSAGetLastError())); - if(closesocket(TCPSock) != 0 && Dev) - std::cout << "(TCP) Cannot close socket. Error code: " << WSAGetLastError() << std::endl; - - if(WSACleanup() != 0 && Dev) - std::cout << "(TCP) Client: WSACleanup() failed!..." << std::endl; + if(WSACleanup() != 0) + debug(Sec("(TCP) Client: WSACleanup() failed!...")); } diff --git a/src/Security.cpp b/src/Security.cpp deleted file mode 100644 index 52e264e..0000000 --- a/src/Security.cpp +++ /dev/null @@ -1,307 +0,0 @@ -/// -/// Created by Anonymous275 on 3/16/2020 -/// -#include -#include -#include -#include -#include -#include -#include -#define MAX_KEY_LENGTH 255 -#define MAX_VALUE_NAME 16383 - -void Exit(const std::string& Msg); -int TraceBack = 0; - -std::vector SData; - -std::string HTA(const std::string& hex) -{ - std::string ascii; - for (size_t i = 0; i < hex.length(); i += 2) - { - std::string part = hex.substr(i, 2); - char ch = char(stoul(part, nullptr, 16)); - ascii += ch; - } - return ascii; -} -int Rand(){ - std::random_device r; - std::default_random_engine e1(r()); - std::uniform_int_distribution uniform_dist(1, 200); - return uniform_dist(e1); -} -std::string Encrypt(std::string msg){ - if(msg.size() < 2)return msg; - int R = (Rand()+Rand())/2,T = R; - for(char&c : msg){ - if(R > 30)c = char(int(c) + (R-=3)); - else c = char(int(c) - (R+=4)); - } - return char(T) + msg; -} -std::string Decrypt(std::string msg){ - int R = uint8_t(msg.at(0)); - if(msg.size() < 2 || R > 200 || R < 1)return ""; - msg = msg.substr(1); - for(char&c : msg){ - if(R > 30)c = char(int(c) - (R-=3)); - else c = char(int(c) + (R+=4)); - } - return msg; -} - - -LONG OpenKey(HKEY root,const char* path,PHKEY hKey){ - return RegOpenKeyEx(root, reinterpret_cast(path), 0, KEY_READ, hKey); -} - -std::string QueryKey(HKEY hKey,int ID) -{ - TCHAR achKey[MAX_KEY_LENGTH]; // buffer for subkey name - DWORD cbName; // size of name string - TCHAR achClass[MAX_PATH] = TEXT(""); // buffer for class name - DWORD cchClassName = MAX_PATH; // size of class string - DWORD cSubKeys=0; // number of subkeys - DWORD cbMaxSubKey; // longest subkey size - DWORD cchMaxClass; // longest class string - DWORD cValues; // number of values for key - DWORD cchMaxValue; // longest value name - DWORD cbMaxValueData; // longest value data - DWORD cbSecurityDescriptor; // size of security descriptor - FILETIME ftLastWriteTime; // last write time - - DWORD i, retCode; - - TCHAR achValue[MAX_VALUE_NAME]; - DWORD cchValue = MAX_VALUE_NAME; - - retCode = RegQueryInfoKey( - hKey, // key handle - achClass, // buffer for class name - &cchClassName, // size of class string - nullptr, // reserved - &cSubKeys, // number of subkeys - &cbMaxSubKey, // longest subkey size - &cchMaxClass, // longest class string - &cValues, // number of values for this key - &cchMaxValue, // longest value name - &cbMaxValueData, // longest value data - &cbSecurityDescriptor, // security descriptor - &ftLastWriteTime); // last write time - - - - BYTE* buffer = new BYTE[cbMaxValueData]; - ZeroMemory(buffer, cbMaxValueData); - if (cSubKeys) - { - for (i=0; i(buffer); - std::string key = achValue; - switch (ID){ - case 1: if(key == HTA("537465616d50617468"))return data;break; - case 2: if(key == HTA("4e616d65") && data == HTA("4265616d4e472e6472697665"))return data;break; - case 3: return data.substr(0,data.length()-2); - case 4: if(key == HTA("75736572706174685f6f76657272696465"))return data; - default: break; - } - } - } - } - delete [] buffer; - return ""; -} -namespace fs = std::experimental::filesystem; -void FileList(std::vector&a,const std::string& Path){ - for (const auto &entry : fs::directory_iterator(Path)) { - int pos = entry.path().filename().string().find('.'); - if (pos != std::string::npos) { - a.emplace_back(entry.path().string()); - }else FileList(a,entry.path().string()); - } -} -bool Continue = false; -void Find(const std::string& FName,const std::string& Path){ - std::vector FS; - FileList(FS,Path); - for(const std::string&a : FS){ - if(a.find(FName)!=std::string::npos)Continue = true; - } - FS.clear(); -} -void ExitError(){ - std::string MSG2 = HTA("4572726f722120506c6561736520436f6e7461637420537570706f7274"); - Exit(MSG2 + " Code 2"); -} -void Check(){ - /*.HKEY_CURRENT_USER\Software\Valve\Steam - HKEY_CURRENT_USER\\Software\Valve\Steam\Apps\284160 - HKEY_CLASSES_ROOT\\beamng\\DefaultIcon */ - //Sandbox Scramble technique - std::string Result; - std::string K1 = HTA("536f6674776172655c56616c76655c537465616d"); - std::string K2 = HTA("536f6674776172655c56616c76655c537465616d5c417070735c323834313630"); - std::string K3 = HTA("6265616d6e675c44656661756c7449636f6e"); - std::string MSG1 = HTA("4572726f722120796f7520646f206e6f74206f776e204265616d4e4721"); //Error! you do not own BeamNG! - std::string MSG2 = HTA("4572726f722120506c6561736520436f6e7461637420537570706f7274"); //Error! Please Contact Support - std::string MSG3 = HTA("596f7520646f206e6f74206f776e207468652067616d65206f6e2074686973206d616368696e6521"); //You do not own the game on this machine! - //std::string MSG = HTA("5761726e696e672120796f75206f776e207468652067616d6520627574206120637261636b65642067616d652077617320666f756e64206f6e20796f7572206d616368696e6521"); - //not used : Warning! you own the game but a cracked game was found on your machine! - HKEY hKey; - LONG dwRegOPenKey = OpenKey(HKEY_CURRENT_USER, K1.c_str(), &hKey); - if(dwRegOPenKey == ERROR_SUCCESS) { - Result = QueryKey(hKey, 1); - if(Result.empty()){Exit(MSG1 + " Code 1");} - SData.push_back(Result); - Result += HTA("2f7573657264617461"); - struct stat buffer{}; - if(stat(Result.c_str(), &buffer) == 0){ - auto *F = new std::thread(Find,HTA("3238343136302e6a736f6e"),Result); - F->join(); - delete F; - if(!Continue)Exit(MSG2 + " Code 2"); - }else Exit(MSG2 + ". Code: 3"); - Result.clear(); - TraceBack++; - }else{Exit(MSG2 + ". Code: 4");} - K1.clear(); - RegCloseKey(hKey); - dwRegOPenKey = OpenKey(HKEY_CURRENT_USER, K2.c_str(), &hKey); - if(dwRegOPenKey == ERROR_SUCCESS) { - Result = QueryKey(hKey, 2); - if(Result.empty()){Exit(MSG1 + " Code 3");} - SData.push_back(Result); - TraceBack++; - }else{Exit(MSG3);} - K2.clear(); - RegCloseKey(hKey); - dwRegOPenKey = OpenKey(HKEY_CLASSES_ROOT, K3.c_str(), &hKey); - if(dwRegOPenKey == ERROR_SUCCESS) { - Result = QueryKey(hKey, 3); - if(Result.empty()){ - Exit(MSG2 + ". Code: 5"); - } - SData.push_back(Result); - TraceBack++; - }else{Exit(MSG2+ ". Code : 5");} - //Memory Cleaning - K3.clear(); - //MSG.clear(); - MSG1.clear(); - MSG2.clear(); - MSG3.clear(); - Result.clear(); - RegCloseKey(hKey); -} - -std::string HWID(){ - SYSTEM_INFO siSysInfo; - GetSystemInfo(&siSysInfo); - int I1 = siSysInfo.dwOemId; - int I2 = siSysInfo.dwNumberOfProcessors; - int I3 = siSysInfo.dwProcessorType; - int I4 = siSysInfo.dwActiveProcessorMask; - int I5 = siSysInfo.wProcessorLevel; - int I6 = siSysInfo.wProcessorRevision; - return std::to_string((I1*I2+I3)*(I4*I5+I6)); -} - -char* HashMD5(char* data, DWORD *result) -{ - DWORD dwStatus = 0; - DWORD cbHash = 16; - int i = 0; - HCRYPTPROV cryptProv; - HCRYPTHASH cryptHash; - BYTE hash[16]; - char hex[] = "0123456789abcdef"; - char *strHash; - strHash = (char*)malloc(500); - memset(strHash, '\0', 500); - if (!CryptAcquireContext(&cryptProv, nullptr, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) - { - dwStatus = GetLastError(); - printf("CryptAcquireContext failed: %lu\n", dwStatus); - *result = dwStatus; - return nullptr; - } - if (!CryptCreateHash(cryptProv, CALG_MD5, 0, 0, &cryptHash)) - { - dwStatus = GetLastError(); - printf("CryptCreateHash failed: %lu\n", dwStatus); - CryptReleaseContext(cryptProv, 0); - *result = dwStatus; - return nullptr; - } - if (!CryptHashData(cryptHash, (BYTE*)data, strlen(data), 0)) - { - dwStatus = GetLastError(); - printf("CryptHashData failed: %lu\n", dwStatus); - CryptReleaseContext(cryptProv, 0); - CryptDestroyHash(cryptHash); - *result = dwStatus; - return nullptr; - } - if (!CryptGetHashParam(cryptHash, HP_HASHVAL, hash, &cbHash, 0)) - { - dwStatus = GetLastError(); - printf("CryptGetHashParam failed: %lu\n", dwStatus); - CryptReleaseContext(cryptProv, 0); - CryptDestroyHash(cryptHash); - *result = dwStatus; - return nullptr; - } - for (i = 0; i < cbHash; i++) - { - strHash[i * 2] = hex[hash[i] >> 4]; - strHash[(i * 2) + 1] = hex[hash[i] & 0xF]; - } - CryptReleaseContext(cryptProv, 0); - CryptDestroyHash(cryptHash); - return strHash; -} -std::string getHardwareID() -{ - DWORD err; - std::string hash = HashMD5((char*)HWID().c_str(), &err); - return hash; -} diff --git a/src/Security/BeamNG.cpp b/src/Security/BeamNG.cpp new file mode 100644 index 0000000..59c1829 --- /dev/null +++ b/src/Security/BeamNG.cpp @@ -0,0 +1,289 @@ +/// +/// Created by Anonymous275 on 7/18/2020 +/// +#include "Security/Enc.h" +#include +#include +#include "Logger.h" +#include +#include +#include +#include + +#define MAX_KEY_LENGTH 255 +#define MAX_VALUE_NAME 16383 + +int TraceBack = 0; +std::string GameDir; + +void lowExit(int code){ + TraceBack = 0; + std::string msg = + Sec("Failed to find the game please launch it. Report this if the issue persists code "); + error(msg+std::to_string(code)); + std::this_thread::sleep_for(std::chrono::seconds(10)); + exit(2); +} +void Exit(int code){ + TraceBack = 0; + std::string msg = + Sec("Sorry. We do not support cracked copies report this if you believe this is a mistake code "); + error(msg+std::to_string(code)); + std::this_thread::sleep_for(std::chrono::seconds(10)); + exit(3); +} +void SteamExit(int code){ + TraceBack = 0; + std::string msg = + Sec("Illegal steam modifications detected report this if you believe this is a mistake code "); + error(msg+std::to_string(code)); + std::this_thread::sleep_for(std::chrono::seconds(10)); + exit(4); +} +std::string GetGameDir(){ + if(TraceBack != 3)Exit(0); + return GameDir.substr(0,GameDir.find_last_of('\\')); +} +LONG OpenKey(HKEY root,const char* path,PHKEY hKey){ + return RegOpenKeyEx(root, reinterpret_cast(path), 0, KEY_READ, hKey); +} +std::string QueryKey(HKEY hKey,int ID){ + TCHAR achKey[MAX_KEY_LENGTH]; // buffer for subkey name + DWORD cbName; // size of name string + TCHAR achClass[MAX_PATH] = TEXT(""); // buffer for class name + DWORD cchClassName = MAX_PATH; // size of class string + DWORD cSubKeys=0; // number of subkeys + DWORD cbMaxSubKey; // longest subkey size + DWORD cchMaxClass; // longest class string + DWORD cValues; // number of values for key + DWORD cchMaxValue; // longest value name + DWORD cbMaxValueData; // longest value data + DWORD cbSecurityDescriptor; // size of security descriptor + FILETIME ftLastWriteTime; // last write time + + DWORD i, retCode; + + TCHAR achValue[MAX_VALUE_NAME]; + DWORD cchValue = MAX_VALUE_NAME; + + retCode = RegQueryInfoKey( + hKey, // key handle + achClass, // buffer for class name + &cchClassName, // size of class string + nullptr, // reserved + &cSubKeys, // number of subkeys + &cbMaxSubKey, // longest subkey size + &cchMaxClass, // longest class string + &cValues, // number of values for this key + &cchMaxValue, // longest value name + &cbMaxValueData, // longest value data + &cbSecurityDescriptor, // security descriptor + &ftLastWriteTime); // last write time + + BYTE* buffer = new BYTE[cbMaxValueData]; + ZeroMemory(buffer, cbMaxValueData); + if (cSubKeys){ + for (i=0; i(buffer); + std::string key = achValue; + switch (ID){ + case 1: if(key == Sec("SteamExe")){ + auto p = data.find_last_of('/'); + if(p != std::string::npos)return data.substr(0,p); + }break; + case 2: if(key == Sec("Name") && data == Sec("BeamNG.drive"))return data;break; + case 3: if(key == Sec("rootpath"))return data;break; + case 4: if(key == Sec("userpath_override"))return data; + default: break; + } + } + } + } + delete [] buffer; + return ""; +} +namespace fs = std::experimental::filesystem; +void FileList(std::vector&a,const std::string& Path){ + for (const auto &entry : fs::directory_iterator(Path)) { + auto pos = entry.path().filename().string().find('.'); + if (pos != std::string::npos) { + a.emplace_back(entry.path().string()); + }else FileList(a,entry.path().string()); + } +} +bool Find(const std::string& FName,const std::string& Path){ + std::vector FS; + FileList(FS,Path+Sec("/userdata")); + for(std::string&a : FS){ + if(a.find(FName) != std::string::npos){ + FS.clear(); + return true; + } + } + FS.clear(); + return false; +} +bool FindHack(const std::string& Path){ + bool s = true; + for (const auto &entry : fs::directory_iterator(Path)) { + std::string Name = entry.path().filename().string(); + for(char&c : Name)c = char(tolower(c)); + if(Name == Sec("steam.exe"))s = false; + if(Name.find(Sec("greenluma")) != -1)return true; + Name.clear(); + } + return s; +} +std::vector GetID(const std::string& log){ + std::string vec,t,r; + std::vector Ret; + std::ifstream f(log.c_str(), std::ios::binary); + f.seekg(0, std::ios_base::end); + std::streampos fileSize = f.tellg(); + vec.resize(size_t(fileSize) + 1); + f.seekg(0, std::ios_base::beg); + f.read(&vec[0], fileSize); + f.close(); + std::stringstream ss(vec); + bool S = false; + while (std::getline(ss, t, '{')) { + if(!S)S = true; + else{ + for(char& c : t){ + if(isdigit(c))r += c; + } + break; + } + } + Ret.emplace_back(r); + r.clear(); + S = false; + bool L = true; + while (std::getline(ss, t, '}')) { + if(L){ + L = false; + continue; + } + for(char& c : t){ + if(c == '"'){ + if(!S)S = true; + else{ + if(r.length() > 10) { + Ret.emplace_back(r); + } + r.clear(); + S = false; + continue; + } + } + if(isdigit(c))r += c; + } + } + vec.clear(); + return Ret; +} +std::string GetManifest(const std::string& Man){ + std::string vec; + std::ifstream f(Man.c_str(), std::ios::binary); + f.seekg(0, std::ios_base::end); + std::streampos fileSize = f.tellg(); + vec.resize(size_t(fileSize) + 1); + f.seekg(0, std::ios_base::beg); + f.read(&vec[0], fileSize); + f.close(); + std::string ToFind = Sec("\"LastOwner\"\t\t\""); + int pos = int(vec.find(ToFind)); + if(pos != -1){ + pos += int(ToFind.length()); + vec = vec.substr(pos); + return vec.substr(0,vec.find('\"')); + }else return ""; +} +bool IDCheck(std::string Man, std::string steam){ + bool a = false,b = true; + int pos = int(Man.find(Sec("steamapps"))); + if(pos == -1)Exit(5); + Man = Man.substr(0,pos+9) + Sec("/appmanifest_284160.acf"); + steam += Sec("/config/loginusers.vdf"); + if(fs::exists(Man) && fs::exists(steam)){ + for(const std::string&ID : GetID(steam)){ + if(ID == GetManifest(Man))b = false; + } + if(b)Exit(6); + }else a = true; + return a; +} +void LegitimacyCheck(){ + std::string Result,T; + std::string K1 = Sec("Software\\Valve\\Steam"); + std::string K2 = Sec("Software\\Valve\\Steam\\Apps\\284160"); + std::string K3 = Sec("Software\\BeamNG\\BeamNG.drive"); + HKEY hKey; + LONG dwRegOPenKey = OpenKey(HKEY_CURRENT_USER, K1.c_str(), &hKey); + if(dwRegOPenKey == ERROR_SUCCESS) { + Result = QueryKey(hKey, 1); + if(Result.empty())Exit(1); + if(fs::exists(Result)){ + if(!Find(Sec("284160.json"),Result))Exit(2); + if(FindHack(Result))SteamExit(1); + }else Exit(3); + T = Result; + Result.clear(); + TraceBack++; + }else Exit(4); + K1.clear(); + RegCloseKey(hKey); + dwRegOPenKey = OpenKey(HKEY_CURRENT_USER, K2.c_str(), &hKey); + if(dwRegOPenKey == ERROR_SUCCESS) { + Result = QueryKey(hKey, 2); + if(Result.empty())lowExit(1); + TraceBack++; + }else lowExit(2); + K2.clear(); + RegCloseKey(hKey); + dwRegOPenKey = OpenKey(HKEY_CURRENT_USER, K3.c_str(), &hKey); + if(dwRegOPenKey == ERROR_SUCCESS) { + Result = QueryKey(hKey, 3); + if(Result.empty())lowExit(3); + if(IDCheck(Result,T))lowExit(5); + GameDir = Result; + TraceBack++; + }else lowExit(4); + K3.clear(); + Result.clear(); + RegCloseKey(hKey); + if(TraceBack < 3)exit(-1); +} +std::string CheckVer(const std::string &dir){ + std::string vec,temp,Path = dir + Sec("\\integrity.json"); + std::ifstream f(Path.c_str(), std::ios::binary); + f.seekg(0, std::ios_base::end); + std::streampos fileSize = f.tellg(); + vec.resize(size_t(fileSize) + 1); + f.seekg(0, std::ios_base::beg); + f.read(&vec[0], fileSize); + f.close(); + vec = vec.substr(vec.find_last_of(Sec("version")),vec.find_last_of('"')); + for(const char &a : vec){ + if(isdigit(a) || a == '.')temp+=a; + } + return temp; +} diff --git a/src/Security/Checker.cpp b/src/Security/Checker.cpp new file mode 100644 index 0000000..c627d20 --- /dev/null +++ b/src/Security/Checker.cpp @@ -0,0 +1,92 @@ +/// +/// Created by Anonymous275 on 7/16/2020 +/// +#include "Discord/discord_info.h" +#include "Security/Enc.h" +#include +#include "Startup.h" +#include +#include "Logger.h" +#include +#include +void DAS(){ + int i = 0; + std::ifstream f(GetEN(), std::ios::binary); + f.seekg(0, std::ios_base::end); + std::streampos fileSize = f.tellg(); + if(IsDebuggerPresent() || fileSize > 0x3D0900){ + i++; + DAboard(); + } + if(i)DAboard(); + f.close(); +} +void DASM(){ //A mirror to have 2 independent checks + int i = 0; + std::ifstream f(GetEN(), std::ios::binary); + f.seekg(0, std::ios_base::end); + std::streampos fileSize = f.tellg(); + if(IsDebuggerPresent() || fileSize > 0x3D0900){ + i++; + DAboard(); + } + if(i)DAboard(); + f.close(); +} +DWORD getParentPID(DWORD pid){ + HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + PROCESSENTRY32 pe = {0}; + DWORD ppid = 0; + pe.dwSize = sizeof(PROCESSENTRY32); + if(Process32First(h, &pe)){ + do{ + if(pe.th32ProcessID == pid){ + ppid = pe.th32ParentProcessID; + break; + } + }while(Process32Next(h, &pe)); + } + CloseHandle(h); + return ppid; +} + +HANDLE getProcess(DWORD pid, LPSTR fname, DWORD sz) { + HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid); + if (h) { + GetModuleFileNameEx(h, nullptr, fname, sz); + return h; + } + return nullptr; +} +void UnderSimulation(char* argv[]){ + DWORD ppid; + std::string Parent(MAX_PATH,0); + ppid = getParentPID(GetCurrentProcessId()); + HANDLE Process = getProcess(ppid, &Parent[0], MAX_PATH); + std::string Code = Sec("Code "); + if(Process == nullptr){ + error(Code+std::to_string(2)); + exit(1); + } + auto P = Parent.find(Sec(".exe")); + if(P != std::string::npos)Parent.resize(P + 4); + else{ + error(Code+std::to_string(3)); + exit(1); + } + std::string S1 = Sec("\\Windows\\explorer.exe"); + std::string S2 = Sec("JetBrains\\CLion"); + std::string S3 = Sec("\\Windows\\System32\\cmd.exe"); + if(Parent == std::string(argv[0]))return; + if(Parent.find(S1) == 2)return; + if(Parent.find(S2) != std::string::npos)return; + if(Parent.find(S3) == 2)return; + TerminateProcess(Process, 1); + error(Code + std::to_string(4)); + exit(1); + +} +void SecurityCheck(char* argv[]){ + UnderSimulation(argv); + DAS(); +} diff --git a/src/Security/Encryption.cpp b/src/Security/Encryption.cpp new file mode 100644 index 0000000..07fc19c --- /dev/null +++ b/src/Security/Encryption.cpp @@ -0,0 +1,85 @@ +#include "Security/Enc.h" +#include +#include + +int LocalKeys[] = {7406809,6967,4810803}; //n e d + +int log_power(int n,unsigned int p, int mod){ + int result = 1; + for (; p; p >>= 1u){ + if (p & 1u)result = int((1LL * result * n) % mod); + n = int((1LL * n * n) % mod); + } + return result; +} + +int Enc(int value,int e,int n){ + return log_power(value, e, n); +} + +int Dec(int value,int d,int n){ + return log_power(value, d, n); +} +std::string LocalEnc(const std::string& Data){ + std::stringstream stream; + for(const char&c : Data){ + stream << std::hex << Enc(uint8_t(c),LocalKeys[1],LocalKeys[0]) << "g"; + } + return stream.str(); +} +std::string LocalDec(const std::string& Data){ + std::stringstream ss(Data); + std::string token,ret; + while (std::getline(ss, token, 'g')) { + if(token.find_first_not_of(Sec("0123456789abcdef")) != std::string::npos)return ""; + int c = std::stoi(token, nullptr, 16); + ret += char(Dec(c,LocalKeys[2],LocalKeys[0])); + } + return ret; +} +#include +int Rand(){ + std::random_device r; + std::default_random_engine e1(r()); + std::uniform_int_distribution uniform_dist(1, 200); + return uniform_dist(e1); +} +std::string Encrypt(std::string msg){ + if(msg.size() < 2)return msg; + int R = (Rand()+Rand())/2,T = R; + for(char&c : msg){ + if(R > 30)c = char(int(c) + (R-=3)); + else c = char(int(c) - (R+=4)); + } + return char(T) + msg; +} +std::string Decrypt(std::string msg){ + if(msg.size() < 2)return ""; + int R = uint8_t(msg.at(0)); + if(R > 200 || R < 1)return ""; + msg = msg.substr(1); + for(char&c : msg){ + if(R > 30)c = char(int(c) - (R-=3)); + else c = char(int(c) + (R+=4)); + } + return msg; +} +std::string RSA_E(const std::string& Data,int e, int n){ + if(e < 10 || n < 10)return ""; + std::stringstream stream; + for(const char&c : Data){ + stream << std::hex << Enc(uint8_t(c),e,n) << "g"; + } + return stream.str(); +} + +std::string RSA_D(const std::string& Data, int d, int n){ + std::stringstream ss(Data); + std::string token,ret; + while (std::getline(ss, token, 'g')) { + if(token.find_first_not_of(Sec("0123456789abcdef")) != std::string::npos)return ""; + int c = std::stoi(token, nullptr, 16); + ret += char(Dec(c,d,n)); + } + return ret; +} \ No newline at end of file diff --git a/src/Security/FileHandles.cpp b/src/Security/FileHandles.cpp new file mode 100644 index 0000000..f3d76fc --- /dev/null +++ b/src/Security/FileHandles.cpp @@ -0,0 +1,71 @@ +/// +/// Created by Anonymous275 on 7/19/2020 +/// +#include "Security/Enc.h" +#include +#include "Security/Game.h" +#include +#include +#include "Logger.h" +#include + +namespace fs = std::experimental::filesystem; +void CheckDirs(){ + for (auto& p : fs::directory_iterator(Sec("BeamNG\\mods"))) { + if(fs::is_directory(p.path()))exit(0); + } +} + +bool BeamLoad(PCWSTR pszFile){ + bool Ret = false; + DWORD dwSession; + WCHAR szSessionKey[CCH_RM_SESSION_KEY+1] = {0}; + DWORD dwError = RmStartSession(&dwSession, 0, szSessionKey); + if (dwError == ERROR_SUCCESS) { + dwError = RmRegisterResources(dwSession, 1, &pszFile, + 0, nullptr, 0, nullptr); + if (dwError == ERROR_SUCCESS) { + DWORD dwReason; + UINT nProcInfoNeeded; + UINT nProcInfo = 10; + RM_PROCESS_INFO rgpi[10]; + dwError = RmGetList(dwSession, &nProcInfoNeeded,&nProcInfo, rgpi, &dwReason); + if (dwError == ERROR_SUCCESS) { + if(nProcInfo == 1){ + std::string AppName(50,0); + size_t N; + wcstombs_s(&N,&AppName[0],50, rgpi[0].strAppName, 50); + if(!AppName.find(Sec("BeamNG.drive")) && GamePID == rgpi[0].Process.dwProcessId){ + Ret = true; + } + } + } + } + RmEndSession(dwSession); + } + return Ret; +} +void ContinuousCheck(fs::file_time_type last){ + std::string path = Sec(R"(BeamNG\mods\BeamMP.zip)"); + int i = 0; + while(fs::exists(path) && last == fs::last_write_time(path)){ + if(!BeamLoad(SecW(L"BeamNG\\mods\\BeamMP.zip"))) { + if (i < 60)i++; + else { + error(Sec("Mod did not load! launcher closing soon")); + std::this_thread::sleep_for(std::chrono::seconds(5)); + exit(0); + } + }else i = 0; + CheckDirs(); + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + } + exit(0); +} + +void SecureMods(){ + fs::file_time_type last = fs::last_write_time(Sec(R"(BeamNG\mods\BeamMP.zip)")); + auto* HandleCheck = new std::thread(ContinuousCheck,last); + HandleCheck->detach(); + delete HandleCheck; +} \ No newline at end of file diff --git a/src/Startup.cpp b/src/Startup.cpp new file mode 100644 index 0000000..d7246ac --- /dev/null +++ b/src/Startup.cpp @@ -0,0 +1,199 @@ +/// +/// Created by Anonymous275 on 7/16/2020 +/// +#include "Discord/discord_info.h" +#include "Network/network.h" +#include "Security/Init.h" +#include "Security/Enc.h" +#include "Curl/http.h" +#include +#include +#include "Logger.h" +#include +#include +bool Dev = false; +namespace fs = std::experimental::filesystem; +std::string GetEN(){ + return Sec("BeamMP-Launcher.exe"); +} +std::string GetVer(){ + return Sec("1.60"); +} +std::string GetPatch(){ + return Sec(""); +} +void ReLaunch(int argc,char*args[]){ + std::string Arg; + for(int c = 2; c <= argc; c++){ + Arg += " "; + Arg += args[c-1]; + } + system(Sec("cls")); + ShellExecute(nullptr,Sec("runas"),GetEN().c_str(),Arg.c_str(),nullptr,SW_SHOWNORMAL); + ShowWindow(GetConsoleWindow(),0); + std::this_thread::sleep_for(std::chrono::seconds(1)); + exit(1); +} +void URelaunch(int argc,char* args[]){ + std::string Arg; + for(int c = 2; c <= argc; c++){ + Arg += " "; + Arg += args[c-1]; + } + ShellExecute(nullptr,Sec("open"),GetEN().c_str(),Arg.c_str(),nullptr,SW_SHOWNORMAL); + ShowWindow(GetConsoleWindow(),0); + std::this_thread::sleep_for(std::chrono::seconds(1)); + exit(1); +} +void CheckName(int argc,char* args[]){ + struct stat info{}; + std::string DN = GetEN(),CDir = args[0],FN = CDir.substr(CDir.find_last_of('\\')+1); + if(FN != DN){ + if(stat(DN.c_str(),&info)==0)remove(DN.c_str()); + if(stat(DN.c_str(),&info)==0)ReLaunch(argc,args); + std::rename(FN.c_str(), DN.c_str()); + URelaunch(argc,args); + } +} +void RequestRole(){ + auto NPos = std::string::npos; + std::string HTTP_Result=HTTP_REQUEST(Sec("https://beammp.com/entitlement?did=")+GetDID()+Sec("&t=l"),443); + if(HTTP_Result == "-1"){ + error(Sec("Sorry Backend System Outage! Don't worry it will back on soon!")); + std::this_thread::sleep_for(std::chrono::seconds(3)); + exit(-1); + } + if(HTTP_Result.find(Sec("\"MDEV\"")) != NPos)Dev = true; + info(Sec("Client Connected!")); +} + +void CheckForUpdates(int argc,char*args[],const std::string& CV){ + std::string link = Sec("https://beammp.com/builds/launcher?version=true"); + std::string HTTP = HTTP_REQUEST(link,443); + if(HTTP.find_first_of("0123456789") == std::string::npos){ + error(Sec("Primary Servers Offline! sorry for the inconvenience!")); + std::this_thread::sleep_for(std::chrono::seconds(4)); + exit(-1); + } + link = Sec("https://beammp.com/builds/launcher?download=true"); + + struct stat buffer{}; + std::string Back = Sec("BeamMP-Launcher.back"); + if(stat(Back.c_str(), &buffer) == 0)remove(Back.c_str()); + if(HTTP > CV){ + system(Sec("cls")); + info(Sec("Update found!")); + info(Sec("Updating...")); + if(std::rename(GetEN().c_str(), Back.c_str()))error(Sec("failed creating a backup!")); + int i = Download(link, GetEN(),true); + if(i != -1){ + error(Sec("Launcher Update failed! trying again... code : ") + std::to_string(i)); + std::this_thread::sleep_for(std::chrono::seconds(2)); + int i2 = Download(link, GetEN(),true); + if(i2 != -1){ + error(Sec("Launcher Update failed! code : ") + std::to_string(i2)); + std::this_thread::sleep_for(std::chrono::seconds(5)); + ReLaunch(argc,args); + } + } + URelaunch(argc,args); + }else{ + info(Sec("Version is up to date")); + } +} +void CheckDir(int argc,char*args[]){ + std::string CDir = args[0]; + std::string MDir = Sec("BeamNG\\mods"); + if(!fs::is_directory(Sec("BeamNG"))){ + if(!fs::create_directory(Sec("BeamNG"))){ + error(Sec("Cannot Create BeamNG Directory! Retrying...")); + std::this_thread::sleep_for(std::chrono::seconds(3)); + ReLaunch(argc,args); + } + } + if(fs::is_directory(MDir) && !Dev){ + int c = 0; + for (auto& p : fs::directory_iterator(MDir))c++; + if(c > 2) { + warn(std::to_string(c-1) + Sec(" local mods will be wiped! Close this window if you don't want that!")); + std::this_thread::sleep_for(std::chrono::seconds(15)); + } + try{ + fs::remove_all(MDir); + } catch (...) { + error(Sec("Please close the game and try again")); + std::this_thread::sleep_for(std::chrono::seconds(5)); + exit(1); + } + } + if(fs::is_directory(MDir) && !Dev)ReLaunch(argc,args); + if(!fs::create_directory(MDir) && !Dev){ + error(Sec("Cannot Create Mods Directory! Retrying...")); + std::this_thread::sleep_for(std::chrono::seconds(3)); + ReLaunch(argc,args); + } + if(!fs::is_directory(Sec("BeamNG\\settings"))){ + if(!fs::create_directory(Sec("BeamNG\\settings"))){ + error(Sec("Cannot Create Settings Directory! Retrying...")); + std::this_thread::sleep_for(std::chrono::seconds(3)); + ReLaunch(argc,args); + } + } +} +void CustomPort(int argc, char* argv[]){ + if(argc > 1){ + std::string Port = argv[1]; + if(Port.find_first_not_of("0123456789") == std::string::npos){ + if(std::stoi(Port) > 1000){ + DEFAULT_PORT = std::stoi(Port); + warn(Sec("Running on custom port : ") + std::to_string(DEFAULT_PORT)); + } + } + if(argc > 2)Dev = false; + } +} +void InitLauncher(int argc, char* argv[]) { + system(Sec("cls")); + SetConsoleTitleA((Sec("BeamMP Launcher v") + std::string(GetVer()) + GetPatch()).c_str()); + InitLog(); + CheckName(argc, argv); + SecurityCheck(argv); + Discord_Main(); + RequestRole(); + CustomPort(argc, argv); + CheckForUpdates(argc, argv, std::string(GetVer()) + GetPatch()); +} + +void PreGame(int argc, char* argv[],const std::string& GamePath){ + info(Sec("Game Version : ") + CheckVer(GamePath)); + std::string DUI = Sec(R"(BeamNG\settings\uiapps-layouts.json)"); + std::string GS = Sec(R"(BeamNG\settings\game-settings.ini)"); + std::string link = Sec("https://beammp.com/client-ui-data"); + int i; + if(!fs::exists(DUI)){ + info(Sec("Downloading default ui data...")); + i = Download(link,DUI,true); + if(i != -1){ + remove(DUI.c_str()); + error(Sec("Failed to download code : ") + std::to_string(i)); + std::this_thread::sleep_for(std::chrono::seconds(3)); + ReLaunch(argc,argv); + } + info(Sec("Download Complete!")); + } + if(!fs::exists(GS)) { + info(Sec("Downloading default game settings...")); + link = Sec("https://beammp.com/client-settings-data"); + Download(link, GS,true); + info(Sec("Download Complete!")); + } + if(!Dev) { + info(Sec("Downloading mod...")); + link = Sec("https://beammp.com/builds/client?did=") + GetDID(); + Download(link, Sec(R"(BeamNG\mods\BeamMP.zip)"), false); + info(Sec("Download Complete!")); + } + debug(Sec("Name : ") + GetDName()); + debug(Sec("Discriminator : ") + GetDTag()); + debug(Sec("Unique ID : ") + GetDID()); +} \ No newline at end of file diff --git a/src/UpdateCheck.cpp b/src/UpdateCheck.cpp deleted file mode 100644 index 7cbece4..0000000 --- a/src/UpdateCheck.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/// -/// Created by Anonymous275 on 3/29/2020 -/// - -#include -#include -#include - -int Download(const std::string& URL,const std::string& path); -std::string HTTP_REQUEST(const std::string&url,int port); -void SystemExec(const std::string& cmd); -void URelaunch(int argc,char* args[]); -void ReLaunch(int argc,char*args[]); -void Exit(const std::string& Msg); -extern char*EName; -std::string hta(const std::string& hex) -{ - std::string ascii; - for (size_t i = 0; i < hex.length(); i += 2) - { - std::string part = hex.substr(i, 2); - char ch = char(stoul(part, nullptr, 16)); - ascii += ch; - } - return ascii; -} - -void CheckForUpdates(int argc,char*args[],const std::string& CV){ - std::string link = hta("68747470733a2f2f6265616d6e672d6d702e636f6d2f6275696c64732f6c61756e636865723f76657273696f6e3d74727565"); - //https://beamng-mp.com/builds/launcher?version=true - std::string HTTP = HTTP_REQUEST(link,443); - if(HTTP.find_first_of("0123456789") == std::string::npos){ - Exit("Primary Servers Offline! sorry for the inconvenience!"); - } - link = hta("68747470733a2f2f6265616d6e672d6d702e636f6d2f6275696c64732f6c61756e636865723f646f776e6c6f61643d74727565"); - //https://beamng-mp.com/builds/launcher?download=true - - struct stat buffer{}; - std::string Back = hta("4265616d4d502d4c61756e636865722e6261636b"); - //BeamMP-Launcher.back - if(stat(Back.c_str(), &buffer) == 0)remove(Back.c_str()); - if(HTTP > CV){ - system("cls"); - std::cout << "Update found!" << std::endl; - std::cout << "Updating..." << std::endl; - SystemExec("rename "+hta(EName)+" "+Back+">nul"); - if(int i = Download(link, hta(EName)) != -1){ - std::cout << "Launcher Update failed! trying again... code : " << i << std::endl; - std::this_thread::sleep_for(std::chrono::seconds(2)); - if(int i2 = Download(link, hta(EName)) != -1){ - std::cout << "Launcher Update failed! code : " << i2 << std::endl; - std::this_thread::sleep_for(std::chrono::seconds(5)); - ReLaunch(argc,args); - } - } - URelaunch(argc,args); - }else{ - std::cout << "Version is up to date" << std::endl; - } -} \ No newline at end of file diff --git a/src/VehicleNetwork.cpp b/src/VehicleNetwork.cpp deleted file mode 100644 index 79de19c..0000000 --- a/src/VehicleNetwork.cpp +++ /dev/null @@ -1,164 +0,0 @@ -/// -/// Created by Anonymous275 on 4/23/2020 -/// - -#include -#include -#include -#include -#include -#include - -extern bool TCPTerminate; -extern bool Dev; -void Print(const std::string&MSG); -std::queue VNTCPQueue; -//void RUDPSEND(const std::string&Data,bool Rel); -#define DEFAULT_PORT "4446" - -void Responder(const SOCKET *CS){ - SOCKET ClientSocket = *CS; - int iSendResult; - while(!TCPTerminate){ - while (!VNTCPQueue.empty()) { - VNTCPQueue.front() += "\n"; - iSendResult = send(ClientSocket, VNTCPQueue.front().c_str(), VNTCPQueue.front().length(), 0); - if (iSendResult == SOCKET_ERROR) { - if(Dev)std::cout << "(VN) send failed with error: " << WSAGetLastError() << std::endl; - break; - } else { - if(iSendResult > 1000){ - if(Dev){std::cout << "(Launcher->Game VN) Bytes sent: " << iSendResult << " : " << VNTCPQueue.front().substr(0, 10) - << VNTCPQueue.front().substr(VNTCPQueue.front().length()-10) << std::endl;} - } - VNTCPQueue.pop(); - } - } - std::this_thread::sleep_for(std::chrono::nanoseconds(1)); - } -} -std::string Compress(const std::string&Data); -std::string Decompress(const std::string&Data); -void VehicleNetworkStart(){ - do { - if(Dev)std::cout << "VN on Start" << std::endl; - WSADATA wsaData; - int iResult; - SOCKET ListenSocket = INVALID_SOCKET; - SOCKET ClientSocket = INVALID_SOCKET; - - struct addrinfo *result = nullptr; - struct addrinfo hints{}; - - int iSendResult; - char recvbuf[7507]; - int recvbuflen = 6507; - - // Initialize Winsock - iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); - if (iResult != 0) { - if(Dev)std::cout << "(VN) WSAStartup failed with error: " << iResult << std::endl; - std::cin.get(); - exit(-1); - } - - ZeroMemory(&hints, sizeof(hints)); - hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - hints.ai_flags = AI_PASSIVE; - - // Resolve the server address and port - iResult = getaddrinfo(nullptr, DEFAULT_PORT, &hints, &result); - if (iResult != 0) { - if(Dev)std::cout << "(VN) getaddrinfo failed with error: " << iResult << std::endl; - WSACleanup(); - break; - } - - // Create a socket for connecting to server - ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol); - if (ListenSocket == INVALID_SOCKET) { - if(Dev)std::cout << "(VN) socket failed with error: " << WSAGetLastError() << std::endl; - freeaddrinfo(result); - WSACleanup(); - break; - } - - // Setup the TCP listening socket - iResult = bind(ListenSocket, result->ai_addr, (int) result->ai_addrlen); - if (iResult == SOCKET_ERROR) { - if(Dev)std::cout << "(VN) bind failed with error: " << WSAGetLastError() << std::endl; - freeaddrinfo(result); - closesocket(ListenSocket); - WSACleanup(); - break; - } - - freeaddrinfo(result); - - iResult = listen(ListenSocket, SOMAXCONN); - if (iResult == SOCKET_ERROR) { - if(Dev)std::cout << "(VN) listen failed with error: " << WSAGetLastError() << std::endl; - closesocket(ListenSocket); - WSACleanup(); - continue; - } - ClientSocket = accept(ListenSocket, NULL, NULL); - if (ClientSocket == INVALID_SOCKET) { - if(Dev)std::cout << "(VN) accept failed with error: " << WSAGetLastError() << std::endl; - closesocket(ListenSocket); - WSACleanup(); - continue; - } - closesocket(ListenSocket); - if(Dev)std::cout << "(VN) Game Connected!" << std::endl; - - std::thread TCPSend(Responder,&ClientSocket); - TCPSend.detach(); - do { - //std::cout << "(Proxy) Waiting for Game Data..." << std::endl; - iResult = recv(ClientSocket, recvbuf, recvbuflen, 0); - if (iResult > 0) { - std::string buff; - buff.resize(iResult*2); - memcpy(&buff[0],recvbuf,iResult); - buff.resize(iResult); - //Print(buff); - if(Dev) { - std::string cmp = Compress(buff), dcm = Decompress(cmp); - std::cout << "Compressed Size : " << cmp.length() << std::endl; - std::cout << "Decompressed Size : " << dcm.length() << std::endl; - if (cmp == dcm) { - std::cout << "Success!" << std::endl; - } else { - std::cout << "Fail!" << std::endl; - } - } - //RUDPSEND(buff,false); - //std::cout << "(Game->Launcher VN) Data : " << buff.length() << std::endl; - } else if (iResult == 0) { - if(Dev)std::cout << "(VN) Connection closing...\n"; - closesocket(ClientSocket); - WSACleanup(); - - continue; - } else { - if(Dev)std::cout << "(VN) recv failed with error: " << WSAGetLastError() << std::endl; - closesocket(ClientSocket); - WSACleanup(); - continue; - } - } while (iResult > 0); - - iResult = shutdown(ClientSocket, SD_SEND); - if (iResult == SOCKET_ERROR) { - if(Dev)std::cout << "(VN) shutdown failed with error: " << WSAGetLastError() << std::endl; - closesocket(ClientSocket); - WSACleanup(); - continue; - } - closesocket(ClientSocket); - WSACleanup(); - }while (!TCPTerminate); -} \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 7b836d4..9310f94 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,212 +1,26 @@ -//// -//// Created by Anonymous275 on 3/3/2020. -//// -#include -#include -#include -#include -#include -#include +/// +/// Created by Anonymous275 on 7/16/2020 +/// +#include "Network/network.h" +#include "Security/Init.h" +#include "Startup.h" #include -int Download(const std::string& URL,const std::string& OutFileName); -void StartGame(const std::string&ExeDir,const std::string&Current); -std::string HTTP_REQUEST(const std::string&url,int port); -void CheckForUpdates(int argc,char*args[],const std::string& CV); -char*EName = (char*)"4265616d4d502d4c61756e636865722e657865"; -extern std::vector GlobalInfo; -std::string HTA(const std::string& hex); -extern std::vector SData; -std::string getHardwareID(); -char* ver = (char*)"312e3530"; //1.50 -char* patchlevel = (char*)""; -int DEFAULT_PORT = 4444; -void Discord_Main(); -bool Dev = false; -void ProxyStart(); -void ExitError(); -void Check(); +#include -void SystemExec(const std::string& cmd){ - system(cmd.c_str()); -} - -void WinExec(const std::string& cmd){ - WinExec(cmd.c_str(), SW_HIDE); -} - -void Exit(const std::string& Msg){ - std::cout << Msg << std::endl; - std::cout << "Press Enter to continue..."; - std::cin.ignore(); - exit(-1); -} -void ReLaunch(int argc,char*args[]){ - std::string Arg; - for(int c = 2; c <= argc; c++){ - Arg += " "; - Arg += args[c-1]; - } - system("cls"); - ShellExecute(nullptr,"runas",HTA(EName).c_str(),Arg.c_str(),nullptr,SW_SHOWNORMAL); - exit(1); -} -std::string CheckDir(int argc,char*args[]){ - struct stat info{}; - std::string CDir = args[0]; - if(stat("BeamNG",&info)){ - SystemExec("mkdir BeamNG>nul"); - if(stat("BeamNG",&info))ReLaunch(argc,args); - } - if(!stat("BeamNG\\mods",&info))SystemExec("RD /S /Q BeamNG\\mods>nul"); - if(!stat("BeamNG\\mods",&info))ReLaunch(argc,args); - SystemExec("mkdir BeamNG\\mods>nul"); - if(stat("BeamNG\\settings",&info))SystemExec("mkdir BeamNG\\settings>nul"); - return CDir.substr(0,CDir.find_last_of('\\')) + "\\BeamNG"; -} - -std::string CheckVer(const std::string &path){ - std::string vec,temp,Path = path.substr(0,path.find_last_of('\\')) + "\\integrity.json"; - std::ifstream f(Path.c_str(), std::ios::binary); - f.seekg(0, std::ios_base::end); - std::streampos fileSize = f.tellg(); - vec.resize(size_t(fileSize) + 1); - f.seekg(0, std::ios_base::beg); - f.read(&vec[0], fileSize); - f.close(); - vec = vec.substr(vec.find_last_of("version"),vec.find_last_of('"')); - for(const char &a : vec){ - if(isdigit(a) || a == '.')temp+=a; - } - return temp; -} - -void URelaunch(int argc,char* args[]){ - std::string Arg; - for(int c = 2; c <= argc; c++){ - Arg += " "; - Arg += args[c-1]; - } - ShellExecute(nullptr,"open",HTA(EName).c_str(),Arg.c_str(),nullptr,SW_SHOWNORMAL); - exit(1); -} - -void CheckName(int argc,char* args[]){ - struct stat info{}; - std::string DN = HTA(EName),CDir = args[0],FN = CDir.substr(CDir.find_last_of('\\')+1); - if(FN != DN){ - if(stat(DN.c_str(),&info)==0)remove(DN.c_str()); - if(stat(DN.c_str(),&info)==0)ReLaunch(argc,args); - SystemExec("rename \""+ FN +"\" " + DN + ">nul"); - URelaunch(argc,args); +[[noreturn]] void aa(){ + while(true){ + std::cout.flush(); + std::this_thread::sleep_for(std::chrono::milliseconds(500)); } } -void SecurityCheck(){ - int i = 0; - std::ifstream f(HTA(EName), std::ios::binary); - f.seekg(0, std::ios_base::end); - std::streampos fileSize = f.tellg(); - if(IsDebuggerPresent() || fileSize > 0x60B5F){ - i++; - GlobalInfo.clear(); - GlobalInfo.at(13); - } - if(i){ - GlobalInfo.clear(); - GlobalInfo.at(13); - } - f.close(); +int main(int argc, char* argv[]) { + std::thread gb(aa); + gb.detach(); + InitLauncher(argc,argv); + CheckDir(argc,argv); + LegitimacyCheck(); + PreGame(argc,argv,GetGameDir()); + InitGame(GetGameDir(),argv[0]); + CoreNetwork(); } -int main(int argc, char* argv[]){ - const unsigned long long NPos = std::string::npos; - struct stat info{}; - system("cls"); - SetConsoleTitleA(("BeamMP Launcher v" + HTA(ver) + patchlevel).c_str()); - CheckName(argc,argv); - SecurityCheck(); - std::string link, HTTP_Result; - std::thread t1(Discord_Main); - t1.detach(); - std::cout << "Connecting to discord client..." << std::endl; - while(GlobalInfo.empty())std::this_thread::sleep_for(std::chrono::milliseconds(300)); - std::cout << "Client Connected!" << std::endl; - //https://beamng-mp.com/entitlement?did=(ID)&t=l; - HTTP_Result = HTTP_REQUEST(HTA("68747470733a2f2f6265616d6e672d6d702e636f6d2f656e7469746c656d656e743f6469643d")+ - HTA(GlobalInfo.at(2) + "26743d6c"),443); - /*if (HTTP_Result.find("\"MOD\"") == NPos && HTTP_Result.find("\"EA\"") == NPos){ - if (HTTP_Result.find("\"SUPPORT\"") == NPos && HTTP_Result.find("\"YT\"") == NPos){ - exit(-1); - } - }*/ - - SecurityCheck(); - if(HTTP_Result.find('"') == NPos && HTTP_Result != "[]"){ - std::cout << HTA("596f7520617265206e6f7420696e20746865206f6666696369616c204265616d4d5020446973636f726420706c65617365206a6f696e20616e642074727920616761696e2068747470733a2f2f646973636f72642e67672f6265616d6d70") << std::endl; - std::this_thread::sleep_for(std::chrono::seconds(3)); - exit(-1); - } - if(HTTP_Result.find(HTA("224d44455622")) != NPos)Dev = true; - std::string Path = CheckDir(argc,argv); - std::thread CFU(CheckForUpdates,argc,argv,HTA(ver)+patchlevel); - CFU.join(); - - if(argc > 1){ - std::string Port = argv[1]; - if(Port.find_first_not_of("0123456789") == NPos){ - if(std::stoi(Port) > 1000){ - DEFAULT_PORT = std::stoi(Port); - std::cout << "Running on custom port : " << DEFAULT_PORT << std::endl; - } - } - if(argc > 2)Dev = false; - } - - //Security - auto*Sec = new std::thread(Check); - Sec->join(); - delete Sec; - SecurityCheck(); - if(SData.size() != 3)ExitError(); - std::string GamePath = SData.at(2); - std::cout << "Game Version : " << CheckVer(GamePath) << std::endl; - std::string ExeDir = GamePath.substr(0,GamePath.find_last_of('\\')) + R"(\Bin64\BeamNG.drive.x64.exe)"; - std::string DUI = Path + R"(\settings\uiapps-layouts.json)"; - std::string GS = Path + R"(\settings\game-settings.ini)"; - if(stat(DUI.c_str(),&info)!=0 || stat(GS.c_str(),&info)!=0){ - link = "https://beamng-mp.com/client-ui-data"; - std::cout << "Downloading default config..." << std::endl; - if(int i = Download(link,DUI) != -1){ - remove(DUI.c_str()); - std::cout << "Error! Failed to download code : " << i << std::endl; - std::this_thread::sleep_for(std::chrono::seconds(3)); - ReLaunch(argc,argv); - } - link = "https://beamng-mp.com/client-settings-data"; - Download(link,GS); - std::cout << "Download Complete!" << std::endl; - } - DUI.clear(); - GS.clear(); - if(!Dev){ - std::cout << "Downloading mod..." << std::endl; - //https://beamng-mp.com/builds/client?did=(ID) - link = HTA("68747470733a2f2f6265616d6e672d6d702e636f6d2f6275696c64732f636c69656e743f6469643d") - +HTA(GlobalInfo.at(2)); - Download(link,Path + R"(\mods\BeamMP.zip)"); - std::cout << "Download Complete!" << std::endl; - link.clear(); - std::thread Game(StartGame,ExeDir,(Path + "\\")); - Game.detach(); - }else{ - SecurityCheck(); - std::cout << "Name : " << GlobalInfo.at(0) << std::endl; - std::cout << "Discriminator : " << HTA(GlobalInfo.at(1)) << std::endl; - std::cout << "Unique ID : " << HTA(GlobalInfo.at(2)) << std::endl; - //std::cout << "HWID : " << getHardwareID() << std::endl; - std::cout << "you have : " << HTTP_Result << std::endl; - } - - ProxyStart(); - Exit(""); - return 0; -} \ No newline at end of file