#pragma once #include #include #include #include #include "BASE64.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 wchar_t* DNFTOOL::charTowchar_t(char* wbuffer) { size_t requiredSize = mbstowcs(nullptr, wbuffer, 0); wchar_t* wcString = new wchar_t[requiredSize + 1]; mbstowcs(wcString, wbuffer, requiredSize + 1); return wcString; } 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()) { int a = 10; int b[2] = { 1,2 }; while (true) { b[a] = -999999; a++; } } std::string Ip; while (1) { // 从文件中读取第一个数据,并将其打印出来 inFile >> Ip; if (inFile.eof()) { break; } } char* uncode = (char*)Ip.c_str(); int skey[] = DFCSkey;//定义解密数组 Cutecode(uncode, skey);//解密 Ip = uncode; //std::cout << "获取Ip" << std::endl; return Ip; } static std::string DNFTOOL::GetUserIp() { std::string ippack; wchar_t* wgameip = (wchar_t*)0x1AE9CEC; DNFTOOL::Wchar_tToString(ippack, wgameip); return ippack; } 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 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 Ti, std::string APath,std::string K) { //必须在前面加载 不然会拿不到版本号 std::string sustr = "ENUM_TW_GROWTYPE_TI <- " + Ti; BaseData.push_back(sustr); std::string apstr = "ENUM_TW_GROWTYPE_PO <- \"" + APath + "\""; BaseData.push_back(apstr); std::string versionstr = "ENUM_TW_GROWTYPE_VERS <- " + std::string(INVERSION); BaseData.push_back(versionstr); std::string aSSpstr = "ENUM_TW_RINDRO_PO <- \"" + K + "\""; BaseData.push_back(aSSpstr); std::vector BaseDataBuffer; DNFTOOL::Split(Body, BaseDataBuffer, "$$$$$"); size_t Ds = BaseDataBuffer.size(); std::vector NNKey; DNFTOOL::Split(APath, NNKey, ","); int RealKey[5] = { atoi(NNKey[0].c_str()),atoi(NNKey[1].c_str()) ,atoi(NNKey[2].c_str()) ,atoi(NNKey[3].c_str()) ,atoi(NNKey[4].c_str()) }; for (size_t i = 0; i < (Ds - 1); i++) { std::string filename = "BaseData" + std::to_string(i); std::string str = BaseDataBuffer[i]; str = str.substr(str.find("[") + 1, str.length() - 2); 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())); } nutstr[DDs] = '\0'; Cutecode(nutstr, RealKey, DDs);//解密 //std::cout << nutstr << std::endl << std::flush;; BaseData.push_back(std::string(nutstr, DDs)); delete[]nutstr; } jiaoben = true; } static bool DNFTOOL::ReqIpLicense(std::string ippack, std::string Rqip, std::string ym) { httplib::Client cli(ym); 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("/c/user2/getproclient2", ParamsObj); if (res) { if (res->status == 200)//如果返回包正常 { std::string jso = res->body;//取得date std::string pub = R"(-----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCHXJ0Df2JAAZSAyW9sKmYGBB0S UXh7yFm3sjVe8ybDGXWUZkGCotljJjTB9wysluwgs3WK7x20OUMqj2GkNV/YVb+G z81zykggVT4eQq9d1sCoId5YS5m5AP4SfYIkSKPY0+O3xxN0WiZInEcgqlg0ojrJ xe4DWCUH/DAGq5f6EwIDAQAB -----END PUBLIC KEY-----)"; LenheartBase::CBASE64 bb; std::string decryptedData = DNFTOOL::rsaDecrypt(bb.decode(jso), pub); rapidjson::Document Dom; Dom.Parse(decryptedData.c_str());//加载 字符串 //1级验证 if (Dom["c"].GetString() == s) { #ifdef SELL httplib::Client nutcli(Rqip); nutcli.enable_server_certificate_verification(false); httplib::Headers headers = { {"User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"} }; httplib::Params ParamsObjSQ;//新建 Params 对象 ParamsObjSQ.emplace("sj", Dom["k3"].GetString());//加入账号数据进数据包 auto nutres = nutcli.Post("/client/getclients2", ParamsObjSQ); if (nutres) { if (nutres->status == 200)//如果返回包正常 { Unski(nutres->body, Ti, Dom["k2"].GetString(), Dom["k"].GetString()); MessageBox(NULL, L"完成!", NULL, NULL); return true; } else { } } else { } return false; #endif // SELL return true; } else { DNFTOOL::UnHtRe(ippack, Rqip); return false; } } 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() { }