commit d57c5a2e169d0d880e8a06e0ba5e74b9e6492dfe Author: c0dycode Date: Sat Jul 31 19:22:15 2021 +0200 Initial push diff --git a/.vs/BL3ProxySettings/v16/.suo b/.vs/BL3ProxySettings/v16/.suo new file mode 100644 index 0000000..f7c2479 Binary files /dev/null and b/.vs/BL3ProxySettings/v16/.suo differ diff --git a/.vs/BL3ProxySettings/v16/Browse.VC.db b/.vs/BL3ProxySettings/v16/Browse.VC.db new file mode 100644 index 0000000..1852781 Binary files /dev/null and b/.vs/BL3ProxySettings/v16/Browse.VC.db differ diff --git a/.vs/BL3ProxySettings/v16/Solution.VC.db b/.vs/BL3ProxySettings/v16/Solution.VC.db new file mode 100644 index 0000000..6cf3d82 Binary files /dev/null and b/.vs/BL3ProxySettings/v16/Solution.VC.db differ diff --git a/.vs/BL3ProxySettings/v16/ipch/AutoPCH/5336a262cf7118e1/BL3PROXYSETTINGS.ipch b/.vs/BL3ProxySettings/v16/ipch/AutoPCH/5336a262cf7118e1/BL3PROXYSETTINGS.ipch new file mode 100644 index 0000000..1b706b3 Binary files /dev/null and b/.vs/BL3ProxySettings/v16/ipch/AutoPCH/5336a262cf7118e1/BL3PROXYSETTINGS.ipch differ diff --git a/.vs/BL3ProxySettings/v16/ipch/AutoPCH/7e154376a901799a/MINHOOK.ipch b/.vs/BL3ProxySettings/v16/ipch/AutoPCH/7e154376a901799a/MINHOOK.ipch new file mode 100644 index 0000000..456c69e Binary files /dev/null and b/.vs/BL3ProxySettings/v16/ipch/AutoPCH/7e154376a901799a/MINHOOK.ipch differ diff --git a/.vs/BL3ProxySettings/v16/ipch/AutoPCH/fafe9dce735647df/BL3PROXYSETTINGS.ipch b/.vs/BL3ProxySettings/v16/ipch/AutoPCH/fafe9dce735647df/BL3PROXYSETTINGS.ipch new file mode 100644 index 0000000..d7ec4b3 Binary files /dev/null and b/.vs/BL3ProxySettings/v16/ipch/AutoPCH/fafe9dce735647df/BL3PROXYSETTINGS.ipch differ diff --git a/BL3ProxySettings.cpp b/BL3ProxySettings.cpp new file mode 100644 index 0000000..4a8200e --- /dev/null +++ b/BL3ProxySettings.cpp @@ -0,0 +1,1485 @@ +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif + +#include +#include +//#include +#include +#include +#include +//#include + +#include "include/MinHook.h" +#ifdef __clang__ +#pragma comment(lib, "lib/libMinHook-MD.x64.Clang.lib") +#else +#pragma comment(lib, "lib/libMinHook-MD.x64.lib") +#endif + +//#include "F:/Programmieren/C++/myhelpers/xorstr.h" +#define JM_XORSTR_DISABLE_AVX_INTRINSICS 1 +#include "F:/Programmieren/C++/xorstr-master/include/xorstr.hpp" +//#include "F:/Programmieren/C++/myhelpers/SuspendResume.hpp" +#include "include/patternscan.hpp" +// +#include "F:/Programmieren/C++/myhelpers/DebugHelper.hpp" + +#include "SparkClasses.h" + +// Link with ws2_32.lib +#pragma comment(lib, "Ws2_32.lib") +#include "F:/Programmieren/C++/json.hpp" +using json = nlohmann::json; + +#include "include/easywsclient.hpp" +#include "include/easywsclient.cpp" + +using easywsclient::WebSocket; +WebSocket::pointer ws = NULL; + +//#include +//#include + +//typedef BOOL(__stdcall* tWinHttpGetIEProxyConfigForCurrentUser)(IN OUT WINHTTP_CURRENT_USER_IE_PROXY_CONFIG*); +//tWinHttpGetIEProxyConfigForCurrentUser oWinHttpGetIEProxyConfigForCurrentUser; + +typedef void*(__stdcall* tCurl_Easy_Init)(); +tCurl_Easy_Init oCurl_Easy_Init; + +typedef void(__stdcall* tCurl_Easy_Cleanup)(void* handle); +tCurl_Easy_Cleanup oCurl_Easy_Cleanup; + +typedef DWORD(__stdcall* tCurl_Easy_SetOpt)(void*, long, void*); +tCurl_Easy_SetOpt oCurl_Easy_SetOpt; + +typedef DWORD(__stdcall* tCurl_Easy_Perform)(void*); +tCurl_Easy_Perform oCurl_Easy_Perform; + +typedef DWORD(__stdcall* tCurl_Multi_Perform)(void* multi_handle, int* running_handles); +tCurl_Multi_Perform oCurl_Multi_Perform; + +typedef void*(__stdcall* tCurl_Multi_Init)(); +tCurl_Multi_Init oCurl_Multi_Init = NULL; + +typedef void* (__fastcall* tFSparkManagerCtor)(void*); +tFSparkManagerCtor oFSparkManagerCtor = NULL; + +//const std::wstring proxyURLW = L"https=127.0.0.1:9999"; +std::string proxyURLA = "https://127.0.0.1:"; +std::string proxyPort = "9999"; +auto curl_easy_init_pattern = xorstr("48 83 EC 28 83 3D ?? ?? ?? ?? 00 75 ?? 48 8B 05"); +auto curl_easy_cleanup_pattern = xorstr("40 53 48 83 EC 20 48 8B D9 48 85 C9 0F 84 ?? ?? ?? ?? 33 D2"); +auto curl_easy_setopt_pattern = xorstr("89 54 24 10 4c 89 44 24 18 4c 89 4c 24 20 48 83 ec 28 48 85 c9 75"); +auto curl_easy_perform_pattern = xorstr("33 d2 e9 09 01 00 00 cc cc cc cc cc cc cc"); +auto curl_easy_getinfo_pattern = xorstr("89 54 24 ?? 4C 89 44 24 ?? 4C 89 4C 24 ?? 48 83 EC 28 4C 8D 44 24 ?? 4D 8B 00"); +auto curl_multi_perform_pattern = xorstr("48 89 5c 24 18 56 57 41 57 48 83 ec 20 4c 8b fa 48 8b f9"); +auto curl_multi_init_pattern = xorstr("BA 61 00 00 00 B9 8F 03 00 00"); +auto sparkManagerCtorPattern = xorstr("40 53 48 83 EC 20 48 8B D9 E8 ?? ?? ?? ?? 4C 8B C8 48 8D 15 ?? ?? ?? ?? 0F 57 D2 48 8B CB E8 ?? ?? ?? ?? 48 8D 05 ?? ?? ?? ?? 48 89 03 33 C0"); +auto generateMicropatchArrayPattern = xorstr("48 89 5C 24 ?? 48 89 74 24 ?? 48 89 7C 24 ?? 55 41 54 41 55 41 56 41 57 48 8D 6C 24 ?? 48 81 EC ?? ?? ?? ?? 8B 72 08"); +auto generateMicropatchArrayBackupPattern = xorstr("48 8D 54 24 ?? E8 ?? ?? ?? ?? 48 8D 55 60"); +auto getNewsItemsPattern = xorstr("48 89 ?? ?? ?? 48 89 ?? ?? ?? 48 89 ?? ?? ?? 48 89 ?? ?? ?? 55 41 ?? 41 ?? 41 ?? 41 ?? 48 8D ?? ?? ?? ?? ?? ?? 48 81 EC ?? ?? ?? ?? ?? 8D"); +auto FGbxSparkModuleStartupModulePattern = xorstr("40 53 48 83 EC 50 48 8B D9 48 89 0D"); +// + 0x33 +auto parseJSONString = xorstr("40 55 53 56 57 48 8D 6C 24 ?? 48 81 EC ?? ?? ?? ?? 48 8B 05 ?? ?? ?? ?? 48 33 C4 48 89 45 10 48 8B D9"); + +// result at +0x88 (E8 ** ** ** **) +auto getNewsServicePattern = xorstr("45 8B C7 48 8D 15 ?? ?? ?? ?? 48 8D 8D ?? ?? ?? ?? E8 ?? ?? ?? ?? 4C 8D 85"); + +auto mallocPattern = xorstr("48 89 5C 24 ?? 57 48 83 EC 20 48 8B F9 8B DA 48 8B 0D ?? ?? ?? ?? 48 85 C9 75 0C E8 ?? ?? ?? ?? 48 8B 0D ?? ?? ?? ?? 48 8B 01 44 8B C3 48 8B D7 48 8B 5C 24 ?? 48 83 C4 20 5F 48 FF 60 10"); +auto reallocPattern = xorstr("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 48 8B F1 41 8B D8 48 8B 0D ?? ?? ?? ?? 48 8B FA 48 85 C9 75 0C E8 ?? ?? ?? ?? 48 8B 0D ?? ?? ?? ?? 48 8B 01 44 8B CB 4C 8B C7 48 8B D6 48 8B 5C 24 ?? 48 8B 74 24 ?? 48 83 C4 20 5F 48 FF 60 18"); + +CRITICAL_SECTION critsec; + +// +//std::string startReceiveHotfixes_Pattern = xorstr("48 63 81 c4 00 00 00 83 f8 06 77 49 4c 8d 05"); +//// +//std::string beforeInit_Pattern = xorstr("40 53 48 83 ec 40 80 b9 c0 00 00 00 00 48 8b d9 0f 85 41 01 00 00 83 b9 cc 00 00 00 00 0f 84 34 01 00 00 f3 0f 58 89 bc 00 00 00 f3 0f 11 89 bc 00 00 00 8b 89 d0 00 00 00 85 c9 0f 84 fe 00 00 00"); +//// +//std::string someInterestingFunc_Pattern = xorstr("40 53 48 83 ec 30 48 8b d9 48 85 d2 74 21 45 8b c8 c7 44 24 28 ff ff ff ff"); +// +//std::ofstream myfile; + +/* long may be 32 or 64 bits, but we should never depend on anything else + but 32 */ +#define CURLOPTTYPE_LONG 0 +#define CURLOPTTYPE_OBJECTPOINT 10000 +#define CURLOPTTYPE_FUNCTIONPOINT 20000 +#define CURLOPTTYPE_OFF_T 30000 +#define CURLOPTTYPE_BLOB 40000 + +#define CURLOPT(na,t,nu) na = t + nu + +/* 'char *' argument to a string with a trailing zero */ +#define CURLOPTTYPE_STRINGPOINT CURLOPTTYPE_OBJECTPOINT + +/* 'struct curl_slist *' argument */ +#define CURLOPTTYPE_SLISTPOINT CURLOPTTYPE_OBJECTPOINT + +/* 'void *' argument passed untouched to callback */ +#define CURLOPTTYPE_CBPOINT CURLOPTTYPE_OBJECTPOINT + +/* 'long' argument with a set of values/bitmask */ +#define CURLOPTTYPE_VALUES CURLOPTTYPE_LONG + +typedef enum { + /* The full URL to get/put */ + CURLOPT(CURLOPT_URL, CURLOPTTYPE_STRINGPOINT, 2), + /* Name of proxy to use. */ + CURLOPT(CURLOPT_PROXY, CURLOPTTYPE_STRINGPOINT, 4), + /* Buffer to receive error messages in, must be at least CURL_ERROR_SIZE + * bytes big. */ + CURLOPT(CURLOPT_ERRORBUFFER, CURLOPTTYPE_OBJECTPOINT, 10), + /* Function that will be called to store the output (instead of fwrite). The + * parameters will use fwrite() syntax, make sure to follow them. */ + CURLOPT(CURLOPT_WRITEFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 11), + /* Function that will be called to read the input (instead of fread). The + * parameters will use fread() syntax, make sure to follow them. */ + CURLOPT(CURLOPT_READFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 12), + /* POST static input fields. */ + CURLOPT(CURLOPT_POSTFIELDS, CURLOPTTYPE_OBJECTPOINT, 15), + /* Set if we should verify the peer in ssl handshake, set 1 to verify. */ + CURLOPT(CURLOPT_SSL_VERIFYPEER, CURLOPTTYPE_LONG, 64), + /* The CApath or CAfile used to validate the peer certificate + this option is used only if SSL_VERIFYPEER is true */ + CURLOPT(CURLOPT_CAINFO, CURLOPTTYPE_STRINGPOINT, 65), + /* Set if we should verify the Common name from the peer certificate in ssl + * handshake, set 1 to check existence, 2 to ensure that it matches the + * provided hostname. */ + CURLOPT(CURLOPT_SSL_VERIFYHOST, CURLOPTTYPE_LONG, 81), + /* The CApath directory used to validate the peer certificate + this option is used only if SSL_VERIFYPEER is true */ + CURLOPT(CURLOPT_CAPATH, CURLOPTTYPE_STRINGPOINT, 97), + /* Enable SSL/TLS for FTP, pick one of: + CURLUSESSL_TRY - try using SSL, proceed anyway otherwise + CURLUSESSL_CONTROL - SSL for the control connection or fail + CURLUSESSL_ALL - SSL for all communication or fail + */ + CURLOPT(CURLOPT_USE_SSL, CURLOPTTYPE_VALUES, 119), + /* send linked-list of name:port:address sets */ + CURLOPT(CURLOPT_RESOLVE, CURLOPTTYPE_SLISTPOINT, 203), + /* Set if we should verify the certificate status. */ + CURLOPT(CURLOPT_SSL_VERIFYSTATUS, CURLOPTTYPE_LONG, 232), + /* The CApath or CAfile used to validate the proxy certificate + this option is used only if PROXY_SSL_VERIFYPEER is true */ + CURLOPT(CURLOPT_PROXY_CAINFO, CURLOPTTYPE_STRINGPOINT, 246), + /* Set if we should verify the proxy in ssl handshake, + set 1 to verify. */ + CURLOPT(CURLOPT_PROXY_SSL_VERIFYPEER, CURLOPTTYPE_LONG, 248), + /* Set if we should verify the Common name from the proxy certificate in ssl + * handshake, set 1 to check existence, 2 to ensure that it matches + * the provided hostname. */ + CURLOPT(CURLOPT_PROXY_SSL_VERIFYHOST, CURLOPTTYPE_LONG, 249), + /* The public key in DER form used to validate the proxy public key + this option is used only if PROXY_SSL_VERIFYPEER is true */ + CURLOPT(CURLOPT_PROXY_PINNEDPUBLICKEY, CURLOPTTYPE_STRINGPOINT, 263), + /* Same as CURLOPT_SSL_VERIFYPEER but for DoH (DNS-over-HTTPS) servers. */ + CURLOPT(CURLOPT_DOH_SSL_VERIFYPEER, CURLOPTTYPE_LONG, 306), + /* Same as CURLOPT_SSL_VERIFYHOST but for DoH (DNS-over-HTTPS) servers. */ + CURLOPT(CURLOPT_DOH_SSL_VERIFYHOST, CURLOPTTYPE_LONG, 307), + /* Same as CURLOPT_SSL_VERIFYSTATUS but for DoH (DNS-over-HTTPS) servers. */ + CURLOPT(CURLOPT_DOH_SSL_VERIFYSTATUS, CURLOPTTYPE_LONG, 308), + /* The CA certificates as "blob" used to validate the peer certificate + this option is used only if SSL_VERIFYPEER is true */ + CURLOPT(CURLOPT_CAINFO_BLOB, CURLOPTTYPE_BLOB, 309), + /* The CA certificates as "blob" used to validate the proxy certificate + this option is used only if PROXY_SSL_VERIFYPEER is true */ + CURLOPT(CURLOPT_PROXY_CAINFO_BLOB, CURLOPTTYPE_BLOB, 310), +}; + +#define CURL_ERROR_SIZE 256 + +typedef enum { + CURLE_OK = 0 +}; + +typedef enum { + CURLPROXY_HTTP = 0, /* added in 7.10, new in 7.19.4 default is to use + CONNECT HTTP/1.1 */ + CURLPROXY_HTTP_1_0 = 1, /* added in 7.19.4, force to use CONNECT + HTTP/1.0 */ + CURLPROXY_HTTPS = 2, /* added in 7.52.0 */ + CURLPROXY_SOCKS4 = 4, /* support added in 7.15.2, enum existed already in 7.10 */ + CURLPROXY_SOCKS5 = 5, /* added in 7.10 */ + CURLPROXY_SOCKS4A = 6, /* added in 7.18.0 */ + CURLPROXY_SOCKS5_HOSTNAME = 7 /* Use the SOCKS5 protocol but pass along the + host name rather than the IP address. added + in 7.18.0 */ +} curl_proxytype; /* this enum was added in 7.10 */ + +/* parameter for the CURLOPT_USE_SSL option */ +typedef enum { + CURLUSESSL_NONE, /* do not attempt to use SSL */ + CURLUSESSL_TRY, /* try using SSL, proceed anyway otherwise */ + CURLUSESSL_CONTROL, /* SSL for the control connection or fail */ + CURLUSESSL_ALL, /* SSL for all communication or fail */ + CURLUSESSL_LAST /* not an option, never use */ +} curl_usessl; + +#define CURLINFO_STRING 0x100000 +#define CURLINFO_LONG 0x200000 +#define CURLINFO_DOUBLE 0x300000 +#define CURLINFO_SLIST 0x400000 +#define CURLINFO_PTR 0x400000 /* same as SLIST */ +#define CURLINFO_SOCKET 0x500000 +#define CURLINFO_OFF_T 0x600000 +#define CURLINFO_MASK 0x0fffff +#define CURLINFO_TYPEMASK 0xf00000 + +typedef enum { + CURLINFO_NONE, /* first, never use this */ + CURLINFO_EFFECTIVE_URL = CURLINFO_STRING + 1, + CURLINFO_RESPONSE_CODE = CURLINFO_LONG + 2, + CURLINFO_TOTAL_TIME = CURLINFO_DOUBLE + 3, + CURLINFO_NAMELOOKUP_TIME = CURLINFO_DOUBLE + 4, + CURLINFO_CONNECT_TIME = CURLINFO_DOUBLE + 5, + CURLINFO_PRETRANSFER_TIME = CURLINFO_DOUBLE + 6, + CURLINFO_SIZE_UPLOAD = CURLINFO_DOUBLE + 7, + CURLINFO_SIZE_UPLOAD_T = CURLINFO_OFF_T + 7, + CURLINFO_SIZE_DOWNLOAD = CURLINFO_DOUBLE + 8, + CURLINFO_SIZE_DOWNLOAD_T = CURLINFO_OFF_T + 8, + CURLINFO_SPEED_DOWNLOAD = CURLINFO_DOUBLE + 9, + CURLINFO_SPEED_DOWNLOAD_T = CURLINFO_OFF_T + 9, + CURLINFO_SPEED_UPLOAD = CURLINFO_DOUBLE + 10, + CURLINFO_SPEED_UPLOAD_T = CURLINFO_OFF_T + 10, + CURLINFO_HEADER_SIZE = CURLINFO_LONG + 11, + CURLINFO_REQUEST_SIZE = CURLINFO_LONG + 12, + CURLINFO_SSL_VERIFYRESULT = CURLINFO_LONG + 13, + CURLINFO_FILETIME = CURLINFO_LONG + 14, + CURLINFO_FILETIME_T = CURLINFO_OFF_T + 14, + CURLINFO_CONTENT_LENGTH_DOWNLOAD = CURLINFO_DOUBLE + 15, + CURLINFO_CONTENT_LENGTH_DOWNLOAD_T = CURLINFO_OFF_T + 15, + CURLINFO_CONTENT_LENGTH_UPLOAD = CURLINFO_DOUBLE + 16, + CURLINFO_CONTENT_LENGTH_UPLOAD_T = CURLINFO_OFF_T + 16, + CURLINFO_STARTTRANSFER_TIME = CURLINFO_DOUBLE + 17, + CURLINFO_CONTENT_TYPE = CURLINFO_STRING + 18, + CURLINFO_REDIRECT_TIME = CURLINFO_DOUBLE + 19, + CURLINFO_REDIRECT_COUNT = CURLINFO_LONG + 20, + CURLINFO_PRIVATE = CURLINFO_STRING + 21, + CURLINFO_HTTP_CONNECTCODE = CURLINFO_LONG + 22, + CURLINFO_HTTPAUTH_AVAIL = CURLINFO_LONG + 23, + CURLINFO_PROXYAUTH_AVAIL = CURLINFO_LONG + 24, + CURLINFO_OS_ERRNO = CURLINFO_LONG + 25, + CURLINFO_NUM_CONNECTS = CURLINFO_LONG + 26, + CURLINFO_SSL_ENGINES = CURLINFO_SLIST + 27, + CURLINFO_COOKIELIST = CURLINFO_SLIST + 28, + CURLINFO_LASTSOCKET = CURLINFO_LONG + 29, + CURLINFO_FTP_ENTRY_PATH = CURLINFO_STRING + 30, + CURLINFO_REDIRECT_URL = CURLINFO_STRING + 31, + CURLINFO_PRIMARY_IP = CURLINFO_STRING + 32, + CURLINFO_APPCONNECT_TIME = CURLINFO_DOUBLE + 33, + CURLINFO_CERTINFO = CURLINFO_PTR + 34, + CURLINFO_CONDITION_UNMET = CURLINFO_LONG + 35, + CURLINFO_RTSP_SESSION_ID = CURLINFO_STRING + 36, + CURLINFO_RTSP_CLIENT_CSEQ = CURLINFO_LONG + 37, + CURLINFO_RTSP_SERVER_CSEQ = CURLINFO_LONG + 38, + CURLINFO_RTSP_CSEQ_RECV = CURLINFO_LONG + 39, + CURLINFO_PRIMARY_PORT = CURLINFO_LONG + 40, + CURLINFO_LOCAL_IP = CURLINFO_STRING + 41, + CURLINFO_LOCAL_PORT = CURLINFO_LONG + 42, + CURLINFO_TLS_SESSION = CURLINFO_PTR + 43, + CURLINFO_ACTIVESOCKET = CURLINFO_SOCKET + 44, + CURLINFO_TLS_SSL_PTR = CURLINFO_PTR + 45, + CURLINFO_HTTP_VERSION = CURLINFO_LONG + 46, + CURLINFO_PROXY_SSL_VERIFYRESULT = CURLINFO_LONG + 47, + CURLINFO_PROTOCOL = CURLINFO_LONG + 48, + CURLINFO_SCHEME = CURLINFO_STRING + 49, + CURLINFO_TOTAL_TIME_T = CURLINFO_OFF_T + 50, + CURLINFO_NAMELOOKUP_TIME_T = CURLINFO_OFF_T + 51, + CURLINFO_CONNECT_TIME_T = CURLINFO_OFF_T + 52, + CURLINFO_PRETRANSFER_TIME_T = CURLINFO_OFF_T + 53, + CURLINFO_STARTTRANSFER_TIME_T = CURLINFO_OFF_T + 54, + CURLINFO_REDIRECT_TIME_T = CURLINFO_OFF_T + 55, + CURLINFO_APPCONNECT_TIME_T = CURLINFO_OFF_T + 56, + CURLINFO_RETRY_AFTER = CURLINFO_OFF_T + 57, + CURLINFO_EFFECTIVE_METHOD = CURLINFO_STRING + 58, + CURLINFO_PROXY_ERROR = CURLINFO_LONG + 59, + CURLINFO_REFERER = CURLINFO_STRING + 60, + + CURLINFO_LASTONE = 60 +} CURLINFO; + +typedef DWORD(__stdcall* tCurl_Easy_GetInfo)(void*, CURLINFO info, void*); +tCurl_Easy_GetInfo oCurl_Easy_GetInfo; + +/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as + CURLINFO_HTTP_CODE */ +#define CURLINFO_HTTP_CODE CURLINFO_RESPONSE_CODE + +typedef enum { + CURLCLOSEPOLICY_NONE, /* first, never use this */ + + CURLCLOSEPOLICY_OLDEST, + CURLCLOSEPOLICY_LEAST_RECENTLY_USED, + CURLCLOSEPOLICY_LEAST_TRAFFIC, + CURLCLOSEPOLICY_SLOWEST, + CURLCLOSEPOLICY_CALLBACK, + + CURLCLOSEPOLICY_LAST /* last, never use this */ +} curl_closepolicy; + +char errbuf[CURL_ERROR_SIZE]; + +typedef void* (__fastcall* tMalloc)(uint32_t, uint32_t); +tMalloc oMalloc; + +typedef void* (__fastcall* tRealloc)(void*, size_t, uint32_t); +tRealloc oRealloc; + +typedef void (__fastcall* tGetNewsItems)(void*); +tGetNewsItems oGetNewsItems = NULL; + +template +struct TArray +{ + friend struct FString; + +public: + inline TArray() + { + Data = nullptr; + Count = Max = 0; + }; + + inline int Num() const + { + return Count; + }; + + inline T& operator[](int i) + { + return Data[i]; + }; + + inline const T& operator[](int i) const + { + return Data[i]; + }; + + inline bool IsValidIndex(int i) const + { + return i < Num(); + } + + FORCEINLINE int32_t DefaultCalculateSlackGrow(int32_t NumElements, int32_t NumAllocatedElements, int32_t BytesPerElement, bool bAllowQuantize, uint32_t Alignment = 0) + { + int32_t Retval = 0; + + int32_t Grow = 4; // this is the amount for the first alloc + if (NumAllocatedElements || size_t(NumElements) > Grow) + { + // Allocate slack for the array proportional to its size. + Grow = size_t(NumElements) + 3 * size_t(NumElements) / 8 + 16; + } + if (bAllowQuantize) + { + //Retval = FMemory::QuantizeSize(Grow * BytesPerElement, Alignment) / BytesPerElement; + Retval = Retval * BytesPerElement; + } + else + { + Retval = Grow; + } + // NumElements and MaxElements are stored in 32 bit signed integers so we must be careful not to overflow here. + if (NumElements > Retval) + { + Retval = ((int32_t)0x7fffffff); + } + + return Retval; + } + + void ResizeGrow(int32_t OldNum, int32_t numElems, size_t sizePElem) + { + if (Data || Count) { + Data = (T*)Realloc(Data, numElems * sizePElem, 0); + } + } + + void* Realloc(void* Original, size_t count, uint32_t alignment) { + if (oRealloc) { + return oRealloc(Original, count, alignment); + } + return NULL; + } + + void* Malloc(uint32_t count, uint32_t alignment) { + if (oMalloc) { + return oMalloc(count, alignment); + } + return NULL; + } + + void ResizeGrow(int32_t OldNum) + { + Max = DefaultCalculateSlackGrow(Count + 1, Max, sizeof(T), 0); + ResizeGrow(Count, Max, sizeof(T)); + } + + /** + * Adds a new item to the end of the array, possibly reallocating the whole array to fit. + * + * @param Item The item to add + * @return Index to the new item + * @see AddDefaulted, AddUnique, AddZeroed, Append, Insert + */ + FORCEINLINE int32_t Add(const T& Item) + { + if (Count + 1 > Max) { + Max = DefaultCalculateSlackGrow(Count + 1, Max, sizeof(T), 0); + ResizeGrow(Count, Max, sizeof(T)); + } + if (Data == NULL) { + Data = (T*)Malloc(Max, sizeof(T)); + //memset(Data, 0, Max * sizeof(T)); + } + Data[Count] = Item; + Count++; + return Count - 1; + } + + /** + * Inserts a given element into the array at given location. + * + * @param Item The element to insert. + * @param Index Tells where to insert the new elements. + * @returns Location at which the insert was done. + * @see Add, Remove + */ + FORCEINLINE int32_t Insert(const T& Item, int32_t Index) + { + if (Index >= 0 && IsValidIndex(Index)) { + const int32_t OldNum = Count; + if ((Count += 1) > Max) + { + ResizeGrow(OldNum); + } + for (int i = Count; i >= Index; i--) + { + Data[i + 1] = Data[i]; + } + Data[Index] = Item; + } + return Index; + } + +public: + T* Data; + int32_t Count; + int32_t Max; +}; + +struct FString : private TArray +{ + inline FString() + { + }; + + FString(const wchar_t* other) + { + Max = Count = *other ? static_cast(std::wcslen(other) + 1) : 0; + + if (Count) + { + this->Data = const_cast(other); + } + }; + + FString(const char* other) + { + if (other && *other) { + size_t len = strlen(other) + 1; + int32_t destLen = int32_t(MultiByteToWideChar(CP_ACP, 0, other, -1, NULL, 0)) + 1; + const int32_t oldNum = Count; + if ((Count += destLen) > Max) { + this->ResizeGrow(oldNum); + } + mbstowcs_s(NULL, this->Data, len, other, len - 1); + } + //if (Data != other) { + // int nchars = MultiByteToWideChar(CP_ACP, 0, other, -1, NULL, 0); + // wchar_t* wc = new wchar_t[nchars]; + // MultiByteToWideChar(CP_ACP, 0, other, -1, (LPWSTR)wc, nchars); + // Max = Count = *wc ? static_cast(std::wcslen(wc) + 1) : 0; + + //} + ///*int nchars = MultiByteToWideChar(CP_ACP, 0, other, -1, NULL, 0); + //wchar_t* wc = new wchar_t[nchars]; + //MultiByteToWideChar(CP_ACP, 0, other, -1, (LPWSTR)wc, nchars); + //Max = Count = *wc ? static_cast(std::wcslen(wc) + 1) : 0;*/ + + /*if (Count) + { + Data = const_cast(wc); + }*/ + }; + + inline bool IsValid() const + { + return this->Data != nullptr; + } + + inline const wchar_t* c_str() const + { + return this->Data; + } + + std::string ToString() const + { + if (!this->Data) + return "NULL"; + auto length = std::wcslen(this->Data); + + std::string str(length, '\0'); + + std::use_facet>(std::locale()).narrow(this->Data, this->Data + length, '?', &str[0]); + + return str; + } +}; + +struct FArticleTag { + FString Tag; + FString TagName; + FString TagValue; +}; + +struct FNewsItem { + FString NewsText; + char Unknown1[0x8]; + char Unknown2[0x8]; + char Unknown3[0x8]; + char Unknown4[0x8]; + char Unknown5[0x8]; + char Unknown6[0x8]; + FString IconName; + FString TargetLink; + char Unknown7[0x8]; + char Unknown8[0x8]; + char Unknown9[0x8]; + char Unknown10[0x8]; + char Unknown11[0x8]; + char Unknown12[0x8]; + TArray ArticleTags; +}; + +class FSparkNewsService +{ +public: + char pad_0000[64]; //0x0000 + class TArray NewsItems; //0x0040 + char pad_0050[64]; //0x0050 +}; //Size: 0x0090 +static_assert(sizeof(FSparkNewsService) == 0x90); + +class FSparkModule +{ +public: + wchar_t* ConfigFile; //0x0008 + char pad_0010[8]; //0x0010 + class FSparkManager* SparkManager; //0x0018 + char pad_0020[240]; //0x0020 + class FSparkNewsService* SparkNewsService; //0x0110 + char pad_0118[1192]; //0x0118 + + virtual void Function0(); + virtual void Function1(); + virtual void Function2(); + virtual void Function3(); + virtual void Function4(); + virtual void Function5(); + virtual void Function6(); + virtual void Function7(); +}; //Size: 0x05C0 +static_assert(sizeof(FSparkModule) == 0x5C0); + +enum HotfixType : uint32_t { + SparkPatchEntry = 1, + SparkLevelPatchEntry = 2, + SparkStreamedPackageEntry = 3, + SparkSaveGameEntry = 4, + SparkPostLoadedEntry = 5, + SparkCharacterLoadedEntry = 6, + SparkEarlyLevelPatchEntry = 7 +}; + +class FMicropatch +{ +public: + HotfixType PatchType; //0x0000 + uint32_t N00001B5E; //0x0004 + FString Patchname; //0x0008 + FString Patchdata; //0x0018 +}; //Size: 0x0028 +static_assert(sizeof(FMicropatch) == 0x28); + +class UserWriteData +{ +public: + char pad_0000[16]; //0x0000 + TArray Content; //0x0010 + //char* Content; + //uint32_t WriteSize; //0x0018 + //uint32_t MaxSize; //0x001C + uint32_t DataSize; //0x0020 + char pad_0024[4]; //0x0024 +}; //Size: 0x0028 +static_assert(sizeof(UserWriteData) == 0x28); + +class Curl_Write_Data +{ +public: + char pad_0000[88]; //0x0000 + class FString RequestURL; //0x0058 + char pad_0068[32]; //0x0068 + class UserWriteData* Body; //0x0088 + char pad_0090[32]; //0x0090 + class TArray* Headers; //0x00B0 +}; //Size: 0x00B8 +static_assert(sizeof(Curl_Write_Data) == 0xB8); + +typedef void(__fastcall* tGenerateMicropatchArray)(void* someTMap, TArray* outMicropatches); +tGenerateMicropatchArray oGenerateMicropatchArray = NULL; + +typedef void* (__fastcall* tParseJSONString)(void** jsonReader, const FString* text); +tParseJSONString oParseJSONString = NULL; + +FSparkModule** pSparkModule = NULL; + + +//std::vector GetObjectNamesWith(const std::string nameToFind) { +// std::vector entries; +// for (int i = 0; i < SDK::UObject::GetGlobalObjects().Num(); i++) { +// SDK::UObject* current = SDK::UObject::GetGlobalObjects().GetByIndex(i).Object; +// if (current && strstr(current->GetFullName().c_str(), nameToFind.c_str()) != NULL) { +// entries.push_back(const_cast(current)); +// } +// } +// return entries; +//} + +//class HotfixInitStuff +//{ +//public: +// char pad_0000[196]; //0x0000 +// uint32_t CurrentInitStep; //0x00C4 +// char pad_00C8[952]; //0x00C8 +//}; //Size: 0x0480 +// +// +//HotfixInitStuff* someObject; +//typedef void(*tstartReceiveHotfixes)(HotfixInitStuff* obj); +//tstartReceiveHotfixes ostartReceiveHotfixes; +// +//void hkstartReceiveHotfixes(HotfixInitStuff* obj) { +// someObject = obj; +// return ostartReceiveHotfixes(obj); +//} +// +//typedef void* (__fastcall *thkBeforeInit)(HotfixInitStuff* pHFX, void* someConst, void* unknown); +//thkBeforeInit oBeforeInit; +// +//static void* sConst = NULL; +//void* __fastcall hkBeforeInit(HotfixInitStuff* pHFX, void* someConst, void* unknown) { +// if (sConst == NULL) { +// sConst = someConst; +// } +// return oBeforeInit(pHFX, sConst, unknown); +//} + +uint64_t TotalHotfixes = 0; +uint64_t ModdedHotfixes = 0; + +static FString modified; +static FString modifiedMailResponse; +void* hkParseJSONString(void** reader, FString* text) { + if (text && text->IsValid()) { + try{ + auto received = json::parse(text->ToString()); + // make sure we are using the "News"-data + if (received.contains("version") && received.contains("status") && received.contains("message") && received.contains("data")) { + + INT rc; + WSADATA wsaData; + + rc = WSAStartup(MAKEWORD(2, 2), &wsaData); + if (rc) + { + printf("WSAStartup Failed.\n"); + if (oParseJSONString) + return oParseJSONString(reader, text); + return NULL; + } + + ws = WebSocket::from_url("ws://localhost:9998/ws", "", true); + if (!ws) + { + if (oParseJSONString) + return oParseJSONString(reader, text); + return NULL; + } + json j; + char buffer[256] = { 0 }; + sprintf(buffer, "%I64u/%I64u", ModdedHotfixes, TotalHotfixes); + + j["eventName"] = "getNews"; + j["content"] = buffer; + j["error"] = "ok"; + + ws->send(j.dump()); + std::string response; + bool gotNews = false; + while (ws->getReadyState() != WebSocket::CLOSED) { + ws->poll(); + ws->dispatch([&](const std::string& incMsg) { + try { + json j = json::from_msgpack(incMsg); + auto eventName = j["EventName"]; + auto content = j["Content"]; + auto bindata = content.get_binary(); + auto output = std::string(bindata.begin(), bindata.end()); + auto data = json::parse(output); + + json fin; + fin["EventName"] = j["EventName"]; + fin["Content"] = output; + fin["Error"] = j["Error"]; + if (eventName == "news") { + auto newsData = data["data"].items(); + auto throwaway = received; + + //throwaway["data"].push_back(newsData); + + + for (auto& [paramKey, paramValue] : newsData) { + try { + throwaway["data"].push_back(paramValue); + } + catch (...) { continue; } + } + std::string dumped = throwaway.dump(); + static std::wstring widened = std::wstring(dumped.begin(), dumped.end()); + modified = FString(widened.c_str()); + + text = &modified; + gotNews = true; + } + } + catch (...) {} + }); + if (gotNews) + break; + } + delete ws; +#ifdef _WIN32 + WSACleanup(); +#endif + std::cout << modified.ToString() << std::endl; + if (oParseJSONString) { + void* result = oParseJSONString(reader, text); + return result; + } + } + // MailItems + /* else if (received.contains("messages") && received.contains("status")) { + INT rc; + WSADATA wsaData; + + rc = WSAStartup(MAKEWORD(2, 2), &wsaData); + if (rc) + { + printf("WSAStartup Failed.\n"); + if (oParseJSONString) + return oParseJSONString(reader, text); + return NULL; + } + + ws = WebSocket::from_url("ws://localhost:9998/ws", "", true); + if (!ws) + { + if (oParseJSONString) + return oParseJSONString(reader, text); + return NULL; + } + json j; + j["eventName"] = "getCustomMailItems"; + j["content"] = ""; + j["error"] = "ok"; + + ws->send(j.dump()); + std::string response; + bool gotMail = false; + while (ws->getReadyState() != WebSocket::CLOSED) { + ws->poll(); + ws->dispatch([&](const std::string& incMsg) { + try { + json j = json::from_msgpack(incMsg); + auto eventName = j["EventName"]; + auto content = j["Content"]; + auto bindata = content.get_binary(); + auto output = std::string(bindata.begin(), bindata.end()); + auto data = json::parse(output); + + json fin; + fin["EventName"] = j["EventName"]; + fin["Content"] = output; + fin["Error"] = j["Error"]; + if (eventName == "mailItems") { + auto mailData = data["messages"].items(); + auto throwaway = received; + + for (auto& [paramKey, paramValue] : mailData) { + try { + throwaway["messages"].push_back(paramValue); + } + catch (...) { continue; } + } + std::string dumped = throwaway.dump(); + static std::wstring widenedMail = std::wstring(dumped.begin(), dumped.end()); + modifiedMailResponse = FString(widenedMail.c_str()); + + text = &modifiedMailResponse; + gotMail = true; + } + } + catch (...) {} + }); + if (gotMail) + break; + } + delete ws; +#ifdef _WIN32 + WSACleanup(); +#endif + std::cout << modifiedMailResponse.ToString() << std::endl; + if (oParseJSONString) { + void* result = oParseJSONString(reader, text); + return result; + } + } + else if (text->ToString().find("\"internal_code\":11007") != std::string::npos) { + json response; + response["result"] = "message rejected"; + response["status"] = "success"; + std::string fakeResponse = response.dump(); + static std::wstring fakeWideResp = std::wstring(fakeResponse.begin(), fakeResponse.end()); + text = &FString(fakeWideResp.c_str()); + }*/ + }catch(...){} + } + if (oParseJSONString) { + return oParseJSONString(reader, text); + } + return NULL; +} + +std::string getMicropatchString() { + INT rc; + WSADATA wsaData; + std::string response; + rc = WSAStartup(MAKEWORD(2, 2), &wsaData); + if (rc) + { + printf("WSAStartup Failed.\n"); + return response; + } + + ws = WebSocket::from_url("ws://localhost:9998/ws", "", true); + if (!ws) + return response; + json j; + j["eventName"] = "getMicropatches"; + j["content"] = ""; + j["error"] = "ok"; + + ws->send(j.dump()); + + bool gotMicropatches = false; + while (ws->getReadyState() != WebSocket::CLOSED) { + ws->poll(); + ws->dispatch([&](const std::string& incMsg) { + try { + json j = json::from_msgpack(incMsg); + auto eventName = j["EventName"]; + auto content = j["Content"]; + auto bindata = content.get_binary(); + response = std::string(bindata.begin(), bindata.end()); + /*auto data = json::parse(output);*/ + + //json fin; + //fin["EventName"] = j["EventName"]; + //fin["Content"] = output; + //fin["Error"] = j["Error"]; + if (eventName == "micropatches" || eventName == "micropatchesR") { + // + // auto params = data["parameters"].items(); + // for (auto& [paramKey, paramValue] : params) { + // //std::cout << "Key: " << paramValue["key"] << " Value: " << paramValue["value"] << std::endl; + // FMicropatch patch; + // std::string patchType = paramValue["key"].get(); + // if (patchType.find("SparkPatchEntry") != std::string::npos) + // patch.PatchType = SparkPatchEntry; + // else if (patchType.find("SparkLevelPatchEntry") != std::string::npos) + // patch.PatchType = SparkLevelPatchEntry; + // else if (patchType.find("SparkStreamedPackageEntry") != std::string::npos) + // patch.PatchType = SparkStreamedPackageEntry; + // else if (patchType.find("SparkSaveGameEntry") != std::string::npos) + // patch.PatchType = SparkSaveGameEntry; + // else if (patchType.find("SparkPostLoadedEntry") != std::string::npos) + // patch.PatchType = SparkPostLoadedEntry; + // else if (patchType.find("SparkCharacterLoadedEntry") != std::string::npos) + // patch.PatchType = SparkCharacterLoadedEntry; + // else if (patchType.find("SparkEarlyLevelPatchEntry") != std::string::npos) + // patch.PatchType = SparkEarlyLevelPatchEntry; + + // patch.N00001B5E = 1; + // patch.Patchname = FString(paramValue["key"].get().c_str()); + // patch.Patchdata = FString(paramValue["value"].get().c_str()); + + // outPatches->Add(patch); + // ++ModdedHotfixes; + // ++TotalHotfixes; + //} + gotMicropatches = true; + } + } + catch (...) {} + }); + if (gotMicropatches) + break; + } + delete ws; +#ifdef _WIN32 + WSACleanup(); +#endif + return response; +} + +static FSparkManager* fsparkManager = NULL; +void* hkFSparkManagerCtor(void* outBuf) { + fsparkManager = reinterpret_cast(oFSparkManagerCtor(outBuf)); + return fsparkManager; +} + +void* __stdcall hkCurl_Easy_Init() { + return oCurl_Easy_Init(); +} + +void* __stdcall hkCurl_Multi_Init() { + void* multihandle = oCurl_Multi_Init(); + return multihandle; +} + +void __stdcall hkCurl_Easy_Cleanup(void* handle) { + if (handle) + oCurl_Easy_Cleanup(handle); +} + +bool hookedWriteCallback = false; +typedef size_t (__stdcall* tWrite_Callback)(char* ptr, size_t size, size_t nmemb, void* userdata); +tWrite_Callback oWrite_Callback = NULL; + +DWORD __stdcall hkCurl_Easy_Perform(void* easy_handle) { + //hkCurl_Easy_SetOpt(easy_handle, CURLOPT_SSL_VERIFYPEER, 0L); + ZeroMemory(errbuf, CURL_ERROR_SIZE); + + //std::cout << "Inside Curl_Easy_perform" << std::endl; + auto result = oCurl_Easy_Perform(easy_handle); + if (result != CURLE_OK) { + std::cout << "Error: " << result << std::endl; + std::cout << errbuf << std::endl; + } + return result; +} + +bool isHotfixRepsonse = false; +static Curl_Write_Data* currentCurlWriteData = NULL; + +size_t __stdcall hkWriteCallback(char* ptr, size_t size, size_t dataSize, void* userdata) { + size_t writeSize = oWrite_Callback(ptr, size, dataSize, userdata); + currentCurlWriteData = (Curl_Write_Data*)userdata; + std::string currentURL = currentCurlWriteData->RequestURL.ToString(); + if (currentURL.find("verification") != std::string::npos && currentURL.find("discovery") != std::string::npos) { + std::cout << "Need to get and alter response here" << std::endl; + /*static std::string moddedHotfixes = getMicropatchString(); + currentCurlWriteData->Body->Content.ResizeGrow(currentCurlWriteData->Body->Content.Count, moddedHotfixes.size(), 1); + strcpy(currentCurlWriteData->Body->Content.Data, &moddedHotfixes.data()[0]); + currentCurlWriteData->Body->Content.Max = moddedHotfixes.size(); + currentCurlWriteData->Body->Content.Count = moddedHotfixes.size();*/ + std::cout << "" << std::endl; + } + return writeSize; +} + +DWORD __stdcall hkCurl_Multi_Perform(void* multi_handle, int* running_handles) { + auto result = oCurl_Multi_Perform(multi_handle, running_handles); + if (!currentCurlWriteData) + return result; + //if (currentCurlWriteData->RequestURL.IsValid()) { + // std::string currentURL = currentCurlWriteData->RequestURL.ToString(); + // if (currentURL.find("verification") != std::string::npos && currentURL.find("discovery") != std::string::npos) { + // std::cout << "Need to get and alter response here" << std::endl; + // /*static std::string moddedHotfixes = getMicropatchString(); + // currentCurlWriteData->Body->Content.ResizeGrow(currentCurlWriteData->Body->Content.Count, moddedHotfixes.size(), 1); + // strcpy(currentCurlWriteData->Body->Content.Data, &moddedHotfixes.data()[0]); + // currentCurlWriteData->Body->Content.Max = moddedHotfixes.size(); + // currentCurlWriteData->Body->Content.Count = moddedHotfixes.size();*/ + // std::cout << "" << std::endl; + // } + //} + return result; +} + +DWORD __stdcall hkCurl_Easy_GetInfo(void* handle, CURLINFO info, void* dataPtr) { + return oCurl_Easy_GetInfo(handle, info, dataPtr); +} + +bool startLogging = false; +DWORD __stdcall hkCurl_Easy_SetOpt(void* curlHandle, long option, void* parameter) +{ + DWORD result; + /*result = oCurl_Easy_SetOpt(curlHandle, option, parameter);*/ + + EnterCriticalSection(&critsec); + + result = oCurl_Easy_SetOpt(curlHandle, CURLOPT_PROXY, const_cast((proxyURLA + proxyPort).c_str())); + if (result != CURLE_OK) { + std::cout << "Failed to set proxy. Errorcode: " << result << std::endl; + } + + result = oCurl_Easy_SetOpt(curlHandle, CURLOPT_ERRORBUFFER, errbuf); + if (result != CURLE_OK) { + std::cout << "Failed to set errorbuffer. Errorcode: " << result << std::endl; + } + + if (option == CURLOPT_SSL_VERIFYHOST) { + parameter = (void*)0L; + result = oCurl_Easy_SetOpt(curlHandle, option, parameter); + } + else if (option == CURLOPT_SSL_VERIFYPEER) { + parameter = (void*)0L; + result = oCurl_Easy_SetOpt(curlHandle, option, parameter); + } + else if (option == CURLOPT_USE_SSL) { + parameter = (void*)CURLUSESSL_TRY; + result = oCurl_Easy_SetOpt(curlHandle, option, parameter); + } + else if (option == CURLOPT_WRITEFUNCTION) { + std::cout << "Write data func at: 0x" << std::hex << parameter << std::endl; + + oWrite_Callback = (tWrite_Callback)parameter; + parameter = &hkWriteCallback; + hookedWriteCallback = true; + result = oCurl_Easy_SetOpt(curlHandle, option, parameter); + } + else if (option == CURLOPT_READFUNCTION) { + std::cout << "Read data func at: 0x" << std::hex << parameter << std::endl; + result = oCurl_Easy_SetOpt(curlHandle, option, parameter); + } + else if (option == CURLOPT_CAINFO) { + result = CURLE_OK; + } + else { + result = oCurl_Easy_SetOpt(curlHandle, option, parameter); + } + + LeaveCriticalSection(&critsec); + + return result; +} + +void hkGenerateMicropatchArray(void* someTMap, TArray* outPatches) { + if (oGenerateMicropatchArray) { + oGenerateMicropatchArray(someTMap, outPatches); + } + TotalHotfixes = outPatches->Count; + //for (int i = 0; i < outPatches->Count; ++i) { + // /*if (outPatches->Data[i].PatchType != 1 || outPatches->Data[i].N00001B5E != 1) {*/ + // std::cout << outPatches->Data[i].Patchname.ToString() << " " << outPatches->Data[i].PatchType << ":" << outPatches->Data[i].N00001B5E << std::endl; + // //} + //} + if (outPatches) { + INT rc; + WSADATA wsaData; + + rc = WSAStartup(MAKEWORD(2, 2), &wsaData); + if (rc) + { + printf("WSAStartup Failed.\n"); + return; + } + + ws = WebSocket::from_url("ws://localhost:9998/ws", "", true); + if (!ws) + return; + json j; + j["eventName"] = "getMicropatches"; + j["content"] = ""; + j["error"] = "ok"; + + ws->send(j.dump()); + std::string response; + bool gotMicropatches = false; + while (ws->getReadyState() != WebSocket::CLOSED) { + ws->poll(); + ws->dispatch([&](const std::string& incMsg) { + try { + json j = json::from_msgpack(incMsg); + auto eventName = j["EventName"]; + auto content = j["Content"]; + auto bindata = content.get_binary(); + auto output = std::string(bindata.begin(), bindata.end()); + auto data = json::parse(output); + + json fin; + fin["EventName"] = j["EventName"]; + fin["Content"] = output; + fin["Error"] = j["Error"]; + if (eventName == "micropatches" || eventName == "micropatchesR") { + bool replaceMode = false; + if (eventName == "micropatchesR") + { + ZeroMemory(outPatches->Data, outPatches->Count * sizeof(FMicropatch)); + outPatches->Max = 0; + outPatches->Count = 0; + TotalHotfixes = 0; + } + ModdedHotfixes = 0; + auto params = data["parameters"].items(); + for (auto& [paramKey, paramValue] : params) { + //std::cout << "Key: " << paramValue["key"] << " Value: " << paramValue["value"] << std::endl; + FMicropatch patch; + std::string patchType = paramValue["key"].get(); + if (patchType.find("SparkPatchEntry") != std::string::npos) + patch.PatchType = SparkPatchEntry; + else if (patchType.find("SparkLevelPatchEntry") != std::string::npos) + patch.PatchType = SparkLevelPatchEntry; + else if (patchType.find("SparkStreamedPackageEntry") != std::string::npos) + patch.PatchType = SparkStreamedPackageEntry; + else if (patchType.find("SparkSaveGameEntry") != std::string::npos) + patch.PatchType = SparkSaveGameEntry; + else if (patchType.find("SparkPostLoadedEntry") != std::string::npos) + patch.PatchType = SparkPostLoadedEntry; + else if (patchType.find("SparkCharacterLoadedEntry") != std::string::npos) + patch.PatchType = SparkCharacterLoadedEntry; + else if (patchType.find("SparkEarlyLevelPatchEntry") != std::string::npos) + patch.PatchType = SparkEarlyLevelPatchEntry; + + patch.N00001B5E = 1; + patch.Patchname = FString(paramValue["key"].get().c_str()); + patch.Patchdata = FString(paramValue["value"].get().c_str()); + + outPatches->Add(patch); + ++ModdedHotfixes; + ++TotalHotfixes; + } + gotMicropatches = true; + } + } + catch (...) {} + }); + if (gotMicropatches) + break; + } + delete ws; +#ifdef _WIN32 + WSACleanup(); +#endif + //std::cout << "Number of Patches: " << outPatches->Count << std::endl; + } + return; +} + +void hkGetNewsItems(void* newsWidget) { + //void* result = NULL; + if (*pSparkModule) { + if ((*pSparkModule)->SparkNewsService && (*pSparkModule)->SparkNewsService->NewsItems.Data != NULL) { + + for (int i = 0; i < (*pSparkModule)->SparkNewsService->NewsItems.Count; ++i) { + std::cout << (*pSparkModule)->SparkNewsService->NewsItems.Data[i].NewsText.ToString() << std::endl; + } + } + } + if (oGetNewsItems) { + return oGetNewsItems(newsWidget); + } + return; +} + +//typedef DNS_STATUS(WINAPI* DNSQUERYEX)(PDNS_QUERY_REQUEST pQueryRequest, PDNS_QUERY_RESULT pQueryResults, PDNS_QUERY_CANCEL pCancelHandle); +//DNSQUERYEX fpDnsQueryEx = NULL; +// +//DNS_STATUS hkDnsQueryEx(PDNS_QUERY_REQUEST pQueryRequest, PDNS_QUERY_RESULT pQueryResults, PDNS_QUERY_CANCEL pCancelHandle) { +// DNS_STATUS result = fpDnsQueryEx(pQueryRequest, pQueryResults, pCancelHandle); +// return result; +//} +// +//typedef DNS_STATUS (WINAPI *DNSQUERYCONFIG)(DNS_CONFIG_TYPE Config, DWORD Flag, PCWSTR pwsAdapterName, PVOID pReserved,PVOID pBuffer,PDWORD pBufLen); +//DNSQUERYCONFIG fpDnsQueryConfig = NULL; +//DNS_STATUS hkDnsQueryConfig(DNS_CONFIG_TYPE Config, DWORD Flag, PCWSTR pwsAdapterName, PVOID pReserved, PVOID pBuffer, PDWORD pBufLen) { +// DNS_STATUS rv = fpDnsQueryConfig(Config, Flag, pwsAdapterName, pReserved, pBuffer, pBufLen); +// return rv; +//} +// +//typedef int (WINAPI* SOCKRCV)(SOCKET s, char* buf, int len, int flags); +//SOCKRCV fpnSockRcv = NULL; +// +//typedef int (WSAAPI* SOCKCONNECT)(SOCKET s, const sockaddr* name, int namelen); +//SOCKCONNECT fpnSockConnect = NULL; +// +//int hkSockRcv(SOCKET s, char* buf, int len, int flags) { +// int result = fpnSockRcv(s, buf, len, flags); +// return result; +//} +// +//int hkSockConnect(SOCKET s, const sockaddr* name, int namelen) { +// int result = fpnSockConnect(s, name, namelen); +// return result; +//} + +//typedef int (WSAAPI* tconnect)(SOCKET s, const sockaddr* name, int namelen); +//tconnect oconnect = NULL; +// +//int WSAAPI hkconnect(SOCKET s, const sockaddr* name, int namelen) { +// int retval = oconnect(s, name, namelen); +// return retval; +//} +// +//typedef SOCKET (WSAAPI* tWSASocketW)(int af, int type, int protocol, LPWSAPROTOCOL_INFOW lpProtocolInfo, GROUP g, DWORD dwFlags); +//tWSASocketW owsaSocketW = NULL; +// +//SOCKET WSAAPI hkWSASocketW(int af, int type, int protocol, LPWSAPROTOCOL_INFOW lpProtocolInfo, GROUP g, DWORD dwFlags) { +// SOCKET result = owsaSocketW(af, type, protocol, lpProtocolInfo, g, dwFlags); +// return result; +//} +// +//typedef INT (WSAAPI* tgetaddrinfo)(PCSTR pNodeName, PCSTR pServiceName, const ADDRINFOA* pHints, PADDRINFOA* ppResult); +//tgetaddrinfo ogetaddrinfo = NULL; +// +//INT WSAAPI hkgetaddrinfo(PCSTR pNodeName, PCSTR pServiceName, const ADDRINFOA* pHints, PADDRINFOA* ppResult) { +// int status = ogetaddrinfo(pNodeName, pServiceName, pHints, ppResult); +// return status; +//} + +// +//typedef void* (*tSomeInterestingFunc)(void* out, char* name, DWORD someNumber); +//tSomeInterestingFunc oSomeInterestingFunc; + +//std::map someFuncInfo; +//const char* test = "DataTable_Mayhem_CoreMods_Easy"; + +//void* hkSomeInterestingFunc(void* out, char* name, DWORD someNumber) { +// //someFuncInfo[std::string(name)] = NULL; +// //std::cout << "[HOOK] SomeInterestingFunc: " << name << std::endl; +// return oSomeInterestingFunc(out, name, someNumber); +//} + +HMODULE thisDLL; +static HMODULE forRefCount; + +void callAtExit() { + MH_DisableHook(MH_ALL_HOOKS); + MH_Uninitialize(); + FreeLibrary(thisDLL); +} + +const auto doThingPattern = xorstr("40 53 48 83 EC 40 80 B9 ?? ?? ?? ?? ?? 48 8B D9 0F 85 ?? ?? ?? ?? 83 B9"); +//const std::string doThingPattern = xorstr("4C 8B ?? 55 56 41 ?? 49 8D ?? ?? 48 81 EC ?? ?? ?? ?? 4C 8D"); +typedef bool(__fastcall* tDoThing)(FSparkInitProcess* fsip); +tDoThing oDoThing = NULL; + +bool doSomething(FSparkInitProcess* fsip) { + return oDoThing(fsip); +} + +DWORD WINAPI MainThread(LPVOID param) +{ +#ifdef _DEBUG + DebugHelper::CreateConsole(); +#endif + + atexit(callAtExit); + GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_PIN, L"BL3ProxySettings.dll", &forRefCount); + + while (!oMalloc) + oMalloc = (tMalloc)PatternScan::FindSignature(NULL, mallocPattern.crypt_get()); + while (!oRealloc) + oRealloc = (tRealloc)PatternScan::FindSignature(NULL, reallocPattern.crypt_get()); + + uintptr_t curl_easy_init = PatternScan::FindSignature(NULL, curl_easy_init_pattern.crypt_get()); + while (curl_easy_init == NULL) + { + curl_easy_init = PatternScan::FindSignature(NULL, curl_easy_init_pattern.crypt_get()); + Sleep(50); + } + std::cout << "Found 1/7 Patterns" << std::endl; + uintptr_t curl_easy_setopt = PatternScan::FindSignature(NULL, curl_easy_setopt_pattern.crypt_get()); + while (curl_easy_setopt == NULL) + { + curl_easy_setopt = PatternScan::FindSignature(NULL, curl_easy_setopt_pattern.crypt_get()); + Sleep(50); + } + std::cout << "Found 2/7 Patterns" << std::endl; + uintptr_t curl_easy_perform = PatternScan::FindSignature(NULL, curl_easy_perform_pattern.crypt_get()); + while (curl_easy_perform == NULL) { + curl_easy_perform = PatternScan::FindSignature(NULL, curl_easy_perform_pattern.crypt_get()); + Sleep(50); + } + std::cout << "Found 3/7 Patterns" << std::endl; + uintptr_t curl_easy_cleanup = PatternScan::FindSignature(NULL, curl_easy_cleanup_pattern.crypt_get()); + while (curl_easy_cleanup == NULL) { + curl_easy_cleanup = PatternScan::FindSignature(NULL, curl_easy_cleanup_pattern.crypt_get()); + Sleep(50); + } + std::cout << "Found 4/7 Patterns" << std::endl; + uintptr_t curl_multi_perform = PatternScan::FindSignature(NULL, curl_multi_perform_pattern.crypt_get()); + while (curl_multi_perform == NULL) { + curl_multi_perform = PatternScan::FindSignature(NULL, curl_multi_perform_pattern.crypt_get()); + Sleep(50); + } + uintptr_t curl_easy_getinfo = PatternScan::FindSignature(NULL, curl_easy_getinfo_pattern.crypt_get()); + while (curl_easy_getinfo == NULL) { + curl_easy_getinfo = PatternScan::FindSignature(NULL, curl_easy_getinfo_pattern.crypt_get()); + Sleep(50); + } + std::cout << "Found 5/7 Patterns" << std::endl; + + /*uintptr_t generateMicropatchArray = PatternScan::FindSignature(NULL, generateMicropatchArrayPattern.crypt_get()); + while (generateMicropatchArray == NULL) { + generateMicropatchArray = PatternScan::FindSignature(NULL, generateMicropatchArrayPattern.crypt_get()); + Sleep(50); + }*/ + std::cout << "Found 6/7 Patterns" << std::endl; + /*uintptr_t getNewsItems = PatternScan::FindSignature(NULL, getNewsItemsPattern.crypt_get()); + while (getNewsItems == NULL) { + getNewsItems = PatternScan::FindSignature(NULL, getNewsItemsPattern.crypt_get()); + Sleep(50); + }*/ + + uintptr_t sparkModuleAddress = PatternScan::FindSignature(NULL, FGbxSparkModuleStartupModulePattern.crypt_get()); + while (sparkModuleAddress == NULL) { + sparkModuleAddress = PatternScan::FindSignature(NULL, FGbxSparkModuleStartupModulePattern.crypt_get()); + Sleep(50); + } + sparkModuleAddress += 9; + DWORD sparkSingletonOffset = *(DWORD*)(sparkModuleAddress + 3); + + pSparkModule = reinterpret_cast(sparkModuleAddress + sparkSingletonOffset + 7); + + /*uintptr_t parseJSONStringAddress = PatternScan::FindSignature(NULL, parseJSONString.crypt_get()); + while (parseJSONStringAddress == NULL) { + parseJSONStringAddress = PatternScan::FindSignature(NULL, parseJSONString.crypt_get()); + Sleep(50); + } + parseJSONStringAddress += 0x33; + + int32_t parseJSONStringOffset = *(int32_t*)(parseJSONStringAddress + 1); + parseJSONStringAddress = parseJSONStringAddress + parseJSONStringOffset + 5;*/ + + std::cout << "Found 7/7 Patterns" << std::endl; + /*uintptr_t fsparkmanagerctor = PatternScan::FindSignature(NULL, sparkManagerCtorPattern.c_str()); + while (fsparkmanagerctor == NULL) { + fsparkmanagerctor = PatternScan::FindSignature(NULL, sparkManagerCtorPattern.c_str()); + Sleep(50); + } + uintptr_t dothingAddress = PatternScan::FindSignature(NULL, doThingPattern.c_str()); + while (dothingAddress == NULL) { + dothingAddress = PatternScan::FindSignature(NULL, doThingPattern.c_str()); + Sleep(50); + } + oDoThing = (tDoThing)dothingAddress;*/ + + MH_STATUS status; + status = MH_Initialize(); + while (status == MH_ERROR_NOT_INITIALIZED) { + Sleep(200); + status = MH_Initialize(); + if (status == MH_ERROR_ALREADY_INITIALIZED) + break; + } + /*while (MH_CreateHookEx((LPVOID)fsparkmanagerctor, &hkFSparkManagerCtor, &oFSparkManagerCtor) != MH_OK) + Sleep(200);*/ + while (MH_CreateHookEx((LPVOID)curl_easy_init, &hkCurl_Easy_Init, &oCurl_Easy_Init) != MH_OK) + Sleep(200); + std::cout << "Placed 1/7 hooks" << std::endl; + while (MH_CreateHookEx((LPVOID)curl_easy_setopt, &hkCurl_Easy_SetOpt, &oCurl_Easy_SetOpt) != MH_OK) + Sleep(200); + std::cout << "Placed 2/7 hooks" << std::endl; + while (MH_CreateHookEx((LPVOID)curl_easy_perform, &hkCurl_Easy_Perform, &oCurl_Easy_Perform) != MH_OK) + Sleep(200); + std::cout << "Placed 3/7 hooks" << std::endl; + while (MH_CreateHookEx((LPVOID)curl_easy_cleanup, &hkCurl_Easy_Cleanup, &oCurl_Easy_Cleanup) != MH_OK) + Sleep(200); + std::cout << "Placed 4/7 hooks" << std::endl; + while (MH_CreateHookEx((LPVOID)curl_multi_perform, &hkCurl_Multi_Perform, &oCurl_Multi_Perform) != MH_OK) + Sleep(200); + while (MH_CreateHookEx((LPVOID)curl_easy_getinfo, &hkCurl_Easy_GetInfo, &oCurl_Easy_GetInfo) != MH_OK) + Sleep(200); + std::cout << "Placed 5/7 hooks" << std::endl; + /*while (MH_CreateHookEx((LPVOID)generateMicropatchArray, &hkGenerateMicropatchArray, &oGenerateMicropatchArray) != MH_OK) + Sleep(200);*/ + std::cout << "Placed 6/7 hooks" << std::endl; + /*while (MH_CreateHookEx((LPVOID)getNewsItems, &hkGetNewsItems, &oGetNewsItems) != MH_OK) + Sleep(200); */ + /*while (MH_CreateHookEx((LPVOID)parseJSONStringAddress, &hkParseJSONString, &oParseJSONString) != MH_OK) + Sleep(200);*/ + std::cout << "Placed 7/7 hooks" << std::endl; + while (MH_EnableHook(MH_ALL_HOOKS) != MH_OK) { + Sleep(200); + } + + std::cout << "Enabled all hooks" << std::endl; + return TRUE; +} + +struct ArgStruct { + const char dllPath[MAX_PATH]; + int portNumber; +}; + +extern "C" __declspec(dllexport) DWORD __stdcall InitFunc(ArgStruct * argstruct) +{ + EnterCriticalSection(&critsec); + proxyPort = std::to_string(argstruct->portNumber); + std::cout << "Set Proxy to: " << proxyURLA << proxyPort << std::endl; + LeaveCriticalSection(&critsec); + return TRUE; +} + +extern "C" __declspec(dllexport) LRESULT CALLBACK WndProc(int nCode, WPARAM wParam, LPARAM lParam) +{ + //std::cout << "Looks like this is working!" << std::endl; + return CallNextHookEx(0, nCode, wParam, lParam); +}; + +//extern "C" __declspec(dllexport) LRESULT RefreshHotfixes() { +// EnterCriticalSection(&critsec); +// if (fsparkManager && fsparkManager->FSparkInitProcessPtr) { +// if (fsparkManager->FSparkInitProcessPtr->FSparkinitProcess) +// fsparkManager->FSparkInitProcessPtr->FSparkinitProcess->InitStep = 0; +// fsparkManager->FSparkInitProcessPtr->FSparkinitProcess->hasBeenRequested = false; +// //fsparkManager->FSparkInitProcessPtr->FSparkinitProcess->N0000160A = 5000.0; +// doSomething(fsparkManager->FSparkInitProcessPtr->FSparkinitProcess); +// } +// LeaveCriticalSection(&critsec); +// return false; +//} + + +BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + InitializeCriticalSection(&critsec); + DisableThreadLibraryCalls(hModule); + thisDLL = hModule; + CreateThread(nullptr, NULL, (LPTHREAD_START_ROUTINE)MainThread, hModule, NULL, nullptr); + break; + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} \ No newline at end of file diff --git a/BL3ProxySettings.sln b/BL3ProxySettings.sln new file mode 100644 index 0000000..cc6829a --- /dev/null +++ b/BL3ProxySettings.sln @@ -0,0 +1,36 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30503.244 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BL3ProxySettings", "BL3ProxySettings.vcxproj", "{E70933C3-6395-4BB1-9B30-FB35D92D1643}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BLua", "..\BL3Lua\BL3Lua.vcxproj", "{DF0B7199-3ED8-49DC-9544-46B6315D4390}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug-JIT|x64 = Debug-JIT|x64 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E70933C3-6395-4BB1-9B30-FB35D92D1643}.Debug|x64.ActiveCfg = Debug|x64 + {E70933C3-6395-4BB1-9B30-FB35D92D1643}.Debug|x64.Build.0 = Debug|x64 + {E70933C3-6395-4BB1-9B30-FB35D92D1643}.Debug-JIT|x64.ActiveCfg = Debug|x64 + {E70933C3-6395-4BB1-9B30-FB35D92D1643}.Debug-JIT|x64.Build.0 = Debug|x64 + {E70933C3-6395-4BB1-9B30-FB35D92D1643}.Release|x64.ActiveCfg = Release|x64 + {E70933C3-6395-4BB1-9B30-FB35D92D1643}.Release|x64.Build.0 = Release|x64 + {DF0B7199-3ED8-49DC-9544-46B6315D4390}.Debug|x64.ActiveCfg = Debug|x64 + {DF0B7199-3ED8-49DC-9544-46B6315D4390}.Debug|x64.Build.0 = Debug|x64 + {DF0B7199-3ED8-49DC-9544-46B6315D4390}.Debug-JIT|x64.ActiveCfg = Debug-JIT|x64 + {DF0B7199-3ED8-49DC-9544-46B6315D4390}.Debug-JIT|x64.Build.0 = Debug-JIT|x64 + {DF0B7199-3ED8-49DC-9544-46B6315D4390}.Release|x64.ActiveCfg = Release|x64 + {DF0B7199-3ED8-49DC-9544-46B6315D4390}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {E5BFF991-181E-41E5-903E-7245BE2D45B0} + EndGlobalSection +EndGlobal diff --git a/BL3ProxySettings.vcxproj b/BL3ProxySettings.vcxproj new file mode 100644 index 0000000..9ff2bc9 --- /dev/null +++ b/BL3ProxySettings.vcxproj @@ -0,0 +1,127 @@ + + + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {e70933c3-6395-4bb1-9b30-fb35d92d1643} + BL3ProxySettings + 10.0.19041.0 + + + + DynamicLibrary + true + v142 + Unicode + + + DynamicLibrary + false + ClangCL + true + Unicode + false + + + + + + + + + + + + + + + true + F:\Programmieren\C++\vcpkg\installed\x64-windows-static-md\include;$(IncludePath) + F:\Programmieren\C++\vcpkg\installed\x64-windows-static-md\debug\lib;$(LibraryPath) + + + false + F:\Programmieren\C++\vcpkg\installed\x64-windows\include;$(IncludePath) + F:\Programmieren\C++\vcpkg\installed\x64-windows\lib;$(LibraryPath) + + + true + x64-windows-static-md + + + true + x64-windows-static-md + + + true + false + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + false + MultiThreadedDebugDLL + stdc17 + /bigobj %(AdditionalOptions) + stdcpp17 + false + OldStyle + + + Console + DebugFull + %(AdditionalDependencies) + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + false + MultiThreadedDLL + MaxSpeed + Speed + stdc17 + stdcpp17 + Async + AnySuitable + false + None + + + Console + true + true + false + + + %(AdditionalDependencies) + /DEBUG:NONE %(AdditionalOptions) + + + + + + + + + + + + + \ No newline at end of file diff --git a/BL3ProxySettings.vcxproj.filters b/BL3ProxySettings.vcxproj.filters new file mode 100644 index 0000000..39c1188 --- /dev/null +++ b/BL3ProxySettings.vcxproj.filters @@ -0,0 +1,30 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/BL3ProxySettings.vcxproj.user b/BL3ProxySettings.vcxproj.user new file mode 100644 index 0000000..8223d61 --- /dev/null +++ b/BL3ProxySettings.vcxproj.user @@ -0,0 +1,13 @@ + + + + E:\SteamLibrary\steamapps\common\Borderlands 3\OakGame\Binaries\Win64\Borderlands3.exe + true + WindowsLocalDebugger + + + E:\SteamLibrary\steamapps\common\Borderlands 3\OakGame\Binaries\Win64\Borderlands3.exe + true + WindowsLocalDebugger + + \ No newline at end of file diff --git a/SparkClasses.h b/SparkClasses.h new file mode 100644 index 0000000..1945a36 --- /dev/null +++ b/SparkClasses.h @@ -0,0 +1,249 @@ +#pragma once +// Created with ReClass.NET 1.2 by KN4CK3R + +class FSparkInitProcess +{ +public: + void* Something; //0x0008 + uint32_t N000015F8; //0x0010 + char pad_0014[84]; //0x0014 + uint32_t N00001603; //0x0068 + uint32_t N00001752; //0x006C + uint32_t N00001604; //0x0070 + uint32_t N00001754; //0x0074 + uint32_t N00001605; //0x0078 + uint32_t N00001756; //0x007C + uint32_t N00001606; //0x0080 + uint32_t N00001758; //0x0084 + uint32_t N00001607; //0x0088 + uint32_t N0000175A; //0x008C + wchar_t* UniqueSparkIDW; //0x0090 + char pad_0098[8]; //0x0098 + float N0000160A; //0x00A0 + int32_t N000016CD; //0x00A4 + int32_t N0000160B; //0x00A8 + float N000016D6; //0x00AC + uint32_t N0000160C; //0x00B0 + float N000016CF; //0x00B4 + int32_t N0000160D; //0x00B8 + float N000016C8; //0x00BC + bool hasBeenRequested; //0x00C0 + int8_t N00002E86; //0x00C1 + int8_t N00002E8A; //0x00C2 + int8_t N00002E90; //0x00C3 + int8_t InitStep; //0x00C4 + int8_t N00002E87; //0x00C5 + int8_t N00002E8D; //0x00C6 + int8_t N00002E88; //0x00C7 + uint8_t N00002E78; //0x00C8 + int8_t N00002E7B; //0x00C9 + int8_t N00002E79; //0x00CA + char pad_00CB[1]; //0x00CB + uint8_t N00002E95; //0x00CC + uint8_t N00002E98; //0x00CD + uint8_t N00002E96; //0x00CE + uint8_t N0000160F; //0x00CF + uint8_t N00002E7F; //0x00D0 + char pad_00D1[2]; //0x00D1 + int32_t N00001729; //0x00D3 + uint32_t N00001610; //0x00D7 + char pad_00DB[56]; //0x00DB + uint32_t N00001775; //0x0113 + char pad_0117[24]; //0x0117 + wchar_t* SteamIDW; //0x012F + uint32_t N0000161C; //0x0137 + uint32_t N0000172C; //0x013B + uint32_t N0000161D; //0x013F + uint32_t N0000172E; //0x0143 + uint32_t N0000161E; //0x0147 + uint32_t N00001730; //0x014B + uint32_t N0000161F; //0x014F + uint32_t N00001732; //0x0153 + char pad_0157[12]; //0x0157 + uint32_t N00001736; //0x0163 + char pad_0167[8]; //0x0167 + char* SteamIDA; //0x016F + char* SteamIDA2; //0x0177 + char pad_017F[8]; //0x017F + wchar_t* UniqueSparkIDW2; //0x0187 + char pad_018F[32]; //0x018F + uint32_t N0000162B; //0x01AF + uint32_t N000016E6; //0x01B3 + char pad_01B7[8]; //0x01B7 + uint32_t N0000162D; //0x01BF + uint32_t N000016EA; //0x01C3 + char* UniqueSparkIDA1; //0x01C7 + char* UniqueSparkIDA2; //0x01CF + char pad_01D7[8]; //0x01D7 + wchar_t* N00001631; //0x01DF + char pad_01E7[56]; //0x01E7 + char* N00001639; //0x021F + char* N0000163A; //0x0227 + char pad_022F[8]; //0x022F + wchar_t* N0000163C; //0x0237 + char pad_023F[56]; //0x023F + char* N00001644; //0x0277 + char* N00001645; //0x027F + char pad_0287[8]; //0x0287 + wchar_t* N00001647; //0x028F + char pad_0297[56]; //0x0297 + char* N0000164F; //0x02CF + char* N00001650; //0x02D7 + char pad_02DF[72]; //0x02DF + void* N0000165A; //0x0327 + void* N0000165B; //0x032F + void* N0000165C; //0x0337 + void* N0000165D; //0x033F + + virtual void Function0(); + virtual void Function1(); + virtual void Function2(); + virtual void Function3(); + virtual void Function4(); + virtual void Function5(); + virtual void Function6(); + virtual void Function7(); + virtual void Function8(); + virtual void Function9(); +}; //Size: 0x0347 + +class N000016AF +{ +public: + class FSparkInitProcess* FSparkinitProcess; //0x0000 + char pad_0008[128]; //0x0008 +}; //Size: 0x0088 +static_assert(sizeof(N000016AF) == 0x88); + +class FSparkManager +{ +public: + char pad_0008[8]; //0x0008 + int64_t N00001928; //0x0010 + void* N00001929; //0x0018 + int32_t N0000192A; //0x0020 + int32_t N00001A91; //0x0024 + int32_t N0000192B; //0x0028 + int32_t N0000199A; //0x002C + void* N0000192C; //0x0030 + int32_t N0000192D; //0x0038 + int32_t N0000199C; //0x003C + int32_t N0000192E; //0x0040 + int32_t N0000199E; //0x0044 + char pad_0048[8]; //0x0048 + int32_t N00001930; //0x0050 + int32_t N00001A8E; //0x0054 + int32_t N00001931; //0x0058 + int32_t N000019A2; //0x005C + char pad_0060[8]; //0x0060 + int32_t N00001933; //0x0068 + int32_t N00001A8B; //0x006C + int32_t N00001934; //0x0070 + int32_t N000019A5; //0x0074 + char pad_0078[16]; //0x0078 + int32_t N00001937; //0x0088 + int32_t N000019A8; //0x008C + char pad_0090[8]; //0x0090 + int32_t N00001939; //0x0098 + int32_t N00001A82; //0x009C + int32_t N0000193A; //0x00A0 + int32_t N000019AB; //0x00A4 + char pad_00A8[8]; //0x00A8 + int32_t N0000193C; //0x00B0 + int32_t N00001A85; //0x00B4 + int32_t N0000193D; //0x00B8 + int32_t N000019AE; //0x00BC + char pad_00C0[8]; //0x00C0 + int32_t N0000193F; //0x00C8 + int32_t N00001A7F; //0x00CC + int32_t N00001940; //0x00D0 + int32_t N000019B1; //0x00D4 + char pad_00D8[8]; //0x00D8 + int32_t N00001942; //0x00E0 + int32_t N00001A9D; //0x00E4 + int32_t N00001943; //0x00E8 + int32_t N000019B4; //0x00EC + char pad_00F0[8]; //0x00F0 + int32_t N00001945; //0x00F8 + int32_t N00001A88; //0x00FC + int32_t N00001946; //0x0100 + int32_t N000019B7; //0x0104 + char pad_0108[8]; //0x0108 + int32_t N00001948; //0x0110 + char pad_0114[12]; //0x0114 + int32_t N0000194A; //0x0120 + char pad_0124[20]; //0x0124 + int32_t N0000194D; //0x0138 + int32_t N000019BA; //0x013C + char pad_0140[8]; //0x0140 + int32_t N0000194F; //0x0148 + int32_t N00001A9A; //0x014C + int32_t N00001950; //0x0150 + int32_t N000019BD; //0x0154 + char pad_0158[8]; //0x0158 + int32_t N00001952; //0x0160 + int32_t N000019C0; //0x0164 + char pad_0168[16]; //0x0168 + int32_t N00001955; //0x0178 + int32_t N000019C3; //0x017C + char pad_0180[8]; //0x0180 + int32_t N00001957; //0x0188 + int32_t N000019C6; //0x018C + char pad_0190[16]; //0x0190 + wchar_t* N0000195A; //0x01A0 + int32_t N0000195B; //0x01A8 + int32_t N00001A73; //0x01AC + char pad_01B0[208]; //0x01B0 + class N000016AF* FSparkInitProcessPtr; //0x0280 + char pad_0288[72]; //0x0288 + void* SparkTMSThings; //0x02D0 + void* N00001981; //0x02D8 + wchar_t* PlatformName; //0x02E0 + int32_t N00001983; //0x02E8 + int32_t N00001A29; //0x02EC + char pad_02F0[32]; //0x02F0 + wchar_t* N00001988; //0x0310 + char pad_0318[8]; //0x0318 + wchar_t* N0000198A; //0x0320 + char pad_0328[16]; //0x0328 + wchar_t* GameTitle; //0x0338 + char pad_0340[24]; //0x0340 + wchar_t* PlatformName2; //0x0358 + char pad_0360[40]; //0x0360 + int32_t N00001997; //0x0388 + int32_t N00001A78; //0x038C + int32_t N00001998; //0x0390 + int32_t N00001A7A; //0x0394 + + virtual void Function0(); + virtual void SomethingBifrostTick(); + virtual void SomethingGbxSpark(); + virtual void Function3(); + virtual void Function4(); + virtual void SomethingTMS_FileVersion(); + virtual void Something_timeoffset(); + virtual void Something_long(); + virtual void Something_timestamp(); + virtual void Function9(); + virtual void Soemthing_boolean(); + virtual void Function11(); + virtual void Function12(); + virtual void Function13(); + virtual void Function14(); + virtual void Something_local_user_id(); + virtual void Something_string(); + virtual void Something_matchid(); + virtual void Something_integer(); + virtual void Something_timeoffset2(); + virtual void Something_long2(); + virtual void Something_timestamp2(); + virtual void Something_float(); + virtual void Something_boolean2(); + virtual void Function24(); + virtual void Function25(); + virtual void Function26(); + virtual void Function27(); + virtual void Function28(); + virtual void Function29(); +}; //Size: 0x0398 +static_assert(sizeof(FSparkManager) == 0x398); \ No newline at end of file diff --git a/include/MinHook.h b/include/MinHook.h new file mode 100644 index 0000000..b59f1d1 --- /dev/null +++ b/include/MinHook.h @@ -0,0 +1,199 @@ +/* + * MinHook - The Minimalistic API Hooking Library for x64/x86 + * Copyright (C) 2009-2017 Tsuda Kageyu. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#if !(defined _M_IX86) && !(defined _M_X64) && !(defined __i386__) && !(defined __x86_64__) +#error MinHook supports only x86 and x64 systems. +#endif + +#include + +// MinHook Error Codes. +typedef enum MH_STATUS +{ + // Unknown error. Should not be returned. + MH_UNKNOWN = -1, + + // Successful. + MH_OK = 0, + + // MinHook is already initialized. + MH_ERROR_ALREADY_INITIALIZED, + + // MinHook is not initialized yet, or already uninitialized. + MH_ERROR_NOT_INITIALIZED, + + // The hook for the specified target function is already created. + MH_ERROR_ALREADY_CREATED, + + // The hook for the specified target function is not created yet. + MH_ERROR_NOT_CREATED, + + // The hook for the specified target function is already enabled. + MH_ERROR_ENABLED, + + // The hook for the specified target function is not enabled yet, or already + // disabled. + MH_ERROR_DISABLED, + + // The specified pointer is invalid. It points the address of non-allocated + // and/or non-executable region. + MH_ERROR_NOT_EXECUTABLE, + + // The specified target function cannot be hooked. + MH_ERROR_UNSUPPORTED_FUNCTION, + + // Failed to allocate memory. + MH_ERROR_MEMORY_ALLOC, + + // Failed to change the memory protection. + MH_ERROR_MEMORY_PROTECT, + + // The specified module is not loaded. + MH_ERROR_MODULE_NOT_FOUND, + + // The specified function is not found. + MH_ERROR_FUNCTION_NOT_FOUND +} MH_STATUS; + +// Can be passed as a parameter to MH_EnableHook, MH_DisableHook, +// MH_QueueEnableHook or MH_QueueDisableHook. +#define MH_ALL_HOOKS NULL + +#ifdef __cplusplus +extern "C" +{ +#endif + + // Initialize the MinHook library. You must call this function EXACTLY ONCE + // at the beginning of your program. + MH_STATUS WINAPI MH_Initialize(VOID); + + // Uninitialize the MinHook library. You must call this function EXACTLY + // ONCE at the end of your program. + MH_STATUS WINAPI MH_Uninitialize(VOID); + + // Creates a Hook for the specified target function, in disabled state. + // Parameters: + // pTarget [in] A pointer to the target function, which will be + // overridden by the detour function. + // pDetour [in] A pointer to the detour function, which will override + // the target function. + // ppOriginal [out] A pointer to the trampoline function, which will be + // used to call the original target function. + // This parameter can be NULL. + MH_STATUS WINAPI MH_CreateHook(LPVOID pTarget, LPVOID pDetour, LPVOID *ppOriginal); + + // Creates a Hook for the specified API function, in disabled state. + // Parameters: + // pszModule [in] A pointer to the loaded module name which contains the + // target function. + // pszTarget [in] A pointer to the target function name, which will be + // overridden by the detour function. + // pDetour [in] A pointer to the detour function, which will override + // the target function. + // ppOriginal [out] A pointer to the trampoline function, which will be + // used to call the original target function. + // This parameter can be NULL. + MH_STATUS WINAPI MH_CreateHookApi( + LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, LPVOID *ppOriginal); + + // Creates a Hook for the specified API function, in disabled state. + // Parameters: + // pszModule [in] A pointer to the loaded module name which contains the + // target function. + // pszTarget [in] A pointer to the target function name, which will be + // overridden by the detour function. + // pDetour [in] A pointer to the detour function, which will override + // the target function. + // ppOriginal [out] A pointer to the trampoline function, which will be + // used to call the original target function. + // This parameter can be NULL. + // ppTarget [out] A pointer to the target function, which will be used + // with other functions. + // This parameter can be NULL. + MH_STATUS WINAPI MH_CreateHookApiEx( + LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, LPVOID *ppOriginal, LPVOID *ppTarget); + + // Removes an already created hook. + // Parameters: + // pTarget [in] A pointer to the target function. + MH_STATUS WINAPI MH_RemoveHook(LPVOID pTarget); + + // Enables an already created hook. + // Parameters: + // pTarget [in] A pointer to the target function. + // If this parameter is MH_ALL_HOOKS, all created hooks are + // enabled in one go. + MH_STATUS WINAPI MH_EnableHook(LPVOID pTarget); + + // Disables an already created hook. + // Parameters: + // pTarget [in] A pointer to the target function. + // If this parameter is MH_ALL_HOOKS, all created hooks are + // disabled in one go. + MH_STATUS WINAPI MH_DisableHook(LPVOID pTarget); + + // Queues to enable an already created hook. + // Parameters: + // pTarget [in] A pointer to the target function. + // If this parameter is MH_ALL_HOOKS, all created hooks are + // queued to be enabled. + MH_STATUS WINAPI MH_QueueEnableHook(LPVOID pTarget); + + // Queues to disable an already created hook. + // Parameters: + // pTarget [in] A pointer to the target function. + // If this parameter is MH_ALL_HOOKS, all created hooks are + // queued to be disabled. + MH_STATUS WINAPI MH_QueueDisableHook(LPVOID pTarget); + + // Applies all queued changes in one go. + MH_STATUS WINAPI MH_ApplyQueued(VOID); + + // Translates the MH_STATUS to its name as a string. + const char *WINAPI MH_StatusToString(MH_STATUS status); + +#ifdef __cplusplus +} +#endif + +template +inline MH_STATUS MH_CreateHookEx(LPVOID pTarget, LPVOID pDetour, T **ppOriginal) +{ + return MH_CreateHook(pTarget, pDetour, reinterpret_cast(ppOriginal)); +} + +template +inline MH_STATUS MH_CreateHookApiEx( + LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, T **ppOriginal) +{ + return MH_CreateHookApi( + pszModule, pszProcName, pDetour, reinterpret_cast(ppOriginal)); +} \ No newline at end of file diff --git a/include/easywsclient.cpp b/include/easywsclient.cpp new file mode 100644 index 0000000..02fbae1 --- /dev/null +++ b/include/easywsclient.cpp @@ -0,0 +1,695 @@ + +#ifdef _WIN32 +#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) +#define _CRT_SECURE_NO_WARNINGS // _CRT_SECURE_NO_WARNINGS for sscanf errors in MSVC2013 Express +#endif +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#include +#include +#pragma comment(lib, "ws2_32") +#include +#include +#include +#include +#include +#ifndef _SSIZE_T_DEFINED +typedef int ssize_t; +#define _SSIZE_T_DEFINED +#endif +#ifndef _SOCKET_T_DEFINED +typedef SOCKET socket_t; +#define _SOCKET_T_DEFINED +#endif +#ifndef snprintf +#define snprintf _snprintf_s +#endif +#if _MSC_VER >= 1600 +// vs2010 or later +#include +#else +typedef __int8 int8_t; +typedef unsigned __int8 uint8_t; +typedef __int32 int32_t; +typedef unsigned __int32 uint32_t; +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; +#endif +#define socketerrno WSAGetLastError() +#define SOCKET_EAGAIN_EINPROGRESS WSAEINPROGRESS +#define SOCKET_EWOULDBLOCK WSAEWOULDBLOCK +#else +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef _SOCKET_T_DEFINED +typedef int socket_t; +#define _SOCKET_T_DEFINED +#endif +#ifndef INVALID_SOCKET +#define INVALID_SOCKET (-1) +#endif +#ifndef SOCKET_ERROR +#define SOCKET_ERROR (-1) +#endif +#define closesocket(s) ::close(s) +#include +#define socketerrno errno +#define SOCKET_EAGAIN_EINPROGRESS EAGAIN +#define SOCKET_EWOULDBLOCK EWOULDBLOCK +#endif + +#include +#include + +#include "easywsclient.hpp" + +using easywsclient::BytesCallback_Imp; +using easywsclient::Callback_Imp; + +namespace +{ // private module-only namespace + + socket_t hostname_connect(const std::string &hostname, int port) + { + struct addrinfo hints; + struct addrinfo *result; + struct addrinfo *p; + int ret; + socket_t sockfd = INVALID_SOCKET; + char sport[16]; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + snprintf(sport, 16, "%d", port); + if ((ret = getaddrinfo(hostname.c_str(), sport, &hints, &result)) != 0) + { + fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(ret)); + return 1; + } + for (p = result; p != NULL; p = p->ai_next) + { + sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol); + if (sockfd == INVALID_SOCKET) + { + continue; + } + if (connect(sockfd, p->ai_addr, p->ai_addrlen) != SOCKET_ERROR) + { + break; + } + closesocket(sockfd); + sockfd = INVALID_SOCKET; + } + freeaddrinfo(result); + return sockfd; + } + + class _DummyWebSocket : public easywsclient::WebSocket + { + public: + void poll(int timeout) {} + void send(const std::string &message) {} + void sendBinary(const std::string &message) {} + void sendBinary(const std::vector &message) {} + void sendPing() {} + void close() {} + readyStateValues getReadyState() const { return CLOSED; } + void _dispatch(Callback_Imp &callable) {} + void _dispatchBinary(BytesCallback_Imp &callable) {} + }; + + class _RealWebSocket : public easywsclient::WebSocket + { + public: + // http://tools.ietf.org/html/rfc6455#section-5.2 Base Framing Protocol + // + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-------+-+-------------+-------------------------------+ + // |F|R|R|R| opcode|M| Payload len | Extended payload length | + // |I|S|S|S| (4) |A| (7) | (16/64) | + // |N|V|V|V| |S| | (if payload len==126/127) | + // | |1|2|3| |K| | | + // +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - + + // | Extended payload length continued, if payload len == 127 | + // + - - - - - - - - - - - - - - - +-------------------------------+ + // | |Masking-key, if MASK set to 1 | + // +-------------------------------+-------------------------------+ + // | Masking-key (continued) | Payload Data | + // +-------------------------------- - - - - - - - - - - - - - - - + + // : Payload Data continued ... : + // + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + // | Payload Data continued ... | + // +---------------------------------------------------------------+ + struct wsheader_type + { + unsigned header_size; + bool fin; + bool mask; + enum opcode_type + { + CONTINUATION = 0x0, + TEXT_FRAME = 0x1, + BINARY_FRAME = 0x2, + CLOSE = 8, + PING = 9, + PONG = 0xa, + } opcode; + int N0; + uint64_t N; + uint8_t masking_key[4]; + }; + + std::vector rxbuf; + std::vector txbuf; + std::vector receivedData; + + socket_t sockfd; + readyStateValues readyState; + bool useMask; + bool isRxBad; + + _RealWebSocket(socket_t sockfd, bool useMask) + : sockfd(sockfd), readyState(OPEN), useMask(useMask), isRxBad(false) + { + } + + readyStateValues getReadyState() const + { + return readyState; + } + + void poll(int timeout) + { // timeout in milliseconds + if (readyState == CLOSED) + { + if (timeout > 0) + { + timeval tv = {timeout / 1000, (timeout % 1000) * 1000}; + select(0, NULL, NULL, NULL, &tv); + } + return; + } + if (timeout != 0) + { + fd_set rfds; + fd_set wfds; + timeval tv = {timeout / 1000, (timeout % 1000) * 1000}; + FD_ZERO(&rfds); + FD_ZERO(&wfds); + FD_SET(sockfd, &rfds); + if (txbuf.size()) + { + FD_SET(sockfd, &wfds); + } + select(sockfd + 1, &rfds, &wfds, 0, timeout > 0 ? &tv : 0); + } + while (true) + { + // FD_ISSET(0, &rfds) will be true + int N = rxbuf.size(); + ssize_t ret; + rxbuf.resize(N + 1500); + ret = recv(sockfd, (char *)&rxbuf[0] + N, 1500, 0); + if (false) + { + } + else if (ret < 0 && (socketerrno == SOCKET_EWOULDBLOCK || socketerrno == SOCKET_EAGAIN_EINPROGRESS)) + { + rxbuf.resize(N); + break; + } + else if (ret <= 0) + { + rxbuf.resize(N); + closesocket(sockfd); + readyState = CLOSED; + fputs(ret < 0 ? "Connection error!\n" : "Connection closed!\n", stderr); + break; + } + else + { + rxbuf.resize(N + ret); + } + } + while (txbuf.size()) + { + int ret = ::send(sockfd, (char *)&txbuf[0], txbuf.size(), 0); + if (false) + { + } // ?? + else if (ret < 0 && (socketerrno == SOCKET_EWOULDBLOCK || socketerrno == SOCKET_EAGAIN_EINPROGRESS)) + { + break; + } + else if (ret <= 0) + { + closesocket(sockfd); + readyState = CLOSED; + fputs(ret < 0 ? "Connection error!\n" : "Connection closed!\n", stderr); + break; + } + else + { + txbuf.erase(txbuf.begin(), txbuf.begin() + ret); + } + } + if (!txbuf.size() && readyState == CLOSING) + { + closesocket(sockfd); + readyState = CLOSED; + } + } + + // Callable must have signature: void(const std::string & message). + // Should work with C functions, C++ functors, and C++11 std::function and + // lambda: + //template + //void dispatch(Callable callable) + virtual void _dispatch(Callback_Imp &callable) + { + struct CallbackAdapter : public BytesCallback_Imp + // Adapt void(const std::string&) to void(const std::string&) + { + Callback_Imp &callable; + CallbackAdapter(Callback_Imp &callable) : callable(callable) {} + void operator()(const std::vector &message) + { + std::string stringMessage(message.begin(), message.end()); + callable(stringMessage); + } + }; + CallbackAdapter bytesCallback(callable); + _dispatchBinary(bytesCallback); + } + + virtual void _dispatchBinary(BytesCallback_Imp &callable) + { + // TODO: consider acquiring a lock on rxbuf... + if (isRxBad) + { + return; + } + while (true) + { + wsheader_type ws; + if (rxbuf.size() < 2) + { + return; /* Need at least 2 */ + } + const uint8_t *data = (uint8_t *)&rxbuf[0]; // peek, but don't consume + ws.fin = (data[0] & 0x80) == 0x80; + ws.opcode = (wsheader_type::opcode_type)(data[0] & 0x0f); + ws.mask = (data[1] & 0x80) == 0x80; + ws.N0 = (data[1] & 0x7f); + ws.header_size = 2 + (ws.N0 == 126 ? 2 : 0) + (ws.N0 == 127 ? 8 : 0) + (ws.mask ? 4 : 0); + if (rxbuf.size() < ws.header_size) + { + return; /* Need: ws.header_size - rxbuf.size() */ + } + int i = 0; + if (ws.N0 < 126) + { + ws.N = ws.N0; + i = 2; + } + else if (ws.N0 == 126) + { + ws.N = 0; + ws.N |= ((uint64_t)data[2]) << 8; + ws.N |= ((uint64_t)data[3]) << 0; + i = 4; + } + else if (ws.N0 == 127) + { + ws.N = 0; + ws.N |= ((uint64_t)data[2]) << 56; + ws.N |= ((uint64_t)data[3]) << 48; + ws.N |= ((uint64_t)data[4]) << 40; + ws.N |= ((uint64_t)data[5]) << 32; + ws.N |= ((uint64_t)data[6]) << 24; + ws.N |= ((uint64_t)data[7]) << 16; + ws.N |= ((uint64_t)data[8]) << 8; + ws.N |= ((uint64_t)data[9]) << 0; + i = 10; + if (ws.N & 0x8000000000000000ull) + { + // https://tools.ietf.org/html/rfc6455 writes the "the most + // significant bit MUST be 0." + // + // We can't drop the frame, because (1) we don't we don't + // know how much data to skip over to find the next header, + // and (2) this would be an impractically long length, even + // if it were valid. So just close() and return immediately + // for now. + isRxBad = true; + fprintf(stderr, "ERROR: Frame has invalid frame length. Closing.\n"); + close(); + return; + } + } + if (ws.mask) + { + ws.masking_key[0] = ((uint8_t)data[i + 0]) << 0; + ws.masking_key[1] = ((uint8_t)data[i + 1]) << 0; + ws.masking_key[2] = ((uint8_t)data[i + 2]) << 0; + ws.masking_key[3] = ((uint8_t)data[i + 3]) << 0; + } + else + { + ws.masking_key[0] = 0; + ws.masking_key[1] = 0; + ws.masking_key[2] = 0; + ws.masking_key[3] = 0; + } + + // Note: The checks above should hopefully ensure this addition + // cannot overflow: + if (rxbuf.size() < ws.header_size + ws.N) + { + return; /* Need: ws.header_size+ws.N - rxbuf.size() */ + } + + // We got a whole message, now do something with it: + if (false) + { + } + else if ( + ws.opcode == wsheader_type::TEXT_FRAME || ws.opcode == wsheader_type::BINARY_FRAME || ws.opcode == wsheader_type::CONTINUATION) + { + if (ws.mask) + { + for (size_t i = 0; i != ws.N; ++i) + { + rxbuf[i + ws.header_size] ^= ws.masking_key[i & 0x3]; + } + } + receivedData.insert(receivedData.end(), rxbuf.begin() + ws.header_size, rxbuf.begin() + ws.header_size + (size_t)ws.N); // just feed + if (ws.fin) + { + callable((const std::vector)receivedData); + receivedData.erase(receivedData.begin(), receivedData.end()); + std::vector().swap(receivedData); // free memory + } + } + else if (ws.opcode == wsheader_type::PING) + { + if (ws.mask) + { + for (size_t i = 0; i != ws.N; ++i) + { + rxbuf[i + ws.header_size] ^= ws.masking_key[i & 0x3]; + } + } + std::string data(rxbuf.begin() + ws.header_size, rxbuf.begin() + ws.header_size + (size_t)ws.N); + sendData(wsheader_type::PONG, data.size(), data.begin(), data.end()); + } + else if (ws.opcode == wsheader_type::PONG) + { + } + else if (ws.opcode == wsheader_type::CLOSE) + { + close(); + } + else + { + fprintf(stderr, "ERROR: Got unexpected WebSocket message.\n"); + close(); + } + + rxbuf.erase(rxbuf.begin(), rxbuf.begin() + ws.header_size + (size_t)ws.N); + } + } + + void sendPing() + { + std::string empty; + sendData(wsheader_type::PING, empty.size(), empty.begin(), empty.end()); + } + + void send(const std::string &message) + { + sendData(wsheader_type::TEXT_FRAME, message.size(), message.begin(), message.end()); + } + + void sendBinary(const std::string &message) + { + sendData(wsheader_type::BINARY_FRAME, message.size(), message.begin(), message.end()); + } + + void sendBinary(const std::vector &message) + { + sendData(wsheader_type::BINARY_FRAME, message.size(), message.begin(), message.end()); + } + + template + void sendData(wsheader_type::opcode_type type, uint64_t message_size, Iterator message_begin, Iterator message_end) + { + // TODO: + // Masking key should (must) be derived from a high quality random + // number generator, to mitigate attacks on non-WebSocket friendly + // middleware: + const uint8_t masking_key[4] = {0x12, 0x34, 0x56, 0x78}; + // TODO: consider acquiring a lock on txbuf... + if (readyState == CLOSING || readyState == CLOSED) + { + return; + } + std::vector header; + header.assign(2 + (message_size >= 126 ? 2 : 0) + (message_size >= 65536 ? 6 : 0) + (useMask ? 4 : 0), 0); + header[0] = 0x80 | type; + if (false) + { + } + else if (message_size < 126) + { + header[1] = (message_size & 0xff) | (useMask ? 0x80 : 0); + if (useMask) + { + header[2] = masking_key[0]; + header[3] = masking_key[1]; + header[4] = masking_key[2]; + header[5] = masking_key[3]; + } + } + else if (message_size < 65536) + { + header[1] = 126 | (useMask ? 0x80 : 0); + header[2] = (message_size >> 8) & 0xff; + header[3] = (message_size >> 0) & 0xff; + if (useMask) + { + header[4] = masking_key[0]; + header[5] = masking_key[1]; + header[6] = masking_key[2]; + header[7] = masking_key[3]; + } + } + else + { // TODO: run coverage testing here + header[1] = 127 | (useMask ? 0x80 : 0); + header[2] = (message_size >> 56) & 0xff; + header[3] = (message_size >> 48) & 0xff; + header[4] = (message_size >> 40) & 0xff; + header[5] = (message_size >> 32) & 0xff; + header[6] = (message_size >> 24) & 0xff; + header[7] = (message_size >> 16) & 0xff; + header[8] = (message_size >> 8) & 0xff; + header[9] = (message_size >> 0) & 0xff; + if (useMask) + { + header[10] = masking_key[0]; + header[11] = masking_key[1]; + header[12] = masking_key[2]; + header[13] = masking_key[3]; + } + } + // N.B. - txbuf will keep growing until it can be transmitted over the socket: + txbuf.insert(txbuf.end(), header.begin(), header.end()); + txbuf.insert(txbuf.end(), message_begin, message_end); + if (useMask) + { + size_t message_offset = txbuf.size() - message_size; + for (size_t i = 0; i != message_size; ++i) + { + txbuf[message_offset + i] ^= masking_key[i & 0x3]; + } + } + } + + void close() + { + if (readyState == CLOSING || readyState == CLOSED) + { + return; + } + readyState = CLOSING; + uint8_t closeFrame[6] = {0x88, 0x80, 0x00, 0x00, 0x00, 0x00}; // last 4 bytes are a masking key + std::vector header(closeFrame, closeFrame + 6); + txbuf.insert(txbuf.end(), header.begin(), header.end()); + } + }; + + easywsclient::WebSocket::pointer from_url(const std::string &url, bool useMask, const std::string &origin, bool internal = false) + { + char host[512]; + int port; + char path[512]; + if (url.size() >= 512) + { + fprintf(stderr, "ERROR: url size limit exceeded: %s\n", url.c_str()); + return NULL; + } + if (origin.size() >= 200) + { + fprintf(stderr, "ERROR: origin size limit exceeded: %s\n", origin.c_str()); + return NULL; + } + if (false) + { + } + else if (sscanf(url.c_str(), "ws://%[^:/]:%d/%s", host, &port, path) == 3) + { + } + else if (sscanf(url.c_str(), "ws://%[^:/]/%s", host, path) == 2) + { + port = 80; + } + else if (sscanf(url.c_str(), "ws://%[^:/]:%d", host, &port) == 2) + { + path[0] = '\0'; + } + else if (sscanf(url.c_str(), "ws://%[^:/]", host) == 1) + { + port = 80; + path[0] = '\0'; + } + else + { + fprintf(stderr, "ERROR: Could not parse WebSocket url: %s\n", url.c_str()); + return NULL; + } + //fprintf(stderr, "easywsclient: connecting: host=%s port=%d path=/%s\n", host, port, path); + socket_t sockfd = hostname_connect(host, port); + if (sockfd == INVALID_SOCKET) + { + fprintf(stderr, "Unable to connect to %s:%d\n", host, port); + return NULL; + } + { + // XXX: this should be done non-blocking, + char line[1024]; + int status; + int i; + snprintf(line, 1024, "GET /%s HTTP/1.1\r\n", path); + ::send(sockfd, line, strlen(line), 0); + if (port == 80) + { + snprintf(line, 1024, "Host: %s\r\n", host); + ::send(sockfd, line, strlen(line), 0); + } + else + { + snprintf(line, 1024, "Host: %s:%d\r\n", host, port); + ::send(sockfd, line, strlen(line), 0); + } + snprintf(line, 1024, "Upgrade: websocket\r\n"); + ::send(sockfd, line, strlen(line), 0); + snprintf(line, 1024, "Connection: Upgrade\r\n"); + ::send(sockfd, line, strlen(line), 0); + if (!origin.empty()) + { + snprintf(line, 1024, "Origin: %s\r\n", origin.c_str()); + ::send(sockfd, line, strlen(line), 0); + } + snprintf(line, 1024, "Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==\r\n"); + ::send(sockfd, line, strlen(line), 0); + if (internal) + { + snprintf(line, 1024, "internal: true\r\n"); + ::send(sockfd, line, strlen(line), 0); + } + snprintf(line, 1024, "Sec-WebSocket-Version: 13\r\n"); + ::send(sockfd, line, strlen(line), 0); + snprintf(line, 1024, "\r\n"); + ::send(sockfd, line, strlen(line), 0); + for (i = 0; i < 2 || (i < 1023 && line[i - 2] != '\r' && line[i - 1] != '\n'); ++i) + { + if (recv(sockfd, line + i, 1, 0) == 0) + { + return NULL; + } + } + line[i] = 0; + if (i == 1023) + { + fprintf(stderr, "ERROR: Got invalid status line connecting to: %s\n", url.c_str()); + return NULL; + } + if (sscanf(line, "HTTP/1.1 %d", &status) != 1 || status != 101) + { + fprintf(stderr, "ERROR: Got bad status connecting to %s: %s", url.c_str(), line); + return NULL; + } + // TODO: verify response headers, + while (true) + { + for (i = 0; i < 2 || (i < 1023 && line[i - 2] != '\r' && line[i - 1] != '\n'); ++i) + { + if (recv(sockfd, line + i, 1, 0) == 0) + { + return NULL; + } + } + if (line[0] == '\r' && line[1] == '\n') + { + break; + } + } + } + int flag = 1; + setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(flag)); // Disable Nagle's algorithm +#ifdef _WIN32 + u_long on = 1; + ioctlsocket(sockfd, FIONBIO, &on); +#else + fcntl(sockfd, F_SETFL, O_NONBLOCK); +#endif + //fprintf(stderr, "Connected to: %s\n", url.c_str()); + return easywsclient::WebSocket::pointer(new _RealWebSocket(sockfd, useMask)); + } + +} // end of module-only namespace + +namespace easywsclient +{ + + WebSocket::pointer WebSocket::create_dummy() + { + static pointer dummy = pointer(new _DummyWebSocket); + return dummy; + } + + WebSocket::pointer WebSocket::from_url(const std::string &url, const std::string &origin, bool internal) + { + return ::from_url(url, true, origin, internal); + } + + WebSocket::pointer WebSocket::from_url_no_mask(const std::string &url, const std::string &origin) + { + return ::from_url(url, false, origin); + } + +} // namespace easywsclient diff --git a/include/easywsclient.hpp b/include/easywsclient.hpp new file mode 100644 index 0000000..629dc8c --- /dev/null +++ b/include/easywsclient.hpp @@ -0,0 +1,89 @@ +#ifndef EASYWSCLIENT_HPP_20120819_MIOFVASDTNUASZDQPLFD +#define EASYWSCLIENT_HPP_20120819_MIOFVASDTNUASZDQPLFD + +// This code comes from: +// https://github.com/dhbaird/easywsclient +// +// To get the latest version: +// wget https://raw.github.com/dhbaird/easywsclient/master/easywsclient.hpp +// wget https://raw.github.com/dhbaird/easywsclient/master/easywsclient.cpp + +#include +#include + +namespace easywsclient +{ + + struct Callback_Imp + { + virtual void operator()(const std::string &message) = 0; + }; + struct BytesCallback_Imp + { + virtual void operator()(const std::vector &message) = 0; + }; + + class WebSocket + { + public: + typedef WebSocket *pointer; + typedef enum readyStateValues + { + CLOSING, + CLOSED, + CONNECTING, + OPEN + } readyStateValues; + + // Factories: + static pointer create_dummy(); + static pointer from_url(const std::string &url, const std::string &origin = std::string()); + static pointer from_url(const std::string &url, const std::string &origin = std::string(), bool internal = false); + static pointer from_url_no_mask(const std::string &url, const std::string &origin = std::string()); + + // Interfaces: + virtual ~WebSocket() {} + virtual void poll(int timeout = 0) = 0; // timeout in milliseconds + virtual void send(const std::string &message) = 0; + virtual void sendBinary(const std::string &message) = 0; + virtual void sendBinary(const std::vector &message) = 0; + virtual void sendPing() = 0; + virtual void close() = 0; + virtual readyStateValues getReadyState() const = 0; + + template + void dispatch(Callable callable) + // For callbacks that accept a string argument. + { // N.B. this is compatible with both C++11 lambdas, functors and C function pointers + struct _Callback : public Callback_Imp + { + Callable &callable; + _Callback(Callable &callable) : callable(callable) {} + void operator()(const std::string &message) { callable(message); } + }; + _Callback callback(callable); + _dispatch(callback); + } + + template + void dispatchBinary(Callable callable) + // For callbacks that accept a std::vector argument. + { // N.B. this is compatible with both C++11 lambdas, functors and C function pointers + struct _Callback : public BytesCallback_Imp + { + Callable &callable; + _Callback(Callable &callable) : callable(callable) {} + void operator()(const std::vector &message) { callable(message); } + }; + _Callback callback(callable); + _dispatchBinary(callback); + } + + protected: + virtual void _dispatch(Callback_Imp &callable) = 0; + virtual void _dispatchBinary(BytesCallback_Imp &callable) = 0; + }; + +} // namespace easywsclient + +#endif /* EASYWSCLIENT_HPP_20120819_MIOFVASDTNUASZDQPLFD */ diff --git a/include/patternscan.hpp b/include/patternscan.hpp new file mode 100644 index 0000000..195f056 --- /dev/null +++ b/include/patternscan.hpp @@ -0,0 +1,655 @@ +#pragma once +// #include +// #include +// #include +#include +// #include +// #include +// #include +#include +// #include +// #include +// #include + +#include + +// enum EPagePermissions +// { +// Execute = PAGE_EXECUTE, +// ExecuteRead = PAGE_EXECUTE_READ, +// ExecuteReadWrite = PAGE_EXECUTE_READWRITE, +// ExecuteWriteCopy = PAGE_EXECUTE_WRITECOPY, +// Read = PAGE_READONLY, +// ReadWrite = PAGE_READWRITE, +// WriteCopy = PAGE_WRITECOPY, +// WriteCombine = PAGE_WRITECOMBINE +// }; + +// struct PatternInfo +// { +// const char *Pattern; +// EPagePermissions Permissions; +// }; + +namespace PatternScan +{ + // struct PatternByte + // { + // struct PatternNibble + // { + // unsigned char data; + // bool wildcard; + // } nibble[2]; + // }; + + // static std::string formathexpattern(std::string patterntext) + // { + // std::string result; + // int len = patterntext.length(); + // for (int i = 0; i < len; i++) + // if (patterntext[i] == '?' || isxdigit(patterntext[i])) + // result += toupper(patterntext[i]); + // return result; + // } + + // static int hexchtoint(char ch) + // { + // if (ch >= '0' && ch <= '9') + // return ch - '0'; + // else if (ch >= 'A' && ch <= 'F') + // return ch - 'A' + 10; + // else if (ch >= 'a' && ch <= 'f') + // return ch - 'a' + 10; + // return 0; + // } + + // static bool patterntransform(std::string patterntext, std::vector &pattern) + // { + // pattern.clear(); + // patterntext = formathexpattern(patterntext); + // int len = patterntext.length(); + // if (!len) + // return false; + + // if (len % 2) //not a multiple of 2 + // { + // patterntext += '?'; + // len++; + // } + + // PatternByte newByte; + // for (int i = 0, j = 0; i < len; i++) + // { + // if (patterntext[i] == '?') //wildcard + // { + // newByte.nibble[j].wildcard = true; //match anything + // } + // else //hex + // { + // newByte.nibble[j].wildcard = false; + // newByte.nibble[j].data = hexchtoint(patterntext[i]) & 0xF; + // } + + // j++; + // if (j == 2) //two nibbles = one byte + // { + // j = 0; + // pattern.push_back(newByte); + // } + // } + // return true; + // } + + // static bool patternmatchbyte(unsigned char byte, const PatternByte &pbyte) + // { + // int matched = 0; + + // unsigned char n1 = (byte >> 4) & 0xF; + // if (pbyte.nibble[0].wildcard) + // matched++; + // else if (pbyte.nibble[0].data == n1) + // matched++; + + // unsigned char n2 = byte & 0xF; + // if (pbyte.nibble[1].wildcard) + // matched++; + // else if (pbyte.nibble[1].data == n2) + // matched++; + + // return (matched == 2); + // } + + // size_t patternfind(std::string pattern, int offset) + // { + // std::vector searchpattern; + + // std::string::iterator end_pos = std::remove(pattern.begin(), pattern.end(), ' '); + // pattern.erase(end_pos, pattern.end()); + + // SYSTEM_INFO sysinf; + // GetSystemInfo(&sysinf); + + // DWORD startAddress = (DWORD)sysinf.lpMinimumApplicationAddress; + + // unsigned char *data = (unsigned char *)startAddress; + + // //MEMORY_BASIC_INFORMATION mbi; + + // if (!patterntransform(pattern.c_str(), searchpattern)) + // return (size_t)-1; + + // //#define MEMORY_READABLE (PAGE_READONLY | PAGE_READWRITE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE) + // //#define MEMORY_WRITABLE (PAGE_READWRITE | PAGE_EXECUTE_READWRITE) + // //#define MEMORY_EXECUTABLE (PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE) + // size_t searchpatternsize = searchpattern.size(); + // for (size_t i = 0, pos = 0; i < 0x7FFFFFFF; i++) //search for the pattern + // { + // //if (VirtualQuery((LPVOID)i, &mbi, sizeof(MEMORY_BASIC_INFORMATION)) != 0 + // // && ((mbi.State != MEM_COMMIT) || !(mbi.Protect & MEMORY_READABLE) || (mbi.Protect & PAGE_GUARD))) + // // //&& mbi.State == MEM_COMMIT && mbi.Protect != PAGE_NOACCESS && !(mbi.Protect & PAGE_GUARD)) + // //{ + // if (patternmatchbyte(data[i], searchpattern.at(pos))) //check if our pattern matches the current byte + // { + // pos++; + // if (pos == searchpatternsize) //everything matched + // { + // if (offset >= 0) + // return startAddress + i - searchpatternsize + 1 + offset; + // if (offset < 0) + // return startAddress + i - searchpatternsize + 1 - offset; + // } + // } + // else if (pos > 0) //fix by Computer_Angel + // { + // i -= pos; + // pos = 0; //reset current pattern position + // } + // /*} + // else + // i += mbi.RegionSize;*/ + // } + // return (size_t)-1; + // } + + // // Find all occurences of the Pattern until a wildcard is hit + // std::vector FindAllOccurences(std::vector pattern, std::vector streamToSearch) + // { + // std::vector positions; + + // // Length of the pattern to look for + // unsigned int patternLength = pattern.size(); + + // // Total length of file to look through + // unsigned int totalLength = streamToSearch.size(); + + // // First Byte of the pattern to look for + // //unsigned char* firstMatchByte; + // auto firstMatchByte = std::strtol(reinterpret_cast(pattern[0]), nullptr, 16); + // std::vector parsedPattern; + // parsedPattern.reserve(pattern.size()); + // for (auto &pat : pattern) + // { + // parsedPattern.push_back((unsigned char)std::strtoul(reinterpret_cast(pat), nullptr, 16)); + // } + + // for (unsigned int i = 0; i < totalLength; i++) + // { + // //auto cmp = (unsigned char)streamToSearch[i]; + // //auto cmp2 = (unsigned char)firstMatchByte; + // //auto cmp2 = std::strtol(reinterpret_cast(streamToSearch.data()[i]), nullptr, 16); + // //auto second = streamToSearch; + // //memcpy(&firstMatchByte, streamToSearch[i], sizeof (unsigned char*)); + // // If the first Byte of the Searchpattern is at the current location of i + // // and the totalLength - i is greater or equal to the pattern length + // //if(i == 0x00000000000dca41) + // //{ + // //Q_ASSERT(false); + // //} + // if ((unsigned char)streamToSearch[i] == firstMatchByte && totalLength - i >= patternLength) + // //if (pattern.data()[0] == *(streamToSearch.begin() +i) && totalLength - i >= patternLength) + // { + // std::vector match; //[patternLength]; + // match.resize(patternLength); + // memcpy(&match[0], &streamToSearch[i], patternLength); + + // // If the current range of the search matches the searchPattern + // // add the current position(i) to the positionList and break + // if (memcmp(match.data(), parsedPattern.data(), patternLength) == 0) + // { + // positions.push_back(static_cast(i)); + // } + // else + // { + // memset(&match, 0, patternLength); + // } + // } + // } + // return positions; + // } + + // // Find all occurences of the Pattern until a wildcard is hit + // std::vector FindAllOccurences(std::vector pattern, uintptr_t startAddress, uintptr_t totalSize = 0x7FFFFFFF) + // { + // std::vector positions; + + // // Length of the pattern to look for + // unsigned int patternLength = pattern.size(); + + // // Total length of file to look through + // unsigned int totalLength = totalSize - startAddress; + + // // First Byte of the pattern to look for + // //unsigned char* firstMatchByte; + // auto firstMatchByte = std::strtol(reinterpret_cast(pattern[0]), nullptr, 16); + // std::vector parsedPattern; + // parsedPattern.reserve(pattern.size()); + + // for (auto &pat : pattern) + // { + // parsedPattern.push_back((unsigned char)std::strtol(reinterpret_cast(pat), nullptr, 16)); + // } + + // for (unsigned int i = 0; i < totalLength; i++) + // { + // if ((*(PBYTE)startAddress + i) == firstMatchByte && totalLength - i >= patternLength) + // { + // std::vector match; //[patternLength]; + // match.resize(patternLength); + // memcpy(&match[0], (LPVOID)(*(PBYTE)startAddress + i), patternLength); + + // // If the current range of the search matches the searchPattern + // // add the current position(i) to the positionList and break + // if (memcmp(match.data(), parsedPattern.data(), patternLength) == 0) + // { + // positions.push_back(static_cast(i)); + // } + // else + // { + // memset(&match, 0, patternLength); + // } + // } + // } + // return positions; + // } + + // // Search the given Pattern iconst n the given& char-vector + // uintptr_t SearchBytePattern(const std::string &pattern, std::vector streamToSearch, int offset) + // { + // std::istringstream buf(pattern); + // std::istream_iterator beg(buf), end; + // std::vector tokens(beg, end); + // std::vector patternArray; + // patternArray.reserve(tokens.size()); + // for (auto &data : tokens) + // { + // patternArray.push_back(_strdup(data.c_str())); + // } + + // std::vector temp; + + // for (unsigned int i = 0; i < tokens.size(); i++) + // { + // // Using QString for the "startsWith function + // // auto value = QString(patternArray[i]); + // // if(!value.startsWith('?', Qt::CaseInsensitive)) + // auto value = std::string(patternArray[i]); + // if (!_strnicmp(value.c_str(), "?", sizeof("?"))) + // { + // temp.push_back(patternArray[i]); + // } + // else + // break; + // } + + // auto occurences = FindAllOccurences(temp, streamToSearch); + + // std::vector parsedPattern; + // parsedPattern.reserve(patternArray.size()); + // for (auto &pat : patternArray) + // { + // parsedPattern.push_back((unsigned char)std::strtol(reinterpret_cast(pat), nullptr, 16)); + // } + + // std::vector check(patternArray.size()); + // for (auto &occ : occurences) + // { + // memset(check.data(), 0, patternArray.size()); + // memcpy(check.data(), &streamToSearch[occ], patternArray.size()); + + // for (unsigned int o = 0; o < patternArray.size(); o++) + // { + // // If the current Patterncharacter is a wildcard, go to next index + // if (isalnum(*patternArray[o]) == 0) // == 0 || isalpha(*patternArray[0]) == 0) + // continue; + + // // Convert current Patternindex + // char pat = (char)std::stoul(std::string(patternArray[o]), nullptr, 16); + + // // Compare memory, if equal, result is 0 + // int mem = memcmp(&check[o], &pat, 1); + + // // If memory is not equal, the pattern doesn't match + // if (mem != 0) + // { + // break; + // } + // // o can only be the size of the pattern if it matches + // if (o == patternArray.size() - 1) + // { + // if (offset < 0) + // return occ - offset; + // if (offset > 0) + // return occ + offset; + // return occ; + // } + // } + // } + // // No result found + // return 0; + // } + + // uintptr_t SearchBytePattern(uintptr_t startAddress, uintptr_t fileSize, const std::string &pattern, int offset) + // { + // MODULEINFO miInfos = {NULL}; + // HMODULE hmModule = GetModuleHandle(NULL); + + // if (hmModule) + // { + // GetModuleInformation(GetCurrentProcess(), hmModule, &miInfos, sizeof(MODULEINFO)); + // } + + // std::istringstream buf(pattern); + // std::istream_iterator beg(buf), end; + // std::vector tokens(beg, end); + // std::vector patternArray; + // patternArray.reserve(tokens.size()); + // for (auto &data : tokens) + // { + // patternArray.push_back(_strdup(data.c_str())); + // } + + // std::vector temp; + + // for (unsigned int i = 0; i < tokens.size(); i++) + // { + // // Using QString for the "startsWith function + // auto value = std::string(patternArray[i]); + // if (_strnicmp(value.c_str(), "?", sizeof("?"))) + // { + // temp.push_back(patternArray[i]); + // } + // else + // break; + // } + + // auto occurences = FindAllOccurences(temp, startAddress); + + // std::vector parsedPattern; + // parsedPattern.reserve(patternArray.size()); + // for (auto &pat : patternArray) + // { + // parsedPattern.push_back((unsigned char)std::strtol(reinterpret_cast(pat), nullptr, 16)); + // } + + // std::vector check(patternArray.size()); + // for (auto &occ : occurences) + // { + // memset(check.data(), 0, patternArray.size()); + // memcpy(check.data(), (LPVOID)(startAddress + occ), patternArray.size()); + + // for (unsigned int o = 0; o < patternArray.size(); o++) + // { + // // If the current Patterncharacter is a wildcard, go to next index + // if (isalnum(*patternArray[o]) == 0) // == 0 || isalpha(*patternArray[0]) == 0) + // continue; + + // // Convert current Patternindex + // char pat = (char)std::stoul(std::string(patternArray[o]), nullptr, 16); + + // // Compare memory, if equal, result is 0 + // int mem = memcmp(&check[o], &pat, 1); + + // // If memory is not equal, the pattern doesn't match + // if (mem != 0) + // { + // break; + // } + // // o can only be the size of the pattern if it matches + // if (o == patternArray.size() - 1) + // { + // if (offset < 0) + // return occ - offset; + // if (offset > 0) + // return occ + offset; + // return occ; + // } + // } + // } + // // No result found + // return 0; + // } + + // /** + // * \brief Returns first occurrence of byte pattern in a module + // * \param module Base address of module + // * \param signature IDA-style byte pattern + // * \return Pointer to first occurrence + // * \see CSGOSimple by MarkHC + // */ + // inline std::uint8_t *patternScan(void *module, std::string signature) + // { + // static auto pattern_to_byte = [](const char *pattern) { + // auto bytes = std::vector{}; + // auto start = const_cast(pattern); + // auto end = const_cast(pattern) + strlen(pattern); + + // for (auto current = start; current < end; ++current) + // { + // if (*current == '??') + // { + // ++current; + // if (*current == '??') + // ++current; + // bytes.push_back(-1); + // } + // else + // bytes.push_back(strtoul(current, ¤t, 16)); + // } + // return bytes; + // }; + + // auto dosHeader = (PIMAGE_DOS_HEADER)module; + // auto ntHeaders = (PIMAGE_NT_HEADERS)((std::uint8_t *)module + dosHeader->e_lfanew); + + // auto sizeOfImage = ntHeaders->OptionalHeader.SizeOfImage; + // auto patternBytes = pattern_to_byte(signature.c_str()); + // auto scanBytes = reinterpret_cast(module); + + // auto s = patternBytes.size(); + // auto d = patternBytes.data(); + + // for (auto i = 0ul; i < sizeOfImage - s; ++i) + // { + // bool found = true; + // for (auto j = 0ul; j < s; ++j) + // { + // if (scanBytes[i + j] != d[j] && d[j] != -1) + // { + // found = false; + // break; + // } + // } + // if (found) + // return &scanBytes[i]; + // } + + // return nullptr; + // } + + // static std::vector ParseSignature(std::string &pattern) + // { + // std::vector bytes; + // for (unsigned int i = 0; i < pattern.length(); i += 2) + // { + // std::string byteString = pattern.substr(i, 2); + // char byte = (char)strtol(byteString.c_str(), NULL, 16); + // bytes.push_back(byte); + // } + // return bytes; + // } + + // static DWORD FindMySignature(const char *szModule, std::string szSignature, int offset) + // { + // /*AllocConsole(); + // freopen("CONIN$", "r", stdin); + // freopen("CONOUT$", "w", stdout); + // freopen("CONOUT$", "w", stderr);*/ + + // MODULEINFO modInfo; + // GetModuleInformation(GetCurrentProcess(), GetModuleHandleA(szModule), &modInfo, sizeof(MODULEINFO)); + // DWORD startAddress = (DWORD)modInfo.lpBaseOfDll; + // DWORD endAddress = startAddress + modInfo.SizeOfImage; + + // std::string pattern = szSignature; + // std::string::iterator end_pos = std::remove(szSignature.begin(), szSignature.end(), ' '); + // szSignature.erase(end_pos, szSignature.end()); + + // //const char* pat = szSignature.c_str(); + // auto pat = ParseSignature(szSignature); + + // DWORD firstMatch = 0; + + // //std::vector check(sizeof(szSignature)); + // //auto firstMatchByte = std::strtol(&pat[0], nullptr, 16); + // auto firstMatchByte = (int)pat[0]; + // std::cout << std::hex << (int)*(unsigned char *)startAddress << '\n'; + // std::cout << "Pattern to search for: " << szSignature << '\n'; + // std::cout << "Length of Pattern: " << szSignature.length() << '\n'; + // std::cout << "FirstMatchByte: " << std::hex << firstMatchByte << '\n'; + + // SYSTEM_INFO sysinf; + // GetSystemInfo(&sysinf); + + // MEMORY_BASIC_INFORMATION mbi; + // //startAddress += 0x4F318C; + + // /*for (int i = 0; i < pat.size(); i++) + // std::cout << (int)pat[i];*/ + + // for (DWORD pCur = startAddress; pCur < 0x7FFFFFFF; pCur++) + // { + // if (VirtualQuery((LPVOID)pCur, &mbi, sizeof(MEMORY_BASIC_INFORMATION)) != 0 + // //&& ((mBI.State != MEM_COMMIT) || !(mBI.Protect & MEMORY_READABLE) || (mBI.Protect & PAGE_GUARD))) + // && mbi.State == MEM_COMMIT && mbi.Protect != PAGE_NOACCESS && !(mbi.Protect & PAGE_GUARD)) + // { + + // //CREDITS: learn_more + // #define INRANGE(x, a, b) (x >= a && x <= b) + // #define getBits(x) (INRANGE((x & (~0x20)), 'A', 'F') ? ((x & (~0x20)) - 'A' + 0xa) : (INRANGE(x, '0', '9') ? x - '0' : 0)) + // #define getByte(x) (getBits(x[0]) << 4 | getBits(x[1])) + + // const char *patt = pattern.c_str(); + + // if (!*patt) + // return firstMatch; + // if (*(PBYTE)patt == '\?' || *(BYTE *)pCur == getByte(patt)) + // { + // if (!firstMatch) + // firstMatch = pCur; + // if (!patt[2]) + // return firstMatch; + // if (*(PWORD)patt == '\?\?' || *(PBYTE)patt != '\?') + // patt += 3; + // else + // patt += 2; //one ? + // } + // else + // { + // patt = szSignature.c_str(); + // firstMatch = 0; + // } + + // if ((int)*(unsigned char *)pCur == (int)firstMatchByte && endAddress - pCur >= szSignature.length()) + // { + // //if (pattern.data()[0] == *(streamToSearch.begin() +i) && totalLength - i >= patternLength) + // for (unsigned int o = 0; o < pat.size(); o++) + // { + // // If the current Patterncharacter is a wildcard, go to next index + // //if (isalnum(szSignature[o]) == 0)// == 0 || isalpha(*patternArray[0]) == 0) + // if (pat[o] == strtol("??", 0, 16)) + // { + // //std::cout << "Current Patternindex is a wildcard: " << pat[o] << '\n'; + // continue; + // } + + // auto currentPat = (int)pat[o]; + + // /*std::cout << '\n\n'; + // std::cout << "Startaddress: 0x" << std::hex << (DWORD)modInfo.lpBaseOfDll << '\n'; + // std::cout << "Currentaddress: 0x" << std::hex << pCur + o << '\n'; + // std::cout << "Current Byte is: " << std::hex << (int)*(unsigned char*)(pCur + o) << '\n'; + // std::cout << "Current Pattern is: " << std::hex << currentPat << '\n'; + // std::cout << '\n';*/ + + // if ((int)*(unsigned char *)(pCur + o) != currentPat) + // { + // //std::cout << "Cur Val: 0x" << std::hex << (int)*(unsigned char*)(pCur + o) << " Pattern: 0x" << std::hex << currentPat << '\n'; + // break; + // } + + // // o can only be the size of the pattern if it matches + // if (o == pat.size() - 1) + // { + // if (offset < 0) + // return pCur - offset; + // if (offset > 0) + // return pCur + offset; + // return pCur; + // } + // } + // } + // } + // else + // pCur += mbi.RegionSize; + // } + // return NULL; + // } + + static uintptr_t FindSignature(const char *szModule, const char *szSignature) + { + //CREDITS: learn_more +#define INRANGE(x, a, b) (x >= a && x <= b) +#define getBits(x) (INRANGE((x & (~0x20)), 'A', 'F') ? ((x & (~0x20)) - 'A' + 0xa) : (INRANGE(x, '0', '9') ? x - '0' : 0)) +#define getByte(x) (getBits(x[0]) << 4 | getBits(x[1])) + + MODULEINFO modInfo; + GetModuleInformation(GetCurrentProcess(), GetModuleHandleA(szModule), &modInfo, sizeof(MODULEINFO)); + uintptr_t startAddress = (uintptr_t)modInfo.lpBaseOfDll; + uintptr_t endAddress = startAddress + modInfo.SizeOfImage; + const char *pat = szSignature; + uintptr_t firstMatch = 0; + for (uintptr_t pCur = startAddress; pCur < endAddress; pCur++) + { + if (!*pat) + return firstMatch; + if (*(PBYTE)pat == '\?' || *(BYTE *)pCur == getByte(pat)) + { + if (!firstMatch) + firstMatch = pCur; + if (!pat[2]) + return firstMatch; + if (*(PWORD)pat == '\?\?' || *(PBYTE)pat != '\?') + //if (*(PWORD)pat == '\?' || *(PBYTE)pat != '\?') + pat += 3; + else + pat += 2; //one ? + } + else + { + pat = szSignature; + firstMatch = 0; + } + } + return 0; + } +} // namespace PatternScan \ No newline at end of file diff --git a/lib/libMinHook-MD.x64.Clang.lib b/lib/libMinHook-MD.x64.Clang.lib new file mode 100644 index 0000000..054205e Binary files /dev/null and b/lib/libMinHook-MD.x64.Clang.lib differ diff --git a/lib/libMinHook-MD.x64.lib b/lib/libMinHook-MD.x64.lib new file mode 100644 index 0000000..8617d26 Binary files /dev/null and b/lib/libMinHook-MD.x64.lib differ diff --git a/x64/Debug/BL3ProxySettings.dll b/x64/Debug/BL3ProxySettings.dll new file mode 100644 index 0000000..c6006e2 Binary files /dev/null and b/x64/Debug/BL3ProxySettings.dll differ diff --git a/x64/Debug/BL3ProxySettings.dll.recipe b/x64/Debug/BL3ProxySettings.dll.recipe new file mode 100644 index 0000000..c54fc93 --- /dev/null +++ b/x64/Debug/BL3ProxySettings.dll.recipe @@ -0,0 +1,11 @@ + + + + + F:\Programmieren\C++\BL3\BL3ProxySettings\x64\Debug\BL3ProxySettings.dll + + + + + + \ No newline at end of file diff --git a/x64/Debug/BL3ProxySettings.exp b/x64/Debug/BL3ProxySettings.exp new file mode 100644 index 0000000..e652349 Binary files /dev/null and b/x64/Debug/BL3ProxySettings.exp differ diff --git a/x64/Debug/BL3ProxySettings.lib b/x64/Debug/BL3ProxySettings.lib new file mode 100644 index 0000000..830e5ff Binary files /dev/null and b/x64/Debug/BL3ProxySettings.lib differ diff --git a/x64/Debug/BL3ProxySettings.log b/x64/Debug/BL3ProxySettings.log new file mode 100644 index 0000000..6b31a4f --- /dev/null +++ b/x64/Debug/BL3ProxySettings.log @@ -0,0 +1,42 @@ +cl : command line warning D9025: overriding '/sdl' with '/GS-' + BL3ProxySettings.cpp +F:\Programmieren\C++\BL3\BL3ProxySettings\include\easywsclient.cpp(98,29): warning C4477: 'fprintf' : format string '%s' requires an argument of type 'char *', but variadic argument 1 has type 'WCHAR *' +F:\Programmieren\C++\BL3\BL3ProxySettings\include\easywsclient.cpp(98,29): message : consider using '%ls' in the format string +F:\Programmieren\C++\BL3\BL3ProxySettings\include\easywsclient.cpp(98,29): message : consider using '%lls' in the format string +F:\Programmieren\C++\BL3\BL3ProxySettings\include\easywsclient.cpp(98,29): message : consider using '%Ls' in the format string +F:\Programmieren\C++\BL3\BL3ProxySettings\include\easywsclient.cpp(98,29): message : consider using '%ws' in the format string +F:\Programmieren\C++\BL3\BL3ProxySettings\include\easywsclient.cpp(108,16): warning C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data +F:\Programmieren\C++\BL3\BL3ProxySettings\include\easywsclient.cpp(217,31): warning C4244: 'argument': conversion from 'socket_t' to 'int', possible loss of data +F:\Programmieren\C++\BL3\BL3ProxySettings\include\easywsclient.cpp(222,1): warning C4267: 'initializing': conversion from 'size_t' to 'int', possible loss of data +F:\Programmieren\C++\BL3\BL3ProxySettings\include\easywsclient.cpp(249,1): warning C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data +F:\Programmieren\C++\BL3\BL3ProxySettings\include\easywsclient.cpp(597,49): warning C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data +F:\Programmieren\C++\BL3\BL3ProxySettings\include\easywsclient.cpp(601,53): warning C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data +F:\Programmieren\C++\BL3\BL3ProxySettings\include\easywsclient.cpp(606,53): warning C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data +F:\Programmieren\C++\BL3\BL3ProxySettings\include\easywsclient.cpp(609,49): warning C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data +F:\Programmieren\C++\BL3\BL3ProxySettings\include\easywsclient.cpp(611,49): warning C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data +F:\Programmieren\C++\BL3\BL3ProxySettings\include\easywsclient.cpp(615,53): warning C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data +F:\Programmieren\C++\BL3\BL3ProxySettings\include\easywsclient.cpp(618,49): warning C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data +F:\Programmieren\C++\BL3\BL3ProxySettings\include\easywsclient.cpp(622,53): warning C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data +F:\Programmieren\C++\BL3\BL3ProxySettings\include\easywsclient.cpp(625,49): warning C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data +F:\Programmieren\C++\BL3\BL3ProxySettings\include\easywsclient.cpp(627,49): warning C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data +F:\Programmieren\C++\BL3\BL3ProxySettings\include\easywsclient.cpp(563,18): warning C4996: 'sscanf': This function or variable may be unsafe. Consider using sscanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +F:\Programmieren\C++\BL3\BL3ProxySettings\include\easywsclient.cpp(566,18): warning C4996: 'sscanf': This function or variable may be unsafe. Consider using sscanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +F:\Programmieren\C++\BL3\BL3ProxySettings\include\easywsclient.cpp(570,18): warning C4996: 'sscanf': This function or variable may be unsafe. Consider using sscanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +F:\Programmieren\C++\BL3\BL3ProxySettings\include\easywsclient.cpp(574,18): warning C4996: 'sscanf': This function or variable may be unsafe. Consider using sscanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +F:\Programmieren\C++\BL3\BL3ProxySettings\include\easywsclient.cpp(641,17): warning C4996: 'sscanf': This function or variable may be unsafe. Consider using sscanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +F:\Programmieren\C++\BL3\BL3ProxySettings\BL3ProxySettings.cpp(188,2): warning C4091: 'typedef ': ignored on left of '' when no variable is declared +F:\Programmieren\C++\BL3\BL3ProxySettings\BL3ProxySettings.cpp(194,2): warning C4091: 'typedef ': ignored on left of '' when no variable is declared +F:\Programmieren\C++\BL3\BL3ProxySettings\BL3ProxySettings.cpp(570,35): warning C4099: 'TArray': type name first seen using 'struct' now seen using 'class' +F:\Programmieren\C++\BL3\BL3ProxySettings\BL3ProxySettings.cpp(570): message : see declaration of 'TArray' +F:\Programmieren\C++\BL3\BL3ProxySettings\BL3ProxySettings.cpp(633,26): warning C4099: 'FString': type name first seen using 'struct' now seen using 'class' +F:\Programmieren\C++\BL3\BL3ProxySettings\BL3ProxySettings.cpp(472): message : see declaration of 'FString' +F:\Programmieren\C++\BL3\BL3ProxySettings\BL3ProxySettings.cpp(637,23): warning C4099: 'TArray': type name first seen using 'struct' now seen using 'class' +F:\Programmieren\C++\BL3\BL3ProxySettings\BL3ProxySettings.cpp(637): message : see declaration of 'TArray' +F:\Programmieren\C++\BL3\BL3ProxySettings\BL3ProxySettings.cpp(723,5): warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. + libMinHook-MD.x64.lib(hook.obj) : MSIL .netmodule or module compiled with /GL found; restarting link with /LTCG; add /LTCG to the link command line to improve linker performance +LINK : warning LNK4075: ignoring '/INCREMENTAL' due to '/LTCG' specification + Creating library F:\Programmieren\C++\BL3\BL3ProxySettings\x64\Debug\BL3ProxySettings.lib and object F:\Programmieren\C++\BL3\BL3ProxySettings\x64\Debug\BL3ProxySettings.exp +LINK : warning LNK4098: defaultlib 'LIBCMT' conflicts with use of other libs; use /NODEFAULTLIB:library + Generating code + Finished generating code + BL3ProxySettings.vcxproj -> F:\Programmieren\C++\BL3\BL3ProxySettings\x64\Debug\BL3ProxySettings.dll diff --git a/x64/Debug/BL3ProxySettings.obj b/x64/Debug/BL3ProxySettings.obj new file mode 100644 index 0000000..7c791b7 Binary files /dev/null and b/x64/Debug/BL3ProxySettings.obj differ diff --git a/x64/Debug/BL3ProxySettings.pdb b/x64/Debug/BL3ProxySettings.pdb new file mode 100644 index 0000000..cafe236 Binary files /dev/null and b/x64/Debug/BL3ProxySettings.pdb differ diff --git a/x64/Debug/BL3ProxySettings.tlog/BL3ProxySettings.lastbuildstate b/x64/Debug/BL3ProxySettings.tlog/BL3ProxySettings.lastbuildstate new file mode 100644 index 0000000..62e8aba --- /dev/null +++ b/x64/Debug/BL3ProxySettings.tlog/BL3ProxySettings.lastbuildstate @@ -0,0 +1,2 @@ +PlatformToolSet=v142:VCToolArchitecture=Native32Bit:VCToolsVersion=14.28.29910:TargetPlatformVersion=10.0.19041.0: +Debug|x64|F:\Programmieren\C++\BL3\BL3ProxySettings\| diff --git a/x64/Debug/BL3ProxySettings.tlog/BL3ProxySettings.write.1u.tlog b/x64/Debug/BL3ProxySettings.tlog/BL3ProxySettings.write.1u.tlog new file mode 100644 index 0000000..9f6596f Binary files /dev/null and b/x64/Debug/BL3ProxySettings.tlog/BL3ProxySettings.write.1u.tlog differ diff --git a/x64/Debug/BL3ProxySettings.tlog/CL.command.1.tlog b/x64/Debug/BL3ProxySettings.tlog/CL.command.1.tlog new file mode 100644 index 0000000..7d50f4a Binary files /dev/null and b/x64/Debug/BL3ProxySettings.tlog/CL.command.1.tlog differ diff --git a/x64/Debug/BL3ProxySettings.tlog/CL.read.1.tlog b/x64/Debug/BL3ProxySettings.tlog/CL.read.1.tlog new file mode 100644 index 0000000..313ffd8 Binary files /dev/null and b/x64/Debug/BL3ProxySettings.tlog/CL.read.1.tlog differ diff --git a/x64/Debug/BL3ProxySettings.tlog/CL.write.1.tlog b/x64/Debug/BL3ProxySettings.tlog/CL.write.1.tlog new file mode 100644 index 0000000..fa0d968 Binary files /dev/null and b/x64/Debug/BL3ProxySettings.tlog/CL.write.1.tlog differ diff --git a/x64/Debug/BL3ProxySettings.tlog/link.command.1.tlog b/x64/Debug/BL3ProxySettings.tlog/link.command.1.tlog new file mode 100644 index 0000000..ae6bae9 Binary files /dev/null and b/x64/Debug/BL3ProxySettings.tlog/link.command.1.tlog differ diff --git a/x64/Debug/BL3ProxySettings.tlog/link.read.1.tlog b/x64/Debug/BL3ProxySettings.tlog/link.read.1.tlog new file mode 100644 index 0000000..a979484 Binary files /dev/null and b/x64/Debug/BL3ProxySettings.tlog/link.read.1.tlog differ diff --git a/x64/Debug/BL3ProxySettings.tlog/link.write.1.tlog b/x64/Debug/BL3ProxySettings.tlog/link.write.1.tlog new file mode 100644 index 0000000..6ffea87 Binary files /dev/null and b/x64/Debug/BL3ProxySettings.tlog/link.write.1.tlog differ diff --git a/x64/Debug/BL3ProxySettings.vcxproj.FileListAbsolute.txt b/x64/Debug/BL3ProxySettings.vcxproj.FileListAbsolute.txt new file mode 100644 index 0000000..bd0130e --- /dev/null +++ b/x64/Debug/BL3ProxySettings.vcxproj.FileListAbsolute.txt @@ -0,0 +1 @@ +F:\Programmieren\C++\BL3\BL3ProxySettings\x64\Debug\BL3ProxySettings.dll diff --git a/x64/Debug/vcpkg.applocal.log b/x64/Debug/vcpkg.applocal.log new file mode 100644 index 0000000..e02abfc --- /dev/null +++ b/x64/Debug/vcpkg.applocal.log @@ -0,0 +1 @@ + diff --git a/x64/Release/BL3ProxySettings.dll b/x64/Release/BL3ProxySettings.dll new file mode 100644 index 0000000..bdf076a Binary files /dev/null and b/x64/Release/BL3ProxySettings.dll differ diff --git a/x64/Release/BL3ProxySettings.dll.recipe b/x64/Release/BL3ProxySettings.dll.recipe new file mode 100644 index 0000000..edfba39 --- /dev/null +++ b/x64/Release/BL3ProxySettings.dll.recipe @@ -0,0 +1,11 @@ + + + + + F:\Programmieren\C++\BL3\BL3ProxySettings\x64\Release\BL3ProxySettings.dll + + + + + + \ No newline at end of file diff --git a/x64/Release/BL3ProxySettings.lib b/x64/Release/BL3ProxySettings.lib new file mode 100644 index 0000000..e37e6a7 Binary files /dev/null and b/x64/Release/BL3ProxySettings.lib differ diff --git a/x64/Release/BL3ProxySettings.log b/x64/Release/BL3ProxySettings.log new file mode 100644 index 0000000..ec8aa48 --- /dev/null +++ b/x64/Release/BL3ProxySettings.log @@ -0,0 +1,41 @@ + In file included from BL3ProxySettings.cpp:24: +./include/patternscan.hpp(641,24): warning : multi-character character constant [-Wmultichar] + In file included from BL3ProxySettings.cpp:36: +./include/easywsclient.cpp(98,50): warning : format specifies type 'char *' but the argument has type 'WCHAR *' (aka 'wchar_t *') [-Wformat] +C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\um\WS2tcpip.h(670,24): message : expanded from macro 'gai_strerror' + In file included from BL3ProxySettings.cpp:36: +./include/easywsclient.cpp(563,18): warning : 'sscanf' is deprecated: This function or variable may be unsafe. Consider using sscanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. [-Wdeprecated-declarations] +C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\ucrt\stdio.h(2239,20): message : 'sscanf' has been explicitly marked deprecated here +I:\Microsoft VisualStudio 2019\VC\Tools\MSVC\14.28.29910\include\vcruntime.h(320,55): message : expanded from macro '_CRT_INSECURE_DEPRECATE' +I:\Microsoft VisualStudio 2019\VC\Tools\MSVC\14.28.29910\include\vcruntime.h(310,47): message : expanded from macro '_CRT_DEPRECATE_TEXT' + In file included from BL3ProxySettings.cpp:36: +./include/easywsclient.cpp(566,18): warning : 'sscanf' is deprecated: This function or variable may be unsafe. Consider using sscanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. [-Wdeprecated-declarations] +C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\ucrt\stdio.h(2239,20): message : 'sscanf' has been explicitly marked deprecated here +I:\Microsoft VisualStudio 2019\VC\Tools\MSVC\14.28.29910\include\vcruntime.h(320,55): message : expanded from macro '_CRT_INSECURE_DEPRECATE' +I:\Microsoft VisualStudio 2019\VC\Tools\MSVC\14.28.29910\include\vcruntime.h(310,47): message : expanded from macro '_CRT_DEPRECATE_TEXT' + In file included from BL3ProxySettings.cpp:36: +./include/easywsclient.cpp(570,18): warning : 'sscanf' is deprecated: This function or variable may be unsafe. Consider using sscanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. [-Wdeprecated-declarations] +C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\ucrt\stdio.h(2239,20): message : 'sscanf' has been explicitly marked deprecated here +I:\Microsoft VisualStudio 2019\VC\Tools\MSVC\14.28.29910\include\vcruntime.h(320,55): message : expanded from macro '_CRT_INSECURE_DEPRECATE' +I:\Microsoft VisualStudio 2019\VC\Tools\MSVC\14.28.29910\include\vcruntime.h(310,47): message : expanded from macro '_CRT_DEPRECATE_TEXT' + In file included from BL3ProxySettings.cpp:36: +./include/easywsclient.cpp(574,18): warning : 'sscanf' is deprecated: This function or variable may be unsafe. Consider using sscanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. [-Wdeprecated-declarations] +C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\ucrt\stdio.h(2239,20): message : 'sscanf' has been explicitly marked deprecated here +I:\Microsoft VisualStudio 2019\VC\Tools\MSVC\14.28.29910\include\vcruntime.h(320,55): message : expanded from macro '_CRT_INSECURE_DEPRECATE' +I:\Microsoft VisualStudio 2019\VC\Tools\MSVC\14.28.29910\include\vcruntime.h(310,47): message : expanded from macro '_CRT_DEPRECATE_TEXT' + In file included from BL3ProxySettings.cpp:36: +./include/easywsclient.cpp(641,17): warning : 'sscanf' is deprecated: This function or variable may be unsafe. Consider using sscanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. [-Wdeprecated-declarations] +C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\ucrt\stdio.h(2239,20): message : 'sscanf' has been explicitly marked deprecated here +I:\Microsoft VisualStudio 2019\VC\Tools\MSVC\14.28.29910\include\vcruntime.h(320,55): message : expanded from macro '_CRT_INSECURE_DEPRECATE' +I:\Microsoft VisualStudio 2019\VC\Tools\MSVC\14.28.29910\include\vcruntime.h(310,47): message : expanded from macro '_CRT_DEPRECATE_TEXT' +BL3ProxySettings.cpp(124,1): warning : typedef requires a name [-Wmissing-declarations] +BL3ProxySettings.cpp(188,1): warning : typedef requires a name [-Wmissing-declarations] +BL3ProxySettings.cpp(464,2): warning : class 'TArray' was previously declared as a struct; this is valid, but may result in linker errors under the Microsoft C++ ABI [-Wmismatched-tags] +BL3ProxySettings.cpp(227,8): message : previous use is here +BL3ProxySettings.cpp(895,12): warning : unused variable 'replaceMode' [-Wunused-variable] +BL3ProxySettings.cpp(1153,49): warning : implicit conversion between pointer-to-function and pointer-to-object is a Microsoft extension [-Wmicrosoft-cast] +BL3ProxySettings.cpp(1156,54): warning : implicit conversion between pointer-to-function and pointer-to-object is a Microsoft extension [-Wmicrosoft-cast] +BL3ProxySettings.cpp(1159,55): warning : implicit conversion between pointer-to-function and pointer-to-object is a Microsoft extension [-Wmicrosoft-cast] +BL3ProxySettings.cpp(1162,52): warning : implicit conversion between pointer-to-function and pointer-to-object is a Microsoft extension [-Wmicrosoft-cast] +BL3ProxySettings.cpp(1165,53): warning : implicit conversion between pointer-to-function and pointer-to-object is a Microsoft extension [-Wmicrosoft-cast] + BL3ProxySettings.vcxproj -> F:\Programmieren\C++\BL3\BL3ProxySettings\x64\Release\BL3ProxySettings.dll diff --git a/x64/Release/BL3ProxySettings.obj b/x64/Release/BL3ProxySettings.obj new file mode 100644 index 0000000..2731877 Binary files /dev/null and b/x64/Release/BL3ProxySettings.obj differ diff --git a/x64/Release/BL3ProxySettings.tlog/BL3ProxySettings.lastbuildstate b/x64/Release/BL3ProxySettings.tlog/BL3ProxySettings.lastbuildstate new file mode 100644 index 0000000..6257b98 --- /dev/null +++ b/x64/Release/BL3ProxySettings.tlog/BL3ProxySettings.lastbuildstate @@ -0,0 +1,2 @@ +PlatformToolSet=ClangCL:VCToolArchitecture=Native32Bit:VCToolsVersion=14.28.29910:TargetPlatformVersion=10.0.19041.0: +I:\Microsoft VisualStudio 2019\VC\Tools\Llvm\x64|11.0.0|Release|x64|F:\Programmieren\C++\BL3\BL3ProxySettings\| diff --git a/x64/Release/BL3ProxySettings.tlog/BL3ProxySettings.write.1u.tlog b/x64/Release/BL3ProxySettings.tlog/BL3ProxySettings.write.1u.tlog new file mode 100644 index 0000000..d2d6b50 Binary files /dev/null and b/x64/Release/BL3ProxySettings.tlog/BL3ProxySettings.write.1u.tlog differ diff --git a/x64/Release/BL3ProxySettings.tlog/clang-cl.command.1.tlog b/x64/Release/BL3ProxySettings.tlog/clang-cl.command.1.tlog new file mode 100644 index 0000000..7ea5012 Binary files /dev/null and b/x64/Release/BL3ProxySettings.tlog/clang-cl.command.1.tlog differ diff --git a/x64/Release/BL3ProxySettings.tlog/clang-cl.delete.1.tlog b/x64/Release/BL3ProxySettings.tlog/clang-cl.delete.1.tlog new file mode 100644 index 0000000..8b7fb9e Binary files /dev/null and b/x64/Release/BL3ProxySettings.tlog/clang-cl.delete.1.tlog differ diff --git a/x64/Release/BL3ProxySettings.tlog/clang-cl.read.1.tlog b/x64/Release/BL3ProxySettings.tlog/clang-cl.read.1.tlog new file mode 100644 index 0000000..7d44b6f Binary files /dev/null and b/x64/Release/BL3ProxySettings.tlog/clang-cl.read.1.tlog differ diff --git a/x64/Release/BL3ProxySettings.tlog/clang-cl.write.1.tlog b/x64/Release/BL3ProxySettings.tlog/clang-cl.write.1.tlog new file mode 100644 index 0000000..637f9c0 Binary files /dev/null and b/x64/Release/BL3ProxySettings.tlog/clang-cl.write.1.tlog differ diff --git a/x64/Release/BL3ProxySettings.tlog/lld-link.command.1.tlog b/x64/Release/BL3ProxySettings.tlog/lld-link.command.1.tlog new file mode 100644 index 0000000..0d21633 Binary files /dev/null and b/x64/Release/BL3ProxySettings.tlog/lld-link.command.1.tlog differ diff --git a/x64/Release/BL3ProxySettings.tlog/lld-link.delete.1.tlog b/x64/Release/BL3ProxySettings.tlog/lld-link.delete.1.tlog new file mode 100644 index 0000000..095cb60 Binary files /dev/null and b/x64/Release/BL3ProxySettings.tlog/lld-link.delete.1.tlog differ diff --git a/x64/Release/BL3ProxySettings.tlog/lld-link.read.1.tlog b/x64/Release/BL3ProxySettings.tlog/lld-link.read.1.tlog new file mode 100644 index 0000000..456dc4c Binary files /dev/null and b/x64/Release/BL3ProxySettings.tlog/lld-link.read.1.tlog differ diff --git a/x64/Release/BL3ProxySettings.tlog/lld-link.write.1.tlog b/x64/Release/BL3ProxySettings.tlog/lld-link.write.1.tlog new file mode 100644 index 0000000..c16f981 Binary files /dev/null and b/x64/Release/BL3ProxySettings.tlog/lld-link.write.1.tlog differ diff --git a/x64/Release/BL3ProxySettings.vcxproj.FileListAbsolute.txt b/x64/Release/BL3ProxySettings.vcxproj.FileListAbsolute.txt new file mode 100644 index 0000000..aec8f0f --- /dev/null +++ b/x64/Release/BL3ProxySettings.vcxproj.FileListAbsolute.txt @@ -0,0 +1 @@ +F:\Programmieren\C++\BL3\BL3ProxySettings\x64\Release\BL3ProxySettings.dll diff --git a/x64/Release/vcpkg.applocal.log b/x64/Release/vcpkg.applocal.log new file mode 100644 index 0000000..e02abfc --- /dev/null +++ b/x64/Release/vcpkg.applocal.log @@ -0,0 +1 @@ +