mirror of
https://git.oceanpay.cc/danial/itunes_server.git
synced 2025-12-18 21:12:33 +00:00
- Introduced a new iTunes Debugger application with main functionality to interact with iTunesAPIs. - Added various third-party libraries including 7zip, bit7z, jsoncpp, libcurl, libeay32, ssleay32, and zlib for enhanced functionality. - Created project files for the iTunes Debugger in Visual Studio, including .vcxproj, .vcxproj.filters, and .sln files. - Included a log file for debugging purposes. - Ensured compatibility with both Debug and Release configurations for Win32 and x64 platforms.
1094 lines
38 KiB
C++
1094 lines
38 KiB
C++
#include <iostream>
|
||
#include <windows.h>
|
||
#include <string>
|
||
#include <vector>
|
||
#include <functional>
|
||
#include <sstream>
|
||
#include <ctime>
|
||
#include <iomanip>
|
||
#include <map>
|
||
#include <mutex>
|
||
#include <fstream>
|
||
#include <random>
|
||
#include <array>
|
||
#include <algorithm>
|
||
#include <regex>
|
||
using namespace std;
|
||
|
||
#include "iTunesAPIs.h"
|
||
#include "resource2.h"
|
||
#include "bit7z/bit7z.hpp"
|
||
#include "utils/writeResourceFile.h"
|
||
#include "utils/encoding.h"
|
||
#include "utils/HttpRequest.h"
|
||
#include "authenticate/authenticate.h"
|
||
#include "glog/logging.h"
|
||
|
||
#include <openssl/sha.h>
|
||
#include <openssl/des.h>
|
||
|
||
#include "utils/jsoncpp_ex.h"
|
||
#include "utils/encoding.h"
|
||
#include "utils/machine_feature.h"
|
||
using namespace ytpp::sys_core;
|
||
using namespace ytpp::json;
|
||
|
||
#include "./iTunesCore/itunes_native_interface.h"
|
||
#include "./iTunesCore/itunes_client_interface.h"
|
||
#include "./iTunesCore/itunes_internal_interface.h"
|
||
#include "./iTunesCore/windows_hardware.h"
|
||
#include "./iTunesCore/itunes_https.h"
|
||
#include "./iTunesCore/itunes_cookie_interface.h"
|
||
#include "./iTunesCore/strings.h"
|
||
#include "./authenticate/confidentialData.h"
|
||
using namespace win_itunes;
|
||
|
||
#define LOG /##/
|
||
|
||
|
||
EXTERN_C IMAGE_DOS_HEADER __ImageBase; //<2F><>ȡ<EFBFBD><C8A1>ǰDLLģ<4C><C4A3>Ļ<EFBFBD><C4BB><EFBFBD>ַ
|
||
#define HINST_THISCOMPONENT ((HINSTANCE)&__ImageBase) //<2F><>ȡ<EFBFBD><C8A1>ǰDLLģ<4C><C4A3>ľ<EFBFBD><C4BE>
|
||
|
||
win_itunes::CalcCallback calc; // <20>ŵ<EFBFBD><C5B5><EFBFBD>ǰ<EFBFBD><C7B0>
|
||
|
||
|
||
#pragma region <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
|
||
std::string replaceNewlineWithCRLF(const std::string& input) {
|
||
std::string output;
|
||
for (char c : input) {
|
||
if (c == '\n') {
|
||
output += "\r\n"; // <20><> \n <20>滻Ϊ \r\n
|
||
} else {
|
||
output += c;
|
||
}
|
||
}
|
||
return output;
|
||
}
|
||
std::string Get_ui_fetch_call() {
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
std::random_device rd;
|
||
std::mt19937 gen(rd());
|
||
std::uniform_int_distribution<> dis('a', 'z');
|
||
std::uniform_int_distribution<> num_dis('0', '9');
|
||
|
||
// <20><>һ<EFBFBD><D2BB><EFBFBD>֣<EFBFBD>10<31><30><EFBFBD><EFBFBD><EFBFBD>Сд<D0A1><D0B4>ĸ
|
||
std::string part1;
|
||
for (int i = 0; i < 10; ++i) {
|
||
part1 += static_cast<char>(dis(gen));
|
||
}
|
||
|
||
// <20>ڶ<EFBFBD><DAB6><EFBFBD><EFBFBD>֣<EFBFBD><D6A3>̶<EFBFBD>"md"<22><><EFBFBD><EFBFBD>3<EFBFBD><33><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֺ<EFBFBD>2<EFBFBD><32><EFBFBD><EFBFBD><EFBFBD>Сд<D0A1><D0B4>ĸ
|
||
std::string part2 = "md";
|
||
for (int i = 0; i < 3; ++i) {
|
||
part2 += static_cast<char>(num_dis(gen));
|
||
}
|
||
for (int i = 0; i < 2; ++i) {
|
||
part2 += static_cast<char>(dis(gen));
|
||
}
|
||
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֲ<EFBFBD><D6B2><EFBFBD>'-'<27><><EFBFBD><EFBFBD>
|
||
return part1 + "-" + part2;
|
||
}
|
||
#pragma endregion
|
||
|
||
|
||
|
||
namespace iTunesAPIs {
|
||
time_t get_timestamp(int year, int month, int day, int hour = 0, int min = 0, int sec = 0) {
|
||
std::tm timeinfo = {};
|
||
timeinfo.tm_year = year - 1900; // <20><>ݴ<EFBFBD>1900<30><30>ʼ
|
||
timeinfo.tm_mon = month - 1; // <20>·ݴ<C2B7>0<EFBFBD><30>ʼ
|
||
timeinfo.tm_mday = day;
|
||
timeinfo.tm_hour = hour;
|
||
timeinfo.tm_min = min;
|
||
timeinfo.tm_sec = sec;
|
||
|
||
return mktime(&timeinfo); // <20><><EFBFBD>ر<EFBFBD><D8B1><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD>Ӧ<EFBFBD><D3A6>ʱ<EFBFBD><CAB1><EFBFBD>
|
||
}
|
||
std::string replaceNewlineWithCRLF(const std::string& input) {
|
||
std::string output;
|
||
for (char c : input) {
|
||
if (c == '\n') {
|
||
output += "\r\n"; // <20><> \n <20>滻Ϊ \r\n
|
||
} else {
|
||
output += c;
|
||
}
|
||
}
|
||
return output;
|
||
}
|
||
// <20><><EFBFBD><EFBFBD> responseHeader <20>е<EFBFBD> Set-Cookie <20>ֶΣ<D6B6><CEA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> "key=value; key=value;" <20><>ʽ
|
||
std::string ParseCookies(const std::string& responseHeader) {
|
||
std::istringstream stream(responseHeader);
|
||
std::string line;
|
||
std::vector<std::string> cookies;
|
||
|
||
while (std::getline(stream, line)) {
|
||
if (line.find("set-cookie:") == 0 || line.find("Set-Cookie:") == 0) {
|
||
size_t start = line.find(":") + 1;
|
||
std::string cookie = line.substr(start);
|
||
cookie = cookie.substr(0, cookie.find(";")); // ֻȡ key=value <20><><EFBFBD><EFBFBD>
|
||
cookies.push_back(cookie);
|
||
}
|
||
}
|
||
|
||
std::string result;
|
||
for (const auto& cookie : cookies) {
|
||
if (!result.empty()) {
|
||
result += " ";
|
||
}
|
||
result += cookie + ";";
|
||
}
|
||
|
||
return result;
|
||
}
|
||
std::string getHeaderValue(const std::string& headers, const std::string& key) {
|
||
size_t start = 0;
|
||
while (start < headers.size()) {
|
||
// <20><><EFBFBD>ҵ<EFBFBD>ǰ<EFBFBD>н<EFBFBD><D0BD><EFBFBD>λ<EFBFBD><CEBB>
|
||
size_t end = headers.find("\r\n", start);
|
||
if (end == std::string::npos) break; // û<><C3BB><EFBFBD>ҵ<EFBFBD><D2B5><EFBFBD><EFBFBD>з<EFBFBD><D0B7><EFBFBD><EFBFBD>˳<EFBFBD>ѭ<EFBFBD><D1AD>
|
||
|
||
// <20><>ȡ<EFBFBD><C8A1>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
std::string line = headers.substr(start, end - start);
|
||
size_t colonPos = line.find(":");
|
||
if (colonPos != std::string::npos) {
|
||
// <20>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD>ȥ<EFBFBD><C8A5><EFBFBD><EFBFBD>β<EFBFBD>հ<EFBFBD>
|
||
std::string currentKey = line.substr(0, colonPos);
|
||
std::string value = line.substr(colonPos + 1);
|
||
currentKey.erase(0, currentKey.find_first_not_of(" \t"));
|
||
currentKey.erase(currentKey.find_last_not_of(" \t") + 1);
|
||
value.erase(0, value.find_first_not_of(" \t"));
|
||
value.erase(value.find_last_not_of(" \t") + 1);
|
||
|
||
// <20><><EFBFBD><EFBFBD>ҵ<EFBFBD>ƥ<EFBFBD><C6A5>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD>ض<F2B7B5BB>Ӧ<EFBFBD><D3A6>ֵ
|
||
if (currentKey == key) {
|
||
return value;
|
||
}
|
||
}
|
||
|
||
// <20>ƶ<EFBFBD><C6B6><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>
|
||
start = end + 2;
|
||
}
|
||
return ""; // <20><><EFBFBD>δ<EFBFBD>ҵ<EFBFBD>ƥ<EFBFBD><C6A5><EFBFBD><EFBFBD>ؿ<F2B7B5BB><D8BF>ַ<EFBFBD><D6B7><EFBFBD>
|
||
}
|
||
|
||
long long gmt_to_timestamp(const std::string& gmt_time) {
|
||
struct tm tm = { 0 };
|
||
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڣ<EFBFBD><DAA3>ɺ<EFBFBD><C9BA>ԣ<EFBFBD>
|
||
std::istringstream ss(gmt_time);
|
||
std::string weekday, month_str;
|
||
int day, year, hour, minute, second;
|
||
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Fri, 28 Mar 2025 12:34:56 GMT
|
||
ss >> weekday >> day >> month_str >> year >> hour;
|
||
ss.ignore(1); // <20><><EFBFBD><EFBFBD>ð<EFBFBD><C3B0> ':'
|
||
ss >> minute;
|
||
ss.ignore(1); // <20><><EFBFBD><EFBFBD>ð<EFBFBD><C3B0> ':'
|
||
ss >> second;
|
||
|
||
// <20><><EFBFBD>·<EFBFBD><C2B7>ַ<EFBFBD><D6B7><EFBFBD>ת<EFBFBD><D7AA>Ϊ<EFBFBD>·<EFBFBD><C2B7><EFBFBD><EFBFBD><EFBFBD>
|
||
int month = 0;
|
||
const char* months[] = {
|
||
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
||
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
|
||
};
|
||
for (int i = 0; i < 12; ++i) {
|
||
if (month_str == months[i]) {
|
||
month = i;
|
||
break;
|
||
}
|
||
}
|
||
|
||
// <20><><EFBFBD> tm <20>ṹ<EFBFBD><E1B9B9>
|
||
tm.tm_mday = day; // <20><>
|
||
tm.tm_mon = month; // <20>£<EFBFBD>0-11<31><31>
|
||
tm.tm_year = year - 1900; // <20>꣨<EFBFBD><EAA3A8> 1900 <20><><EFBFBD>㣩
|
||
tm.tm_hour = hour; // ʱ
|
||
tm.tm_min = minute; // <20><>
|
||
tm.tm_sec = second; // <20><>
|
||
tm.tm_isdst = 0; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ
|
||
|
||
// ʹ<><CAB9> _mkgmtime ת<><D7AA>Ϊʱ<CEAA><CAB1><EFBFBD>
|
||
time_t timestamp = _mkgmtime(&tm);
|
||
if (timestamp == -1) {
|
||
std::cerr << "ʱ<EFBFBD><EFBFBD><EFBFBD>ת<EFBFBD><EFBFBD>ʧ<EFBFBD>ܣ<EFBFBD>" << std::endl;
|
||
return -1;
|
||
}
|
||
|
||
return static_cast<long long>(timestamp);
|
||
}
|
||
|
||
std::time_t stringToTimestamp(const std::string& timeStr) {
|
||
// <20><>ʼ<EFBFBD><CABC>tm<74>ṹ<EFBFBD><E1B9B9>
|
||
tm timeInfo = {};
|
||
|
||
// <20><><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>
|
||
if (sscanf(timeStr.c_str(), "%d<><64>%d<><64>%d<><64>%dʱ%d<><64>%d<><64>",
|
||
&timeInfo.tm_year, &timeInfo.tm_mon, &timeInfo.tm_mday,
|
||
&timeInfo.tm_hour, &timeInfo.tm_min, &timeInfo.tm_sec) != 6) {
|
||
return -1; // <20><><EFBFBD><EFBFBD>ʧ<EFBFBD><CAA7>
|
||
}
|
||
|
||
// <20><><EFBFBD><EFBFBD>tm<74>ṹ<EFBFBD><E1B9B9><EFBFBD>е<EFBFBD><D0B5>ֶ<EFBFBD>
|
||
timeInfo.tm_year -= 1900; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1900<30><30><EFBFBD>ƫ<EFBFBD><C6AB><EFBFBD><EFBFBD>
|
||
timeInfo.tm_mon--; // <20>·ݴ<C2B7>0<EFBFBD><30>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>
|
||
|
||
// <20><>tm<74>ṹ<EFBFBD><E1B9B9>ת<EFBFBD><D7AA>Ϊʱ<CEAA><CAB1><EFBFBD>
|
||
return mktime(&timeInfo);
|
||
}
|
||
|
||
std::string calculate_sha256(const std::string& input) {
|
||
unsigned char hash[SHA256_DIGEST_LENGTH];
|
||
SHA256_CTX sha256;
|
||
SHA256_Init(&sha256);
|
||
SHA256_Update(&sha256, input.c_str(), input.size());
|
||
SHA256_Final(hash, &sha256);
|
||
|
||
// <20><><EFBFBD><EFBFBD>ϣ<EFBFBD><CFA3><EFBFBD>ת<EFBFBD><D7AA>Ϊʮ<CEAA><CAAE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>
|
||
std::stringstream ss;
|
||
for (int i = 0; i < SHA256_DIGEST_LENGTH; ++i) {
|
||
ss << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(hash[i]);
|
||
}
|
||
return ss.str();
|
||
}
|
||
// DES <20><><EFBFBD>ܺ<EFBFBD><DCBA><EFBFBD>
|
||
std::string des_encrypt(const std::string& clearText, const std::string& key) {
|
||
std::string cipherText;
|
||
DES_cblock keyEncrypt;
|
||
memset(&keyEncrypt, 0, sizeof(keyEncrypt));
|
||
|
||
// ʹ<><CAB9><EFBFBD>ṩ<EFBFBD><E1B9A9><EFBFBD><EFBFBD>Կ<EFBFBD><D4BF>ʼ<EFBFBD><CABC> keyEncrypt
|
||
if (key.length() <= 8) {
|
||
memcpy(&keyEncrypt, key.c_str(), key.length());
|
||
} else {
|
||
memcpy(&keyEncrypt, key.c_str(), 8);
|
||
}
|
||
|
||
DES_key_schedule keySchedule;
|
||
DES_set_key_unchecked(&keyEncrypt, &keySchedule);
|
||
|
||
// <20>ֿ<EFBFBD><D6BF><EFBFBD><EFBFBD>
|
||
for (size_t i = 0; i < clearText.length(); i += 8) {
|
||
DES_cblock inputBlock, outputBlock;
|
||
size_t blockLength = std::min<size_t>(8, clearText.length() - i);
|
||
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
memset(&inputBlock, 0, sizeof(inputBlock));
|
||
memcpy(&inputBlock, clearText.c_str() + i, blockLength);
|
||
|
||
// <20><><EFBFBD><EFBFBD>
|
||
DES_ecb_encrypt(&inputBlock, &outputBlock, &keySchedule, DES_ENCRYPT);
|
||
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD>ܽ<EFBFBD><DCBD><EFBFBD>ӵ<EFBFBD> cipherText
|
||
cipherText.append(reinterpret_cast<char*>(&outputBlock), sizeof(outputBlock));
|
||
}
|
||
|
||
return cipherText;
|
||
}
|
||
|
||
// DES <20><><EFBFBD>ܺ<EFBFBD><DCBA><EFBFBD>
|
||
std::string des_decrypt(const std::string& cipherText, const std::string& key) {
|
||
std::string clearText;
|
||
DES_cblock keyDecrypt;
|
||
memset(&keyDecrypt, 0, sizeof(keyDecrypt));
|
||
|
||
// ʹ<><CAB9><EFBFBD>ṩ<EFBFBD><E1B9A9><EFBFBD><EFBFBD>Կ<EFBFBD><D4BF>ʼ<EFBFBD><CABC> keyDecrypt
|
||
if (key.length() <= 8) {
|
||
memcpy(&keyDecrypt, key.c_str(), key.length());
|
||
} else {
|
||
memcpy(&keyDecrypt, key.c_str(), 8);
|
||
}
|
||
|
||
DES_key_schedule keySchedule;
|
||
DES_set_key_unchecked(&keyDecrypt, &keySchedule);
|
||
|
||
// <20>ֿ<EFBFBD><D6BF><EFBFBD><EFBFBD>
|
||
for (size_t i = 0; i < cipherText.length(); i += 8) {
|
||
DES_cblock inputBlock, outputBlock;
|
||
memcpy(&inputBlock, cipherText.c_str() + i, sizeof(inputBlock));
|
||
|
||
// <20><><EFBFBD><EFBFBD>
|
||
DES_ecb_encrypt(&inputBlock, &outputBlock, &keySchedule, DES_DECRYPT);
|
||
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD>ܽ<EFBFBD><DCBD><EFBFBD>ӵ<EFBFBD> clearText
|
||
clearText.append(reinterpret_cast<char*>(&outputBlock), sizeof(outputBlock));
|
||
}
|
||
|
||
return clearText;
|
||
}
|
||
}
|
||
|
||
|
||
string g_temp_path = "";
|
||
namespace iTunesAPIs {
|
||
bool access = true; // <20>Ƿ<EFBFBD><C7B7><EFBFBD>Ȩ<EFBFBD><C8A8>
|
||
|
||
|
||
DLL_EXPORT bool _stdcall init_dll(OUT char* iTunesDllPath) {
|
||
//<2F><>ȡϵͳ<CFB5><CDB3>ʱĿ¼
|
||
char temp_path_chars[MAX_PATH];
|
||
GetTempPathA(MAX_PATH, temp_path_chars);
|
||
string temp_path = { temp_path_chars };
|
||
g_temp_path = temp_path;
|
||
|
||
//<2F><>ѹ<EFBFBD><D1B9>ɺ<EFBFBD><C9BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
function<bool()> patch;
|
||
function<bool(void)> finish = [&]()->bool {
|
||
//<2F>ж<EFBFBD>CoreFP.dll<6C>ļ<EFBFBD>·<EFBFBD><C2B7><EFBFBD><EFBFBD>ע<EFBFBD><D7A2><EFBFBD><EFBFBD>Dz<EFBFBD><C7B2><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD>ʱĿ¼
|
||
confirm_reg: //ȷ<><C8B7>ע<EFBFBD><D7A2><EFBFBD><EFBFBD><EFBFBD><DFBC><EFBFBD>ʼ
|
||
HKEY hKey_read;
|
||
LSTATUS lResult = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Apple Inc.\\CoreFP", 0, KEY_READ | KEY_WOW64_32KEY, &hKey_read);
|
||
if (lResult == ERROR_SUCCESS) {
|
||
char LibraryPath[MAX_PATH];
|
||
DWORD LibraryPathSize = MAX_PATH;
|
||
RegQueryValueExA(hKey_read, "LibraryPath", 0, NULL, (LPBYTE)LibraryPath, &LibraryPathSize);
|
||
if (strcmp(LibraryPath, (temp_path + "iTunesDLLs\\CoreFP.dll").c_str()) != 0) {
|
||
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><C2B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>CoreFP.dll<6C>ļ<EFBFBD>·<EFBFBD><C2B7><EFBFBD><EFBFBD>ע<EFBFBD><D7A2><EFBFBD>
|
||
HKEY hKey_write;
|
||
LSTATUS lResult = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Apple Inc.\\CoreFP", 0, KEY_WRITE | KEY_WOW64_32KEY, &hKey_write);
|
||
if (lResult == ERROR_SUCCESS) {
|
||
RegSetValueExA(hKey_write, "LibraryPath", 0, REG_SZ, (LPBYTE)(temp_path + "iTunesDLLs\\CoreFP.dll").c_str(), (temp_path + "iTunesDLLs/CoreFP.dll").length() + 1);
|
||
} else if (lResult == ERROR_ACCESS_DENIED) {
|
||
cout << "<EFBFBD><EFBFBD>ע<EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD>ܣ<EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD>" << endl;
|
||
return false;
|
||
}
|
||
}
|
||
} else if (lResult == ERROR_FILE_NOT_FOUND) {
|
||
//<2F><><EFBFBD><EFBFBD>ע<EFBFBD><D7A2><EFBFBD>
|
||
HKEY hKey_create;
|
||
LSTATUS lResult = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Apple Inc.\\CoreFP", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE | KEY_WOW64_32KEY, NULL, &hKey_create, NULL);
|
||
goto confirm_reg; // <20>ص<EFBFBD><D8B5><EFBFBD><EFBFBD>棬<EFBFBD><E6A3AC><EFBFBD><EFBFBD>ȷ<EFBFBD><C8B7>ע<EFBFBD><D7A2><EFBFBD>
|
||
} else if (lResult == ERROR_ACCESS_DENIED) {
|
||
cout << "<EFBFBD><EFBFBD>ע<EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD>ܣ<EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD>" << endl;
|
||
return false;
|
||
}
|
||
|
||
//<2F><><EFBFBD>iTunes.dll<6C><6C>·<EFBFBD><C2B7>
|
||
if (iTunesDllPath) {
|
||
strcpy_s(iTunesDllPath, MAX_PATH, (temp_path + "iTunesDLLs\\iTunes.dll").c_str());
|
||
}
|
||
SetDllDirectory(ytpp::sys_core::encoding_ANSI_to_wstring(temp_path + "iTunesDLLs").c_str());
|
||
|
||
if (!patch()) {
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
};
|
||
|
||
//<2F><>iTunes<65><EFBFBD>
|
||
patch = [&]()->bool {
|
||
bool update = true;
|
||
if (update) {
|
||
//<2F><>iTunes<65><EFBFBD>
|
||
HMODULE hModule = LoadLibraryA((temp_path + "iTunesDLLs\\iTunesPatch.dll").c_str());
|
||
if (!hModule) {
|
||
return false;
|
||
}
|
||
bool(*iTunesPatch)(char*);
|
||
iTunesPatch = (bool(*)(char*))GetProcAddress(hModule, "iTunesPatch");
|
||
char data[20480] = { 0 };
|
||
if (!iTunesPatch(data)) {
|
||
return false;
|
||
}
|
||
if (strlen(data) == 0) {
|
||
return 0;
|
||
}
|
||
Json::Value json_result;
|
||
json_fromString(data, json_result);
|
||
if (json_result["code"] != 0) {
|
||
return false;
|
||
}
|
||
|
||
Json::Value main_data = json_result["main_data"];
|
||
//json_fromString(json_result["main_data"].asString(), main_data);
|
||
ConfidentialData::Instance()->Kbsync = main_data["1"].asInt();
|
||
ConfidentialData::Instance()->KbsyncID = main_data["2"].asInt();
|
||
ConfidentialData::Instance()->CigHash = main_data["3"].asInt();
|
||
ConfidentialData::Instance()->WriteSIDD = main_data["4"].asInt();
|
||
ConfidentialData::Instance()->WriteSIDB = main_data["5"].asInt();
|
||
ConfidentialData::Instance()->DeAuthSIDB = main_data["6"].asInt();
|
||
ConfidentialData::Instance()->CalcUnkP1 = main_data["7"].asInt();
|
||
ConfidentialData::Instance()->SetAFSyncRQ = main_data["8"].asInt();
|
||
ConfidentialData::Instance()->PreAuthByDSID = main_data["9"].asInt();
|
||
ConfidentialData::Instance()->VerifyAFSyncRQ = main_data["10"].asInt();
|
||
ConfidentialData::Instance()->GenerateAFSyncRS = main_data["11"].asInt();
|
||
ConfidentialData::Instance()->GetCltDat = main_data["12"].asInt();
|
||
ConfidentialData::Instance()->TranSetInf = main_data["13"].asInt();
|
||
ConfidentialData::Instance()->UpdCDID = main_data["14"].asInt();
|
||
ConfidentialData::Instance()->GetMD = main_data["15"].asInt();
|
||
ConfidentialData::Instance()->SapInit = main_data["16"].asInt();
|
||
ConfidentialData::Instance()->SapGetP1 = main_data["17"].asInt();
|
||
ConfidentialData::Instance()->SapCalcBuffer = main_data["18"].asInt();
|
||
ConfidentialData::Instance()->SapGetAS = main_data["19"].asInt();
|
||
ConfidentialData::Instance()->SapGetASFD = main_data["20"].asInt();
|
||
ConfidentialData::Instance()->SapGetASFD_a = main_data["21"].asInt();
|
||
}
|
||
};
|
||
|
||
//<2F>ж<EFBFBD>DLL<4C>ļ<EFBFBD><C4BC>Ƿ<C7B7><F1B6BCB4><EFBFBD>
|
||
DeleteFileA((temp_path + "iTunesDLLs\\iTunesPatch.dll").c_str());
|
||
vector<string> essential_dlls = { "ASL.dll", "CoreFoundation.dll", "CoreFP.dll", "CoreGraphics.dll",
|
||
"iTunes.dll", "libdispatch.dll", "libicuin.dll", "libicuuc.dll", "objc.dll", "zlib1.dll", "iTunesPatch.dll" };
|
||
bool complete = true;
|
||
for (auto& dll : essential_dlls) {
|
||
if (GetFileAttributesA((temp_path + "iTunesDLLs/" + dll).c_str()) == INVALID_FILE_ATTRIBUTES) {
|
||
complete = false;
|
||
break;
|
||
}
|
||
}
|
||
if (complete) {
|
||
return finish();
|
||
}
|
||
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
//<2F><><EFBFBD><EFBFBD>Դ<EFBFBD>ļ<EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱĿ¼
|
||
WriteResourceFile(HINST_THISCOMPONENT, IDR_SEVENZIP1, "sevenzip", temp_path + "iTunesDLLs.7z");
|
||
|
||
WriteResourceFile(HINST_THISCOMPONENT, IDR_DLL1, "dll", temp_path + "7z.dll"); //<2F>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>7zip.lib<69><62>̬<EFBFBD>⣬<EFBFBD><E2A3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><D0B4>7z.dll
|
||
|
||
bit7z::Bit7zLibrary lib(temp_path + "7z.dll"); //<2F>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>7zip.lib<69><62>̬<EFBFBD>⣬<EFBFBD><E2A3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>7z.dll<6C><6C>·<EFBFBD><C2B7>
|
||
bit7z::BitFileExtractor extractor(lib, bit7z::BitFormat::SevenZip);
|
||
extractor.extract((temp_path + "iTunesDLLs.7z").c_str(), (temp_path + "iTunesDlls").c_str());
|
||
|
||
//ɾ<><C9BE><EFBFBD><EFBFBD>ʱ<EFBFBD>ļ<EFBFBD>
|
||
DeleteFileA((temp_path + "iTunesDLLs.7z").c_str());
|
||
DeleteFileA((temp_path + "7z.dll").c_str());
|
||
|
||
return finish();
|
||
}
|
||
DLL_EXPORT bool _stdcall init_environment(IN const char* proxy, IN const char* proxy_user, IN const char* proxy_pwd)
|
||
{
|
||
if (!access) {
|
||
return false;
|
||
}
|
||
string proxy_str = ""; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ
|
||
if (proxy != NULL)
|
||
proxy_str = proxy;
|
||
|
||
string proxy_user_str = "";
|
||
if (proxy_user != NULL)
|
||
proxy_user_str = proxy_user;
|
||
|
||
string proxy_pwd_str = "";
|
||
if (proxy_pwd != NULL)
|
||
proxy_pwd_str = proxy_pwd;
|
||
|
||
|
||
HttpResponse cert = HttpRequest::Get("https://s.mzstatic.com/sap/setupCert.plist", "", proxy_str, false, [=](CURL* curl) {
|
||
if(!proxy_user_str.empty()) curl_easy_setopt(curl, CURLOPT_PROXYUSERNAME, proxy_user_str.c_str());
|
||
if(!proxy_pwd_str.empty()) curl_easy_setopt(curl, CURLOPT_PROXYPASSWORD, proxy_pwd_str.c_str());
|
||
});
|
||
if (cert.content.size() == 0 || cert.success == false) {
|
||
return false;
|
||
}
|
||
cert.content = cert.content.substr(string("<plist>\n<dict>\n<key>sign-sap-setup-cert</key>\n<data>").size());
|
||
cert.content = cert.content.substr(0, cert.content.size() - string("</data>\n</dict>\n</plist>\n").size());
|
||
if (cert.content.size() == 0 || cert.content.find("CURL Error") != string::npos) {
|
||
std::cout << "GET֤<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩʧ<EFBFBD><EFBFBD>" << endl;
|
||
return false;
|
||
}
|
||
|
||
calc.Initialize();
|
||
|
||
char bf[99999] = { 0 };
|
||
calc.SapSetupInitialize(false, cert.content.c_str(), bf, 99999);
|
||
string cert_buf(bf);
|
||
//std::cout << "cert_buf = " << cert_buf << endl;
|
||
//<2F><><EFBFBD><EFBFBD><CDB8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>µ<EFBFBD>cert_buf<75><66><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>Ϊ֤<CEAA>齻<EFBFBD><E9BDBB>
|
||
|
||
string postData = R"(<?xml version="1.0" encoding="UTF-8"?>
|
||
<plist version="1.0">
|
||
<dict>
|
||
<key>sign-sap-setup-buffer</key>
|
||
<data>)";
|
||
postData.append(cert_buf);
|
||
postData.append(R"(</data>
|
||
</dict>
|
||
</plist>)");
|
||
string headers = R"(Host: play.itunes.apple.com
|
||
User-Agent: iTunes/12.2.2 (Windows; Microsoft Windows 8 x64 Business Edition (Build 9200)) AppleWebKit/7605.1033.1002.2
|
||
Content-Type: application/x-apple-plist
|
||
Referer: https://apps.apple.com/WebObjects/MZStore.woa/wa/viewGrouping?cc=cn&id=29099
|
||
Date: Mon, 17 Mar 2025 11:14:07 GMT
|
||
Accept-Language: zh-cn, zh;q=0.75, en-us;q=0.50, en;q=0.25
|
||
X-Apple-Tz: 28800
|
||
X-Apple-Store-Front: 143465-19,32
|
||
Connection: close
|
||
Proxy-Connection: close)";
|
||
|
||
string headers_out;
|
||
string cookies;
|
||
HttpResponse result = HttpRequest::Post("https://play.itunes.apple.com/WebObjects/MZPlay.woa/wa/signSapSetup", postData, headers, proxy_str, false, [=](CURL* curl) {
|
||
if(!proxy_user_str.empty())
|
||
curl_easy_setopt(curl, CURLOPT_PROXYUSERNAME, proxy_user_str.c_str());
|
||
if (!proxy_pwd_str.empty())
|
||
curl_easy_setopt(curl, CURLOPT_PROXYPASSWORD, proxy_pwd_str.c_str());
|
||
});
|
||
cert_buf = result.content;
|
||
//std::cout << "cert_buf = " << cert_buf << endl;
|
||
if (cert_buf.size() == 0 || result.success == false) {
|
||
std::cout << "POST֤<EFBFBD>齻<EFBFBD><EFBFBD>ʧ<EFBFBD><EFBFBD>" << endl;
|
||
return false;
|
||
}
|
||
cert_buf = cert_buf.substr(string("<plist>\n<dict>\n<key>sign-sap-setup-buffer</key>\n<data>").size());
|
||
cert_buf = cert_buf.substr(0, cert_buf.size() - string("</data>\n</dict>\n</plist>\n").size());
|
||
|
||
|
||
//<2F>õ<EFBFBD><C3B5>µ<EFBFBD>֤<EFBFBD><D6A4><EFBFBD><EFBFBD>ٽ<EFBFBD><D9BD>г<EFBFBD>ʼ<EFBFBD><CABC>
|
||
calc.SapSetupInitialize2(false, cert_buf.c_str(), bf, 99999);
|
||
|
||
return true;
|
||
}
|
||
|
||
#pragma endregion
|
||
|
||
}
|
||
|
||
namespace iTunesFunctions {
|
||
mutex g_lockMap; // <20>߳<EFBFBD><DFB3><EFBFBD>
|
||
map<string, LoggedInStatus> loggedInUsers; // <20><><EFBFBD><EFBFBD><EFBFBD>ѵ<EFBFBD>¼<EFBFBD>û<EFBFBD><C3BB><EFBFBD>״̬<D7B4><CCAC><EFBFBD><EFBFBD>
|
||
|
||
|
||
// ״̬ά<CCAC><CEAC><EFBFBD>߳<EFBFBD>
|
||
void keepAliveThread() {
|
||
thread th([=]() {
|
||
while (true) {
|
||
//this_thread::sleep_for(chrono::minutes(3)); // ÿ<><C3BF><EFBFBD><EFBFBD><EFBFBD>ӱ<EFBFBD><D3B1><EFBFBD>һ<EFBFBD>ε<EFBFBD>¼״̬
|
||
this_thread::sleep_for(chrono::seconds(20)); // ÿ20<32>뱣<EFBFBD><EBB1A3>һ<EFBFBD>ε<EFBFBD>¼״̬
|
||
|
||
|
||
//// ÿ<><C3BF>ѭ<EFBFBD><D1AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƽ<EFBFBD>
|
||
//HMODULE hModule = LoadLibraryA((g_temp_path + "iTunesDLLs\\iTunesPatch.dll").c_str());
|
||
//if (!hModule) {
|
||
// exit(250);
|
||
//}
|
||
//bool(*iTunesPatch)(char*);
|
||
//iTunesPatch = (bool(*)(char*))GetProcAddress(hModule, "iTunesPatch");
|
||
//char data[20480] = { 0 };
|
||
//if (!iTunesPatch(data)) {
|
||
// exit(251);
|
||
//}
|
||
//if (strlen(data) == 0) {
|
||
// exit(252);
|
||
//}
|
||
//Json::Value json_result;
|
||
//json_fromString(data, json_result);
|
||
//if (json_result["code"] != 0) {
|
||
// exit(253);
|
||
//}
|
||
|
||
|
||
for (auto &item : loggedInUsers)
|
||
{
|
||
thread th([&]() {
|
||
HttpHeadersWrapper headers;
|
||
headers.ParseHeaders(R"(User-Agent: MacAppStore/2.0 (Macintosh; OS X 12.6) AppleWebKit/613.3.9.1.16 build/7 (dt:1)
|
||
X-Apple-Store-Front: 143465-19,30
|
||
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
|
||
X-Dsid: 107815378
|
||
X-Token: C44ED6AE0F6F1EBDB9EE63CDFB0408AE
|
||
X-Apple-Client-Application: Software
|
||
X-Apple-Connection-Type: WiFi
|
||
X-Apple-Client-Versions: iBooks/??; iTunesU/??; GameCenter/??; Podcasts/3.9
|
||
X-Apple-Tz: 28800
|
||
Accept-Language: zh-CN, en;q=0.9, *;q=0.1
|
||
Accept: */*
|
||
Connection: keep-alive)");
|
||
headers.SetHeader("X-Dsid", item.second.headers.GetHeaderValue("X-Dsid"));
|
||
headers.SetHeader("X-Token", item.second.headers.GetHeaderValue("X-Token"));
|
||
headers.SetHeader("cookie", item.second.cookies.ToRequestCookieString());
|
||
string url = "https://" + item.second.pod + "-buy.itunes.apple.com/WebObjects/MZFinance.woa/wa/accountSummary";
|
||
HttpResponse result = HttpRequest::Get(url, headers.GetAllHeaders(), item.second.proxy, false, [=](CURL* curl) {
|
||
if (!item.second.proxy_user.empty()) curl_easy_setopt(curl, CURLOPT_PROXYUSERNAME, item.second.proxy_user.c_str());
|
||
if (!item.second.proxy_pwd.empty()) curl_easy_setopt(curl, CURLOPT_PROXYPASSWORD, item.second.proxy_pwd.c_str());
|
||
});
|
||
result.content = Strings::Utf8ToGBK(result.content);
|
||
if (result.success == false) {
|
||
std::cout << "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD>ܣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>IP<EFBFBD><EFBFBD>ʧЧ<EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><EFBFBD>Ƴ<EFBFBD>" << std::endl;
|
||
g_lockMap.lock();
|
||
loggedInUsers.erase(item.first);
|
||
g_lockMap.unlock();
|
||
} else if (result.code != 200) {
|
||
std::cout << "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Appleʧ<EFBFBD>ܣ<EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>⣬<EFBFBD>Ѵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><EFBFBD>Ƴ<EFBFBD>" << std::endl;
|
||
g_lockMap.lock();
|
||
loggedInUsers.erase(item.first);
|
||
g_lockMap.unlock();
|
||
} else if (result.content.find("<EFBFBD><EFBFBD>¼<EFBFBD>Բ鿴<EFBFBD>˻<EFBFBD><EFBFBD><EFBFBD>Ϣ") != string::npos) {
|
||
std::cout << "<EFBFBD><EFBFBD>¼<EFBFBD><EFBFBD>Ϣ<EFBFBD>ѹ<EFBFBD><EFBFBD>ڣ<EFBFBD><EFBFBD>Ѵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><EFBFBD>Ƴ<EFBFBD>" << std::endl;
|
||
g_lockMap.lock();
|
||
loggedInUsers.erase(item.first);
|
||
g_lockMap.unlock();
|
||
} else {
|
||
std::cout << item.first << " ---- <20><><EFBFBD>ֵ<EFBFBD>¼״̬<D7B4>ɹ<EFBFBD>" << std::endl;
|
||
}
|
||
});
|
||
th.detach();
|
||
}
|
||
}
|
||
});
|
||
th.detach();
|
||
std::cout << "<EFBFBD><EFBFBD>¼<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD><EFBFBD>ѿ<EFBFBD><EFBFBD><EFBFBD>" << endl;
|
||
}
|
||
|
||
// 0<>ɹ<EFBFBD><C9B9><EFBFBD>1<EFBFBD><31>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>⣬2<E2A3AC><32><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
int _stdcall iTunes_login(IN const char* appleAccount, IN const char* applePassword, IN const char* proxy, IN const char* proxy_user, IN const char* proxy_pwd, OUT char** org)
|
||
{
|
||
string appleAccount_str = "";
|
||
string applePassword_str = "";
|
||
string redemmCode_str = "";
|
||
string proxy_str = "";
|
||
string proxy_user_str = "";
|
||
string proxy_pwd_str = "";
|
||
if (appleAccount != NULL)
|
||
appleAccount_str = appleAccount;
|
||
if (applePassword != NULL)
|
||
applePassword_str = applePassword;
|
||
if (proxy != NULL)
|
||
proxy_str = proxy;
|
||
if (proxy_user != NULL)
|
||
proxy_user_str = proxy_user;
|
||
if (proxy_pwd != NULL)
|
||
proxy_pwd_str = proxy_pwd;
|
||
|
||
|
||
string XAppleActionSignature;
|
||
const size_t BUF_SIZE = 1024;
|
||
char* buf = new char[BUF_SIZE];
|
||
ZeroMemory(buf, BUF_SIZE);
|
||
|
||
string guid = GenerateMachineGuid(); // ÿ<><C3BF><EFBFBD><EFBFBD>¼<EFBFBD>˺Ŷ<CBBA><C5B6><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>guid<69><64><EFBFBD><EFBFBD><EFBFBD><EFBFBD>α<EFBFBD><CEB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
|
||
|
||
win_itunes::HardwareInfo info;
|
||
//<2F><>ʼ<EFBFBD><CABC>¼
|
||
string postData = R"(<?xml version="1.0" encoding="UTF-8"?>
|
||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||
<plist version="1.0">
|
||
<dict>
|
||
<key>appleId</key>
|
||
<string>)";
|
||
postData.append(appleAccount_str);
|
||
postData.append(R"(</string>
|
||
<key>attempt</key>
|
||
<string>1</string>
|
||
<key>guid</key>
|
||
<string>)");
|
||
postData.append(guid);
|
||
postData.append(R"(</string>
|
||
<key>password</key>
|
||
<string>)");
|
||
postData.append(applePassword_str);
|
||
postData.append(R"(</string>
|
||
<key>rmp</key>
|
||
<string>0</string>
|
||
<key>createSession</key>
|
||
<string>true</string>
|
||
<key>why</key>
|
||
<string>purchase</string>
|
||
</dict>
|
||
</plist>)");
|
||
postData = replaceNewlineWithCRLF(postData);
|
||
calc.CalcXAppleActionSignature(postData.c_str(), postData.length(), buf, BUF_SIZE);
|
||
XAppleActionSignature.assign(buf);
|
||
cout << "\n\nXAppleActionSignature <20><><EFBFBD><EFBFBD>ֵ = " << "xxxx" << endl << endl;
|
||
|
||
string headers = R"(Host: buy.itunes.apple.com
|
||
User-Agent: MacAppStore/2.0 (Macintosh; OS X 12.6) AppleWebKit/613.3.9.1.16 build/7 (dt:1)
|
||
X-Apple-Store-Front: 143465-19,17
|
||
X-Apple-ActionSignature: )";
|
||
headers.append(XAppleActionSignature);
|
||
headers.append(R"(
|
||
Content-Type: application/x-www-form-urlencoded; charset=UTF-8)");
|
||
headers.append(R"(
|
||
X-Apple-Client-Application: Software
|
||
X-Apple-Connection-Type: WiFi
|
||
X-Apple-Client-Versions: iBooks/??; iTunesU/??; GameCenter/??; Podcasts/3.9
|
||
X-Apple-Tz: 28800
|
||
Accept-Language: zh-CN, en;q=0.9, *;q=0.1
|
||
Accept: */*
|
||
Connection: keep-alive)");
|
||
|
||
HttpResponse responseData = HttpRequest::Post("https://buy.itunes.apple.com/WebObjects/MZFinance.woa/wa/authenticate", postData, headers, proxy_str, false, [=](CURL* curl) {
|
||
if (!proxy_user_str.empty()) curl_easy_setopt(curl, CURLOPT_PROXYUSERNAME, proxy_user_str.c_str());
|
||
if (!proxy_pwd_str.empty()) curl_easy_setopt(curl, CURLOPT_PROXYPASSWORD, proxy_pwd_str.c_str());
|
||
|
||
//cout << "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7>" << proxy_str << endl;
|
||
//cout << "<22><><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD>" << proxy_user_str << endl;
|
||
//cout << "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>룺" << proxy_pwd_str << endl;
|
||
});
|
||
if (responseData.success == false) {
|
||
if(org) *org = nullptr;
|
||
return 2;
|
||
}
|
||
string cookies = responseData.cookies.ToRequestCookieString();
|
||
//responseData.content = Strings::Utf8ToGBK(responseData.content);
|
||
|
||
if (responseData.content.find(guid) == string::npos && responseData.code != 302) {
|
||
// û<>ҵ<EFBFBD><D2B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˺<EFBFBD><CBBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>⣬<EFBFBD><E2A3AC><EFBFBD>ش<EFBFBD><D8B4><EFBFBD>ԭ<EFBFBD><D4AD>
|
||
if (org) {
|
||
*org = new char[responseData.content.length() + 1];
|
||
strcpy(*org, responseData.content.c_str());
|
||
}
|
||
return 1;
|
||
}
|
||
|
||
string pod = "p" + responseData.headers.GetHeaderValue("pod");
|
||
string pod_value = responseData.headers.GetHeaderValue("pod");
|
||
string x_apple_store_front = responseData.headers.GetHeaderValue("x-set-apple-store-front");
|
||
|
||
|
||
// <20><><EFBFBD><EFBFBD>302<30><32><EFBFBD><EFBFBD>Ҫ<EFBFBD>ض<EFBFBD><D8B6><EFBFBD>
|
||
if (responseData.code == 302) {
|
||
headers = string("Host: ") + pod + R"(-buy.itunes.apple.com
|
||
User-Agent: MacAppStore/2.0 (Macintosh; OS X 12.6) AppleWebKit/613.3.9.1.16 build/7 (dt:1)
|
||
X-Apple-Store-Front: )";
|
||
headers.append(x_apple_store_front);
|
||
headers.append(R"(
|
||
X-Apple-ActionSignature: )");
|
||
; headers.append(XAppleActionSignature);
|
||
headers.append(R"(
|
||
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
|
||
X-Apple-Software-Guid: )");
|
||
headers.append(guid);
|
||
headers.append(R"(
|
||
X-Apple-Client-Application: Software
|
||
X-Apple-Connection-Type: WiFi
|
||
X-Apple-Client-Versions: iBooks/??; iTunesU/??; GameCenter/??; Podcasts/3.9
|
||
X-Apple-Tz: 28800
|
||
Accept-Language: zh-CN, en;q=0.9, *;q=0.1
|
||
Accept: */*
|
||
Connection: keep-alive)");
|
||
headers.append("\ncookie: " + cookies);
|
||
responseData = HttpRequest::Post("https://p" + pod_value + "-buy.itunes.apple.com/WebObjects/MZFinance.woa/wa/authenticate?Pod=" + pod_value + "&PRH=" + pod_value, postData, headers, proxy_str, false, [=](CURL* curl) {
|
||
if (!proxy_user_str.empty()) curl_easy_setopt(curl, CURLOPT_PROXYUSERNAME, proxy_user_str.c_str());
|
||
if (!proxy_pwd_str.empty()) curl_easy_setopt(curl, CURLOPT_PROXYPASSWORD, proxy_pwd_str.c_str());
|
||
});
|
||
if (responseData.success == false) {
|
||
if (org) *org = nullptr;
|
||
return 2;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
iTunesCookieInterface::GetInstance()->set_x_dsid(internal::GetKeyValue("dsPersonId", responseData.content));
|
||
iTunesCookieInterface::GetInstance()->set_x_token(internal::GetKeyValue("passwordToken", responseData.content));
|
||
iTunesCookieInterface::GetInstance()->set_credit_display(internal::GetKeyValue("creditDisplay", responseData.content));
|
||
bool success = internal::GetKbsyncToken();
|
||
//x_apple_store_front = responseData.headers.GetHeaderValue("X-Set-Apple-Store-Front");
|
||
|
||
if (org) {
|
||
*org = new char[responseData.content.length() + 1];
|
||
strcpy(*org, responseData.content.c_str());
|
||
}
|
||
|
||
string dsid = iTunesCookieInterface::GetInstance()->x_dsid();
|
||
string coo_dsid = "mz_at_ssl-" + dsid;
|
||
//<2F><><EFBFBD><EFBFBD><EFBFBD>¼״̬
|
||
HttpCookiesWrapper saveCookies;
|
||
saveCookies.SetCookie(coo_dsid, responseData.cookies.GetCookieValue(coo_dsid));
|
||
saveCookies.SetCookie("wosid-lite", responseData.cookies.GetCookieValue("wosid-lite"));
|
||
HttpHeadersWrapper saveHeaders;
|
||
saveHeaders.SetHeader("X-Dsid", dsid);
|
||
saveHeaders.SetHeader("X-Token", iTunesCookieInterface::GetInstance()->x_token());
|
||
saveHeaders.SetHeader("X-Apple-Store-Front", x_apple_store_front);
|
||
LoggedInStatus saveStatus; // <20><>¼״̬<D7B4>ṹ
|
||
saveStatus.cookies = saveCookies;
|
||
saveStatus.headers = saveHeaders;
|
||
saveStatus.guid = guid;
|
||
saveStatus.pod = pod;
|
||
saveStatus.pod_value = pod_value;
|
||
saveStatus.proxy = proxy_str;
|
||
saveStatus.proxy_user = proxy_user_str;
|
||
saveStatus.proxy_pwd = proxy_pwd_str;
|
||
// <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>
|
||
g_lockMap.lock();
|
||
loggedInUsers[appleAccount_str] = saveStatus;
|
||
g_lockMap.unlock();
|
||
|
||
return 0;
|
||
}
|
||
|
||
// 0<>ɹ<EFBFBD><C9B9><EFBFBD>1<EFBFBD>˺Ų<CBBA><C5B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><D0B1><EFBFBD>2<EFBFBD><32><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
int _stdcall iTunes_logout(IN const char* appleAccount, OUT char** org)
|
||
{
|
||
string appleAccount_str = appleAccount;
|
||
|
||
g_lockMap.lock();
|
||
if (loggedInUsers.find(appleAccount_str) == loggedInUsers.end()) {
|
||
g_lockMap.unlock();
|
||
return 1;
|
||
}
|
||
LoggedInStatus status = loggedInUsers[appleAccount_str];
|
||
g_lockMap.unlock();
|
||
|
||
|
||
HttpHeadersWrapper headers;
|
||
headers.ParseHeaders(R"(User-Agent: MacAppStore/2.0 (Macintosh; OS X 12.6) AppleWebKit/613.3.9.1.16 build/7 (dt:1)
|
||
X-Apple-Store-Front: 143465-19,30
|
||
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
|
||
X-Dsid: 107815378
|
||
X-Token: C44ED6AE0F6F1EBDB9EE63CDFB0408AE
|
||
X-Apple-Client-Application: Software
|
||
X-Apple-Connection-Type: WiFi
|
||
X-Apple-Client-Versions: iBooks/??; iTunesU/??; GameCenter/??; Podcasts/3.9
|
||
X-Apple-Tz: 28800
|
||
Accept-Language: zh-CN, en;q=0.9, *;q=0.1
|
||
Accept: */*
|
||
Connection: close)");
|
||
headers.SetHeader("Cookie", status.cookies.ToRequestCookieString());
|
||
headers.SetHeader("X-Dsid", status.headers.GetHeaderValue("X-Dsid"));
|
||
headers.SetHeader("X-Token", status.headers.GetHeaderValue("X-Token"));
|
||
|
||
string postData = R"(<?xml version="1.0" encoding="UTF-8"?>
|
||
<plist version="1.0">
|
||
<dict>
|
||
<key>guid</key>
|
||
<string>)";
|
||
postData.append(status.guid);
|
||
postData.append(R"(</string>
|
||
</dict>
|
||
</plist>)");
|
||
|
||
string url = "https://" + status.pod + "-buy.itunes.apple.com/WebObjects/MZFinance.woa/wa/logout";
|
||
HttpResponse result = HttpRequest::Post(url, postData, headers.GetAllHeaders(), status.proxy, false, [=](CURL* curl) {
|
||
if (!status.proxy_user.empty()) curl_easy_setopt(curl, CURLOPT_PROXYUSERNAME, status.proxy_user.c_str());
|
||
if (!status.proxy_pwd.empty()) curl_easy_setopt(curl, CURLOPT_PROXYPASSWORD, status.proxy_pwd.c_str());
|
||
});
|
||
if (result.success == false) {
|
||
// <20><><EFBFBD><EFBFBD>ʴ<EFBFBD><CAB4><EFBFBD>ʧЧ
|
||
g_lockMap.lock();
|
||
loggedInUsers.erase(appleAccount_str); // ֱ<><D6B1><EFBFBD>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD>
|
||
g_lockMap.unlock();
|
||
|
||
cout << appleAccount_str << " <20>˳<EFBFBD>ʧ<EFBFBD><CAA7>" << endl;
|
||
if (org) *org = nullptr;
|
||
return 2;
|
||
}
|
||
|
||
g_lockMap.lock();
|
||
loggedInUsers.erase(appleAccount_str);
|
||
g_lockMap.unlock();
|
||
|
||
if (org) {
|
||
*org = new char[result.content.length() + 1];
|
||
strcpy(*org, result.content.c_str());
|
||
}
|
||
|
||
cout << appleAccount_str << " <20>˳<EFBFBD><CBB3>ɹ<EFBFBD>" << endl;
|
||
return 0;
|
||
}
|
||
|
||
// 0<>ɹ<EFBFBD><C9B9><EFBFBD>1<EFBFBD>˺Ų<CBBA><C5B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><D0B1><EFBFBD>2<EFBFBD><32><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
int _stdcall iTunes_redeem(IN const char* appleAccount, IN const char* redeemCode, OUT char** org, OUT char** moreInfo)
|
||
{
|
||
string appleAccount_str = appleAccount;
|
||
string redemmCode_str = redeemCode;
|
||
|
||
g_lockMap.lock();
|
||
if (loggedInUsers.find(appleAccount_str) == loggedInUsers.end()) {
|
||
g_lockMap.unlock();
|
||
return 1;
|
||
}
|
||
LoggedInStatus status = loggedInUsers[appleAccount_str];
|
||
g_lockMap.unlock();
|
||
|
||
// <20><>ʼ<EFBFBD>һ<EFBFBD>
|
||
string postData = R"(<?xml version="1.0" encoding="UTF-8"?>
|
||
<plist version="1.0">
|
||
<dict>
|
||
<key>attemptCount</key>
|
||
<string>1</string>
|
||
<key>cameraReCOGnizedCode</key>
|
||
<string>false</string>
|
||
<key>cl</key>
|
||
<string>iTunes</string>
|
||
<key>code</key>
|
||
<string>)";
|
||
postData.append(redemmCode_str);
|
||
postData.append(R"(</string>
|
||
<key>dsPersonId</key>
|
||
<string>)");
|
||
postData.append(status.headers.GetHeaderValue("X-Dsid"));
|
||
postData.append(R"(</string>
|
||
<key>guid</key>
|
||
<string>)");
|
||
postData.append(status.guid);
|
||
postData.append(R"(</string>
|
||
<key>has4GBLimit</key>
|
||
<string>false</string>
|
||
<key>kbsync</key>
|
||
<data></data>
|
||
<key>pg</key>
|
||
<string>Music</string>
|
||
<key>response-content-type</key>
|
||
<string>application/json</string>
|
||
</dict>
|
||
</plist>)");
|
||
|
||
postData = replaceNewlineWithCRLF(postData);
|
||
|
||
|
||
//Cookie<69><65>Ҫע<D2AA>⣬ֻ<E2A3AC><D6BB><EFBFBD>ύmz_at_ssl-xxxxxx<78><78>wosid-lite<74><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE>Ҫ<EFBFBD><D2AA>¼
|
||
string headers = string("Host: ") + status.pod + R"(-buy.itunes.apple.com
|
||
Cookie: )";
|
||
headers.append(status.cookies.ToRequestCookieString());
|
||
headers.append(R"(
|
||
Connection: keep-alive
|
||
X-Apple-Store-Front: )");
|
||
headers.append(status.headers.GetHeaderValue("X-Apple-Store-Front")); //X-Set-Apple-Store-Front
|
||
headers.append(R"(
|
||
X-Dsid: )");
|
||
headers.append(status.headers.GetHeaderValue("X-Dsid"));
|
||
headers.append(R"(
|
||
X-Token: )");
|
||
headers.append(status.headers.GetHeaderValue("X-Token"));
|
||
headers.append(R"(
|
||
X-Apple-Partner: origin.0
|
||
X-Apple-Client-Application: Software
|
||
X-Apple-Connection-Type: WiFi
|
||
X-Apple-Client-Versions: GameCenter/2.0
|
||
X-Token-T: M
|
||
X-Apple-Tz: 28800
|
||
Accept-Language: zh-CN,zh;q=0.9,en;q=0
|
||
Accept: */*
|
||
Content-Type: application/x-apple-plist; Charset=UTF-8
|
||
User-Agent: MacAppStore/2.0 (Macintosh; OS X 12.6) AppleWebKit/613.3.9.1.16 build/7 (dt:1)
|
||
Referer: https://)");
|
||
headers.append(status.pod);
|
||
headers.append(R"(-buy.itunes.apple.com/WebObjects/MZFinance.woa/wa/com.apple.jingle.app.finance.DirectAction/redeemCode?cl=iTunes&pg=Music)");
|
||
|
||
HttpResponse responseData = HttpRequest::Post("https://" + status.pod + "-buy.itunes.apple.com/WebObjects/MZFinance.woa/wa/redeemCodeSrv", postData, headers, status.proxy, false, [=](CURL* curl) {
|
||
if (!status.proxy_user.empty()) curl_easy_setopt(curl, CURLOPT_PROXYUSERNAME, status.proxy_user.c_str());
|
||
if (!status.proxy_pwd.empty()) curl_easy_setopt(curl, CURLOPT_PROXYPASSWORD, status.proxy_pwd.c_str());
|
||
});
|
||
|
||
//<2F>ȰѸ<C8B0><D1B8><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD>ȥ
|
||
if (moreInfo) {
|
||
Json::Value root;
|
||
root["response_code"] = responseData.code; // HTTPԭʼ<D4AD><CABC><EFBFBD><EFBFBD>Ӧ״̬<D7B4><CCAC>
|
||
root["response_body"] = responseData.content; // <20><>Ӧ<EFBFBD><D3A6>
|
||
root["curl_code"] = responseData.curl_code; // curl<72><6C><EFBFBD><EFBFBD><EFBFBD>룬0<EBA3AC><30>ʾ<EFBFBD><CABE>ȫû<C8AB><C3BB><EFBFBD>⣬<EFBFBD><E2A3AC><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
root["curl_error"] = responseData.error; // curl<72><6C><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD>curl_code<64><65><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֶλ<D6B6>չʾ<D5B9><CABE><EFBFBD><EFBFBD>ԭ<EFBFBD><D4AD>
|
||
std::string root_str = json_toString(root);
|
||
*moreInfo = new char[root_str.length() + 1];
|
||
strcpy(*moreInfo, root_str.c_str());
|
||
}
|
||
|
||
if (responseData.success == false) {
|
||
g_lockMap.lock();
|
||
loggedInUsers.erase(appleAccount_str); // <20><><EFBFBD><EFBFBD>ʧЧ<CAA7><D0A7>ֱ<EFBFBD><D6B1><EFBFBD>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD>
|
||
g_lockMap.unlock();
|
||
|
||
if (org) *org = nullptr;
|
||
return 2;
|
||
}
|
||
|
||
//responseData.content = Strings::Utf8ToGBK(responseData.content);
|
||
//cout << "<22>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>" << responseData.content << endl << endl;
|
||
if (org) {
|
||
*org = new char[responseData.content.length() + 1];
|
||
strcpy(*org, responseData.content.c_str());
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
// 0<>ɹ<EFBFBD><C9B9><EFBFBD>1<EFBFBD>˺Ų<CBBA><C5B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><D0B1><EFBFBD>2<EFBFBD><32><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
int _stdcall iTunes_summary(IN const char* appleAccount, OUT char** org)
|
||
{
|
||
string appleAccount_str = appleAccount;
|
||
|
||
g_lockMap.lock();
|
||
if (loggedInUsers.find(appleAccount_str) == loggedInUsers.end()) {
|
||
g_lockMap.unlock();
|
||
|
||
return 1;
|
||
}
|
||
LoggedInStatus status = loggedInUsers[appleAccount_str];
|
||
g_lockMap.unlock();
|
||
|
||
|
||
HttpHeadersWrapper headers;
|
||
headers.ParseHeaders(R"(User-Agent: MacAppStore/2.0 (Macintosh; OS X 12.6) AppleWebKit/613.3.9.1.16 build/7 (dt:1)
|
||
X-Apple-Store-Front: 143465-19,30
|
||
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
|
||
X-Dsid: 107815378
|
||
X-Token: C44ED6AE0F6F1EBDB9EE63CDFB0408AE
|
||
X-Apple-Client-Application: Software
|
||
X-Apple-Connection-Type: WiFi
|
||
X-Apple-Client-Versions: iBooks/??; iTunesU/??; GameCenter/??; Podcasts/3.9
|
||
X-Apple-Tz: 28800
|
||
Accept-Language: zh-CN, en;q=0.9, *;q=0.1
|
||
Accept: */*
|
||
Connection: keep-alive)");
|
||
headers.SetHeader("X-Dsid", status.headers.GetHeaderValue("X-Dsid"));
|
||
headers.SetHeader("X-Token", status.headers.GetHeaderValue("X-Token"));
|
||
headers.SetHeader("cookie", status.cookies.ToRequestCookieString());
|
||
string url = "https://" + status.pod + "-buy.itunes.apple.com/WebObjects/MZFinance.woa/wa/accountSummary";
|
||
HttpResponse result = HttpRequest::Get(url, headers.GetAllHeaders(), status.proxy, false, [=](CURL* curl) {
|
||
if (!status.proxy_user.empty()) curl_easy_setopt(curl, CURLOPT_PROXYUSERNAME, status.proxy_user.c_str());
|
||
if (!status.proxy_pwd.empty()) curl_easy_setopt(curl, CURLOPT_PROXYPASSWORD, status.proxy_pwd.c_str());
|
||
});
|
||
//result.content = Strings::Utf8ToGBK(result.content);
|
||
if (result.success == false) {
|
||
g_lockMap.lock();
|
||
loggedInUsers.erase(appleAccount_str); // <20><><EFBFBD><EFBFBD>ʧЧ<CAA7><D0A7>ֱ<EFBFBD><D6B1><EFBFBD>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD>
|
||
g_lockMap.unlock();
|
||
|
||
if (org) *org = nullptr;
|
||
return 2;
|
||
}
|
||
|
||
if (org) {
|
||
*org = new char[result.content.length() + 1];
|
||
strcpy(*org, result.content.c_str());
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
// 0<>˺<EFBFBD><CBBA>ѵ<EFBFBD>¼<EFBFBD><C2BC>1<EFBFBD>˺Ų<CBBA><C5B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD>
|
||
int _stdcall iTunes_login_status(IN const char* appleAccount)
|
||
{
|
||
string appleAccount_str = appleAccount;
|
||
|
||
g_lockMap.lock();
|
||
if (loggedInUsers.find(appleAccount_str) == loggedInUsers.end()) {
|
||
g_lockMap.unlock();
|
||
return 1;
|
||
}
|
||
LoggedInStatus status = loggedInUsers[appleAccount_str];
|
||
g_lockMap.unlock();
|
||
|
||
return 0;
|
||
}
|
||
|
||
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD>
|
||
void _stdcall iTunes_get_heartbeat_list(OUT char** org) {
|
||
Json::Value root;
|
||
g_lockMap.lock();
|
||
for (auto& it : loggedInUsers) {
|
||
Json::Value item;
|
||
item["appleAccount"] = it.first;
|
||
item["proxy"] = it.second.proxy;
|
||
item["proxy_user"] = it.second.proxy_user;
|
||
item["proxy_pwd"] = it.second.proxy_pwd;
|
||
root.append(item);
|
||
}
|
||
g_lockMap.unlock();
|
||
std::string root_str = json_toString(root);
|
||
*org = new char[root_str.length() + 1];
|
||
strcpy(*org, root_str.c_str());
|
||
}
|
||
|
||
// <20>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
|
||
void _stdcall iTunes_free(void* ptr)
|
||
{
|
||
delete[] ptr;
|
||
}
|
||
|
||
}
|