From 3d412a4b30a9f7c7f51ea6562e694315948bd3da Mon Sep 17 00:00:00 2001 From: boris Date: Wed, 28 Nov 2018 16:00:02 +1300 Subject: cleaned up in short, the cheat and loader are now separate solutions. unused stuff was moved into the legacy solution in case anyone wants to compile it or whatever. i can change this back if you want to. also, i configured the loader to compile in x64, and have separate build types for linux and win64 --- loader/client/client.vcxproj | 262 ++++++++++++++++++++++++++++++++ loader/client/client.vcxproj.filters | 12 ++ loader/client/client_windows.cpp | 58 +++++++ loader/client/connect.hpp | 282 +++++++++++++++++++++++++++++++++++ loader/client/err.hpp | 22 +++ loader/client/strings.hpp | 163 ++++++++++++++++++++ loader/client/util.hpp | 33 ++++ 7 files changed, 832 insertions(+) create mode 100644 loader/client/client.vcxproj create mode 100644 loader/client/client.vcxproj.filters create mode 100644 loader/client/client_windows.cpp create mode 100644 loader/client/connect.hpp create mode 100644 loader/client/err.hpp create mode 100644 loader/client/strings.hpp create mode 100644 loader/client/util.hpp (limited to 'loader/client') diff --git a/loader/client/client.vcxproj b/loader/client/client.vcxproj new file mode 100644 index 0000000..0e44455 --- /dev/null +++ b/loader/client/client.vcxproj @@ -0,0 +1,262 @@ + + + + + Debug + Win32 + + + D_LinuxServer + Win32 + + + D_LinuxServer + x64 + + + Release_Windows + Win32 + + + Release_Windows + x64 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + + + + + + + + + + 15.0 + {B03A0B07-AA28-4122-842D-1B2457F70334} + client + 10.0.17763.0 + + + + Application + true + v141 + MultiByte + + + Application + true + v141 + MultiByte + + + Application + false + v141 + true + MultiByte + + + Application + false + v141 + true + MultiByte + + + Application + true + v141 + MultiByte + + + Application + true + v141 + MultiByte + + + Application + false + v141 + true + MultiByte + + + Application + false + v141 + true + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + false + + + false + + + false + + + + Level3 + Disabled + true + true + + + + + Level3 + Disabled + true + true + + + + + Level4 + Disabled + true + true + stdcpplatest + FastCall + AdvancedVectorExtensions2 + _CRT_SECURE_NO_WARNINGS;WIN64;VC_EXTRALEAN;_MBCS;%(PreprocessorDefinitions) + + + false + + + + + Level4 + Disabled + true + true + stdcpplatest + FastCall + AdvancedVectorExtensions2 + _CRT_SECURE_NO_WARNINGS;WIN64;VC_EXTRALEAN;_MBCS;%(PreprocessorDefinitions) + + + false + + + + + Level3 + MaxSpeed + true + true + true + true + + + true + true + + + + + Level3 + MaxSpeed + true + true + true + true + + + true + true + + + + + Level4 + MaxSpeed + true + true + true + true + stdcpplatest + FastCall + AdvancedVectorExtensions2 + _CRT_SECURE_NO_WARNINGS;WIN64;VC_EXTRALEAN;_MBCS;%(PreprocessorDefinitions) + + + true + true + false + + + + + Level4 + MaxSpeed + true + true + true + true + stdcpplatest + FastCall + AdvancedVectorExtensions2 + _CRT_SECURE_NO_WARNINGS;WIN64;VC_EXTRALEAN;_MBCS;%(PreprocessorDefinitions) + + + true + true + false + + + + + + \ No newline at end of file diff --git a/loader/client/client.vcxproj.filters b/loader/client/client.vcxproj.filters new file mode 100644 index 0000000..b5f56db --- /dev/null +++ b/loader/client/client.vcxproj.filters @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/loader/client/client_windows.cpp b/loader/client/client_windows.cpp new file mode 100644 index 0000000..1b493d6 --- /dev/null +++ b/loader/client/client_windows.cpp @@ -0,0 +1,58 @@ +#include +#include +#include +#include +#include +#include + +#pragma comment( lib, "ws2_32.lib" ) + +#include "connect.hpp" + +/* + 1. Connect + 2. Send hello message + 3. Receive hello message from server, + 4. Enter and send username + 5. Enter and send password (use bcrypt or some shit idk) + 6. Send and let server check hardware id. + 7. Recieve list of games. + 8. Select game and send to server + 9. Receive space of dll. + 10. Allocate space for dll. + 11. Send base address of dll. + 12a. Server does relocations. + 12b. Server does imports. + 13. Server sends dll + 14. Client Manual maps dll + 15. Send game module list and possibly PE headers + 16. Server sends back needed module base addresses and possibly size. + 17. Call DLLMain with correct parameters (Included Base Addresses) + 18. In cheat DLLMain set up base addresses and do cheat stuff. +*/ + + + + +// note below is just pseudo unprotected code... +// will make not retarded soon. +int main( ) { + // TEMPORARY, WE NEED TO ENCRYPT IP STRING SO WE DON'T HAVE DDOS NOOBS. + // or we could do char address[] = { 127, 0, 0, 1 }; + std::string ip = "127.0.0.1"; + // std::cin >> ip; + + // START. + client::c_connect c( ip.c_str( ) ); + if( !c.setup( ) ) + return 1; + + if( !c.connect( ) ) + return 2; + + c.handle( ); + + system( "pause" ); + + return 0; +} diff --git a/loader/client/connect.hpp b/loader/client/connect.hpp new file mode 100644 index 0000000..ddf23a0 --- /dev/null +++ b/loader/client/connect.hpp @@ -0,0 +1,282 @@ +#pragma once + +#include +#include +#include +#include +#include + +#pragma comment( lib, "ws2_32.lib" ) + +#include + +/* TEST */ +#include +#include +/* TEST */ + +#include "err.hpp" +#include "util.hpp" + +/* +protocol rules: +every msg must be xored +first byte is the xorkey + +*/ + +namespace client +{ + constexpr auto PORT_NUM = 6969; + constexpr auto BUFFER_SIZE = 255; + + class c_connect { + public: + c_connect( const char* ip ) : + m_ip( inet_addr( ip ) ) { } + + ~c_connect( ) { + if( m_socket ) + closesocket( m_socket ); + + WSACleanup( ); + } + + bool setup( ) { + int code{ }; + + if( WSAStartup( MAKEWORD( 2, 2 ), &m_wsdata ) ) + code = err::ERR_WSA; + else { + m_socket = socket( AF_INET, SOCK_STREAM, 0 ); + if( m_socket == INVALID_SOCKET ) + code = err::ERR_WSA; + } + + if( code != err::ERR_NONE ) { + MessageBoxA( nullptr, err::translate_err( code ), "", MB_OK ); + return false; + } + + return true; + } + + bool connect( ) { + sockaddr_in server_address{ }; + int code{ }; + + server_address.sin_addr.s_addr = m_ip; + server_address.sin_port = htons( PORT_NUM ); + server_address.sin_family = AF_INET; + + code = ::connect( m_socket, ( sockaddr* )( &server_address ), + sizeof( server_address ) ); + + if( code == -1 ) { + MessageBoxA( nullptr, err::translate_err( err::ERR_CONNECT ), "", MB_OK ); + return false; + } + + return true; + } + + void decode_buffer( uint8_t* buf, size_t length ) { + auto key = buf[ 0 ]; + for( size_t i{ 1 }; i < length; ++i ) + buf[ i ] ^= key; + } + + std::string get_string( ) { + std::string ret{ }; + char buffer[ BUFFER_SIZE ]; + + + while ( true ) { + int received = recv( m_socket, buffer, BUFFER_SIZE, 0 ); + if ( received < 0 ) + break; + + for ( int i{ }; i < received; ++i ) + ret.push_back( buffer[ i ] ); + + if ( received < BUFFER_SIZE ) + break; + } + + if ( ret.size( ) ) { + decode_buffer( ( uint8_t* )ret.data( ), ret.size( ) ); + ret.erase( ret.begin( ) ); + } + + return ret; + } + + std::vector< uint8_t > get_msg( ) { + std::vector< uint8_t > ret; + char buffer[ BUFFER_SIZE ]; + int received = 0; + + while( true ) { + received = recv( m_socket, buffer, BUFFER_SIZE, 0 ); + if( received < 0 ) + break; + + for( int i{ }; i < received; ++i ) + ret.push_back( buffer[ i ] ); + + if( received < BUFFER_SIZE ) + break; + } + + if( ret.size( ) ) { + decode_buffer( ret.data( ), ret.size( ) ); + ret.erase( ret.begin( ) ); + } + return ret; + } + + void send_msg( const uint8_t* msg, int length ) { + auto buffer = std::make_unique< uint8_t[ ] >( length + 1 ); + uint8_t key = util::random_number( 0, 255 ) & 0xff; + + buffer[ 0 ] = key; + memcpy( buffer.get( ) + 1, + msg, + length ); + + for( int i = 1; i <= length; ++i ) { + buffer[ i ] ^= key; + } + + int ret = send( m_socket, ( char* )buffer.get( ), length + 1, 0 ); + if ( ret == SOCKET_ERROR ) { + printf( xors( "error sending message error code: %d" ), WSAGetLastError( ) ); + } + } + + void send_msg( const char* msg ) { + auto length = strlen( msg ); + auto buffer = std::make_unique< uint8_t[ ] >( length + 1 ); + uint8_t key = util::random_number( 0, 255 ) & 0xff; + + buffer[ 0 ] = key; + memcpy( buffer.get( ) + 1, + msg, + length ); + + for ( size_t i = 1; i <= length; ++i ) { + buffer[ i ] ^= key; + } + + int ret = send( m_socket, ( char* )buffer.get( ), (int) length + 1, 0 ); + if ( ret == SOCKET_ERROR ) { + printf( xors( "error sending message error code: %d" ), WSAGetLastError( ) ); + } + } + + + void send_msg( const char msg ) { + auto buffer = std::make_unique< uint8_t[ ] >( 2 ); + uint8_t key = util::random_number( 0, 255 ) & 0xff; + + buffer[ 0 ] = key; + buffer[ 1 ] = msg; + buffer[ 1 ] ^= buffer[ 0 ]; + + int ret = send( m_socket, ( char* )buffer.get( ), 2, 0 ); + if ( ret == SOCKET_ERROR ) { + printf( xors( "error sending message error code: %d" ), WSAGetLastError( ) ); + } + } + + void handle( ) { + + auto msg = get_string( ); + if ( msg != xors( "hello" ) ) { + std::cout << "connection failed." << std::endl; + //return 0; + } + + send_msg( "hello" ); + + std::string username{ }, password{ }; + std::cout << "Enter your username" << std::endl << "> "; + std::cin >> username; + + send_msg( username.c_str( ) ); + msg = get_string( ); + std::cout < "; + std::cin >> password; + + send_msg( password.c_str( ) ); + if ( get_string( ) != xors( "correct password" ) ) { + std::cout << "incorrect password"; + //return 0; // remember to close connection on server when bad values were sent. + } + + // Receive list of games, + msg = get_string( ); + std::cout << msg << std::endl; + + + std::cout << "For what game do you want to inject on?" << std::endl << "> "; + + char game_id{ }; + std::cin >> game_id; + + send_msg( game_id ); + + // get process name. + msg = get_string( ); + + std::cout << msg << std::endl; + + int process_identifier{ }; + + HANDLE snapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 ); + if ( snapshot != INVALID_HANDLE_VALUE ) { + PROCESSENTRY32 entry{ sizeof( PROCESSENTRY32 ) }; + + if ( Process32First( snapshot, &entry ) ) { + do { + if ( msg == entry.szExeFile ) { + process_identifier = entry.th32ProcessID; + break; + } + } while ( Process32Next( snapshot, &entry ) ); + } + } + + if ( !process_identifier ) { + std::cout << "Could not find process." << std::endl; + return; + } + + std::cout << "found" << std::endl; + send_msg( "found" ); + + auto file = get_msg( ); + auto file_data = file.data( ); + auto file_size = file.size( ); + + auto save_file = std::ofstream( "gmod.txt", std::ofstream::binary ); + if ( save_file.is_open( ) ) { + save_file.write( ( const char* )file_data, file_size ); + save_file.close( ); + } + + + } + + private: + SOCKET m_socket; + WSADATA m_wsdata; + int m_ip; + }; +} \ No newline at end of file diff --git a/loader/client/err.hpp b/loader/client/err.hpp new file mode 100644 index 0000000..5a6691d --- /dev/null +++ b/loader/client/err.hpp @@ -0,0 +1,22 @@ +#pragma once +#include "strings.hpp" + +namespace err +{ + enum ErrCode_t { + ERR_NONE = 0, + ERR_WSA = 1, + ERR_CONNECT = 2, + }; + + const char* translate_err( int code ) { + switch( code ) { + case ERR_WSA: + return xors( "socket error" ); + case ERR_CONNECT: + return xors( "connection error" ); + } + + return xors( "unknown error" ); + } +} \ No newline at end of file diff --git a/loader/client/strings.hpp b/loader/client/strings.hpp new file mode 100644 index 0000000..b5dba75 --- /dev/null +++ b/loader/client/strings.hpp @@ -0,0 +1,163 @@ +//-------------------------------------------------------------------------------- +//-- XorCompileTime.hpp +// +// Author: frk +// Date: 12.12.2015 +// +//-------------------------------------------------------------------------------- + +#pragma once +#include +#include +#include + +#define BEGIN_NAMESPACE( x ) namespace x { +#define END_NAMESPACE } + +BEGIN_NAMESPACE( strenc ) + +constexpr auto time = __TIME__; +constexpr auto seed = static_cast< int >( time[ 7 ] ) + static_cast< int >( time[ 6 ] ) * 10 + static_cast< int >( time[ 4 ] ) * 60 + static_cast< int >( 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 < int N > +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 & 0xFFFF ); // Multiply lower 16 bits by 16807 + static constexpr unsigned hi = a * ( s >> 16 ); // Multiply higher 16 bits by 16807 + static constexpr unsigned lo2 = lo + ( ( hi & 0x7FFF ) << 16 ); // Combine lower 15 bits of hi with lo's upper bits + static constexpr unsigned hi2 = hi >> 15; // 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 < int N, int M > +struct RandomInt { + static constexpr auto value = RandomGenerator< N + 1 >::value % M; +}; + +template < int N > +struct RandomChar { + static const char value = static_cast< char >( 1 + RandomInt< N, 0x7F - 1 >::value ); +}; + +template < size_t N, int K > +struct XorString { +private: + const char _key; + std::array< char, N + 1 > _encrypted; + bool decrypted = false; + + constexpr char enc( char c ) const { + return c ^ _key; + } + + char dec( char c ) const { + return c ^ _key; + } + +public: + template < size_t... Is > + constexpr __forceinline XorString( const char* const str, std::index_sequence< Is... > ) : _key( RandomChar< K >::value ), _encrypted{ enc( str[ Is ] )... } { + } + + __forceinline const char* decrypt( void ) { + if( !decrypted ) { + for( size_t i = 0; i < N; ++i ) { + _encrypted[ i ] = dec( _encrypted[ i ] ); + } + _encrypted[ N ] = '\0'; + decrypted = true; + } + + return _encrypted.data( ); + } +}; + +//-------------------------------------------------------------------------------- +//-- Note: XorStr will __NOT__ work directly with functions like printf. +// To work with them you need a wrapper function that takes a const char* +// as parameter and passes it to printf and alike. +// +// The Microsoft Compiler/Linker is not working correctly with variadic +// templates! +// +// Use the functions below or use std::cout (and similar)! +//-------------------------------------------------------------------------------- + +#if( 1 ) +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_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 ); +}; +#endif + +//for compatibility with debug mode +struct debug_ret { +private: + const char* ret; + +public: + debug_ret( const char* str ) : ret( str ) { }; + + auto decrypt( ) { + return ret; + } +}; + +constexpr size_t strlen_ct( const char* const str ) { + size_t out = 1; + + for( ; str[ out ] != '\0'; ++out ); + + return out; +} + +#if TRUE +#define xors_raw( s ) ( strenc::XorString< strenc::strlen_ct( s ), __COUNTER__ >( s, std::make_index_sequence< sizeof( s ) - 1>() ) ) +#define xors( s ) ( strenc::XorString< strenc::strlen_ct( s ), __COUNTER__ >( s, std::make_index_sequence< sizeof( s ) - 1>() ).decrypt() ) +#else +#define xors_raw( s ) ( [ ]{ strenc::debug_ret ret{ s }; return ret; }( ) ) +#define xors( s ) ( s ) +#endif + +END_NAMESPACE \ No newline at end of file diff --git a/loader/client/util.hpp b/loader/client/util.hpp new file mode 100644 index 0000000..aabfd69 --- /dev/null +++ b/loader/client/util.hpp @@ -0,0 +1,33 @@ +#pragma once + +#include +#include "strings.hpp" + +#include + +namespace util +{ + namespace { + //make a random generator and seed it with a p random number + static std::random_device rd; + static std::mt19937 gen( rd( ) ); + } + + template < typename t > + __forceinline t random_number( t min, t max ) { + if constexpr( !std::is_integral_v< t > ) { + std::uniform_real_distribution< t > dist( min, max ); + return dist( gen ); + } + else { + std::uniform_int_distribution< t > dist( min, max ); + return dist( gen ); + } + } + + // okay now this is epic + __forceinline void raise_error(const char *error) { + MessageBoxA(0, error, xors("error"), MB_ICONERROR); + ExitProcess(0); + } +} \ No newline at end of file -- cgit v1.2.3