|
- #ifndef WIN32_LEAN_AND_MEAN
- #define WIN32_LEAN_AND_MEAN
- #endif
-
- #include <string>
- #include <windows.h>
- //#include <winhttp.h>
- #include <iostream>
- #include <fstream>
- #include <atomic>
- //#include <vector>
-
- #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 <map>
- //#include <fstream>
-
- //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<class T>
- 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<wchar_t>
- {
- inline FString()
- {
- };
-
- FString(const wchar_t* other)
- {
- Max = Count = *other ? static_cast<int32_t>(std::wcslen(other) + 1) : 0;
-
- if (Count)
- {
- this->Data = const_cast<wchar_t*>(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<int32_t>(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<int32_t>(std::wcslen(wc) + 1) : 0;*/
-
- /*if (Count)
- {
- Data = const_cast<wchar_t*>(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::ctype<wchar_t>>(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<FArticleTag> ArticleTags;
- };
-
- class FSparkNewsService
- {
- public:
- char pad_0000[64]; //0x0000
- class TArray<FNewsItem> 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<char> 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<FString>* Headers; //0x00B0
- }; //Size: 0x00B8
- static_assert(sizeof(Curl_Write_Data) == 0xB8);
-
- typedef void(__fastcall* tGenerateMicropatchArray)(void* someTMap, TArray<FMicropatch>* outMicropatches);
- tGenerateMicropatchArray oGenerateMicropatchArray = NULL;
-
- typedef void* (__fastcall* tParseJSONString)(void** jsonReader, const FString* text);
- tParseJSONString oParseJSONString = NULL;
-
- FSparkModule** pSparkModule = NULL;
-
-
- //std::vector<SDK::UObject*> GetObjectNamesWith(const std::string nameToFind) {
- // std::vector<SDK::UObject*> 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<SDK::UObject*>(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<std::string>();
- // 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<std::string>().c_str());
- // patch.Patchdata = FString(paramValue["value"].get<std::string>().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<FSparkManager*>(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<char*>((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<FMicropatch>* 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<std::string>();
- 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<std::string>().c_str());
- patch.Patchdata = FString(paramValue["value"].get<std::string>().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<std::string, void*> 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<FSparkModule**>(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;
- }
|