ParallelsDesktopCrack/src/main.cpp

337 lines
15 KiB
C++

// hack to use objc_msgSend
#define _OBJC_MESSAGE_H
#include <CoreFoundation/CoreFoundation.h>
#include <objc/objc.h>
#include <objc/runtime.h>
#include <objc/NSObjCRuntime.h>
#include <dlfcn.h>
#include <mach/mach.h>
#include <mach/mach_vm.h>
#include <mach-o/dyld.h>
#include <mach-o/getsect.h>
#include <os/log.h>
#include <sys/stat.h>
#include <errno.h>
#include <type_traits>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <stdarg.h>
#define JM_XORSTR_DISABLE_AVX_INTRINSICS
#include "xorstr.hpp"
OBJC_EXPORT id _Nullable
objc_msgSend(id _Nullable self, SEL _Nonnull op, ...)
OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);
#if defined(_M_X64) || defined(__x86_64__)
#define TARGET_ARCH_X64 1
#elif defined(__AARCH64EL__)
#define TARGET_ARCH_ARM64 1
#else
#error unsupported arch
#endif
// #define ENABLE_DLOG 1
#if defined(ENABLE_DLOG)
#define dlog(format, ...) { os_log(OS_LOG_DEFAULT, "[PARALLELS_PATCH_LOG] " format, ##__VA_ARGS__); }
#else
#define dlog(format, ...)
#endif
id vars_g_static_class = nullptr;
bool str_ends_with(const char* a1, const char* a2) {
auto a1_len = strlen(a1);
auto a2_len = strlen(a2);
if (a1_len < a2_len) return false;
return 0 == strcmp(a1 + a1_len - a2_len, a2);
}
void func_write_fake_license()
{
unsigned char fake_license_data[829] = {
0xA1, 0xD0, 0xFA, 0xFA, 0xFA, 0xFA, 0xF8, 0xB6, 0xB3, 0xB9, 0xBF, 0xB4, 0xA9, 0xBF, 0xF8, 0xE0,
0xFA, 0xF8, 0xA1, 0x86, 0xF8, 0xB4, 0xBB, 0xB7, 0xBF, 0x86, 0xF8, 0xE0, 0xFA, 0xB4, 0xAF, 0xB6,
0xB6, 0xF6, 0xFA, 0x86, 0xF8, 0xAF, 0xAF, 0xB3, 0xBE, 0x86, 0xF8, 0xE0, 0xFA, 0x86, 0xF8, 0x86,
0xF8, 0xF6, 0xFA, 0x86, 0xF8, 0xB6, 0xB3, 0xB9, 0x85, 0xB1, 0xBF, 0xA3, 0x86, 0xF8, 0xE0, 0xFA,
0x86, 0xF8, 0x86, 0xF8, 0xF6, 0xFA, 0x86, 0xF8, 0xAA, 0xA8, 0xB5, 0xBE, 0xAF, 0xB9, 0xAE, 0x85,
0xAC, 0xBF, 0xA8, 0xA9, 0xB3, 0xB5, 0xB4, 0x86, 0xF8, 0xE0, 0xFA, 0x86, 0xF8, 0xEB, 0xE2, 0xF4,
0xF0, 0x86, 0xF8, 0xF6, 0xFA, 0x86, 0xF8, 0xB3, 0xA9, 0x85, 0xAF, 0xAA, 0xBD, 0xA8, 0xBB, 0xBE,
0xBF, 0x86, 0xF8, 0xE0, 0xFA, 0xBC, 0xBB, 0xB6, 0xA9, 0xBF, 0xF6, 0xFA, 0x86, 0xF8, 0xB3, 0xA9,
0x85, 0xA9, 0xAF, 0xB8, 0xB6, 0xB3, 0xB9, 0xBF, 0xB4, 0xA9, 0xBF, 0x86, 0xF8, 0xE0, 0xFA, 0xBC,
0xBB, 0xB6, 0xA9, 0xBF, 0xF6, 0xFA, 0x86, 0xF8, 0xAA, 0xBB, 0xA8, 0xBF, 0xB4, 0xAE, 0x85, 0xB1,
0xBF, 0xA3, 0x86, 0xF8, 0xE0, 0xFA, 0xB4, 0xAF, 0xB6, 0xB6, 0xF6, 0xFA, 0x86, 0xF8, 0xAA, 0xBB,
0xA8, 0xBF, 0xB4, 0xAE, 0x85, 0xAF, 0xAF, 0xB3, 0xBE, 0x86, 0xF8, 0xE0, 0xFA, 0xB4, 0xAF, 0xB6,
0xB6, 0xF6, 0xFA, 0x86, 0xF8, 0xB7, 0xBB, 0xB3, 0xB4, 0x85, 0xAA, 0xBF, 0xA8, 0xB3, 0xB5, 0xBE,
0x85, 0xBF, 0xB4, 0xBE, 0xA9, 0x85, 0xBB, 0xAE, 0x86, 0xF8, 0xE0, 0xFA, 0x86, 0xF8, 0xE8, 0xEA,
0xE3, 0xE3, 0xF7, 0xEA, 0xE3, 0xF7, 0xEA, 0xE3, 0xFA, 0xEA, 0xEA, 0xE0, 0xEA, 0xEA, 0xE0, 0xEA,
0xEA, 0x86, 0xF8, 0xF6, 0xFA, 0x86, 0xF8, 0xBD, 0xA8, 0xBB, 0xB9, 0xBF, 0x85, 0xAA, 0xBF, 0xA8,
0xB3, 0xB5, 0xBE, 0x85, 0xBF, 0xB4, 0xBE, 0xA9, 0x85, 0xBB, 0xAE, 0x86, 0xF8, 0xE0, 0xFA, 0x86,
0xF8, 0xE8, 0xEA, 0xE3, 0xE3, 0xF7, 0xEA, 0xE3, 0xF7, 0xEA, 0xE3, 0xFA, 0xEA, 0xEA, 0xE0, 0xEA,
0xEA, 0xE0, 0xEA, 0xEA, 0x86, 0xF8, 0xF6, 0xFA, 0x86, 0xF8, 0xB3, 0xA9, 0x85, 0xBB, 0xAF, 0xAE,
0xB5, 0x85, 0xA8, 0xBF, 0xB4, 0xBF, 0xAD, 0xBB, 0xB8, 0xB6, 0xBF, 0x86, 0xF8, 0xE0, 0xFA, 0xBC,
0xBB, 0xB6, 0xA9, 0xBF, 0xF6, 0xFA, 0x86, 0xF8, 0xB3, 0xA9, 0x85, 0xB4, 0xBC, 0xA8, 0x86, 0xF8,
0xE0, 0xFA, 0xBC, 0xBB, 0xB6, 0xA9, 0xBF, 0xF6, 0xFA, 0x86, 0xF8, 0xB3, 0xA9, 0x85, 0xB8, 0xBF,
0xAE, 0xBB, 0x86, 0xF8, 0xE0, 0xFA, 0xBC, 0xBB, 0xB6, 0xA9, 0xBF, 0xF6, 0xFA, 0x86, 0xF8, 0xB3,
0xA9, 0x85, 0xB9, 0xB2, 0xB3, 0xB4, 0xBB, 0x86, 0xF8, 0xE0, 0xFA, 0xBC, 0xBB, 0xB6, 0xA9, 0xBF,
0xF6, 0xFA, 0x86, 0xF8, 0xB3, 0xA9, 0x85, 0xA9, 0xAF, 0xA9, 0xAA, 0xBF, 0xB4, 0xBE, 0xBF, 0xBE,
0x86, 0xF8, 0xE0, 0xFA, 0xBC, 0xBB, 0xB6, 0xA9, 0xBF, 0xF6, 0xFA, 0x86, 0xF8, 0xB3, 0xA9, 0x85,
0xBF, 0xA2, 0xAA, 0xB3, 0xA8, 0xBF, 0xBE, 0x86, 0xF8, 0xE0, 0xFA, 0xBC, 0xBB, 0xB6, 0xA9, 0xBF,
0xF6, 0xFA, 0x86, 0xF8, 0xB3, 0xA9, 0x85, 0xBD, 0xA8, 0xBB, 0xB9, 0xBF, 0x85, 0xAA, 0xBF, 0xA8,
0xB3, 0xB5, 0xBE, 0x86, 0xF8, 0xE0, 0xFA, 0xBC, 0xBB, 0xB6, 0xA9, 0xBF, 0xF6, 0xFA, 0x86, 0xF8,
0xB3, 0xA9, 0x85, 0xAA, 0xAF, 0xA8, 0xB9, 0xB2, 0xBB, 0xA9, 0xBF, 0xBE, 0x85, 0xB5, 0xB4, 0xB6,
0xB3, 0xB4, 0xBF, 0x86, 0xF8, 0xE0, 0xFA, 0xBC, 0xBB, 0xB6, 0xA9, 0xBF, 0xF6, 0xFA, 0x86, 0xF8,
0xB6, 0xB3, 0xB7, 0xB3, 0xAE, 0x86, 0xF8, 0xE0, 0xFA, 0xEB, 0xEA, 0xF6, 0xFA, 0x86, 0xF8, 0xAF,
0xA9, 0xBB, 0xBD, 0xBF, 0x86, 0xF8, 0xE0, 0xFA, 0xEB, 0xF6, 0xFA, 0x86, 0xF8, 0xBF, 0xBE, 0xB3,
0xAE, 0xB3, 0xB5, 0xB4, 0x86, 0xF8, 0xE0, 0xFA, 0xE8, 0xF6, 0xFA, 0x86, 0xF8, 0xAA, 0xB6, 0xBB,
0xAE, 0xBC, 0xB5, 0xA8, 0xB7, 0x86, 0xF8, 0xE0, 0xFA, 0xE9, 0xF6, 0xFA, 0x86, 0xF8, 0xAA, 0xA8,
0xB5, 0xBE, 0xAF, 0xB9, 0xAE, 0x86, 0xF8, 0xE0, 0xFA, 0xED, 0xF6, 0xFA, 0x86, 0xF8, 0xB5, 0xBC,
0xBC, 0xB6, 0xB3, 0xB4, 0xBF, 0x86, 0xF8, 0xE0, 0xFA, 0xAE, 0xA8, 0xAF, 0xBF, 0xF6, 0xFA, 0x86,
0xF8, 0xB9, 0xAA, 0xAF, 0x85, 0xB6, 0xB3, 0xB7, 0xB3, 0xAE, 0x86, 0xF8, 0xE0, 0xFA, 0xE9, 0xE8,
0xF6, 0xFA, 0x86, 0xF8, 0xA8, 0xBB, 0xB7, 0x85, 0xB6, 0xB3, 0xB7, 0xB3, 0xAE, 0x86, 0xF8, 0xE0,
0xFA, 0xEB, 0xE9, 0xEB, 0xEA, 0xED, 0xE8, 0xF6, 0xFA, 0x86, 0xF8, 0xB2, 0xB5, 0xA9, 0xAE, 0xA9,
0x86, 0xF8, 0xE0, 0xFA, 0x81, 0xA1, 0x86, 0xF8, 0xB4, 0xBB, 0xB7, 0xBF, 0x86, 0xF8, 0xE0, 0xFA,
0x86, 0xF8, 0x9D, 0x9E, 0x8A, 0x88, 0x85, 0x92, 0x93, 0x9E, 0x9E, 0x9F, 0x94, 0x86, 0xF8, 0xF6,
0xFA, 0x86, 0xF8, 0xB2, 0xAD, 0x85, 0xB3, 0xBE, 0x86, 0xF8, 0xE0, 0xFA, 0x86, 0xF8, 0x86, 0xF8,
0xF6, 0xFA, 0x86, 0xF8, 0xAA, 0xA8, 0xB5, 0xBE, 0xAF, 0xB9, 0xAE, 0x85, 0xAC, 0xBF, 0xA8, 0xA9,
0xB3, 0xB5, 0xB4, 0x86, 0xF8, 0xE0, 0xFA, 0x86, 0xF8, 0x86, 0xF8, 0xF6, 0xFA, 0x86, 0xF8, 0xBB,
0xB9, 0xAE, 0xB3, 0xAC, 0xBB, 0xAE, 0xBF, 0xBE, 0x85, 0xBB, 0xAE, 0x86, 0xF8, 0xE0, 0xFA, 0x86,
0xF8, 0xE8, 0xEA, 0xE8, 0xEB, 0xF7, 0xEA, 0xEF, 0xF7, 0xEA, 0xE3, 0xFA, 0xEA, 0xEA, 0xE0, 0xEA,
0xEA, 0xE0, 0xEA, 0xEA, 0x86, 0xF8, 0xA7, 0x87, 0xF6, 0xFA, 0x86, 0xF8, 0xB3, 0xA9, 0x85, 0xAE,
0xA8, 0xB3, 0xBB, 0xB6, 0x86, 0xF8, 0xE0, 0xFA, 0xBC, 0xBB, 0xB6, 0xA9, 0xBF, 0xA7, 0xF8, 0xF6,
0xD0, 0xFA, 0xFA, 0xFA, 0xFA, 0xF8, 0xAA, 0xAF, 0xB8, 0xB6, 0xB3, 0xB9, 0x99, 0xBF, 0xA8, 0xAE,
0xA9, 0xF8, 0xE0, 0xFA, 0xF8, 0xF8, 0xF6, 0xD0, 0xFA, 0xFA, 0xFA, 0xFA, 0xF8, 0xA9, 0xB3, 0xBD,
0xB4, 0xBB, 0xAE, 0xAF, 0xA8, 0xBF, 0xF8, 0xE0, 0xFA, 0xF8, 0xF8, 0xD0, 0xA7
};
// const char* fake_license_data = "{\n "license": "{\\"name\\": null, \\"uuid\\": \\"\\", \\"lic_key\\": \\"\\", \\"product_version\\": \\"18.*\\", \\"is_upgrade\\": false, \\"is_sublicense\\": false, \\"parent_key\\": null, \\"parent_uuid\\": null, \\"main_period_ends_at\\": \\"2099-09-09 00:00:00\\", \\"grace_period_ends_at\\": \\"2099-09-09 00:00:00\\", \\"is_auto_renewable\\": false, \\"is_nfr\\": false, \\"is_beta\\": false, \\"is_china\\": false, \\"is_suspended\\": false, \\"is_expired\\": false, \\"is_grace_period\\": false, \\"is_purchased_online\\": false, \\"limit\\": 10, \\"usage\\": 1, \\"edition\\": 2, \\"platform\\": 3, \\"product\\": 7, \\"offline\\": true, \\"cpu_limit\\": 32, \\"ram_limit\\": 131072, \\"hosts\\": [{\\"name\\": \\"GDPR_HIDDEN\\", \\"hw_id\\": \\"\\", \\"product_version\\": \\"\\", \\"activated_at\\": \\"2021-05-09 00:00:00\\"}], \\"is_trial\\": false}",\n "publicCerts": "",\n "signature": ""\n}";
auto file = fopen(xorstr_("/Library/Preferences/Parallels/licenses.json"), xorstr_("wb"));
if (file)
{
for(int i = 0; i < sizeof(fake_license_data); i++)
fake_license_data[i] ^= 0xda;
fseek(file, 0, 0);
fwrite(fake_license_data, sizeof(fake_license_data), 1, file);
fclose(file);
for(int i = 0; i < sizeof(fake_license_data); i++)
fake_license_data[i] = 0;
dlog("[+] write fake license to (/Library/Preferences/Parallels/licenses.json)");
}
else
{
dlog("[-] open fail. (/Library/Preferences/Parallels/licenses.json)");
}
}
void func_patch_prl_disp_service()
{
func_write_fake_license();
}
void func_hook_applicationDidBecomeActive(id, SEL)
{
dlog("[+] enter hookapplicationDidBecomeActive.");
// @autoreleasepool {
// auto main_menu = [[NSApplication sharedApplication] mainMenu];
// auto main_menu_count = [main_menu numberOfItems];
// if (main_menu_count) {
// auto main_menu_last = [main_menu itemAtIndex:main_menu_count-1];
// if ([main_menu_last hasSubmenu]) {
// auto menu_1 = [NSMenuItem separatorItem];
// auto menu_2 = [[NSMenuItem alloc] init];
//
// auto title = [NSString stringWithUTF8String:xorstr_("K'ed by day")];
// [menu_2 setTitle:title];
//
// auto sub_menu = [main_menu_last submenu];
// [sub_menu addItem:menu_1];
// [sub_menu addItem:menu_2];
// }
// }
// }
auto cls_NSApplication = (id)objc_getClass(xorstr_("NSApplication"));
if (!cls_NSApplication) {
dlog("[-] get class NSApplication fail");
return;
}
dlog("[+] get class NSApplication success");
auto cls_NSMenuItem = (id)objc_getClass(xorstr_("NSMenuItem"));
if (!cls_NSMenuItem) {
dlog("[-] get class NSMenuItem fail");
return;
}
dlog("[+] get class NSMenuItem success");
auto cls_NSString = (id)objc_getClass(xorstr_("NSString"));
if (!cls_NSString) {
dlog("[-] get class NSString fail");
return;
}
dlog("[+] get class NSString success");
auto sel_sharedApplication = sel_registerName(xorstr_("sharedApplication"));
auto sel_mainMenu = sel_registerName(xorstr_("mainMenu"));
auto sel_numberOfItems = sel_registerName(xorstr_("numberOfItems"));
auto sel_itemAtIndex = sel_registerName(xorstr_("itemAtIndex:"));
auto sel_hasSubmenu = sel_registerName(xorstr_("hasSubmenu"));
auto sel_separatorItem = sel_registerName(xorstr_("separatorItem"));
auto sel_alloc = sel_registerName(xorstr_("alloc"));
auto sel_init = sel_registerName(xorstr_("init"));
auto sel_stringWithUTF8String = sel_registerName(xorstr_("stringWithUTF8String:"));
auto sel_setTitle = sel_registerName(xorstr_("setTitle:"));
auto sel_submenu = sel_registerName(xorstr_("submenu"));
auto sel_addItem = sel_registerName(xorstr_("addItem:"));
auto cls_sharedApplication = (id)objc_msgSend(cls_NSApplication, sel_sharedApplication);
if (!cls_sharedApplication) {
dlog("[-] [NSApplication sharedApplication] fail");
return;
}
dlog("[+] [NSApplication sharedApplication] success");
auto cls_mainMenu = (id)objc_msgSend(cls_sharedApplication, sel_mainMenu);
if (!cls_mainMenu) {
dlog("[-] [sharedApplication mainMenu] fail");
return;
}
dlog("[+] [sharedApplication mainMenu] success");
int main_menu_count = (int)(intptr_t)objc_msgSend(cls_mainMenu, sel_numberOfItems);
dlog("[*] mainMenu count: %d", main_menu_count);
if (main_menu_count > 0) {
auto cls_menu_last = (id)objc_msgSend(cls_mainMenu, sel_itemAtIndex, main_menu_count - 1);
if (!cls_menu_last) {
dlog("[-] [mainMenu itemAtIndex: %d] fail", main_menu_count - 1);
return;
}
dlog("[+] [mainMenu itemAtIndex: %d] success", main_menu_count - 1);
bool menu_last_hassubmenu = (bool)objc_msgSend(cls_menu_last, sel_hasSubmenu);
dlog("[*] hasSubmenu: %d", menu_last_hassubmenu? 1 : 0);
if (menu_last_hassubmenu) {
auto cls_menu_1 = (id)objc_msgSend(cls_NSMenuItem, sel_separatorItem);
auto cls_menu_2 = (id)objc_msgSend((id)objc_msgSend(cls_NSMenuItem, sel_alloc), sel_init);
if (!cls_menu_1) {
dlog("[-] [NSMenuItem separatorItem] fail");
return;
}
dlog("[+] [NSMenuItem separatorItem] success");
if (!cls_menu_2) {
dlog("[-] [[NSMenuItem alloc] init] fail");
return;
}
dlog("[+] [[NSMenuItem alloc] init] success");
auto title = (id)objc_msgSend(cls_NSString, sel_stringWithUTF8String, xorstr_("K'ed by Day"));
if (!title) {
dlog("[-] [NSString stringWithUTF8String] fail");
return;
}
dlog("[+] [NSString stringWithUTF8String] success");
objc_msgSend(cls_menu_2, sel_setTitle, title);
auto sub_menu = (id)objc_msgSend(cls_menu_last, sel_submenu);
if (!sub_menu) {
dlog("[-] [menu submenu] fail");
return;
}
dlog("[+] [menu submenu] success");
objc_msgSend(sub_menu, sel_addItem, cls_menu_1);
objc_msgSend(sub_menu, sel_addItem, cls_menu_2);
dlog("[+] add menu success");
}
}
auto file_path = xorstr_("/Library/Preferences/Parallels/licenses.json");
auto file = fopen(file_path, xorstr_("wb"));
if (file) {
dlog("[*] write empty license data.");
auto content = xorstr_("{\n \"license\": \"\",\n \"signature\": \"\"\n}");
fseek(file, 0, 0);
fwrite(content, strlen(content), 1, file);
fclose(file);
}
}
void func_hook_menu()
{
auto cls_NSObject = (id)objc_getMetaClass(xorstr_("NSObject"));
if(!cls_NSObject) {
dlog("[-] get class NSObject fail");
return;
}
auto sel_applicationDidBecomeActive = sel_registerName(xorstr_("applicationDidBecomeActive:"));
if ( !class_addMethod((Class)cls_NSObject, sel_applicationDidBecomeActive, (IMP)func_hook_applicationDidBecomeActive, xorstr_("n")) ) {
dlog("[-] class_addMethod applicationDidBecomeActive fail.");
return;
}
dlog("[+] class_addMethod applicationDidBecomeActive success.");
auto cls_NSNotificationCenter = (id)objc_getClass(xorstr_("NSNotificationCenter"));
if (!cls_NSNotificationCenter) {
dlog("[-] get class NSNotificationCenter fail");
return;
}
auto cls_NSString = (id)objc_getClass(xorstr_("NSString"));
if (!cls_NSString) {
dlog("[-] get class NSString fail");
return;
}
auto sel_defaultCenter = sel_registerName(xorstr_("defaultCenter"));
auto sel_stringWithUTF8String = sel_registerName(xorstr_("stringWithUTF8String:"));
auto sel_addObserver = sel_registerName(xorstr_("addObserver:selector:name:object:"));
auto sel_class = sel_registerName(xorstr_("class"));
auto cls_defaultCenter = (id)objc_msgSend(cls_NSNotificationCenter, sel_defaultCenter);
if (!cls_defaultCenter) {
dlog("[-] [NSNotificationCenter defaultCenter] fail");
return;
}
auto cls_name = (id)objc_msgSend(cls_NSString, sel_stringWithUTF8String, xorstr_("NSApplicationDidFinishLaunchingNotification"));
if (!cls_name) {
dlog("[-] [NSString stringWithUTF8String] fail");
return;
}
if (nullptr == vars_g_static_class) {
auto sel_alloc = sel_registerName(xorstr_("alloc"));
id v = (id)objc_msgSend(cls_NSObject, sel_alloc);
vars_g_static_class = v;
}
objc_msgSend(cls_defaultCenter, sel_addObserver, vars_g_static_class, sel_applicationDidBecomeActive, cls_name, 0);
dlog("[+] addObserver success");
}
__attribute__((constructor))
void func_load()
{
const char *moduleName = _dyld_get_image_name(0);
dlog("[*] load %s", moduleName);
if (str_ends_with(moduleName, xorstr_("prl_disp_service")))
{
dlog("patch prl_disp_service start");
func_patch_prl_disp_service();
dlog("patch prl_disp_service over");
}
func_hook_menu();
}