Update crack

This commit is contained in:
somebasj 2022-09-06 18:14:53 +08:00
parent 7b75d676a8
commit e09afa6863
12 changed files with 207 additions and 940 deletions

View File

@ -1,34 +0,0 @@
cmake_minimum_required(VERSION 3.20)
project(UIWarp)
add_library(${PROJECT_NAME} SHARED
src/main.cpp
)
target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_17)
target_compile_options(${PROJECT_NAME} PRIVATE
-stdlib=libc++
-fno-rtti
-fvisibility=hidden
-fvisibility-inlines-hidden
)
# Add OLLVM plugin if exists
if (EXISTS ${CMAKE_SOURCE_DIR}/ollvm.dylib)
target_compile_options(${PROJECT_NAME} PRIVATE
-fpass-plugin=${CMAKE_SOURCE_DIR}/ollvm.dylib
)
endif()
target_link_libraries(${PROJECT_NAME} PRIVATE
"-framework Foundation"
"-framework CoreFoundation"
"-framework AppKit"
"-framework Cocoa"
)
target_link_libraries(${PROJECT_NAME} PRIVATE
objc
)

View File

@ -1,6 +1,152 @@
# patch prl_disp_app
## 1. patch /usr/bin/codesign verify
## 2. patch Signature::SignCheckerImpl
### 2.1 find vtable
#### x86_64
```
__const:00000001009B2A70 ; `vtable for'Signature::SignCheckerImpl
__const:00000001009B2A70 00 00 00 00 00 00 00 00 _ZTVN9Signature15SignCheckerImplE dq 0 ; DATA XREF: sub_100349A00+28↑o
__const:00000001009B2A70 ; offset to this
__const:00000001009B2A78 A8 2A 9B 00 01 00 00 00 dq offset _ZTIN9Signature15SignCheckerImplE ; `typeinfo for'Signature::SignCheckerImpl
__const:00000001009B2A80 00 0B 5B 00 01 00 00 00 dq offset sub_1005B0B00
__const:00000001009B2A88 10 0B 5B 00 01 00 00 00 dq offset sub_1005B0B10
__const:00000001009B2A90 80 07 5B 00 01 00 00 00 dq offset sub_1005B0780
```
#### arm64
```
__const:0000000100988520 ; `vtable for'Signature::SignCheckerImpl
__const:0000000100988520 00 00 00 00 00 00 00 00 _ZTVN9Signature15SignCheckerImplE DCQ 0 ; DATA XREF: sub_100369410+28↑o
__const:0000000100988520 ; offset to this
__const:0000000100988528 58 85 98 00 01 00 00 00 DCQ _ZTIN9Signature15SignCheckerImplE ; `typeinfo for'Signature::SignCheckerImpl
__const:0000000100988530 28 E9 5D 00 01 00 00 00 DCQ nullsub_201
__const:0000000100988538 2C E9 5D 00 01 00 00 00 DCQ j___ZdlPv_267
__const:0000000100988540 84 E5 5D 00 01 00 00 00 DCQ sub_1005DE584
```
### 2.2 patch function `sub_1005B0780`
#### x86_64
```
__text:00000001005B0780 55 push rbp
__text:00000001005B0781 48 89 E5 mov rbp, rsp
__text:00000001005B0784 41 57 push r15
__text:00000001005B0786 41 56 push r14
__text:00000001005B0788 41 54 push r12
__text:00000001005B078A 53 push rbx
__text:00000001005B078B 48 81 EC A0 00 00 00 sub rsp, 0A0h
__text:00000001005B0792 49 89 CE mov r14, rcx
__text:00000001005B0795 49 89 D7 mov r15, rdx
__text:00000001005B0798 49 89 F4 mov r12, rsi
__text:00000001005B079B BF D0 0A 00 00 mov edi, 0AD0h ; unsigned __int64
__text:00000001005B07A0 E8 D7 4E 23 00 call __Znwm ; operator new(ulong)
__text:00000001005B07A5 48 89 C3 mov rbx, rax
__text:00000001005B07A8 48 89 45 A0 mov [rbp+var_60], rax
__text:00000001005B07AC 0F 28 05 DD 8F 38 00 movaps xmm0, cs:xmmword_100939790
__text:00000001005B07B3 0F 29 45 90 movaps [rbp+var_70], xmm0
__text:00000001005B07B7 48 8D 35 58 8F 31 00 lea rsi, aBeginCertifica ; "-----BEGIN CERTIFICATE-----\nMIIHzTCCBb"...
__text:00000001005B07BE BA CC 0A 00 00 mov edx, 0ACCh ; __n
__text:00000001005B07C3 48 89 C7 mov rdi, rax ; __dst
__text:00000001005B07C6 E8 3D 53 23 00 call _memcpy
__text:00000001005B07CB C6 83 CC 0A 00 00 00 mov byte ptr [rbx+0ACCh], 0
__text:00000001005B07D2 48 8D BD 48 FF FF FF lea rdi, [rbp+var_B8]
__text:00000001005B07D9 48 8D 75 90 lea rsi, [rbp+var_70]
__text:00000001005B07DD E8 CE 07 00 00 call sub_1005B0FB0
__text:00000001005B07E2 F6 45 90 01 test byte ptr [rbp+var_70], 1
__text:00000001005B07E6 74 09 jz short loc_1005B07F1
__text:00000001005B07E8 48 8B 7D A0 mov rdi, [rbp+var_60] ; void *
__text:00000001005B07EC E8 61 4E 23 00 call __ZdlPv ; operator delete(void *)
__text:00000001005B07F1
```
opcode
```
55 48 89 E5 41 57 41 56 41 54 53 48 81 EC A0 00
00 00 49 89 CE 49 89 D7 49 89 F4 BF D0 0A 00 00
E8 D7 4E 23 00 48 89 C3 48 89 45 A0 0F 28 05 DD
8F 38 00 0F 29 45 90 48 8D 35 58 8F 31 00 BA CC
```
patch
```
6A 01 58 C3
```
after
```
__text:00000001005B0780 sub_1005B0780 proc near ; DATA XREF: __const:00000001009B2A90↓o
__text:00000001005B0780 6A 01 push 1
__text:00000001005B0782 58 pop rax
__text:00000001005B0783 C3 retn
__text:00000001005B0783 sub_1005B0780 endp
```
#### arm64
```
__text:00000001005DE584 FF 03 03 D1 SUB SP, SP, #0xC0
__text:00000001005DE588 F6 57 09 A9 STP X22, X21, [SP,#0xB0+var_20]
__text:00000001005DE58C F4 4F 0A A9 STP X20, X19, [SP,#0xB0+var_10]
__text:00000001005DE590 FD 7B 0B A9 STP X29, X30, [SP,#0xB0+var_s0]
__text:00000001005DE594 FD C3 02 91 ADD X29, SP, #0xB0
__text:00000001005DE598 F3 03 03 AA MOV X19, X3
__text:00000001005DE59C F4 03 02 AA MOV X20, X2
__text:00000001005DE5A0 F5 03 01 AA MOV X21, X1
__text:00000001005DE5A4 00 5A 81 52 MOV W0, #0xAD0 ; unsigned __int64
__text:00000001005DE5A8 70 C8 07 94 BL __Znwm ; operator new(ulong)
__text:00000001005DE5AC F6 03 00 AA MOV X22, X0
__text:00000001005DE5B0 E0 2B 00 F9 STR X0, [SP,#0xB0+var_60]
__text:00000001005DE5B4 E8 10 00 B0 ADRP X8, #xmmword_1007FB2D0@PAGE
__text:00000001005DE5B8 00 B5 C0 3D LDR Q0, [X8,#xmmword_1007FB2D0@PAGEOFF]
__text:00000001005DE5BC E0 83 85 3C STUR Q0, [SP,#0xB0+var_58]
__text:00000001005DE5C0 C1 18 00 F0 21 84 25 91 ADRL X1, aBeginCertifica ; "-----BEGIN CERTIFICATE-----\nMIIHzTCCBb"...
__text:00000001005DE5C8 82 59 81 52 MOV W2, #0xACC ; __n
__text:00000001005DE5CC A7 CA 07 94 BL _memcpy
__text:00000001005DE5D0 DF 32 2B 39 STRB WZR, [X22,#0xACC]
__text:00000001005DE5D4 A0 23 01 D1 SUB X0, X29, #-var_48
__text:00000001005DE5D8 E1 43 01 91 ADD X1, SP, #0xB0+var_60
__text:00000001005DE5DC 00 02 00 94 BL j___ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEC1ERKS5_ ; std::string::basic_string(std::string const&)
__text:00000001005DE5E0 E8 9F C1 39 LDRSB W8, [SP,#0xB0+var_58+0xF]
__text:00000001005DE5E4 68 00 F8 36 TBZ W8, #0x1F, loc_1005DE5F0
__text:00000001005DE5E8 E0 2B 40 F9 LDR X0, [SP,#0xB0+var_60] ; void *
__text:00000001005DE5EC 4A C8 07 94 BL __ZdlPv ; operator delete(void *)
__text:00000001005DE5F0
```
opcode
```
FF 03 03 D1 F6 57 09 A9 F4 4F 0A A9 FD 7B 0B A9
FD C3 02 91 F3 03 03 AA F4 03 02 AA F5 03 01 AA
00 5A 81 52 70 C8 07 94 F6 03 00 AA E0 2B 00 F9
E8 10 00 B0 00 B5 C0 3D E0 83 85 3C C1 18 00 F0
```
patch
```
20 00 80 D2 C0 03 5F D6
```
after
```
__text:00000001005DE584 sub_1005DE584 ; DATA XREF: __const:0000000100988540↓o
__text:00000001005DE584 20 00 80 D2 MOV X0, #1
__text:00000001005DE588 C0 03 5F D6 RET
__text:00000001005DE588 ; End of function sub_1005DE584
```
## 2. patch /usr/bin/codesign verify
find string xref to "/usr/bin/codesign"
@ -39,6 +185,21 @@ __text:00000001007C92FD 85 C0 test eax, eax
__text:00000001007C92FF 74 29 jz short loc_1007C932A
```
opcode
```
55 48 89 E5 41 57 41 56 41 55 41 54 53 48 81 EC
38 04 00 00 4C 89 85 B8 FB FF FF 48 89 8D B0 FB
FF FF 48 89 95 A8 FB FF FF 41 89 F4 48 89 FB 48
8B 05 7A 70 1C 00 48 8B 00 48 89 45 D0 48 8B 0D
```
patch
```
6A 01 58 C3
```
after
```
@ -83,6 +244,21 @@ __text:00000001007B3A88 E0 01 00 34 CBZ
__text:00000001007B3A8C
```
opcode
```
FA 67 BB A9 F8 5F 01 A9 F6 57 02 A9 F4 4F 03 A9
FD 7B 04 A9 FD 03 01 91 FF 43 11 D1 F6 03 04 AA
F7 03 03 AA F4 03 02 AA F5 03 01 AA F3 03 00 AA
C8 0D 00 B0 08 6D 41 F9 08 01 40 F9 A8 83 1B F8
```
patch
```
20 00 80 D2 C0 03 5F D6
```
after
```
@ -91,112 +267,3 @@ __text:00000001007B3A14 20 00 80 D2 MOV
__text:00000001007B3A18 C0 03 5F D6 RET
__text:00000001007B3A18 ; End of function sub_1007B3A14
```
## 2. patch Signature::SignCheckerImpl
### 2.1 find vtable
x86_64
```
__const:00000001009B2A70 ; `vtable for'Signature::SignCheckerImpl
__const:00000001009B2A70 00 00 00 00 00 00 00 00 _ZTVN9Signature15SignCheckerImplE dq 0 ; DATA XREF: sub_100349A00+28↑o
__const:00000001009B2A70 ; offset to this
__const:00000001009B2A78 A8 2A 9B 00 01 00 00 00 dq offset _ZTIN9Signature15SignCheckerImplE ; `typeinfo for'Signature::SignCheckerImpl
__const:00000001009B2A80 00 0B 5B 00 01 00 00 00 dq offset sub_1005B0B00
__const:00000001009B2A88 10 0B 5B 00 01 00 00 00 dq offset sub_1005B0B10
__const:00000001009B2A90 80 07 5B 00 01 00 00 00 dq offset sub_1005B0780
```
arm64
```
```
### 2.2 patch function `sub_1005B0780`
x86_64
```
__text:00000001005B0780 55 push rbp
__text:00000001005B0781 48 89 E5 mov rbp, rsp
__text:00000001005B0784 41 57 push r15
__text:00000001005B0786 41 56 push r14
__text:00000001005B0788 41 54 push r12
__text:00000001005B078A 53 push rbx
__text:00000001005B078B 48 81 EC A0 00 00 00 sub rsp, 0A0h
__text:00000001005B0792 49 89 CE mov r14, rcx
__text:00000001005B0795 49 89 D7 mov r15, rdx
__text:00000001005B0798 49 89 F4 mov r12, rsi
__text:00000001005B079B BF D0 0A 00 00 mov edi, 0AD0h ; unsigned __int64
__text:00000001005B07A0 E8 D7 4E 23 00 call __Znwm ; operator new(ulong)
__text:00000001005B07A5 48 89 C3 mov rbx, rax
__text:00000001005B07A8 48 89 45 A0 mov [rbp+var_60], rax
__text:00000001005B07AC 0F 28 05 DD 8F 38 00 movaps xmm0, cs:xmmword_100939790
__text:00000001005B07B3 0F 29 45 90 movaps [rbp+var_70], xmm0
__text:00000001005B07B7 48 8D 35 58 8F 31 00 lea rsi, aBeginCertifica ; "-----BEGIN CERTIFICATE-----\nMIIHzTCCBb"...
__text:00000001005B07BE BA CC 0A 00 00 mov edx, 0ACCh ; __n
__text:00000001005B07C3 48 89 C7 mov rdi, rax ; __dst
__text:00000001005B07C6 E8 3D 53 23 00 call _memcpy
__text:00000001005B07CB C6 83 CC 0A 00 00 00 mov byte ptr [rbx+0ACCh], 0
__text:00000001005B07D2 48 8D BD 48 FF FF FF lea rdi, [rbp+var_B8]
__text:00000001005B07D9 48 8D 75 90 lea rsi, [rbp+var_70]
__text:00000001005B07DD E8 CE 07 00 00 call sub_1005B0FB0
__text:00000001005B07E2 F6 45 90 01 test byte ptr [rbp+var_70], 1
__text:00000001005B07E6 74 09 jz short loc_1005B07F1
__text:00000001005B07E8 48 8B 7D A0 mov rdi, [rbp+var_60] ; void *
__text:00000001005B07EC E8 61 4E 23 00 call __ZdlPv ; operator delete(void *)
__text:00000001005B07F1
```
after
```
__text:00000001005B0780 sub_1005B0780 proc near ; DATA XREF: __const:00000001009B2A90↓o
__text:00000001005B0780 6A 01 push 1
__text:00000001005B0782 58 pop rax
__text:00000001005B0783 C3 retn
__text:00000001005B0783 sub_1005B0780 endp
```
arm64
```
__text:00000001005DE584 FF 03 03 D1 SUB SP, SP, #0xC0
__text:00000001005DE588 F6 57 09 A9 STP X22, X21, [SP,#0xB0+var_20]
__text:00000001005DE58C F4 4F 0A A9 STP X20, X19, [SP,#0xB0+var_10]
__text:00000001005DE590 FD 7B 0B A9 STP X29, X30, [SP,#0xB0+var_s0]
__text:00000001005DE594 FD C3 02 91 ADD X29, SP, #0xB0
__text:00000001005DE598 F3 03 03 AA MOV X19, X3
__text:00000001005DE59C F4 03 02 AA MOV X20, X2
__text:00000001005DE5A0 F5 03 01 AA MOV X21, X1
__text:00000001005DE5A4 00 5A 81 52 MOV W0, #0xAD0 ; unsigned __int64
__text:00000001005DE5A8 70 C8 07 94 BL __Znwm ; operator new(ulong)
__text:00000001005DE5AC F6 03 00 AA MOV X22, X0
__text:00000001005DE5B0 E0 2B 00 F9 STR X0, [SP,#0xB0+var_60]
__text:00000001005DE5B4 E8 10 00 B0 ADRP X8, #xmmword_1007FB2D0@PAGE
__text:00000001005DE5B8 00 B5 C0 3D LDR Q0, [X8,#xmmword_1007FB2D0@PAGEOFF]
__text:00000001005DE5BC E0 83 85 3C STUR Q0, [SP,#0xB0+var_58]
__text:00000001005DE5C0 C1 18 00 F0 21 84 25 91 ADRL X1, aBeginCertifica ; "-----BEGIN CERTIFICATE-----\nMIIHzTCCBb"...
__text:00000001005DE5C8 82 59 81 52 MOV W2, #0xACC ; __n
__text:00000001005DE5CC A7 CA 07 94 BL _memcpy
__text:00000001005DE5D0 DF 32 2B 39 STRB WZR, [X22,#0xACC]
__text:00000001005DE5D4 A0 23 01 D1 SUB X0, X29, #-var_48
__text:00000001005DE5D8 E1 43 01 91 ADD X1, SP, #0xB0+var_60
__text:00000001005DE5DC 00 02 00 94 BL j___ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEC1ERKS5_ ; std::string::basic_string(std::string const&)
__text:00000001005DE5E0 E8 9F C1 39 LDRSB W8, [SP,#0xB0+var_58+0xF]
__text:00000001005DE5E4 68 00 F8 36 TBZ W8, #0x1F, loc_1005DE5F0
__text:00000001005DE5E8 E0 2B 40 F9 LDR X0, [SP,#0xB0+var_60] ; void *
__text:00000001005DE5EC 4A C8 07 94 BL __ZdlPv ; operator delete(void *)
__text:00000001005DE5F0
```
after
```
__text:00000001005DE584 sub_1005DE584 ; DATA XREF: __const:0000000100988540↓o
__text:00000001005DE584 20 00 80 D2 MOV X0, #1
__text:00000001005DE588 C0 03 5F D6 RET
__text:00000001005DE588 ; End of function sub_1005DE584
```

View File

@ -1,53 +1,39 @@
# Parallels Desktop Crack
Crack for Parallels Desktop.
Crack for Parallels Desktop 18.0.1-53056
- [x] Support Intel
- [ ] Support Apple Silicon (M1)
- [ ] Network
- [ ] USB
- [x] Support Apple Silicon (M1)
- [x] Network
- [x] USB
# Apple Silicon (M1) & Network & USB problem
# Usage
Parallels Desktop new version use Apple's hypervisor framework vmnet API need a paid Developer ID and request to Apple enable vmnet access permission.
run install.sh
Parallels Desktop M1 version only support Apple's hypervisor framework.
# Manual
I don't know how to bypass it. So this crack version not support M1.
But Intel version have a temp solution:
1. Exit Parallels Desktop
```
killall -9 prl_client_app
sudo sed -i '' 's|<UseKextless>.*</UseKextless>|<UseKextless>0</UseKextless>|' /Library/Preferences/Parallels/network.desktop.xml
sudo sed -i '' 's|<Usb>.*</Usb>|<Usb>1</Usb>|' /Library/Preferences/Parallels/dispatcher.desktop.xml
killall -9 prl_disp_service
```
After this, network will work, USB only work with storage device.
# Build
2. Copy crack file
```
./scripts/build.bat
sudo copy -f prl_disp_service "/Applications/Parallels Desktop.app/Contents/MacOS/Parallels Service.app/Contents/MacOS/prl_disp_service"
```
# Install & Test
3. Copy licenses.json
```
sudo ./scripts/install.sh
sudo echo '{"license":"{\\"product_version\\":\\"18.*\\",\\"edition\\":2,\\"platform\\":3,\\"product\\":7,\\"offline\\":true,\\"cpu_limit\\":32,\\"ram_limit\\":131072}"}' > "/Library/Preferences/Parallels/licenses.json"
```
# Publish DMG
4. Sign
```
brew install create-dmg
./scripts/publish.sh
sudo codesign -f -s - --timestamp=none --all-architectures --entitlements ParallelsService.entitlements "/Applications/Parallels Desktop.app/Contents/MacOS/Parallels Service.app/Contents/MacOS/prl_disp_service"
```
You can found packaged dmg file in `publish` folder.
Good Luck!

View File

@ -1,12 +0,0 @@
#!/bin/bash
CUR_PATH=$(cd "$(dirname $(readlink -f "$0"))" && pwd)
ROOT_PATH=$(cd "${CUR_PATH}/../" && pwd)
cmake -S "${ROOT_PATH}" -B "${ROOT_PATH}/build" \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_OSX_ARCHITECTURES="x86_64;arm64" \
-DCMAKE_OSX_DEPLOYMENT_TARGET="11.0" \
&& \
cmake --build "${ROOT_PATH}/build" --target UIWarp -j8 \
&& echo "[*] Build Success"

Binary file not shown.

View File

@ -4,17 +4,10 @@ CUR_PATH=$(cd "$(dirname $(readlink -f "$0"))" && pwd)
ROOT_PATH=$(cd "${CUR_PATH}/../" && pwd)
PTFM_APP_DIR="/Applications/Parallels Toolbox.app"
PDFM_APP_DIR="/Applications/Parallels Desktop.app"
CRACK_LIB="${ROOT_PATH}/build/libUIWarp.dylib"
CRACK_LIB_DST_NAME="libUIWarp"
CODESIGN_CERT=-
if [ -n "$(security find-identity -v -p codesigning | grep 6E7BDDB56DD3D9C35A1EAFC787040ADF426EE7F2)" ]; then
CODESIGN_CERT=6E7BDDB56DD3D9C35A1EAFC787040ADF426EE7F2
fi
function sign_cmd() {
codesign -f -s ${CODESIGN_CERT} --all-architectures --deep "$@"
codesign -f -s ${CODESIGN_CERT} --timestamp=none --all-architectures --deep "$@"
}
function kill_ptfm_app() {
@ -25,135 +18,25 @@ function kill_pdfm_app() {
killall -9 prl_client_app 2> /dev/null
}
function apply_ptfm_crack() {
echo "[*] Apply patch"
if [ -f /usr/local/opt/llvm/bin/llvm-strip ]; then
/usr/local/opt/llvm/bin/llvm-strip -s "${CRACK_LIB}" > /dev/null
fi
RPATH="@rpath/${CRACK_LIB_DST_NAME}.dylib"
DST="${PTFM_APP_DIR}/Contents/Frameworks/${CRACK_LIB_DST_NAME}.dylib"
LOADER="${PTFM_APP_DIR}/Contents/Frameworks/libLogging.dylib"
if ! grep -q "${RPATH}" "${LOADER}"; then
echo "[*] insert_dylib \"${LOADER}\""
"${CUR_PATH}/insert_dylib" --inplace --overwrite --no-strip-codesig --all-yes \
"${RPATH}" "${LOADER}" > /dev/null
fi
echo "[*] Copy \"${CRACK_LIB}\" to \"${DST}\""
cp -f -X "${CRACK_LIB}" "${DST}" > /dev/null
}
function apply_pdfm_crack() {
echo "[*] Apply patch"
if [ -f /usr/local/opt/llvm/bin/llvm-strip ]; then
/usr/local/opt/llvm/bin/llvm-strip -s "${CRACK_LIB}" > /dev/null
fi
SRC="${ROOT_PATH}/crack/pdfm-18.0.1.53056/prl_client_app"
DST="${PDFM_TMP_DIR}/Parallels Desktop.app/Contents/MacOS/prl_client_app"
echo "[*] Copy \"${SRC}\" to \"${DST}\""
cp -f -X "${SRC}" "${DST}" > /dev/null
RPATH="@rpath/${CRACK_LIB_DST_NAME}.dylib"
DST="${PDFM_APP_DIR}/Contents/Frameworks/${CRACK_LIB_DST_NAME}.dylib"
LOADER="${PDFM_APP_DIR}/Contents/Frameworks/QtXml.framework/Versions/5/QtXml"
if ! grep -q "${RPATH}" "${LOADER}"; then
echo "[*] insert_dylib \"${LOADER}\""
"${CUR_PATH}/insert_dylib" --inplace --overwrite --no-strip-codesig --all-yes \
"${RPATH}" "${LOADER}" > /dev/null
fi
echo "[*] Copy \"${CRACK_LIB}\" to \"${DST}\""
cp -f -X "${CRACK_LIB}" "${DST}" > /dev/null
}
function sign_ptfm() {
echo "[*] Sign Parallels Toolbox App"
sign_cmd "${PTFM_APP_DIR}/Contents/Applications/Airplane Mode.app"
sign_cmd "${PTFM_APP_DIR}/Contents/Applications/Alarm.app"
sign_cmd "${PTFM_APP_DIR}/Contents/Applications/Archive.app"
sign_cmd "${PTFM_APP_DIR}/Contents/Applications/Barcode Generator.app"
sign_cmd "${PTFM_APP_DIR}/Contents/Applications/Barcode Reader.app"
sign_cmd "${PTFM_APP_DIR}/Contents/Applications/Break Time.app"
sign_cmd "${PTFM_APP_DIR}/Contents/Applications/CPU Temperature.app"
sign_cmd "${PTFM_APP_DIR}/Contents/Applications/Capture Area.app"
sign_cmd "${PTFM_APP_DIR}/Contents/Applications/Capture Screen.app"
sign_cmd "${PTFM_APP_DIR}/Contents/Applications/Capture Window.app"
sign_cmd "${PTFM_APP_DIR}/Contents/Applications/Clean Drive.app"
sign_cmd "${PTFM_APP_DIR}/Contents/Applications/Clipboard History.app"
sign_cmd "${PTFM_APP_DIR}/Contents/Applications/Convert Video.app"
sign_cmd "${PTFM_APP_DIR}/Contents/Applications/Date Countdown.app"
sign_cmd "${PTFM_APP_DIR}/Contents/Applications/Do Not Disturb.app"
sign_cmd "${PTFM_APP_DIR}/Contents/Applications/Do Not Sleep.app"
sign_cmd "${PTFM_APP_DIR}/Contents/Applications/Download Audio.app"
sign_cmd "${PTFM_APP_DIR}/Contents/Applications/Download Video.app"
sign_cmd "${PTFM_APP_DIR}/Contents/Applications/Eject Volumes.app"
sign_cmd "${PTFM_APP_DIR}/Contents/Applications/Encrypt Files.app"
sign_cmd "${PTFM_APP_DIR}/Contents/Applications/Energy Saver.app"
sign_cmd "${PTFM_APP_DIR}/Contents/Applications/Find Duplicates.app"
sign_cmd "${PTFM_APP_DIR}/Contents/Applications/Focus on Window.app"
sign_cmd "${PTFM_APP_DIR}/Contents/Applications/Free Memory.app"
sign_cmd "${PTFM_APP_DIR}/Contents/Applications/Hidden Files.app"
sign_cmd "${PTFM_APP_DIR}/Contents/Applications/Hide Desktop Files.app"
sign_cmd "${PTFM_APP_DIR}/Contents/Applications/Hide Menu Icons.app"
sign_cmd "${PTFM_APP_DIR}/Contents/Applications/Launch.app"
sign_cmd "${PTFM_APP_DIR}/Contents/Applications/Lock Screen.app"
sign_cmd "${PTFM_APP_DIR}/Contents/Applications/Make GIF.app"
sign_cmd "${PTFM_APP_DIR}/Contents/Applications/Mute Microphone.app"
sign_cmd "${PTFM_APP_DIR}/Contents/Applications/Parallels Tool Launcher.app"
sign_cmd "${PTFM_APP_DIR}/Contents/Applications/Presentation Mode.app"
sign_cmd "${PTFM_APP_DIR}/Contents/Applications/Recognize Text.app"
sign_cmd "${PTFM_APP_DIR}/Contents/Applications/Record Area.app"
sign_cmd "${PTFM_APP_DIR}/Contents/Applications/Record Audio.app"
sign_cmd "${PTFM_APP_DIR}/Contents/Applications/Record Screen.app"
sign_cmd "${PTFM_APP_DIR}/Contents/Applications/Record Window.app"
sign_cmd "${PTFM_APP_DIR}/Contents/Applications/Resize Images.app"
sign_cmd "${PTFM_APP_DIR}/Contents/Applications/Screenshot Page.app"
sign_cmd "${PTFM_APP_DIR}/Contents/Applications/Show Desktop.app"
sign_cmd "${PTFM_APP_DIR}/Contents/Applications/Sleep Timer.app"
sign_cmd "${PTFM_APP_DIR}/Contents/Applications/Stopwatch.app"
sign_cmd "${PTFM_APP_DIR}/Contents/Applications/Switch Resolution.app"
sign_cmd "${PTFM_APP_DIR}/Contents/Applications/Take Photo.app"
sign_cmd "${PTFM_APP_DIR}/Contents/Applications/Take Video.app"
sign_cmd "${PTFM_APP_DIR}/Contents/Applications/Timer.app"
sign_cmd "${PTFM_APP_DIR}/Contents/Applications/Transform Text.app"
sign_cmd "${PTFM_APP_DIR}/Contents/Applications/Unarchive.app"
sign_cmd "${PTFM_APP_DIR}/Contents/Applications/Uninstall Apps.app"
sign_cmd "${PTFM_APP_DIR}/Contents/Applications/Unit Converter.app"
sign_cmd "${PTFM_APP_DIR}/Contents/Applications/Verify Checksum.app"
sign_cmd "${PTFM_APP_DIR}/Contents/Applications/Window Manager.app"
sign_cmd "${PTFM_APP_DIR}/Contents/Applications/World Time.app"
sign_cmd "${PTFM_APP_DIR}/Parallels Toolbox.app"
SRC="${ROOT_PATH}/crack/pdfm-18.0.1.53056/prl_disp_service"
DST="${PDFM_TMP_DIR}/Parallels Desktop.app/Contents/MacOS/Parallels Service.app/Contents/MacOS/prl_disp_service"
echo "[*] Copy \"${SRC}\" to \"${DST}\""
cp -f -X "${SRC}" "${DST}" > /dev/null
}
function sign_pdfm() {
echo "[*] Sign Parallels Desktop App"
sign_cmd "${PDFM_APP_DIR}/Contents/Library/QuickLook/ExeQL.qlgenerator"
sign_cmd "${PDFM_APP_DIR}/Contents/Library/QuickLook/ParallelsQL.qlgenerator"
sign_cmd "${PDFM_APP_DIR}/Contents/Resources/launchd_wrapper"
sign_cmd "${PDFM_APP_DIR}/Contents/Resources/libprl_shared_apps.dylib"
sign_cmd "${PDFM_APP_DIR}/Contents/Resources/lua/ssl.so"
sign_cmd "${PDFM_APP_DIR}/Contents/Resources/lua/mime/core.so"
sign_cmd "${PDFM_APP_DIR}/Contents/Resources/lua/socket/core.so"
sign_cmd "${PDFM_APP_DIR}/Contents/Resources/lua/socket/serial.so"
sign_cmd "${PDFM_APP_DIR}/Contents/Resources/lua/socket/unix.so"
sign_cmd "${PDFM_APP_DIR}/Contents/Applications/Parallels Link.app"
sign_cmd "${PDFM_APP_DIR}/Contents/Applications/Parallels Mounter.app"
sign_cmd "${PDFM_APP_DIR}/Contents/Applications/Parallels Technical Data Reporter.app"
sign_cmd --entitlements "${ROOT_PATH}/entitlements/ParallelsDesktop/ParallelsMacVM.entitlements" "${PDFM_APP_DIR}/Contents/MacOS/Parallels Mac VM.app"
sign_cmd --entitlements "${ROOT_PATH}/entitlements/ParallelsDesktop/ParallelsService.entitlements" "${PDFM_APP_DIR}/Contents/MacOS/Parallels Service.app"
sign_cmd --entitlements "${ROOT_PATH}/entitlements/ParallelsDesktop/ParallelsVM1014.entitlements" "${PDFM_APP_DIR}/Contents/MacOS/Parallels VM 10.14.app"
sign_cmd --entitlements "${ROOT_PATH}/entitlements/ParallelsDesktop/ParallelsVM.entitlements" "${PDFM_APP_DIR}/Contents/MacOS/Parallels VM.app"
sign_cmd --entitlements "${ROOT_PATH}/entitlements/ParallelsDesktop/ParallelsDesktop.entitlements" "${PDFM_APP_DIR}"
sign_cmd --entitlements "${ROOT_PATH}/entitlements/ParallelsDesktop/ParallelsService.entitlements" "${PDFM_APP_DIR}/Contents/MacOS/Parallels Service.app/Contents/MacOS/prl_disp_service"
}
if [ -d "${PTFM_APP_DIR}" ]; then
echo "[*] Install Parallels Toolbox patch"
kill_ptfm_app
apply_ptfm_crack
sign_ptfm
else
echo "[*] not found ${PTFM_APP_DIR}, skip."
fi
if [ -d "${PDFM_APP_DIR}" ]; then
echo "[*] Install Parallels Desktop patch"
kill_pdfm_app

View File

@ -22,18 +22,11 @@ PDFM_PUBLISH_FILE="${PUBLISH_PATH}/ParallelsDesktop-${PDFM_VERSION}_Crack.dmg"
CODESIGN_CERT=-
if [ -n "$(security find-identity -v -p codesigning | grep 6E7BDDB56DD3D9C35A1EAFC787040ADF426EE7F2)" ]; then
CODESIGN_CERT=6E7BDDB56DD3D9C35A1EAFC787040ADF426EE7F2
fi
CRACK_LIB_DST_NAME="libUIWarp"
CRACK_LIB="${ROOT_PATH}/build/${CRACK_LIB_DST_NAME}.dylib"
PTFM_TMP_DIR="${TEMP_PATH}/ptfm_files"
PDFM_TMP_DIR="${TEMP_PATH}/pdfm_files"
function sign_cmd() {
codesign -f -s ${CODESIGN_CERT} --all-architectures --deep "$@"
codesign -f -s ${CODESIGN_CERT} --timestamp=none --all-architectures --deep "$@"
}
function ensure_download_ptfm_dmg() {
@ -123,25 +116,14 @@ function apply_ptfm_crack() {
function apply_pdfm_crack() {
echo "[*] Apply patch"
if [ -f /usr/local/opt/llvm/bin/llvm-strip ]; then
/usr/local/opt/llvm/bin/llvm-strip -s "${CRACK_LIB}" > /dev/null
fi
RPATH="@rpath/${CRACK_LIB_DST_NAME}.dylib"
DST="${PDFM_TMP_DIR}/Parallels Desktop.app/Contents/Frameworks/${CRACK_LIB_DST_NAME}.dylib"
LOADER="${PDFM_TMP_DIR}/Parallels Desktop.app/Contents/Frameworks/QtXml.framework/Versions/5/QtXml"
"${CUR_PATH}/insert_dylib" --inplace --overwrite --no-strip-codesig --all-yes \
"${RPATH}" "${LOADER}" > /dev/null
cp -f -X "${CRACK_LIB}" "${DST}" > /dev/null
SRC="${ROOT_PATH}/crack/pdfm-18.0.1.53056/prl_client_app"
DST="${PDFM_TMP_DIR}/Parallels Desktop.app/Contents/MacOS/prl_client_app"
echo "[*] Copy \"${SRC}\" to \"${DST}\""
cp -f -X "${SRC}" "${DST}" > /dev/null
SRC="${ROOT_PATH}/crack/pdfm-18.0.1.53056/prl_disp_service"
DST="${PDFM_TMP_DIR}/Parallels Desktop.app/Contents/MacOS/Parallels Service.app/Contents/MacOS/prl_disp_service"
echo "[*] Copy \"${SRC}\" to \"${DST}\""
cp -f -X "${SRC}" "${DST}" > /dev/null
}
@ -207,25 +189,8 @@ function sign_ptfm() {
function sign_pdfm() {
echo "[*] Sign Parallels Desktop App"
sign_cmd "${PDFM_TMP_DIR}/Parallels Desktop.app/Contents/Library/QuickLook/ExeQL.qlgenerator"
sign_cmd "${PDFM_TMP_DIR}/Parallels Desktop.app/Contents/Library/QuickLook/ParallelsQL.qlgenerator"
sign_cmd "${PDFM_TMP_DIR}/Parallels Desktop.app/Contents/Resources/launchd_wrapper"
sign_cmd "${PDFM_TMP_DIR}/Parallels Desktop.app/Contents/Resources/libprl_shared_apps.dylib"
sign_cmd "${PDFM_TMP_DIR}/Parallels Desktop.app/Contents/Resources/lua/ssl.so"
sign_cmd "${PDFM_TMP_DIR}/Parallels Desktop.app/Contents/Resources/lua/mime/core.so"
sign_cmd "${PDFM_TMP_DIR}/Parallels Desktop.app/Contents/Resources/lua/socket/core.so"
sign_cmd "${PDFM_TMP_DIR}/Parallels Desktop.app/Contents/Resources/lua/socket/serial.so"
sign_cmd "${PDFM_TMP_DIR}/Parallels Desktop.app/Contents/Resources/lua/socket/unix.so"
sign_cmd "${PDFM_TMP_DIR}/Parallels Desktop.app/Contents/Applications/Parallels Link.app"
sign_cmd "${PDFM_TMP_DIR}/Parallels Desktop.app/Contents/Applications/Parallels Mounter.app"
sign_cmd "${PDFM_TMP_DIR}/Parallels Desktop.app/Contents/Applications/Parallels Technical Data Reporter.app"
sign_cmd --entitlements "${ROOT_PATH}/entitlements/ParallelsDesktop/ParallelsMacVM.entitlements" "${PDFM_TMP_DIR}/Parallels Desktop.app/Contents/MacOS/Parallels Mac VM.app"
sign_cmd --entitlements "${ROOT_PATH}/entitlements/ParallelsDesktop/ParallelsService.entitlements" "${PDFM_TMP_DIR}/Parallels Desktop.app/Contents/MacOS/Parallels Service.app"
sign_cmd --entitlements "${ROOT_PATH}/entitlements/ParallelsDesktop/ParallelsVM1014.entitlements" "${PDFM_TMP_DIR}/Parallels Desktop.app/Contents/MacOS/Parallels VM 10.14.app"
sign_cmd --entitlements "${ROOT_PATH}/entitlements/ParallelsDesktop/ParallelsVM.entitlements" "${PDFM_TMP_DIR}/Parallels Desktop.app/Contents/MacOS/Parallels VM.app"
sign_cmd --entitlements "${ROOT_PATH}/entitlements/ParallelsDesktop/ParallelsDesktop.entitlements" "${PDFM_TMP_DIR}/Parallels Desktop.app"
sign_cmd --entitlements "${ROOT_PATH}/entitlements/ParallelsDesktop/ParallelsDesktop.entitlements" "${PDFM_TMP_DIR}/Parallels Desktop.app"
sign_cmd "${PDFM_TMP_DIR}/Install.app"
sign_cmd --entitlements "${ROOT_PATH}/entitlements/ParallelsDesktop/ParallelsService.entitlements" "${PDFM_TMP_DIR}/Parallels Desktop.app/Contents/MacOS/Parallels Service.app/Contents/MacOS/prl_disp_service"
sign_cmd --entitlements "${ROOT_PATH}/entitlements/ParallelsDesktop/ParallelsService.entitlements" "${PDFM_TMP_DIR}/Parallels Desktop.app/Contents/MacOS/Parallels Service.app/Contents/MacOS/prl_disp_service"
}
function set_pdfm_app_hide() {

View File

@ -1,10 +0,0 @@
#!/bin/bash
CUR_PATH=$(cd "$(dirname $(readlink -f "$0"))" && pwd)
ROOT_PATH=$(cd "${CUR_PATH}/../" && pwd)
if [ -d "${ROOT_PATH}/build" ]; then
rm -rf "${ROOT_PATH}/build" > /dev/null
fi
exec "${CUR_PATH}/build.sh"

View File

@ -1,336 +0,0 @@
// 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();
}

View File

@ -1,242 +0,0 @@
/*
* Copyright 2017 - 2021 Justas Masiulis
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef JM_XORSTR_HPP
#define JM_XORSTR_HPP
#if defined(_M_ARM64) || defined(__aarch64__) || defined(_M_ARM) || defined(__arm__)
#include <arm_neon.h>
#elif defined(_M_X64) || defined(__amd64__) || defined(_M_IX86) || defined(__i386__)
#include <immintrin.h>
#else
#error Unsupported platform
#endif
#include <cstdint>
#include <cstddef>
#include <utility>
#include <type_traits>
#define xorstr(str) ::OqYAfkhl::swG([]() { return str; }, std::integral_constant<std::size_t, sizeof(str) / sizeof(*str)>{}, std::make_index_sequence<::OqYAfkhl::CtKWt::UfWL<sizeof(str)>()>{})
#define xorstr_(str) xorstr(str).Pr()
#ifdef _MSC_VER
#define XORSTR_FORCEINLINE __forceinline
#else
#define XORSTR_FORCEINLINE __attribute__((always_inline)) inline
#endif
namespace OqYAfkhl {
namespace CtKWt {
template<std::size_t Size>
XORSTR_FORCEINLINE constexpr std::size_t UfWL()
{
return ((Size / 16) + (Size % 16 != 0)) * 2;
}
template<std::uint32_t Seed>
XORSTR_FORCEINLINE constexpr std::uint32_t rY() noexcept
{
std::uint32_t value = Seed;
for(char c : __TIME__)
value = static_cast<std::uint32_t>((value ^ c) * 16777619ull);
return value;
}
template<std::size_t S>
XORSTR_FORCEINLINE constexpr std::uint64_t WL()
{
constexpr auto first_part = rY<2166136261 + S>();
constexpr auto second_part = rY<first_part>();
return (static_cast<std::uint64_t>(first_part) << 32) | second_part;
}
// loads up to 8 characters of string into uint64 and xors it with the key
template<std::size_t N, class CharT>
XORSTR_FORCEINLINE constexpr std::uint64_t
EE(std::uint64_t key, std::size_t idx, const CharT* str) noexcept
{
using cast_type = typename std::make_unsigned<CharT>::type;
constexpr auto value_size = sizeof(CharT);
constexpr auto idx_offset = 8 / value_size;
std::uint64_t value = key;
for(std::size_t i = 0; i < idx_offset && i + idx * idx_offset < N; ++i)
value ^=
(std::uint64_t{ static_cast<cast_type>(str[i + idx * idx_offset]) }
<< ((i % idx_offset) * 8 * value_size));
return value;
}
// forces compiler to use registers instead of stuffing constants in rdata
XORSTR_FORCEINLINE std::uint64_t Fw(std::uint64_t value) noexcept
{
#if defined(__clang__) || defined(__GNUC__)
asm("" : "=r"(value) : "0"(value) :);
return value;
#else
volatile std::uint64_t reg = value;
return reg;
#endif
}
} // namespace detail
template<class CharT, std::size_t Size, class Keys, class Indices>
class swG;
template<class CharT, std::size_t Size, std::uint64_t... Keys, std::size_t... Indices>
class swG<CharT, Size, std::integer_sequence<std::uint64_t, Keys...>, std::index_sequence<Indices...>> {
#ifndef JM_XORSTR_DISABLE_AVX_INTRINSICS
constexpr static inline std::uint64_t alignment = ((Size > 16) ? 32 : 16);
#else
constexpr static inline std::uint64_t alignment = 16;
#endif
alignas(alignment) std::uint64_t _storage[sizeof...(Keys)];
public:
using value_type = CharT;
using size_type = std::size_t;
using pointer = CharT*;
using const_pointer = const CharT*;
template<class L>
XORSTR_FORCEINLINE swG(L l, std::integral_constant<std::size_t, Size>, std::index_sequence<Indices...>) noexcept
: _storage{ ::OqYAfkhl::CtKWt::Fw((std::integral_constant<std::uint64_t, CtKWt::EE<Size>(Keys, Indices, l())>::value))... }
{}
XORSTR_FORCEINLINE constexpr size_type size() const noexcept
{
return Size - 1;
}
XORSTR_FORCEINLINE void fO() noexcept
{
// everything is inlined by hand because a certain compiler with a certain linker is _very_ slow
#if defined(__clang__)
alignas(alignment)
std::uint64_t arr[]{ ::OqYAfkhl::CtKWt::Fw(Keys)... };
std::uint64_t* keys =
(std::uint64_t*)::OqYAfkhl::CtKWt::Fw((std::uint64_t)arr);
#else
alignas(alignment) std::uint64_t keys[]{ ::OqYAfkhl::CtKWt::Fw(Keys)... };
#endif
#if defined(_M_ARM64) || defined(__aarch64__) || defined(_M_ARM) || defined(__arm__)
#if defined(__clang__)
((Indices >= sizeof(_storage) / 16 ? static_cast<void>(0) : __builtin_neon_vst1q_v(
reinterpret_cast<uint64_t*>(_storage) + Indices * 2,
veorq_u64(__builtin_neon_vld1q_v(reinterpret_cast<const uint64_t*>(_storage) + Indices * 2, 51),
__builtin_neon_vld1q_v(reinterpret_cast<const uint64_t*>(keys) + Indices * 2, 51)),
51)), ...);
#else // GCC, MSVC
((Indices >= sizeof(_storage) / 16 ? static_cast<void>(0) : vst1q_u64(
reinterpret_cast<uint64_t*>(_storage) + Indices * 2,
veorq_u64(vld1q_u64(reinterpret_cast<const uint64_t*>(_storage) + Indices * 2),
vld1q_u64(reinterpret_cast<const uint64_t*>(keys) + Indices * 2)))), ...);
#endif
#elif !defined(JM_XORSTR_DISABLE_AVX_INTRINSICS)
((Indices >= sizeof(_storage) / 32 ? static_cast<void>(0) : _mm256_store_si256(
reinterpret_cast<__m256i*>(_storage) + Indices,
_mm256_xor_si256(
_mm256_load_si256(reinterpret_cast<const __m256i*>(_storage) + Indices),
_mm256_load_si256(reinterpret_cast<const __m256i*>(keys) + Indices)))), ...);
if constexpr(sizeof(_storage) % 32 != 0)
_mm_store_si128(
reinterpret_cast<__m128i*>(_storage + sizeof...(Keys) - 2),
_mm_xor_si128(_mm_load_si128(reinterpret_cast<const __m128i*>(_storage + sizeof...(Keys) - 2)),
_mm_load_si128(reinterpret_cast<const __m128i*>(keys + sizeof...(Keys) - 2))));
#else
((Indices >= sizeof(_storage) / 16 ? static_cast<void>(0) : _mm_store_si128(
reinterpret_cast<__m128i*>(_storage) + Indices,
_mm_xor_si128(_mm_load_si128(reinterpret_cast<const __m128i*>(_storage) + Indices),
_mm_load_si128(reinterpret_cast<const __m128i*>(keys) + Indices)))), ...);
#endif
}
XORSTR_FORCEINLINE const_pointer Ce() const noexcept
{
return reinterpret_cast<const_pointer>(_storage);
}
XORSTR_FORCEINLINE pointer Ce() noexcept
{
return reinterpret_cast<pointer>(_storage);
}
XORSTR_FORCEINLINE pointer Pr() noexcept
{
// fO() is inlined by hand because a certain compiler with a certain linker is _very_ slow
#if defined(__clang__)
alignas(alignment)
std::uint64_t arr[]{ ::OqYAfkhl::CtKWt::Fw(Keys)... };
std::uint64_t* keys =
(std::uint64_t*)::OqYAfkhl::CtKWt::Fw((std::uint64_t)arr);
#else
alignas(alignment) std::uint64_t keys[]{ ::OqYAfkhl::CtKWt::Fw(Keys)... };
#endif
#if defined(_M_ARM64) || defined(__aarch64__) || defined(_M_ARM) || defined(__arm__)
#if defined(__clang__)
((Indices >= sizeof(_storage) / 16 ? static_cast<void>(0) : __builtin_neon_vst1q_v(
reinterpret_cast<uint64_t*>(_storage) + Indices * 2,
veorq_u64(__builtin_neon_vld1q_v(reinterpret_cast<const uint64_t*>(_storage) + Indices * 2, 51),
__builtin_neon_vld1q_v(reinterpret_cast<const uint64_t*>(keys) + Indices * 2, 51)),
51)), ...);
#else // GCC, MSVC
((Indices >= sizeof(_storage) / 16 ? static_cast<void>(0) : vst1q_u64(
reinterpret_cast<uint64_t*>(_storage) + Indices * 2,
veorq_u64(vld1q_u64(reinterpret_cast<const uint64_t*>(_storage) + Indices * 2),
vld1q_u64(reinterpret_cast<const uint64_t*>(keys) + Indices * 2)))), ...);
#endif
#elif !defined(JM_XORSTR_DISABLE_AVX_INTRINSICS)
((Indices >= sizeof(_storage) / 32 ? static_cast<void>(0) : _mm256_store_si256(
reinterpret_cast<__m256i*>(_storage) + Indices,
_mm256_xor_si256(
_mm256_load_si256(reinterpret_cast<const __m256i*>(_storage) + Indices),
_mm256_load_si256(reinterpret_cast<const __m256i*>(keys) + Indices)))), ...);
if constexpr(sizeof(_storage) % 32 != 0)
_mm_store_si128(
reinterpret_cast<__m128i*>(_storage + sizeof...(Keys) - 2),
_mm_xor_si128(_mm_load_si128(reinterpret_cast<const __m128i*>(_storage + sizeof...(Keys) - 2)),
_mm_load_si128(reinterpret_cast<const __m128i*>(keys + sizeof...(Keys) - 2))));
#else
((Indices >= sizeof(_storage) / 16 ? static_cast<void>(0) : _mm_store_si128(
reinterpret_cast<__m128i*>(_storage) + Indices,
_mm_xor_si128(_mm_load_si128(reinterpret_cast<const __m128i*>(_storage) + Indices),
_mm_load_si128(reinterpret_cast<const __m128i*>(keys) + Indices)))), ...);
#endif
return (pointer)(_storage);
}
};
template<class L, std::size_t Size, std::size_t... Indices>
swG(L l, std::integral_constant<std::size_t, Size>, std::index_sequence<Indices...>) -> swG<
std::remove_const_t<std::remove_reference_t<decltype(l()[0])>>,
Size,
std::integer_sequence<std::uint64_t, CtKWt::WL<Indices>()...>,
std::index_sequence<Indices...>>;
} // namespace jm
#endif // include guard