Files
itunes_server/iTunesAPIs/src/iTunesAPIs.cpp
danial 9f481c5e8c Add iTunes Debugger and third-party libraries
- 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.
2025-11-15 23:06:05 +08:00

1094 lines
38 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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;
}
}