#pragma once #include #include #include #include #include #include #include using namespace asio; using asio::ip::tcp; // 单个字符解密 char CutcodeChar(char c, int key, int key2) { char a = (((c - 1) ^ key) ^ key2) - key; return a; } // 解密 void Cutecode(char *pstr, int *pkey, int len) { if (len == -1) len = strlen(pstr); for (int i = 0; i < len; i++) *(pstr + i) = CutcodeChar(*(pstr + i), pkey[i % 5], pkey[(i + 18) % 5]); } // 加密函数 static std::string r_encryptDecrypt(const std::string &input, const std::string &key) { std::string output = input; for (size_t i = 0; i < input.size(); i++) { output[i] = input[i] ^ key[i % key.size()]; // 使用异或运算进行加密 } return output; } static std::string ReqScriptUrl(std::string ce) { asio::io_context io_context; asio::ssl::context ctx(asio::ssl::context::tlsv12_client); asio::ssl::stream socket(io_context, ctx); asio::ip::tcp::resolver resolver(io_context); auto endpoints = resolver.resolve("www.rindro.cn", "https"); asio::connect(socket.lowest_layer(), endpoints); socket.handshake(asio::ssl::stream_base::handshake_type::client); std::string post_data = "s=" + ce; std::string request = "POST /c/user/getServiceUrl2 HTTP/1.1\r\n"; request += "Host: www.rindro.cn\r\n"; request += "Content-Length: " + std::to_string(post_data.size()) + "\r\n"; request += "Content-Type: application/x-www-form-urlencoded\r\n"; request += "\r\n"; request += post_data; asio::write(socket, asio::buffer(request)); asio::streambuf response; asio::read_until(socket, response, "\r\n"); std::istream response_stream(&response); std::string http_version; response_stream >> http_version; std::stringstream ss; ss << &response; std::string response_data = ss.str(); return response_data; } static std::string make_request(const std::string &host, const std::string &port, const std::string &path) { asio::io_context io_context; tcp::resolver resolver(io_context); tcp::resolver::results_type endpoints = resolver.resolve(host, port); tcp::socket socket(io_context); asio::connect(socket, endpoints); // Form the request. We specify the "Connection: close" header so that the // server will close the socket after transmitting the response. This // will allow us to treat all data up until the EOF as the content. std::string request = "GET " + path + " HTTP/1.1\r\n"; request += "Host: " + host + "\r\n"; request += "Connection: close\r\n\r\n"; // Send the request. asio::write(socket, asio::buffer(request)); // Read the response status line. The response streambuf will automatically // grow to accommodate the entire line. The growth may be limited by passing // a maximum size to the streambuf constructor. asio::streambuf response; asio::read_until(socket, response, "\r\n"); // Check that response is OK. std::istream response_stream(&response); std::string http_version; response_stream >> http_version; unsigned int status_code; response_stream >> status_code; std::string status_message; std::getline(response_stream, status_message); if (!response_stream || http_version.substr(0, 5) != "HTTP/") { throw std::runtime_error("Invalid response"); } if (status_code != 200) { throw std::runtime_error("Response returned with status code " + std::to_string(status_code)); } // Read the response headers, which are terminated by a blank line. asio::read_until(socket, response, "\r\n\r\n"); // Process the response headers. std::string header; while (std::getline(response_stream, header) && header != "\r") { // std::cout << header << "\n"; } // std::cout << "\n"; // Write whatever content we already have to output. std::ostringstream response_body; if (response.size() > 0) { response_body << &response; } // Read until EOF, writing data to output as we go. asio::error_code error; while (asio::read(socket, response, asio::transfer_at_least(1), error)) { response_body << &response; } if (error != asio::error::eof) { throw asio::system_error(error); } return response_body.str(); } static std::string ReqScript(std::string url) { std::vector UrlData; Tool::Split(url, UrlData, ","); try { std::string host = UrlData[0]; std::string port = UrlData[1]; std::string path = "/" + UrlData[2]; std::string response = make_request(host, port, path); // std::cout << "Response body:\n" // << response << "\n"; return response; } catch (std::exception &e) { // std::cerr << "Exception: " << e.what() << "\n"; return "null"; } } static void ReqSquirrelScript(HSQUIRRELVM v) { // 获取随机值 clock_t start = clock(); double elapsed_time = double(start) / CLOCKS_PER_SEC; std::string ce = "" + std::to_string(elapsed_time); std::string UrlRes = ReqScriptUrl(ce); UrlRes = UrlRes.substr(UrlRes.find("RindroXXXXXX") + 12); UrlRes = r_encryptDecrypt(UrlRes, "aesgfasdgdrshdfbtykuilhnvbcera5634%#t$"); std::vector Buf; Tool::Split(UrlRes, Buf, "$$$$"); if (Buf[1] != ce) return; std::vector keyBuf; Tool::Split(Buf[2].substr(1, -1), keyBuf, ","); // std::cout << "key: " << Buf[2] << std::endl; int RealKey[5] = {}; for (size_t i = 0; i < keyBuf.size(); i++) { RealKey[i] = (std::stoi(keyBuf[i])); } std::string Script = ReqScript(Buf[0]); if (Script != "null") { std::vector ScriptMan; Tool::Split(Script, ScriptMan, "$$$$"); std::vector SquirrelFilePath; for (size_t i = 0; i < ScriptMan.size(); i += 2) { std::string str = ScriptMan[i + 1].substr(ScriptMan[i + 1].find("[") + 1, ScriptMan[i + 1].length() - 2); std::vector Data; Tool::Split(str, Data, ", "); size_t DDs = Data.size(); char *nutstr = new char[DDs + 1]; for (size_t s = 0; s < DDs; s++) { nutstr[s] = char(atoi(Data[s].c_str())); } nutstr[DDs] = '\0'; Cutecode(nutstr, RealKey, DDs); // 解密 std::string FileData(nutstr); // std::cout << "文件名: " << ScriptMan[i] << std::endl; // std::cout // << "文件内容: " << FileData << std::endl; if (SQ_SUCCEEDED(sq_compilebuffer(v, (SQChar *)(FileData.c_str()), FileData.length(), (SQChar *)(ScriptMan[i].c_str()), true))) { sq_pushroottable(v); sq_call(v, 1, 1, 1); sq_pop(v, 1); } // SquirrelFilePath.push_back(FileData); } } }