#pragma once #include #include #include #include #include "BASE64.h" #include "json.hpp" #include "zlib.h" #define CPPHTTPLIB_OPENSSL_SUPPORT #include "httplib.h" #include #include #include #include "rapidjson/document.h" #include "rapidjson/writer.h" #include "rapidjson/stringbuffer.h" #include "rapidjson/filereadstream.h" #include "rapidjson/filewritestream.h" #include "rapidjson/istreamwrapper.h" bool jiaoben = false; std::vector BaseData; class DNFTOOL { public: DNFTOOL(); ~DNFTOOL(); private: public: static void DNFTOOL::Wchar_tToString(std::string& szDst, wchar_t* wchar) { wchar_t* wText = wchar; DWORD dwNum = WideCharToMultiByte(CP_OEMCP, NULL, wText, -1, NULL, 0, NULL, FALSE);// WideCharToMultiByte的运用 char* psText; // psText为char*的临时数组,作为赋值给std::string的中间变量 psText = new char[dwNum]; WideCharToMultiByte(CP_OEMCP, NULL, wText, -1, psText, dwNum, NULL, FALSE);// WideCharToMultiByte的再次运用 szDst = psText;// std::string赋值 delete[]psText;// psText的清除 } static std::wstring DNFTOOL::charTowchar_t(char* wbuffer,size_t len = 0) { size_t requiredSize = 0; if (len == 0)requiredSize = mbstowcs(nullptr, wbuffer, 0); else requiredSize = len; wchar_t* wcString = new wchar_t[requiredSize + 1]; mbstowcs(wcString, wbuffer, requiredSize + 1); std::wstring NewStr(wcString); delete[]wcString; return NewStr; } static void DNFTOOL::Split(const std::string& src, std::vector& dest, const std::string& separator) { std::string str = src; std::string substring; std::string::size_type start = 0, index; dest.clear(); index = str.find_first_of(separator, start); do { if (index != std::string::npos) { substring = str.substr(start, index - start); dest.push_back(substring); start = index + separator.size(); index = str.find(separator, start); if (start == std::string::npos) break; } } while (index != std::string::npos); //the last part substring = str.substr(start); dest.push_back(substring); } static char* DNFTOOL::U8ToUnicode(const char* szU8) { //UTF8 to Unicode //预转换,得到所需空间的大小 int wcsLen = ::MultiByteToWideChar(CP_UTF8, NULL, szU8, strlen(szU8), NULL, 0); //分配空间要给'\0'留个空间,MultiByteToWideChar不会给'\0'空间 wchar_t* wszString = new wchar_t[wcsLen + 1]; //转换 ::MultiByteToWideChar(CP_UTF8, NULL, szU8, strlen(szU8), wszString, wcsLen); //最后加上'\0' wszString[wcsLen] = '\0'; char* m_char; int len = WideCharToMultiByte(CP_ACP, 0, wszString, wcslen(wszString), NULL, 0, NULL, NULL); m_char = new char[len + 1]; WideCharToMultiByte(CP_ACP, 0, wszString, wcslen(wszString), m_char, len, NULL, NULL); delete[]wszString; m_char[len] = '\0'; return m_char; } static char* DNFTOOL::SquirrelU2WOut(const wchar_t* Str) { size_t len = 0; char* wbuffer = (char*)(Str); while (true) { if (wbuffer[len] == 0 && wbuffer[len - 1] == 0)break; ++len; } char* cbuffer = new char[len / 2 + 1]; int k = 0; for (size_t i = 0; i < len; i++) { if (i % 2 == 0) { cbuffer[k] = wbuffer[i]; ++k; } } cbuffer[len / 2] = '\0'; return cbuffer; } static char* DNFTOOL::SquirrelU2W(const wchar_t* Str) { size_t len = 0; char* wbuffer = (char*)(Str); while (true) { if (wbuffer[len] == 0 && wbuffer[len - 1] == 0)break; ++len; } char* cbuffer = new char[len / 2 + 1]; int k = 0; for (size_t i = 0; i < len; i++) { if (i % 2 == 0) { cbuffer[k] = wbuffer[i]; ++k; } } cbuffer[len / 2] = '\0'; char* Text = U8ToUnicode(cbuffer); delete[]cbuffer; return Text; } static char* DNFTOOL::GBKTOUTF8(std::string& strGBK)//转码 GBK编码转成UTF8编码 { int len = MultiByteToWideChar(CP_ACP, 0, strGBK.c_str(), -1, NULL, 0); wchar_t* wszUtf8 = new wchar_t[len]; memset(wszUtf8, 0, len); MultiByteToWideChar(CP_ACP, 0, strGBK.c_str(), -1, wszUtf8, len); len = WideCharToMultiByte(CP_UTF8, 0, wszUtf8, -1, NULL, 0, NULL, NULL); char* szUtf8 = new char[len + 1]; memset(szUtf8, 0, len + 1); WideCharToMultiByte(CP_UTF8, 0, wszUtf8, -1, szUtf8, len, NULL, NULL); strGBK = szUtf8; delete[] szUtf8; delete[] wszUtf8; return (char*)strGBK.c_str(); } static char* DNFTOOL::wchar_tTochar(wchar_t* wbuffer) { size_t requiredSize = wcstombs(nullptr, wbuffer, 0); char* key = new char[requiredSize + 1]; wcstombs(key, wbuffer, requiredSize + 1); return key; } static std::string& ReplaceAll(std::string& str, const std::string& src, const std::string& dst) { std::string::size_type pos(0); while (true) { if ((pos = str.find(src)) != std::string::npos) { str.replace(pos, src.length(), dst); } else { break; } } return str; } static char* DNFTOOL::UnicodeToUtf8(const wchar_t* unicode, int len = -1) { if (len == -1) len = WideCharToMultiByte(CP_UTF8, 0, unicode, -1, NULL, 0, NULL, NULL); char* szUtf8 = (char*)malloc(len + 1); memset(szUtf8, 0, len + 1); WideCharToMultiByte(CP_UTF8, 0, unicode, -1, szUtf8, len, NULL, NULL); return szUtf8; } static wchar_t* BIG5ToUnicode(const char* szBIG5String) { UINT nCodePage = 950; //BIG5 int nLength = MultiByteToWideChar(nCodePage, 0, szBIG5String, -1, NULL, 0); wchar_t* pBuffer = new wchar_t[nLength + 1]; MultiByteToWideChar(nCodePage, 0, szBIG5String, -1, pBuffer, nLength); pBuffer[nLength] = 0; return pBuffer; } static char* Big5ToUtf8(const wchar_t* big5WideChar , int len = -1) { if(len == -1) len = WideCharToMultiByte(CP_UTF8, 0, big5WideChar, -1, NULL, 0, NULL, NULL); char* szUtf8 = (char*)malloc(len + 1); memset(szUtf8, 0, len + 1); // 设置从 Big5 编码转换为 UTF-8 SetThreadLocale(MAKELCID(0x0404, SORT_DEFAULT)); WideCharToMultiByte(CP_UTF8, 0, big5WideChar, -1, szUtf8, len, NULL, NULL); return szUtf8; } static int DNFTOOL::DNFDeCode(int Address) { DWORD nEax, nEcx8, nEsi, nEdx, nTmp; nEax = *(int*)(Address); if (nEax == -1) return nEax; nEcx8 = *(int*)(Address + 8); if (nEcx8 == -1) return nEcx8; nEsi = *(int*)(0x1AF8D78); nEdx = nEax >> 16; nTmp = (nEdx << 2) + nEsi + 36; nEdx = *(int*)(nTmp); if (nEdx == -1) return nEdx; nEax = nEax & 65535; nTmp = (nEax << 2) + nEdx + 8468; nEax = *(int*)(nTmp); if (nEax == -1) return nEax; _asm { mov eax, nEax movzx edx, ax mov nEdx, edx } nEsi = nEdx << 16; nEsi = nEsi | nEdx; nEax = nEsi ^ nEcx8; return nEax; } static void DNFTOOL::DNFEnCode(int AddreSs, int Data) { long JEdi, JEcx, JEax, JEsi, JEdx, JSs; JEcx = AddreSs; JEax = *(int*)(0x1AF8DB8); JEax = JEax + 1; *(int*)(0x1AF8DB8) = JEax; JEdx = JEax; JEdx = JEdx >> 8; JEdx = JEdx << 24; JEdx = JEdx >> 24; JEdx = *(int*)(JEdx * 2 + 0x1843F58); JEdx = JEdx & 0xFFFF; JEax = JEax << 24; JEax = JEax >> 24; JSs = *(int*)(JEax * 2 + 0x1844158); JSs = JSs & 0xFFFF; JEdx = JEdx ^ JSs; JEax = JEdx; JEax = JEax & 0xFFFF; JEsi = Data; JEdx = JEsi >> 16; Sleep(10); JSs = JEsi & 0xFFFF; JEdx = JEdx + JSs; JEdx = JEdx ^ JEax; JEdi = JEdx; JEdx = JEax; JEax = JEax << 16; JEax = JEax + JEdx; JEsi = Data; JEax = JEax ^ JEsi; JEsi = AddreSs + 8; *(int*)(JEsi) = JEax; JEax = *(int*)(AddreSs); JEsi = *(int*)(0x1AF8D78); JEcx = JEdi; JEcx = JEcx << 16; JEcx = JEcx + JEdx; JEdx = JEax; JEdx = JEdx >> 16; JEdx = *(int*)(JEsi + JEdx * 4 + 36); JEax = JEax & 0xFFFF; *(int*)(JEdx + JEax * 4 + 8468) = JEcx; } static int DNFTOOL::GetEquAddr(int addr) { switch (addr) { case 1: return 0x3038; break; case 2: return 0x304C; break; case 3: return 0x3048; break; case 4: return 0x3050; break; case 5: return 0x3044; break; case 6: return 0x3040; break; case 7: return 0x3058; break; case 8: return 0x305C; break; case 9: return 0x3054; break; case 10: return 0x3060; break; case 11: return 0x3064; break; case 12: return 0x303c; break; case 13://帽子 return 0x3010; break; case 14://头部 return 0x3014; break; case 15://脸 return 0x3018; break; case 16: return 0x301c; break; case 17: return 0x3020; break; case 18: return 0x3024; break; case 19: return 0x3028; break; case 20: return 0x302c; break; case 21: return 0x3030; break; case 22: return 0x3034; break; case 23: return 0x3030; break; case 24: return 0x3068; break; case 25: return 0x306C; break; case 26: return 0x3070; break; case 27: return 0x3074; break; } return -1; } static wchar_t* DNFTOOL::char2wchar(const char* cchar) { wchar_t* m_wchar; int len = MultiByteToWideChar(CP_ACP, 0, cchar, strlen(cchar), NULL, 0); m_wchar = new wchar_t[len + 1]; MultiByteToWideChar(CP_ACP, 0, cchar, strlen(cchar), m_wchar, len); m_wchar[len] = '\0'; return m_wchar; } public: static void DNFTOOL::WriteInt(int addr, int buf) { *(int*)addr = buf; } static void DNFTOOL::WriteByteArr(int addr, BYTE buf[], int len) { for (size_t i = 0; i < len; i++) { *(BYTE*)(addr + i) = (int)buf[i]; } } static int DNFTOOL::GetHook(int Addr, std::string 地址, int Type) { size_t pos = 地址.find("+"); size_t size = 地址.size(); int GetHookArr[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; int i = 0; while (pos != std::string::npos) { std::string x = 地址.substr(0, pos); GetHookArr[i] = stoi(x, 0, 16); i++; 地址 = 地址.substr(pos + 1, size); pos = 地址.find("+"); } int num; num = *(int*)(Addr); if (num != 0) { for (int z = 0; z < i; z++) { if (num <= 0 && z != i - 1)//可能读取发生了错误 { num = 0; return num; } if (z == i - 1) { if (Type == 0)return *(int*)(num + GetHookArr[z]); else return (num + GetHookArr[z]); } else { num = *(int*)(num + GetHookArr[z]); } } } return num; } static std::string DNFTOOL::GetIP() { std::ifstream inFile; inFile.open("DFC180.dll"); // 默认当方式打开文件 if (inFile.is_open()) { std::string Ip; inFile >> Ip; inFile.close(); std::string pub = R"(-----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDafyp7gGautPZZ3I3IlYLf8Qyw xGigvg0rkmXPaP34C6sHi//GLuYjwM6AUJTtbfo0pCNmLqBbCiiuzkBXEqM+GeS2 +7zhu1yeEXv+i9iySFPbYydy851uVip7oqsbNM4iGYpS5ERND9XYuhSGUFI5p9ik Nsvz+z7r4iT2rd8vrwIDAQAB -----END PUBLIC KEY-----)"; LenheartBase::CBASE64 bb; std::string decryptedData = DNFTOOL::rsaDecrypt(bb.decode(Ip), pub); return decryptedData; } else { return ""; } } static std::string DNFTOOL::GetUserIp() { std::string ippack; wchar_t* wgameip = (wchar_t*)0x1AE9CEC; DNFTOOL::Wchar_tToString(ippack, wgameip); return ippack; } //zlib解压 static std::string gzip_decompress(const std::string& compressed) { z_stream zs; memset(&zs, 0, sizeof(zs)); if (inflateInit2(&zs, 16 + MAX_WBITS) != Z_OK) { //throw std::runtime_error("inflateInit failed"); return "null"; } zs.next_in = (Bytef*)compressed.data(); zs.avail_in = compressed.size(); int ret; char outbuffer[32768]; std::string outstring; do { zs.next_out = reinterpret_cast(outbuffer); zs.avail_out = sizeof(outbuffer); ret = inflate(&zs, 0); if (outstring.size() < zs.total_out) { outstring.append(outbuffer, zs.total_out - outstring.size()); } } while (ret == Z_OK); inflateEnd(&zs); if (ret != Z_STREAM_END) { //throw std::runtime_error("Exception during zlib decompression: (" + std::to_string(ret) + ") " + zs.msg); return "null"; } return outstring; } static std::string DNFTOOL::rsaDecrypt(const std::string& encryptedData, const std::string& publicKeyStr) { RSA* rsa = RSA_new(); BIO* bio = BIO_new_mem_buf(const_cast(publicKeyStr.c_str()), -1); PEM_read_bio_RSA_PUBKEY(bio, &rsa, NULL, NULL); int rsaSize = RSA_size(rsa); std::string decryptedData(rsaSize, 0); int decryptedSize = RSA_public_decrypt(encryptedData.size(), reinterpret_cast(encryptedData.c_str()), reinterpret_cast(&decryptedData[0]), rsa, RSA_PKCS1_PADDING); if (decryptedSize == -1) { std::cerr << "Error decrypting data" << std::endl; return ""; } RSA_free(rsa); BIO_free(bio); decryptedData.resize(decryptedSize); return decryptedData; } static std::string rsaDecrypt8(const std::string& encryptedData, const std::string& publicKeyStr) { RSA* rsa = nullptr; BIO* bio = BIO_new_mem_buf(const_cast(publicKeyStr.c_str()), -1); if (bio == nullptr) { std::cerr << "Error creating BIO" << std::endl; return ""; } rsa = PEM_read_bio_RSA_PUBKEY(bio, &rsa, nullptr, nullptr); if (rsa == nullptr) { std::cerr << "Error reading public key" << std::endl; BIO_free(bio); return ""; } int rsaSize = RSA_size(rsa); std::string decryptedData(rsaSize, 0); int decryptedSize = RSA_public_decrypt(encryptedData.size(), reinterpret_cast(encryptedData.c_str()), reinterpret_cast(&decryptedData[0]), rsa, RSA_PKCS1_PADDING); if (decryptedSize == -1) { std::cerr << "Error decrypting data" << std::endl; RSA_free(rsa); BIO_free(bio); return ""; } RSA_free(rsa); BIO_free(bio); decryptedData.resize(decryptedSize); return decryptedData; } static void UnHtRe(std::string ippack, std::string Rqip) { httplib::Client* CliObj = NULL;// http连接主体 CliObj = new httplib::Client(Rqip);//初始化 http 对象 } static void Unski(std::string Body , std::string KeyString) { #ifndef SELL std::string sustr = "ENUM_RINDRO_LOCAL <- true"; BaseData.push_back(sustr); #endif // SELL std::vector BaseDataBuffer; DNFTOOL::Split(Body, BaseDataBuffer, "$$$$$"); size_t Ds = BaseDataBuffer.size(); int RealKey[20] = { 0 }; // 转换字符串到数组 for (size_t i = 0; i < KeyString.length() && i < 20; ++i) { RealKey[i] = KeyString[i] - '0'; // 将字符转换为对应的数字 } for (size_t i = 0; i < (Ds - 1); i++) { std::string str = BaseDataBuffer[i]; //得到有多少个逗号 std::vector Data; DNFTOOL::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())); } Cutecode(nutstr, RealKey, DDs,20);//解密 nutstr[DDs] = '\0'; std::string RealStr(nutstr, DDs); delete[]nutstr; BaseData.push_back(RealStr); // 写入文件:文件名格式为 "file + i"(如 file0, file1 等) std::string filename = "jb/file" + std::to_string(i); std::ofstream outFile(filename, std::ios::binary); // 使用二进制模式确保数据完整性 if (outFile.is_open()) { outFile.write(RealStr.c_str(), RealStr.size()); outFile.close(); } } jiaoben = true; //std::cout << "Decode" << clock() << std::endl; } static bool DNFTOOL::ReqIpLicense(std::string ippack, std::string Rqip) { httplib::Client cli(Rqip); httplib::Params ParamsObj;//新建 Params 对象 ParamsObj.emplace("ip", ippack.c_str());//加入账号数据进数据包 //程序运行时间 std::string Ti = std::to_string(clock()); FILE* file2 = fopen("Script.pvf", "rb"); fseek(file2, 60, SEEK_SET); int code1 = fgetc(file2); fseek(file2, 1500, SEEK_SET); int code2 = fgetc(file2); fseek(file2, 4000, SEEK_SET); int code3 = fgetc(file2); fseek(file2, 16008, SEEK_SET); int code4 = fgetc(file2); fseek(file2, 24003, SEEK_SET); int code5 = fgetc(file2); fclose(file2); std::string Apath = std::to_string(code1 % 10) + "," + std::to_string(code2 % 10) + "," + std::to_string(code3 % 10) + "," + std::to_string(code4 % 10) + "," + std::to_string(code5 % 10); //随机值 std::string s = Ti + Apath; ParamsObj.emplace("s", s.c_str());//随机值 ParamsObj.emplace("su", Ti.c_str());//程序运行的时间 auto now = std::chrono::system_clock::now(); auto now_c = std::chrono::system_clock::to_time_t(now); std::string timestamp = std::ctime(&now_c); timestamp.pop_back(); // Remove trailing newline character ParamsObj.emplace("l", timestamp);//时间戳 auto res = cli.Post("/script/client", ParamsObj); if (res) { //std::cout << "status: " << res->status << std::endl; if (res->status == 200)//如果返回包正常 { try { std::string StrBuf = LenheartBase::CBASE64::decode(res->body); StrBuf = gzip_decompress(StrBuf); nlohmann::json Jso = nlohmann::json::parse(StrBuf); std::string Key = Jso["key"].dump(); Key = Key.substr(1, Key.length() - 2); std::string Script = Jso["getBaseScriptStr"].dump(); Script = Script.substr(1, Script.length() - 2); std::string pub = R"(-----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDafyp7gGautPZZ3I3IlYLf8Qyw xGigvg0rkmXPaP34C6sHi//GLuYjwM6AUJTtbfo0pCNmLqBbCiiuzkBXEqM+GeS2 +7zhu1yeEXv+i9iySFPbYydy851uVip7oqsbNM4iGYpS5ERND9XYuhSGUFI5p9ik Nsvz+z7r4iT2rd8vrwIDAQAB -----END PUBLIC KEY-----)"; std::string RealKey = DNFTOOL::rsaDecrypt(LenheartBase::CBASE64::decode(Key), pub); Unski(Script,RealKey); } catch (const std::exception& e) { std::cout << e.what() << std::endl; } } else { DNFTOOL::UnHtRe(ippack, Rqip); return false; } } else { // 获取HTTP请求的错误码 DNFTOOL::UnHtRe(ippack, Rqip); return false; } DNFTOOL::UnHtRe(ippack, Rqip); return false; } }; DNFTOOL::DNFTOOL() { } DNFTOOL::~DNFTOOL() { } class Base64 { private: static const std::string base64_chars; static inline bool is_base64(unsigned char c) { return (isalnum(c) || (c == '+') || (c == '/')); } public: static std::vector decode(const std::string& encoded_string) { int in_len = encoded_string.size(); int i = 0; int j = 0; int in_ = 0; unsigned char char_array_4[4], char_array_3[3]; std::vector ret; while (in_len-- && (encoded_string[in_] != '=') && is_base64(encoded_string[in_])) { char_array_4[i++] = encoded_string[in_]; in_++; if (i == 4) { for (i = 0; i < 4; i++) char_array_4[i] = base64_chars.find(char_array_4[i]); char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; for (i = 0; (i < 3); i++) ret.push_back(char_array_3[i]); i = 0; } } if (i) { for (j = i; j < 4; j++) char_array_4[j] = 0; for (j = 0; j < 4; j++) char_array_4[j] = base64_chars.find(char_array_4[j]); char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; for (j = 0; (j < i - 1); j++) ret.push_back(char_array_3[j]); } return ret; } }; const std::string Base64::base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789+/";