Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Artifact: integrity.wasm (557fd3a402e23aaa204c2c1f313ba2e8ee2e4b16b56b75fe40e444e9da12e491)
- // Date: 06-02-2024
- // Toolchain: emscript 3.1.56
- // Build: emcc -O3 -sASYNCIFY -sENVIRONMENT=web -sFETCH -lwebsocket.js integrity.c -o integrity
- // Description: WASM module for protecting the integrity of https://soyjack.party/
- //
- // Summary:
- // There are 2 main objectives of this module:
- // - Reporting if tuxler is detected as open when the module started
- // - Replying to commands from the integrity server located at wss://soyjak.party/ws
- // The integrity server is able to send arbitrary javascript to be run on the client and
- // have a result be returned to the server.
- // Additionally, there is some functionality built into the module itself for:
- // - Reporting whether Discord was detected as open when the module started
- // - Reporting the timezone of the client
- //
- // As expected of C, UNIX brain damage continues to result in people making memory errors.
- //
- // Decompilation Status:
- // This decompilation is functionally accurate, but it is not quite a perfect decompilation.
- // The following issues exist preventing the exact artifact to be compilable from this file:
- // - The order of setting the command and the echo for replying to CMD_ECHO is swapped.
- // - The signature info char* for getTimezoneOffset is stored 1 off from
- // where it should be on the stack.
- // - The code for handling CMD_TIMEZONE is being moved to the end of the
- // function by the branch fold LLVM optimization pass.
- #include <emscripten.h>
- #include <emscripten/fetch.h>
- #include <emscripten/websocket.h>
- #include <stdio.h>
- #include <string.h>
- #define CMD_ECHO 0x1
- #define CMD_TIMEZONE 0x2
- #define CMD_FINISH 0x3
- #define CMD_EVAL 0x4
- #define CMD_DISCORD 0x5
- #define CMD_NO_DISCORD 0x6
- #define CMD_EVAL_VOID 0x0
- #define CMD_EVAL_INT32 0x1
- #define CMD_EVAL_DOUBLE 0x2
- #define CMD_EVAL_STRING 0x3
- #define ECHO_KEY 0x2f497cdd
- #define TIMEZONE_KEY 0xd19aabff
- unsigned char eval_key[1024] = {
- 0x64, 0x43, 0x34, 0x9a, 0xff, 0x1d, 0xed, 0xef, 0x0, 0x47, 0xde, 0xba, 0xbd, 0xa9, 0x2f, 0x41,
- 0xcb, 0x6d, 0x6, 0x5a, 0x87, 0x51, 0x9e, 0xaa, 0x28, 0x42, 0x26, 0x51, 0xd9, 0x90, 0xb3, 0xb5,
- 0xf0, 0x1b, 0x93, 0x77, 0x95, 0xbf, 0x82, 0xea, 0x53, 0x27, 0x7c, 0xc4, 0xd8, 0xf2, 0x51, 0xc5,
- 0x45, 0x21, 0x71, 0x5d, 0x37, 0x4, 0x2, 0xa, 0x73, 0x5d, 0x23, 0x80, 0xce, 0xd1, 0xb6, 0xfe,
- 0xe3, 0xa0, 0xcb, 0xbc, 0x0, 0xfe, 0xdc, 0x21, 0x51, 0xef, 0x50, 0x73, 0xdd, 0x64, 0x72, 0x99,
- 0x1c, 0xff, 0xb, 0x44, 0xa, 0x6f, 0xd7, 0xc6, 0x25, 0x84, 0x21, 0xc1, 0xec, 0x37, 0x85, 0x92,
- 0xc1, 0xcf, 0x63, 0x57, 0xdd, 0x2e, 0x4e, 0xdb, 0x72, 0x53, 0xad, 0x4c, 0x7e, 0x28, 0xef, 0xf4,
- 0x75, 0xc1, 0xb9, 0x88, 0xda, 0x94, 0xb8, 0xbe, 0x1d, 0x42, 0x84, 0x6, 0xc1, 0xfe, 0x19, 0xf8,
- 0x71, 0xaf, 0x2a, 0xcf, 0xa8, 0x5c, 0xf4, 0x9f, 0xf4, 0xe9, 0xea, 0xd0, 0x3f, 0x54, 0x12, 0x84,
- 0x98, 0x1d, 0x82, 0x5a, 0xbb, 0x5e, 0xb7, 0x8c, 0xe6, 0x55, 0x14, 0xcb, 0x95, 0x47, 0x4c, 0x5c,
- 0xe4, 0xa3, 0xb8, 0x41, 0x3d, 0x30, 0x71, 0x38, 0xc6, 0xab, 0x53, 0xbe, 0xb2, 0x59, 0xae, 0x51,
- 0xde, 0x1b, 0xbd, 0xb6, 0xb9, 0x5, 0x75, 0x85, 0x4f, 0x74, 0x7b, 0x7f, 0xc9, 0x81, 0xa1, 0xa,
- 0xcc, 0x80, 0xe7, 0x28, 0x8f, 0x1, 0x4e, 0x12, 0x44, 0x5, 0x2a, 0x57, 0x8e, 0x99, 0x38, 0x59,
- 0x97, 0x3d, 0xde, 0x57, 0xc3, 0x45, 0xae, 0x81, 0x23, 0xd7, 0x1a, 0x94, 0xf0, 0xf3, 0xb, 0x3e,
- 0x29, 0x64, 0xf4, 0xe2, 0xdd, 0x1a, 0xc7, 0xc2, 0xa2, 0xc, 0x4a, 0x1a, 0xba, 0x6f, 0x15, 0xa8,
- 0x9c, 0xe1, 0xfa, 0xb5, 0x9a, 0x1c, 0xc7, 0x7c, 0xf9, 0x4e, 0x2c, 0x14, 0x79, 0xb8, 0xb7, 0x94,
- 0xa6, 0xe5, 0x54, 0xbb, 0xa, 0xe3, 0x4c, 0x67, 0xab, 0x35, 0xec, 0x6d, 0xbc, 0x5f, 0x13, 0x8e,
- 0xa4, 0x78, 0xf5, 0xeb, 0xfe, 0x72, 0xc9, 0x87, 0x45, 0x26, 0xc1, 0x55, 0x92, 0x39, 0x8d, 0xbb,
- 0xc0, 0x4e, 0xb9, 0x77, 0x33, 0x2c, 0x62, 0x9e, 0xfb, 0xb5, 0xbe, 0x4c, 0xae, 0xe1, 0xcd, 0xdf,
- 0x89, 0x38, 0x4, 0xd7, 0x42, 0xc9, 0xf8, 0xe3, 0xb3, 0x1f, 0x6b, 0xbe, 0x99, 0x35, 0xdd, 0xcf,
- 0x94, 0x16, 0xd7, 0x12, 0x9, 0xcb, 0x1e, 0xe9, 0xef, 0x6f, 0x35, 0x50, 0x2, 0x2d, 0x13, 0x5a,
- 0x69, 0x62, 0x3a, 0xc8, 0xf5, 0x22, 0xa5, 0xb6, 0x35, 0x19, 0xc2, 0x78, 0x4e, 0xa2, 0x5e, 0x97,
- 0x74, 0x25, 0x86, 0x73, 0x25, 0x61, 0x92, 0xcf, 0x92, 0x12, 0xe5, 0xf8, 0xb1, 0x2, 0x26, 0x5e,
- 0x9a, 0x5a, 0x13, 0x14, 0xd0, 0x2f, 0x3d, 0xe3, 0x92, 0xb, 0xa7, 0x9b, 0x42, 0x86, 0xfc, 0xdc,
- 0x8, 0xd4, 0x39, 0x16, 0x2e, 0xd1, 0x32, 0x27, 0xa, 0xf8, 0xc1, 0x80, 0xc2, 0xf2, 0x49, 0xef,
- 0x7f, 0xe2, 0x3b, 0x91, 0x93, 0xd5, 0xb2, 0x1f, 0x90, 0x5e, 0xee, 0xca, 0xb2, 0x4b, 0x2a, 0x2,
- 0xb9, 0x9d, 0x1a, 0x35, 0xf6, 0x2, 0x76, 0x2d, 0x37, 0x1d, 0x7f, 0x6b, 0x0, 0x88, 0x2a, 0x90,
- 0xf, 0xd0, 0x9, 0xe8, 0x45, 0x8d, 0xe7, 0x6d, 0xb9, 0x9b, 0xac, 0x11, 0x75, 0x5d, 0xcf, 0xe2,
- 0x9f, 0x71, 0x12, 0x46, 0xcd, 0x27, 0xdb, 0x9b, 0xa7, 0xb6, 0x69, 0x36, 0x1b, 0x8f, 0xa3, 0x46,
- 0xda, 0xeb, 0x70, 0xfd, 0x69, 0xa1, 0x2c, 0x51, 0x1f, 0x97, 0xb3, 0xb1, 0x4b, 0x82, 0xc, 0xef,
- 0xca, 0x4e, 0xca, 0x88, 0x57, 0xfa, 0x1f, 0x25, 0x25, 0xbb, 0xb0, 0x5e, 0x5, 0xfb, 0xf4, 0xa4,
- 0x11, 0x0, 0xfb, 0x35, 0xbe, 0xff, 0xea, 0x6f, 0x87, 0xc7, 0xfd, 0x7b, 0x82, 0xa, 0xaf, 0x34,
- 0x63, 0x1e, 0x8d, 0x5, 0x39, 0xe0, 0x76, 0x44, 0x59, 0x9b, 0xd3, 0x60, 0x71, 0x1, 0x37, 0xdf,
- 0x83, 0x8b, 0x9d, 0xcb, 0x4d, 0x8e, 0x81, 0x55, 0xc9, 0xf9, 0x76, 0x81, 0xdb, 0xbe, 0xb0, 0x93,
- 0x76, 0xa1, 0x44, 0xf8, 0xef, 0xf4, 0xcd, 0x3e, 0x52, 0xdd, 0xe0, 0xc0, 0x75, 0xf7, 0x75, 0xc,
- 0x1a, 0xd4, 0x41, 0x53, 0x65, 0xb4, 0x5a, 0x10, 0x53, 0x53, 0x6f, 0x46, 0xbb, 0x1e, 0xe3, 0x8d,
- 0x1d, 0x81, 0xcf, 0xaa, 0x8d, 0x7f, 0xe1, 0xc8, 0x6f, 0x8f, 0xd4, 0x3b, 0x10, 0x47, 0x52, 0x9,
- 0xcc, 0x74, 0x75, 0x24, 0x41, 0x42, 0x69, 0x43, 0x21, 0xb4, 0x88, 0xbb, 0x97, 0xc2, 0xda, 0x8b,
- 0x53, 0x28, 0x53, 0x93, 0x75, 0x9f, 0xe7, 0x91, 0x3e, 0x5d, 0x5d, 0x58, 0x3c, 0xf3, 0x1a, 0x4a,
- 0xa4, 0x38, 0x3c, 0xd5, 0xbe, 0xd6, 0x11, 0x66, 0xdc, 0x8c, 0x75, 0x90, 0x68, 0x83, 0x3f, 0x1a,
- 0x54, 0x83, 0xc4, 0xc, 0x73, 0xd9, 0x27, 0x90, 0x7c, 0x1b, 0xd, 0xd4, 0xaf, 0xa8, 0x24, 0xac,
- 0xfb, 0xa1, 0x55, 0x97, 0xd7, 0xb1, 0x39, 0x3, 0xb5, 0xab, 0x7d, 0xf0, 0x8e, 0x98, 0xf0, 0x0,
- 0xa2, 0x96, 0xaf, 0x7, 0x53, 0xb2, 0x18, 0x1c, 0xaa, 0xe3, 0xc2, 0xd9, 0xb3, 0x33, 0x23, 0xb7,
- 0x66, 0xbc, 0xe7, 0xb2, 0x76, 0xe0, 0xdf, 0x88, 0xad, 0xb9, 0xa9, 0xc6, 0xeb, 0x66, 0x73, 0x61,
- 0x14, 0x2b, 0xaa, 0x6e, 0xd9, 0xd5, 0xe, 0x55, 0x2, 0xf4, 0xd1, 0x25, 0x8d, 0x55, 0xd, 0xf3,
- 0x85, 0xad, 0x4a, 0x71, 0x90, 0x78, 0x32, 0x59, 0xa4, 0xfe, 0xd4, 0x67, 0xb5, 0x8, 0x4d, 0x18,
- 0x11, 0x82, 0x80, 0x69, 0xea, 0x58, 0xb7, 0x1f, 0x5c, 0xda, 0xeb, 0x10, 0x77, 0x13, 0xba, 0x25,
- 0x25, 0xe8, 0xb2, 0x1e, 0xba, 0x3e, 0x56, 0x4d, 0x4, 0x6e, 0x2f, 0x6e, 0x71, 0x81, 0x52, 0x85,
- 0x71, 0x93, 0xeb, 0x2b, 0xcd, 0xb6, 0x36, 0x1b, 0xa9, 0x30, 0x9f, 0x9, 0xb4, 0x1c, 0x2, 0x6a,
- 0x3c, 0x7d, 0xe1, 0x35, 0x6a, 0xb2, 0xe8, 0xc6, 0xec, 0xe, 0xa7, 0x2c, 0xbe, 0x36, 0x36, 0xbb,
- 0x7b, 0xf9, 0xc3, 0x16, 0xe6, 0xdd, 0x4b, 0x2, 0xde, 0x5a, 0x12, 0x8e, 0x2f, 0x86, 0xcc, 0x81,
- 0xf7, 0x29, 0xf6, 0x53, 0x5d, 0x69, 0x64, 0xce, 0x2, 0xce, 0x7d, 0xaf, 0x3, 0xa2, 0x17, 0x63,
- 0xd2, 0x1c, 0x78, 0xf0, 0x13, 0x3e, 0xf9, 0x83, 0x9, 0xd0, 0xd3, 0x22, 0xb3, 0xaa, 0x44, 0xe1,
- 0xf4, 0x6c, 0x9d, 0x9a, 0xbc, 0x92, 0xfd, 0xcd, 0x8a, 0x6f, 0xe9, 0x2b, 0xe6, 0x87, 0x4d, 0x6f,
- 0x4c, 0x26, 0x59, 0x70, 0x29, 0x36, 0x13, 0x17, 0x83, 0x7b, 0x4c, 0x7e, 0x4f, 0xb7, 0xbe, 0xb0,
- 0xfb, 0xfa, 0x32, 0x79, 0x10, 0x18, 0x46, 0x97, 0x94, 0xd0, 0xbc, 0x6d, 0x3c, 0x62, 0x17, 0xd5,
- 0xfe, 0xca, 0x14, 0x34, 0xc5, 0x46, 0x90, 0x94, 0x13, 0xfd, 0x3c, 0xab, 0x59, 0xe7, 0xce, 0x87,
- 0x37, 0xdf, 0x7, 0x58, 0xed, 0x35, 0x50, 0xc4, 0xae, 0xc1, 0x86, 0x64, 0xa3, 0x3c, 0x7c, 0x91,
- 0x44, 0xeb, 0xb2, 0x26, 0x61, 0x16, 0xad, 0xb0, 0xba, 0xbc, 0xa6, 0x46, 0x6a, 0x9c, 0x61, 0x76,
- 0x9e, 0x15, 0x9e, 0xa1, 0xa0, 0x95, 0xb0, 0x24, 0x6, 0x8, 0x5, 0x5, 0x30, 0x31, 0xe7, 0xd7,
- 0x28, 0xf6, 0xed, 0xa1, 0x1c, 0x2c, 0x5, 0xb6, 0xba, 0xa, 0xfd, 0x3b, 0xae, 0x2a, 0xdf, 0x61,
- 0x40, 0x11, 0x15, 0xef, 0xc5, 0x6, 0xf, 0xde, 0xda, 0x8c, 0x8f, 0x6d, 0x34, 0x50, 0x3a, 0x49,
- 0x46, 0xff, 0xad, 0x43, 0x68, 0x98, 0x44, 0x75, 0xbc, 0xd3, 0x77, 0xb, 0xcf, 0xd1, 0x35, 0x35,
- 0x47, 0x98, 0xdd, 0x91, 0xaa, 0x93, 0x65, 0x2c, 0xef, 0x31, 0x61, 0xc8, 0xb0, 0xad, 0xa8, 0xbe,
- };
- const char* integrity_server_uri = "wss://soyjak.party/ws";
- uint8_t send_discord_data = 0;
- uint8_t send_no_discord_data = 0;
- uint8_t finished = 0;
- uint8_t reconnecting = 0;
- uint64_t discord_check_start_time = 0;
- uint64_t discord_check_last_error_time = 0;
- void integrity_ws_reconnect(void* userData);
- /**
- * Cleans up the resources from the fetch reporting discord.
- */
- void tuxler_fetch_cleanup(emscripten_fetch_t *fetch) {
- // This if block can be deleted as data is already freed by emscripten_fetch_close
- if (fetch->data) {
- free((void*) fetch->data);
- }
- emscripten_fetch_close(fetch);
- }
- /**
- * Callback for when a websocket is connected
- *
- * If a connection to the websocket is made to Tuxler then it reports it.
- * The report is done by sending a POST request to /b4.php with i=1.
- *
- * Although a connection is opened it is held open and is not used any further.
- */
- EM_BOOL tuxler_ws_open(int eventType, const EmscriptenWebSocketOpenEvent *websocketEvent, void *userData) {
- emscripten_fetch_attr_t attr;
- emscripten_fetch_attr_init(&attr);
- strcpy(attr.requestMethod, "POST");
- attr.attributes = EMSCRIPTEN_FETCH_LOAD_TO_MEMORY;
- attr.onsuccess = tuxler_fetch_cleanup;
- attr.onerror = tuxler_fetch_cleanup;
- char* data = malloc(4);
- strcpy(data, "i=1");
- attr.requestData = data;
- attr.requestDataSize = strlen(data);
- const char* headers[] = {"Content-Type", "application/x-www-form-urlencoded", NULL};
- attr.requestHeaders = headers;
- emscripten_fetch(&attr, "/b4.php");
- return EM_FALSE;
- }
- /**
- * Sends CMD_DISCORD and CMD_NO_DISCORD if needed
- */
- void send_extra(int8_t* reply, const EmscriptenWebSocketMessageEvent *websocketEvent) {
- if (send_discord_data) {
- uint8_t command = CMD_DISCORD;
- emscripten_websocket_send_binary(websocketEvent->socket, &command, sizeof(command));
- send_discord_data = 0;
- }
- if (send_no_discord_data) {
- // The following command is not sent if the browser is detected as Safari.
- // Passing at least 4 / 6 tests counts the browser as Safari.
- //
- // ApplePayError Safari Desktop 11 Safari Mobile 11
- // CSSPrimitiveValue Safari Dekstop 3 Safari Mobile 1
- // Counter Safari Desktop 3 Safari Mobile 1
- // WebKitMediaKeys Safari Desktop 10.1 Safari Mobile 10.1
- // navigator.vendor Safari Desktop 1 Safari Mobile 1
- // getStorageUpdates Safari Desktop 5 Safari Mobile 4
- //
- // This means that out of the box only Safari Desktop 5+ and Safari Mobile 4+ are counted
- //
- // Since the flag is cleared within the if block, every echo command will test if the
- // browser is no longer detected as Safari.
- if (emscripten_run_script_int(
- "['ApplePayError', 'CSSPrimitiveValue', 'Counter', 'WebKitMediaKeys'].filter(key => key in window).length + "
- "(navigator.vendor.indexOf('Apple') === 0) + "
- "('getStorageUpdates' in navigator)") < 4) {
- uint8_t command = CMD_NO_DISCORD;
- emscripten_websocket_send_binary(websocketEvent->socket, &command, sizeof(command));
- send_no_discord_data = 0;
- }
- }
- }
- /**
- * Gets the timezone offset defined as the minutes away from UTC
- */
- double get_timezone_offset() {
- return EM_ASM_DOUBLE({
- return (new Date).getTimezoneOffset();
- });
- }
- /**
- * Handles communicating with and taking actions on behalf of the server.
- *
- * Packet Structure
- * 0 1 2 3 4 5 6
- * +-+-+-+-+-+-+-+
- * |C| Payload ...
- * +-+-+-+-+-+-+-+
- * C: The command stored in the packaet
- * Paylaod: The rest of the data in the packet
- *
- * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- * Server -> Client
- * vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
- * =============================================================================
- * 0x1 CMD_ECHO
- * =============================================================================
- * 0 1 2 3
- * +-+-+-+-+
- * | Echo |
- * +-+-+-+-+
- * Echo: The data that should be echoed by the client
- *
- * Echo commands can test if the client is alive and is at least pretending to
- * be a valid client. The client must reply with a CMD_ECHO packet with the
- * same data xored with the ECHO_KEY.
- * Echo commands also trigger the client to send CMD_DISCORD or CMD_NO_DISCORD
- * if the client is elgible.
- * =============================================================================
- * 0x2 CMD_TIMEZONE
- * =============================================================================
- * Timezone commands requests client to send a CMD_TIMEZONE packet with the
- * client's timezone via it sending the minutes it is offset from UTC.
- * =============================================================================
- * 0x3 CMD_FINISH
- * =============================================================================
- * The finish command signals to the packet that the client is done dealing
- * with the server and may permanently disconnect.
- * =============================================================================
- * 0x4 CMD_EVAL
- * =============================================================================
- * 0 1 2
- * +-+-+-+
- * |T|Id |
- * +-+-+-+
- * | :
- * :Data :
- * : |
- * +-+-+-+
- * T: The return type of the eval expression
- * - 0x0 CMD_EVAL_VOID
- * - 0x0 CMD_EVAL_INT32
- * - 0x0 CMD_EVAL_DOUBLE
- * - 0x0 CMD_EVAL_STRING
- * Id: A unique id that the client will include in the reply
- * Data: A encrypted null terminated string of javascript to evaluate
- *
- * Eval commands allow the server to evaluate javascript on clients and get
- * the results back.
- * The eval string is hidden by xoring it with eval_key.
- * If the return type is string, the server must guarantee that the length of
- * the result string is less then or equal to 252 bytes, including counting the
- * null terminator.
- *
- * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- * Client->Server
- * vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
- * =============================================================================
- * 0x1 CMD_ECHO
- * =============================================================================
- * 0 1 2 3
- * +-+-+-+-+
- * | Echo |
- * +-+-+-+-+
- * Echo: An encrypted version of the echo from the server
- *
- * When the server send an echo command the client should xor the echo
- * with the ECHO_KEY and send it back.
- * If the client needs to send CMD_DISCORD or CMD_NO_DISCORD then it should do
- * so right after sending the reply to the echo.
- * =============================================================================
- * 0x2 CMD_TIMEZONE
- * =============================================================================
- * 0 1 2 3
- * +-+-+-+-+
- * |Minutes|
- * +-+-+-+-+
- * Minutes: An encrypted float minutes the client is offset from UTC
- *
- * The client can get the needed value by calling getTimezoneOffset on a Date
- * object in javascript, casting it to a float, and xoring it with TIMEZONE_KEY
- * =============================================================================
- * 0x3 CMD_FINISH
- * =============================================================================
- * The client should disconnect from the server.
- * =============================================================================
- * 0x4 CMD_EVAL
- * =============================================================================
- * 0 1 2
- * +-+-+-+
- * |T|Id |
- * +-+-+-+
- * | :
- * :Data :
- * : |
- * +-+-+-+
- * T: The return type of the eval expression the client evaluated
- * - 0x0 CMD_EVAL_VOID
- * - 0x0 CMD_EVAL_INT32
- * - 0x0 CMD_EVAL_DOUBLE
- * - 0x0 CMD_EVAL_STRING
- * Id: A unique id associated with the request the client evaluated
- * Data: An encrypted result of the evaluating the javascript
- *
- * After handling a CMD_EVAL packet, the client sends back the result to the
- * server. The result is also encrypted by xoring each byte with eval_key.
- * For the CMD_EVAL_VOID type the second byte of the id should not be sent.
- * =============================================================================
- * 0x5 CMD_DISCORD
- * =============================================================================
- * This command signals that the client had Discord open
- * =============================================================================
- * 0x3 CMD_NO_DISCORD
- * =============================================================================
- * This command signals that the client did not have Discord open.
- * This command is not supposed to be sent if the user's browser is Safari.
- */
- EM_BOOL integrity_ws_message(int eventType, const EmscriptenWebSocketMessageEvent *websocketEvent, void *userData) {
- int8_t reply[256];
- switch (websocketEvent->data[0]) {
- case CMD_ECHO: {
- reply[0] = CMD_ECHO;
- int echo;
- memcpy(&echo, websocketEvent->data + 1, 4);
- // Encrypt echo
- echo ^= ECHO_KEY;
- memcpy(reply + 1, &echo, sizeof(echo));
- emscripten_websocket_send_binary(websocketEvent->socket, &reply, 5);
- send_extra(reply, websocketEvent);
- break;
- }
- case CMD_TIMEZONE: {
- float timezoneFloat = get_timezone_offset();
- int32_t timezone;
- memcpy(&timezone, &timezoneFloat, 4);
- // Encrypt timezone
- timezone ^= TIMEZONE_KEY;
- memcpy(reply + 1, &timezone, 4);
- reply[0] = CMD_TIMEZONE;
- emscripten_websocket_send_binary(websocketEvent->socket, &reply, 1 + sizeof(timezone));
- break;
- }
- case CMD_FINISH: {
- finished = 1;
- emscripten_websocket_close(websocketEvent->socket, 1000, "close");
- break;
- }
- case CMD_EVAL: {
- uint8_t* body = websocketEvent->data + 4;
- int body_length = websocketEvent->numBytes - 4;
- uint8_t type = websocketEvent->data[1];
- uint16_t id = ((uint16_t* ) websocketEvent->data)[1];
- // Decrypt the message body
- for (int i = 0; i != body_length; i++) {
- body[i] ^= eval_key[i];
- }
- memset(reply, 0, sizeof(reply));
- reply[0] = CMD_EVAL;
- memcpy(reply + 1, &id, sizeof(id));
- switch (type) {
- case CMD_EVAL_VOID: {
- EM_ASM_INT({
- eval(UTF8ToString($0));
- }, body);
- // BUG: The second byte of the id is not sent.
- emscripten_websocket_send_binary(websocketEvent->socket, &reply, 3);
- break;
- }
- case CMD_EVAL_INT32: {
- int32_t result = EM_ASM_INT({
- return eval(UTF8ToString($0));
- }, body);
- reply[3] = CMD_EVAL_INT32;
- memcpy(reply + 4, &result, sizeof(result));
- // Encrypt result
- for (int i = 0; i != 252; i++) {
- reply[i + 4] ^= eval_key[i];
- }
- emscripten_websocket_send_binary(websocketEvent->socket, &reply, 4 + sizeof(result));
- break;
- }
- case CMD_EVAL_DOUBLE: {
- double result = EM_ASM_DOUBLE({
- return eval(UTF8ToString($0));
- }, body);
- reply[3] = CMD_EVAL_DOUBLE;
- memcpy(reply + 4, &result, sizeof(result));
- // Encrypt result
- for (int i = 0; i != 252; i++) {
- reply[i + 4] ^= eval_key[i];
- }
- emscripten_websocket_send_binary(websocketEvent->socket, &reply, 4 + sizeof(result));
- break;
- }
- case CMD_EVAL_STRING: {
- char *result = EM_ASM_PTR({
- var res = eval(UTF8ToString($0));
- if (typeof res !== "string") {
- res = ""
- }
- var lengthBytes = lengthBytesUTF8(res) + 1;
- var stringOnWasmHeap = _malloc(lengthBytes);
- stringToUTF8(res, stringOnWasmHeap, lengthBytes);
- return stringOnWasmHeap
- }, body);
- reply[3] = CMD_EVAL_STRING;
- // BUG: There is a buffer flow here since the size of result is not checked.
- strcpy((char*) reply + 4, result);
- // Encrypt result
- for (int i = 0; i != 252; i++) {
- reply[i + 4] ^= eval_key[i];
- }
- emscripten_websocket_send_binary(websocketEvent->socket, &reply, 4 + strlen(result) + 1);
- free(result);
- break;
- }
- }
- break;
- }
- }
- return EM_FALSE;
- }
- /**
- * If integrity websocket unexpectedly closes the client will reconnect.
- */
- EM_BOOL integrity_ws_close(int eventType, const EmscriptenWebSocketCloseEvent *websocketEvent, void *userData) {
- if (!finished) {
- emscripten_set_timeout(integrity_ws_reconnect, 30000, userData);
- }
- return EM_FALSE;
- }
- /**
- * If the integrity websocket has an error while being used it will reconnect.
- */
- EM_BOOL integrity_ws_error(int eventType, const EmscriptenWebSocketErrorEvent *websocketEvent, void *userData) {
- if (!finished) {
- emscripten_set_timeout(integrity_ws_reconnect, 30000, userData);
- }
- return EM_FALSE;
- }
- /**
- * Flags that the client was able to connect to Discord's RPC.
- */
- EM_BOOL discord_ws_open(int eventType, const EmscriptenWebSocketOpenEvent *websocketEvent, void *userData) {
- send_discord_data = 1;
- return EM_FALSE;
- }
- /**
- * Initiates a reconnection to the integrity server.
- */
- void integrity_ws_reconnect(void* userData) {
- if (!reconnecting) {
- reconnecting = 1;
- EmscriptenWebSocketCreateAttributes integrityAttr;
- emscripten_websocket_init_create_attributes(&integrityAttr);
- integrityAttr.url = integrity_server_uri;
- EMSCRIPTEN_WEBSOCKET_T integritySocket = emscripten_websocket_new(&integrityAttr);
- emscripten_websocket_set_onmessage_callback(integritySocket, NULL, integrity_ws_message);
- emscripten_websocket_set_onclose_callback(integritySocket, NULL, integrity_ws_close);
- emscripten_websocket_set_onerror_callback(integritySocket, NULL, integrity_ws_error);
- // BUG: Setting reconnecting back to 0 here makes this check effectively do nothing.
- // To make it so that 2 reconnects can not happen at the same timereconnecting should be
- // reset to 0 once the connection succeeds or fails.
- reconnecting = 0;
- }
- }
- /**
- * Callback for when the Discord RPC encounters an error.
- *
- * An error can happen because Discord is not running, Discord is closed, or something else.
- * If Discord is not considered running then this flags your session to send extra data when queried.
- * Discord is considered not running if the websocket errors within 99ms of attempting to connect.
- */
- EM_BOOL discord_ws_error(int eventType, const EmscriptenWebSocketErrorEvent *websocketEvent, void *userData) {
- uint64_t now = (uint64_t) emscripten_get_now();
- discord_check_last_error_time = now;
- if (now - discord_check_start_time <= 99) {
- send_no_discord_data = 1;
- }
- return EM_FALSE;
- }
- int main() {
- // Discord Detection
- EmscriptenWebSocketCreateAttributes attr;
- emscripten_websocket_init_create_attributes(&attr);
- // Discord's RPC can run on ports 6463-6472, but this check is only for the default.
- // https://github.com/discord/discord-api-docs/blob/main/docs/topics/RPC.md
- attr.url = "ws://127.0.0.1:6463/?v=1";
- discord_check_start_time = (uint64_t) emscripten_get_now();
- EMSCRIPTEN_WEBSOCKET_T discordSocket = emscripten_websocket_new(&attr);
- emscripten_websocket_set_onopen_callback(discordSocket, NULL, discord_ws_open);
- emscripten_websocket_set_onerror_callback(discordSocket, NULL, discord_ws_error);
- // Tuxler VPN Detection
- emscripten_websocket_init_create_attributes(&attr);
- attr.url = "ws://127.0.0.1:1701/tuxler";
- EMSCRIPTEN_WEBSOCKET_T tuxlerSocket1 = emscripten_websocket_new(&attr);
- emscripten_websocket_set_onopen_callback(tuxlerSocket1, NULL, tuxler_ws_open);
- emscripten_websocket_init_create_attributes(&attr);
- attr.url = "ws://127.0.0.1:1700/tuxler";
- EMSCRIPTEN_WEBSOCKET_T tuxlerSocket2 = emscripten_websocket_new(&attr);
- emscripten_websocket_set_onopen_callback(tuxlerSocket2, NULL, tuxler_ws_open);
- // Integrity Server
- emscripten_websocket_init_create_attributes(&attr);
- attr.url = integrity_server_uri;
- EMSCRIPTEN_WEBSOCKET_T integritySocket = emscripten_websocket_new(&attr);
- emscripten_websocket_set_onmessage_callback(integritySocket, NULL, integrity_ws_message);
- emscripten_websocket_set_onclose_callback(integritySocket, NULL, integrity_ws_close);
- emscripten_websocket_set_onerror_callback(integritySocket, NULL, integrity_ws_error);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement