1
0
mirror of https://github.com/opa334/TrollStore.git synced 2025-04-12 23:33:11 +08:00

Compare commits

...

110 Commits
2.0.3 ... main

Author SHA1 Message Date
opa334
d11c04666a
2.1 2024-09-02 13:27:04 +02:00
alfiecg24
1092d91b5d 2.0.15 2024-03-30 17:31:09 +00:00
alfiecg24
8e9b3caa93 Fix broken error output 2024-03-30 17:24:27 +00:00
alfiecg24
4d8982545d Allow specifying binary paths for persistence helper 2024-03-30 12:08:58 +00:00
alfiecg24
e6b5c000a9 2.0.14 2024-03-27 22:39:42 +00:00
Lars Fröder
f7f69684ae
Merge pull request #753 from luken11/signing-fast-path-v2
Fix inaccurate exploit type identification
2024-03-23 22:20:16 +01:00
Luke Noble
815145f922
Fix inaccurate exploit type identification 2024-03-23 19:37:15 +00:00
alfiecg24
2e646919f6 ldid and CoreTrust bypass used the same error code 2024-03-22 21:50:21 +00:00
alfiecg24
ac42b6b6c0 Don't print if there is no pre-applied exploit 2024-03-22 21:46:18 +00:00
alfiecg24
976f3596d5 2.0.13 2024-03-03 09:16:06 +00:00
opa334
75ad067562 Fix intendation 2024-03-02 20:35:47 +01:00
Alfie CG
afd09b7838
Merge pull request #732 from TheMasterOfMike/main
Account for 16.7 RC in determinePlatformVulnerableExploitTypes
2024-02-16 01:07:16 +00:00
Michael
8ddfe1361c
Account for 16.7 RC in determinePlatformVulnerableExploitTypes
this is completely untested and is probably not entirely needed, but it avoids 16.7 RC falling back to fallback behavior (which should still work fine but shouldn't be necessary on 16.7 RC anyways?
2024-02-15 19:05:15 -06:00
Lars Fröder
c2073db982
Merge pull request #709 from QuanTrieuPCYT/patch-1
Update URL schemes supported version in readme
2024-02-13 10:22:28 +01:00
alfiecg24
00887a9145 Support new ChOma signing method 2024-02-09 20:13:18 +00:00
alfiecg24
09957974ba Forgot to add this check to fastPathSign 2024-02-09 19:58:29 +00:00
opa334
3913abfd8d Add skip-uicache option 2024-02-01 22:46:06 +01:00
alfiecg24
600193f7b4 Bump ChOma version 2024-02-01 21:42:51 +00:00
alfiecg24
11eb142d3b Fix signing unsupported MachO types 2024-02-01 21:40:23 +00:00
Alfie CG
ac24773858
Merge pull request #716 from TheMasterOfMike/main
App Store Fast Path wasn't introduced until 14.0 beta 2
2024-01-30 07:49:03 +00:00
Michael
0bfc1179a0
App Store Fast Path wasn't introduced until 14.0 beta 2
I love when stuff is made even more complicated

(yes there are people still on 14.0 beta 1, yes this distinction is warranted, yes it could probably be done better - I'm not sure how best to format that beta 1 is not supported, but I felt this is the easy way out in regards to doing so)
2024-01-30 01:05:28 -06:00
QuanTrieuPCYT
f912ffc31e
wording changes 2024-01-27 22:50:09 +07:00
QuanTrieuPCYT
b24652afcb
Update URL schemes supported version in readme 2024-01-27 09:09:56 +07:00
opa334
5b467392e5 2.0.12 2024-01-27 01:53:38 +01:00
opa334
1264e022c4 Fix style 2024-01-27 01:52:58 +01:00
opa334
f98b2a2094 Reload icons on app (un)install 2024-01-27 01:49:53 +01:00
opa334
0d5b72b19d Update README, update credits 2024-01-27 01:27:40 +01:00
opa334
79250bc7fb Dynamically get libarchive include path 2024-01-26 16:47:29 +01:00
Lars Fröder
fdc4caba03
Merge pull request #672 from L1ghtmann/main
Adjust libarchive include/imports
2024-01-26 16:46:50 +01:00
Lars Fröder
e4fa7ae399
Merge pull request #525 from dlevi309/main
fixes blank view / empty launch screen
2024-01-26 16:36:00 +01:00
Lars Fröder
f21dfff284
Merge pull request #703 from khanhduytran0/main
Add an option to open app with JIT (rework)
2024-01-26 16:34:33 +01:00
khanhduytran0
b83c53cb46 Add enable-jit URL scheme endpoint 2024-01-25 20:04:24 +07:00
Duy Tran Khanh
4bfc994f70
Almost forgot this 2024-01-23 18:47:55 +07:00
khanhduytran0
647f43087c Add option to open app with JIT 2024-01-23 18:18:57 +07:00
opa334
0cc5ab1978 2.0.11 2024-01-12 21:46:52 +01:00
opa334
373c0c6add Maybe works correctly now? 2024-01-12 21:03:05 +01:00
opa334
b6579c6a09 Attempt to fix icons bugging out 2024-01-12 20:10:32 +01:00
opa334
f5a2dfae01 2.0.10 2024-01-12 18:05:47 +01:00
alfiecg24
f5a90a0899 Update alert message for encrypted binaries 2024-01-12 17:02:57 +00:00
opa334
cddfdcfed1 Improve check for main binary 2024-01-12 17:03:10 +01:00
alfiecg24
713ecf43a5 Merge branch 'main' of https://github.com/opa334/TrollStore 2024-01-12 15:56:37 +00:00
alfiecg24
d66d45fd9a Fix installing of partially-decrypted IPAs 2024-01-12 15:56:11 +00:00
Lars Fröder
ecbbc5ea20
Merge pull request #689 from ryanfortner/main
Update copyright & license to 2024
2024-01-12 16:52:40 +01:00
Ryan Fortner
9c57ababa1
Update copyright & license to 2024 2024-01-12 10:41:47 -05:00
opa334
b700590174 Actually just make ChOma a submodule, much better 2024-01-12 16:34:28 +01:00
opa334
9197bd1652 Don't defend against executables with no entitlements 2024-01-12 16:28:28 +01:00
opa334
913969ac8c Make sure to remove dylibs 2024-01-12 16:16:03 +01:00
opa334
214f279485 Improve a bit, add back libcrypto 2024-01-12 15:57:57 +01:00
opa334
3b43facaa5 Decouple ChOma from TrollStore (Can be added and updated using 'make update-choma' now) 2024-01-12 15:53:39 +01:00
opa334
206541d9f0 Update ChOma (yes this sucks) 2024-01-12 15:40:20 +01:00
opa334
2587c320d0 2.0.9 2024-01-11 20:22:05 +01:00
opa334
ae32e41bad Switch to 16.5 SDK, fix compilation error when XPC is already included 2024-01-11 20:21:33 +01:00
Alfie CG
e16fe8e1e7
Merge pull request #679 from TheMasterOfMike/main
CVE-2023-41991 is supported on 16.7 RC (20H18)
2024-01-07 13:18:50 +00:00
Michael
3d649c8d6f
Apple moment 2024-01-07 07:12:52 -06:00
Alfie CG
783ab43c3e
Merge pull request #635 from dhinakg/main
Arm developer mode if needed
2023-12-30 22:39:41 +00:00
Dhinak G
c1090cf790
Change close buttons to UIAlertActionStyleCancel 2023-12-30 14:15:26 -05:00
Dhinak G
9f9fd76310
Add FrontBoardServices to Makefiles 2023-12-30 13:40:05 -05:00
Dhinak G
fa948c0646
Fix last 2023-12-30 13:38:09 -05:00
Dhinak G
e157415304
Merge remote-tracking branch 'upstream/main' 2023-12-30 13:35:00 -05:00
Dhinak G
3474468189
Fix dev mode specifier always showing up 2023-12-30 13:32:02 -05:00
Dhinak G
eed1d42792
Fix rebooting
reboot3 requires platformization. Use FrontBoardServices to do it instead
2023-12-30 13:23:54 -05:00
Lightmann
fb5e73e82f Adjust libarchive include/imports
Theos previously provided these headers but we have since decided
against providing headers vended by their respective authors. In this
case, libarchive provides their headers in the libarchive-dev package on
Linux and the libarchive package via Homebrew/MacPorts on OSX (I think).
2023-12-23 10:52:38 -05:00
Dhinak G
28aab08dec
Fix last 2023-12-22 00:27:09 -05:00
Dhinak G
8dc50d7555
Add reboot code 2023-12-22 00:08:23 -05:00
Dhinak G
f1f42778d8
Invert output from RootHelper 2023-12-21 23:21:26 -05:00
Dhinak G
d502576e1f
Remove dev mode from app info 2023-12-21 21:39:31 -05:00
Dhinak G
afb45b110e
Fix issue in entitlement checking 2023-12-21 21:38:47 -05:00
opa334
b136e3a292 Print more info if adding to icon cache did not work 2023-12-12 15:18:47 +01:00
opa334
8cdef95733 Properly handle errors where an app cannot be added to icon cache 2023-12-12 13:21:58 +01:00
alfiecg24
bbdd0fdcdd Fix if statement that broke app installations 2023-12-10 16:10:31 +00:00
alfiecg24
16d4771621 Defend against apps with encrypted binaries 2023-12-10 15:47:58 +00:00
Dhinak G
a56bf738bd
Add in other restricted entitlements 2023-12-02 23:45:41 -05:00
Alfie CG
0759b7717a
Wrong TrollHelperOTA version range 2023-12-01 20:04:30 +00:00
Alfie CG
6a4c67c430
Update README.md to reflect version 2.0 2023-12-01 19:55:01 +00:00
Dhinak G
5eecb677a7
Document the actions 2023-11-30 20:34:56 -05:00
Dhinak G
c130a04ff5
Fix copy & paste typo 2023-11-30 20:19:06 -05:00
Dhinak G
f57326e0a4
Show developer mode status in app info 2023-11-30 19:52:00 -05:00
Dhinak G
2ac6bc280f
Add code to check and arm developer mode 2023-11-30 19:51:51 -05:00
opa334
6094bc024f 2.0.8 2023-11-29 18:47:24 +01:00
opa334
c30206b57e Fix compilation 2023-11-29 18:36:31 +01:00
Lars Fröder
c1f0677c90
Merge pull request #618 from Halo-Michael/main
Fix Network for Chinese model
2023-11-29 18:30:50 +01:00
Lars Fröder
4433ec2f97
Merge pull request #617 from eltociear/patch-1
Update TSAppInfo.m
2023-11-29 18:30:03 +01:00
Halo-Michael
c6ce29251e Remove unused entitlements 2023-11-30 01:03:25 +08:00
Halo-Michael
b90a540d1d oops 2023-11-30 00:18:50 +08:00
Ikko Eltociear Ashimine
694973fda5
Update TSAppInfo.m
arbitary -> arbitrary
2023-11-30 01:05:13 +09:00
Halo-Michael
252d489ba3 Fix Network for Chinese model 2023-11-29 23:59:10 +08:00
Lars Fröder
9daa349a68
Merge pull request #604 from luken11/signing-fast-path-v2
Add support for multi-exploit Info.plist fast path
2023-11-29 16:02:42 +01:00
Lars Fröder
d0781fb223
Merge pull request #613 from xiky/main
Update README.md
2023-11-29 16:00:26 +01:00
Livy Yao
e0ecb70a43
Update README.md 2023-11-29 19:38:28 +08:00
Luke Noble
e267749ada
Add support for multi-exploit Info.plist fast path
Deprecates TSBundlePreSigned in favour of TSPreAppliedExploitType
2023-11-28 21:44:12 +00:00
opa334
5ac7448fb8 2.0.7 2023-11-28 14:13:28 +01:00
opa334
dbaa03f8a6 Restore support for apps that have the com.apple.private.security.no-sandbox entitlement 2023-11-28 14:12:45 +01:00
opa334
8baab5e2e2 woops 2023-11-28 13:09:45 +01:00
opa334
1c4e567247 add back supported versions 2023-11-28 13:09:28 +01:00
opa334
d028cdf979 Merge branch 'main' of https://github.com/opa334/TrollStore 2023-11-28 13:08:08 +01:00
Lars Fröder
28066c580c
Merge pull request #581 from TheMasterOfMike/main
Shift installation method chart to ios.cfw.guide
2023-11-28 13:07:59 +01:00
opa334
30160e5c59 (2.0.6) One last fix 🤞 2023-11-28 12:41:53 +01:00
opa334
9e27e74fc9 2.0.6 2023-11-28 12:38:34 +01:00
opa334
18612495b3 Also update app info to be more accurate in terms of com.apple.private.security.container-required 2023-11-28 12:24:35 +01:00
opa334
a22414d34a Always prefer the string in com.apple.private.security.container-required (if it exists) to the bundle identifier when creating a data container 2023-11-28 12:17:35 +01:00
opa334
accf995dfc Sync uicache with upstream 2023-11-28 12:03:15 +01:00
opa334
1699abd9ab Fix every installed app getting assigned the same data container 2023-11-28 11:54:12 +01:00
Michael McAuliff
6b8c3fa201 Move everything to ios.cfw.guide, link there as appropriate 2023-11-28 01:48:49 -06:00
Michael
ffbd1d8a00
Make install_trollhelperota_ios15.md more accurate 2023-11-27 21:55:01 -06:00
Michael
b1d7030cc6
bump install_trollhelperota_arm64e.md to 15.6.1 2023-11-27 21:54:17 -06:00
Michael
71cfac0fa3
Start implementing updated guides
arm64 15.7.7-15.8 and arm64 16.2+ still need jailbreak-agonistic installation guides but I don't entirely understand installing it on rootless personally so I'm opting to push this off for now
2023-11-27 21:53:51 -06:00
opa334
3fe3e7f241 2.0.5 2023-11-28 03:36:02 +01:00
opa334
9abd926196 2.0.4 2023-11-28 02:59:06 +01:00
opa334
1bd49022fa Back to Security.framework on iOS 16+, apparently ldid signed binaries don't work on 16+ 2023-11-28 02:58:01 +01:00
daniel
4bc05b11b0 fixes blank view / empty launch screen 2023-09-01 16:38:41 -07:00
123 changed files with 2391 additions and 2488 deletions

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "ChOma"]
path = ChOma
url = https://github.com/opa334/ChOma

1
ChOma Submodule

@ -0,0 +1 @@
Subproject commit 964023ddac2286ef8e843f90df64d44ac6a673df

View File

@ -2,11 +2,11 @@ TARGET = fastPathSign
CC = clang
CFLAGS = -framework Foundation -framework CoreServices -framework Security -fobjc-arc $(shell pkg-config --cflags libcrypto) -Isrc/external/include
LDFLAGS = $(shell pkg-config --libs libcrypto) -Lsrc/external/lib -lchoma
CFLAGS = -framework Foundation -framework CoreServices -framework Security -fobjc-arc $(shell pkg-config --cflags libcrypto) -I../../ChOma/src
LDFLAGS = $(shell pkg-config --libs libcrypto)
$(TARGET): $(wildcard src/*.m src/*.c)
$(TARGET): $(wildcard src/*.m src/*.c ../../ChOma/src/*.c)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^
clean:
@rm -f $(TARGET)
@rm -f $(TARGET)

View File

@ -0,0 +1,259 @@
unsigned char CACert[] = {
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43,
0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d,
0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x44, 0x6d, 0x54, 0x43, 0x43,
0x41, 0x6f, 0x47, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x42,
0x41, 0x54, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47,
0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x44, 0x42, 0x44,
0x4d, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47,
0x45, 0x77, 0x4a, 0x56, 0x55, 0x7a, 0x45, 0x30, 0x0a, 0x4d, 0x44, 0x49,
0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x77, 0x77, 0x72, 0x56, 0x48, 0x4a,
0x76, 0x62, 0x47, 0x78, 0x54, 0x64, 0x47, 0x39, 0x79, 0x5a, 0x53, 0x41,
0x79, 0x49, 0x47, 0x6c, 0x51, 0x61, 0x47, 0x39, 0x75, 0x5a, 0x53, 0x42,
0x44, 0x5a, 0x58, 0x4a, 0x30, 0x61, 0x57, 0x5a, 0x70, 0x59, 0x32, 0x46,
0x30, 0x61, 0x57, 0x39, 0x75, 0x49, 0x45, 0x46, 0x31, 0x64, 0x47, 0x68,
0x76, 0x0a, 0x63, 0x6d, 0x6c, 0x30, 0x65, 0x54, 0x41, 0x65, 0x46, 0x77,
0x30, 0x79, 0x4d, 0x7a, 0x45, 0x79, 0x4d, 0x6a, 0x59, 0x79, 0x4d, 0x7a,
0x41, 0x30, 0x4e, 0x44, 0x46, 0x61, 0x46, 0x77, 0x30, 0x79, 0x4d, 0x7a,
0x45, 0x79, 0x4d, 0x6a, 0x59, 0x79, 0x4d, 0x7a, 0x41, 0x30, 0x4e, 0x44,
0x46, 0x61, 0x4d, 0x45, 0x4d, 0x78, 0x43, 0x7a, 0x41, 0x4a, 0x42, 0x67,
0x4e, 0x56, 0x42, 0x41, 0x59, 0x54, 0x0a, 0x41, 0x6c, 0x56, 0x54, 0x4d,
0x54, 0x51, 0x77, 0x4d, 0x67, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x44,
0x43, 0x74, 0x55, 0x63, 0x6d, 0x39, 0x73, 0x62, 0x46, 0x4e, 0x30, 0x62,
0x33, 0x4a, 0x6c, 0x49, 0x44, 0x49, 0x67, 0x61, 0x56, 0x42, 0x6f, 0x62,
0x32, 0x35, 0x6c, 0x49, 0x45, 0x4e, 0x6c, 0x63, 0x6e, 0x52, 0x70, 0x5a,
0x6d, 0x6c, 0x6a, 0x59, 0x58, 0x52, 0x70, 0x62, 0x32, 0x34, 0x67, 0x0a,
0x51, 0x58, 0x56, 0x30, 0x61, 0x47, 0x39, 0x79, 0x61, 0x58, 0x52, 0x35,
0x4d, 0x49, 0x49, 0x42, 0x49, 0x6a, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71,
0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x45, 0x46,
0x41, 0x41, 0x4f, 0x43, 0x41, 0x51, 0x38, 0x41, 0x4d, 0x49, 0x49, 0x42,
0x43, 0x67, 0x4b, 0x43, 0x41, 0x51, 0x45, 0x41, 0x39, 0x72, 0x6c, 0x2f,
0x36, 0x49, 0x6a, 0x74, 0x0a, 0x50, 0x44, 0x6d, 0x45, 0x79, 0x34, 0x31,
0x55, 0x5a, 0x53, 0x38, 0x65, 0x58, 0x4a, 0x56, 0x75, 0x33, 0x4a, 0x52,
0x6d, 0x31, 0x71, 0x6c, 0x34, 0x39, 0x7a, 0x75, 0x2b, 0x35, 0x2b, 0x70,
0x73, 0x46, 0x42, 0x35, 0x56, 0x2f, 0x5a, 0x59, 0x53, 0x6a, 0x35, 0x41,
0x61, 0x48, 0x4c, 0x42, 0x33, 0x41, 0x5a, 0x6a, 0x78, 0x37, 0x31, 0x76,
0x49, 0x52, 0x37, 0x55, 0x72, 0x53, 0x2f, 0x4f, 0x48, 0x0a, 0x64, 0x35,
0x45, 0x73, 0x61, 0x36, 0x67, 0x6c, 0x4d, 0x47, 0x67, 0x58, 0x36, 0x50,
0x6b, 0x76, 0x76, 0x47, 0x6c, 0x79, 0x71, 0x44, 0x6e, 0x53, 0x4b, 0x39,
0x71, 0x49, 0x6a, 0x38, 0x77, 0x6d, 0x77, 0x53, 0x49, 0x46, 0x52, 0x43,
0x36, 0x76, 0x74, 0x2b, 0x59, 0x2b, 0x4f, 0x6d, 0x50, 0x5a, 0x46, 0x68,
0x73, 0x6f, 0x73, 0x39, 0x4b, 0x42, 0x43, 0x4c, 0x72, 0x4b, 0x42, 0x4f,
0x44, 0x53, 0x0a, 0x2f, 0x44, 0x49, 0x31, 0x6c, 0x33, 0x2f, 0x45, 0x73,
0x7a, 0x49, 0x61, 0x61, 0x50, 0x46, 0x64, 0x79, 0x6d, 0x48, 0x49, 0x4e,
0x76, 0x42, 0x30, 0x47, 0x32, 0x49, 0x39, 0x6e, 0x4f, 0x77, 0x67, 0x2f,
0x49, 0x4a, 0x4a, 0x61, 0x6f, 0x61, 0x78, 0x39, 0x71, 0x30, 0x63, 0x31,
0x58, 0x34, 0x51, 0x48, 0x6a, 0x61, 0x71, 0x35, 0x55, 0x37, 0x42, 0x70,
0x41, 0x50, 0x6d, 0x53, 0x59, 0x50, 0x57, 0x0a, 0x59, 0x76, 0x6d, 0x43,
0x65, 0x31, 0x30, 0x32, 0x67, 0x58, 0x48, 0x56, 0x50, 0x39, 0x6d, 0x59,
0x39, 0x32, 0x43, 0x57, 0x6d, 0x34, 0x6b, 0x4e, 0x68, 0x6e, 0x67, 0x73,
0x73, 0x35, 0x4c, 0x67, 0x65, 0x49, 0x4a, 0x37, 0x58, 0x41, 0x4a, 0x50,
0x58, 0x6e, 0x56, 0x31, 0x42, 0x4b, 0x73, 0x36, 0x69, 0x7a, 0x6a, 0x76,
0x54, 0x70, 0x6c, 0x45, 0x57, 0x77, 0x48, 0x68, 0x5a, 0x38, 0x31, 0x37,
0x0a, 0x56, 0x72, 0x4c, 0x5a, 0x41, 0x6d, 0x53, 0x63, 0x46, 0x7a, 0x36,
0x4e, 0x66, 0x62, 0x4f, 0x67, 0x43, 0x6c, 0x76, 0x6c, 0x43, 0x4b, 0x74,
0x71, 0x68, 0x49, 0x34, 0x41, 0x32, 0x4e, 0x4d, 0x33, 0x67, 0x46, 0x57,
0x46, 0x63, 0x56, 0x56, 0x44, 0x75, 0x46, 0x61, 0x73, 0x6b, 0x32, 0x2f,
0x44, 0x45, 0x48, 0x63, 0x67, 0x78, 0x2b, 0x55, 0x47, 0x4f, 0x74, 0x61,
0x48, 0x4a, 0x74, 0x73, 0x36, 0x0a, 0x51, 0x76, 0x69, 0x54, 0x6d, 0x39,
0x37, 0x5a, 0x63, 0x78, 0x55, 0x67, 0x34, 0x51, 0x49, 0x44, 0x41, 0x51,
0x41, 0x42, 0x6f, 0x34, 0x47, 0x58, 0x4d, 0x49, 0x47, 0x55, 0x4d, 0x41,
0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x45, 0x42, 0x2f, 0x77,
0x51, 0x46, 0x4d, 0x41, 0x4d, 0x42, 0x41, 0x66, 0x38, 0x77, 0x44, 0x67,
0x59, 0x44, 0x56, 0x52, 0x30, 0x50, 0x41, 0x51, 0x48, 0x2f, 0x0a, 0x42,
0x41, 0x51, 0x44, 0x41, 0x67, 0x4b, 0x45, 0x4d, 0x42, 0x4d, 0x47, 0x41,
0x31, 0x55, 0x64, 0x4a, 0x51, 0x51, 0x4d, 0x4d, 0x41, 0x6f, 0x47, 0x43,
0x43, 0x73, 0x47, 0x41, 0x51, 0x55, 0x46, 0x42, 0x77, 0x4d, 0x44, 0x4d,
0x42, 0x49, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x59,
0x32, 0x51, 0x47, 0x46, 0x67, 0x45, 0x42, 0x2f, 0x77, 0x51, 0x43, 0x42,
0x51, 0x41, 0x77, 0x0a, 0x45, 0x77, 0x59, 0x4b, 0x4b, 0x6f, 0x5a, 0x49,
0x68, 0x76, 0x64, 0x6a, 0x5a, 0x41, 0x59, 0x42, 0x41, 0x77, 0x45, 0x42,
0x2f, 0x77, 0x51, 0x43, 0x42, 0x51, 0x41, 0x77, 0x46, 0x41, 0x59, 0x4c,
0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76, 0x64, 0x6a, 0x5a, 0x41, 0x59, 0x42,
0x47, 0x51, 0x45, 0x42, 0x41, 0x66, 0x38, 0x45, 0x41, 0x67, 0x55, 0x41,
0x4d, 0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x64, 0x0a, 0x44, 0x67, 0x51,
0x57, 0x42, 0x42, 0x54, 0x42, 0x46, 0x75, 0x62, 0x4e, 0x57, 0x64, 0x4c,
0x6d, 0x6a, 0x5a, 0x74, 0x51, 0x78, 0x31, 0x46, 0x33, 0x70, 0x49, 0x46,
0x6c, 0x67, 0x52, 0x53, 0x32, 0x34, 0x54, 0x41, 0x4e, 0x42, 0x67, 0x6b,
0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73,
0x46, 0x41, 0x41, 0x4f, 0x43, 0x41, 0x51, 0x45, 0x41, 0x4b, 0x78, 0x4d,
0x6d, 0x0a, 0x50, 0x32, 0x41, 0x68, 0x4e, 0x4a, 0x5a, 0x55, 0x35, 0x54,
0x49, 0x72, 0x4a, 0x71, 0x75, 0x6e, 0x6b, 0x78, 0x4d, 0x48, 0x75, 0x59,
0x71, 0x57, 0x6c, 0x38, 0x67, 0x56, 0x67, 0x32, 0x4f, 0x64, 0x6d, 0x48,
0x39, 0x33, 0x52, 0x49, 0x78, 0x66, 0x63, 0x32, 0x47, 0x4d, 0x4b, 0x6a,
0x4a, 0x58, 0x4e, 0x43, 0x61, 0x37, 0x43, 0x6e, 0x4b, 0x43, 0x6c, 0x68,
0x55, 0x4d, 0x79, 0x43, 0x6b, 0x70, 0x0a, 0x6f, 0x6f, 0x61, 0x6f, 0x76,
0x41, 0x55, 0x66, 0x59, 0x66, 0x65, 0x6c, 0x6f, 0x61, 0x39, 0x76, 0x7a,
0x6a, 0x72, 0x6d, 0x50, 0x6b, 0x35, 0x53, 0x4d, 0x67, 0x55, 0x4d, 0x43,
0x73, 0x55, 0x54, 0x4b, 0x5a, 0x6f, 0x73, 0x39, 0x50, 0x58, 0x76, 0x7a,
0x57, 0x4e, 0x56, 0x77, 0x72, 0x61, 0x6b, 0x76, 0x71, 0x39, 0x7a, 0x74,
0x6d, 0x74, 0x30, 0x6f, 0x46, 0x39, 0x34, 0x64, 0x53, 0x64, 0x6e, 0x0a,
0x74, 0x7a, 0x56, 0x37, 0x33, 0x54, 0x34, 0x45, 0x4d, 0x4d, 0x2f, 0x56,
0x73, 0x33, 0x31, 0x41, 0x4b, 0x37, 0x63, 0x4a, 0x4e, 0x70, 0x46, 0x5a,
0x34, 0x68, 0x34, 0x57, 0x5a, 0x54, 0x43, 0x49, 0x6d, 0x34, 0x6b, 0x78,
0x33, 0x55, 0x65, 0x32, 0x47, 0x54, 0x68, 0x32, 0x61, 0x4e, 0x47, 0x4a,
0x52, 0x50, 0x54, 0x6a, 0x78, 0x54, 0x73, 0x36, 0x76, 0x73, 0x50, 0x78,
0x38, 0x68, 0x2b, 0x58, 0x0a, 0x6b, 0x45, 0x66, 0x44, 0x70, 0x77, 0x30,
0x5a, 0x4c, 0x35, 0x39, 0x4a, 0x54, 0x4b, 0x6e, 0x78, 0x47, 0x6a, 0x53,
0x72, 0x38, 0x4d, 0x41, 0x59, 0x64, 0x7a, 0x7a, 0x56, 0x31, 0x4f, 0x59,
0x4b, 0x34, 0x45, 0x67, 0x37, 0x67, 0x52, 0x57, 0x77, 0x6d, 0x79, 0x6b,
0x49, 0x56, 0x4f, 0x6a, 0x57, 0x45, 0x2b, 0x76, 0x71, 0x66, 0x44, 0x68,
0x4b, 0x4e, 0x64, 0x50, 0x6f, 0x48, 0x52, 0x4b, 0x45, 0x0a, 0x6c, 0x6d,
0x7a, 0x41, 0x46, 0x79, 0x4d, 0x34, 0x78, 0x69, 0x55, 0x67, 0x2f, 0x6b,
0x54, 0x6a, 0x6c, 0x6d, 0x7a, 0x55, 0x6f, 0x46, 0x56, 0x50, 0x73, 0x58,
0x46, 0x4e, 0x6b, 0x35, 0x6b, 0x42, 0x4f, 0x4d, 0x6a, 0x51, 0x61, 0x35,
0x61, 0x49, 0x79, 0x35, 0x36, 0x32, 0x57, 0x37, 0x5a, 0x43, 0x75, 0x75,
0x4a, 0x4f, 0x33, 0x78, 0x41, 0x59, 0x4b, 0x61, 0x61, 0x6d, 0x73, 0x63,
0x65, 0x2f, 0x0a, 0x58, 0x78, 0x44, 0x6a, 0x6e, 0x6c, 0x75, 0x62, 0x47,
0x70, 0x67, 0x44, 0x53, 0x6e, 0x4c, 0x67, 0x47, 0x41, 0x3d, 0x3d, 0x0a,
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, 0x45, 0x52,
0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d,
0x2d, 0x0a
};
unsigned int CACertLength = 1310;
unsigned char CAKey[] = {
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x50,
0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x20, 0x4b, 0x45, 0x59, 0x2d, 0x2d,
0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x45, 0x76, 0x51, 0x49, 0x42,
0x41, 0x44, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47,
0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x45, 0x46, 0x41, 0x41, 0x53, 0x43,
0x42, 0x4b, 0x63, 0x77, 0x67, 0x67, 0x53, 0x6a, 0x41, 0x67, 0x45, 0x41,
0x41, 0x6f, 0x49, 0x42, 0x41, 0x51, 0x44, 0x32, 0x75, 0x58, 0x2f, 0x6f,
0x69, 0x4f, 0x30, 0x38, 0x4f, 0x59, 0x54, 0x4c, 0x0a, 0x6a, 0x56, 0x52,
0x6c, 0x4c, 0x78, 0x35, 0x63, 0x6c, 0x57, 0x37, 0x63, 0x6c, 0x47, 0x62,
0x57, 0x71, 0x58, 0x6a, 0x33, 0x4f, 0x37, 0x37, 0x6e, 0x36, 0x6d, 0x77,
0x55, 0x48, 0x6c, 0x58, 0x39, 0x6c, 0x68, 0x4b, 0x50, 0x6b, 0x42, 0x6f,
0x63, 0x73, 0x48, 0x63, 0x42, 0x6d, 0x50, 0x48, 0x76, 0x57, 0x38, 0x68,
0x48, 0x74, 0x53, 0x74, 0x4c, 0x38, 0x34, 0x64, 0x33, 0x6b, 0x53, 0x78,
0x72, 0x0a, 0x71, 0x43, 0x55, 0x77, 0x61, 0x42, 0x66, 0x6f, 0x2b, 0x53,
0x2b, 0x38, 0x61, 0x58, 0x4b, 0x6f, 0x4f, 0x64, 0x49, 0x72, 0x32, 0x6f,
0x69, 0x50, 0x7a, 0x43, 0x62, 0x42, 0x49, 0x67, 0x56, 0x45, 0x4c, 0x71,
0x2b, 0x33, 0x35, 0x6a, 0x34, 0x36, 0x59, 0x39, 0x6b, 0x57, 0x47, 0x79,
0x69, 0x7a, 0x30, 0x6f, 0x45, 0x49, 0x75, 0x73, 0x6f, 0x45, 0x34, 0x4e,
0x4c, 0x38, 0x4d, 0x6a, 0x57, 0x58, 0x0a, 0x66, 0x38, 0x53, 0x7a, 0x4d,
0x68, 0x70, 0x6f, 0x38, 0x56, 0x33, 0x4b, 0x59, 0x63, 0x67, 0x32, 0x38,
0x48, 0x51, 0x62, 0x59, 0x6a, 0x32, 0x63, 0x37, 0x43, 0x44, 0x38, 0x67,
0x6b, 0x6c, 0x71, 0x68, 0x72, 0x48, 0x32, 0x72, 0x52, 0x7a, 0x56, 0x66,
0x68, 0x41, 0x65, 0x4e, 0x71, 0x72, 0x6c, 0x54, 0x73, 0x47, 0x6b, 0x41,
0x2b, 0x5a, 0x4a, 0x67, 0x39, 0x5a, 0x69, 0x2b, 0x59, 0x4a, 0x37, 0x0a,
0x58, 0x54, 0x61, 0x42, 0x63, 0x64, 0x55, 0x2f, 0x32, 0x5a, 0x6a, 0x33,
0x59, 0x4a, 0x61, 0x62, 0x69, 0x51, 0x32, 0x47, 0x65, 0x43, 0x79, 0x7a,
0x6b, 0x75, 0x42, 0x34, 0x67, 0x6e, 0x74, 0x63, 0x41, 0x6b, 0x39, 0x65,
0x64, 0x58, 0x55, 0x45, 0x71, 0x7a, 0x71, 0x4c, 0x4f, 0x4f, 0x39, 0x4f,
0x6d, 0x55, 0x52, 0x62, 0x41, 0x65, 0x46, 0x6e, 0x7a, 0x58, 0x74, 0x57,
0x73, 0x74, 0x6b, 0x43, 0x0a, 0x5a, 0x4a, 0x77, 0x58, 0x50, 0x6f, 0x31,
0x39, 0x73, 0x36, 0x41, 0x4b, 0x57, 0x2b, 0x55, 0x49, 0x71, 0x32, 0x71,
0x45, 0x6a, 0x67, 0x44, 0x59, 0x30, 0x7a, 0x65, 0x41, 0x56, 0x59, 0x56,
0x78, 0x56, 0x55, 0x4f, 0x34, 0x56, 0x71, 0x79, 0x54, 0x62, 0x38, 0x4d,
0x51, 0x64, 0x79, 0x44, 0x48, 0x35, 0x51, 0x59, 0x36, 0x31, 0x6f, 0x63,
0x6d, 0x32, 0x7a, 0x70, 0x43, 0x2b, 0x4a, 0x4f, 0x62, 0x0a, 0x33, 0x74,
0x6c, 0x7a, 0x46, 0x53, 0x44, 0x68, 0x41, 0x67, 0x4d, 0x42, 0x41, 0x41,
0x45, 0x43, 0x67, 0x67, 0x45, 0x41, 0x41, 0x65, 0x58, 0x78, 0x52, 0x6e,
0x53, 0x42, 0x2f, 0x49, 0x42, 0x35, 0x36, 0x59, 0x76, 0x68, 0x4f, 0x54,
0x42, 0x78, 0x74, 0x61, 0x4d, 0x30, 0x7a, 0x37, 0x32, 0x30, 0x72, 0x54,
0x68, 0x76, 0x59, 0x73, 0x6e, 0x51, 0x36, 0x78, 0x6c, 0x74, 0x4a, 0x71,
0x49, 0x5a, 0x0a, 0x66, 0x64, 0x53, 0x52, 0x47, 0x4d, 0x32, 0x61, 0x54,
0x56, 0x50, 0x6b, 0x58, 0x51, 0x44, 0x51, 0x64, 0x50, 0x4f, 0x30, 0x47,
0x71, 0x7a, 0x68, 0x72, 0x2f, 0x31, 0x51, 0x45, 0x71, 0x6a, 0x31, 0x54,
0x6b, 0x42, 0x63, 0x56, 0x61, 0x4d, 0x5a, 0x34, 0x72, 0x34, 0x43, 0x7a,
0x6e, 0x71, 0x53, 0x56, 0x6a, 0x6e, 0x77, 0x61, 0x48, 0x76, 0x6e, 0x57,
0x4d, 0x47, 0x67, 0x6e, 0x31, 0x51, 0x56, 0x0a, 0x35, 0x62, 0x6c, 0x39,
0x47, 0x71, 0x74, 0x69, 0x32, 0x58, 0x32, 0x33, 0x32, 0x34, 0x4d, 0x6d,
0x79, 0x75, 0x77, 0x69, 0x31, 0x2f, 0x4b, 0x52, 0x74, 0x41, 0x51, 0x58,
0x72, 0x48, 0x62, 0x39, 0x6a, 0x59, 0x42, 0x76, 0x4c, 0x73, 0x53, 0x6a,
0x45, 0x6c, 0x46, 0x50, 0x31, 0x43, 0x4d, 0x67, 0x70, 0x47, 0x39, 0x51,
0x2b, 0x64, 0x35, 0x56, 0x69, 0x48, 0x54, 0x69, 0x76, 0x37, 0x57, 0x55,
0x0a, 0x4b, 0x56, 0x77, 0x55, 0x64, 0x62, 0x67, 0x67, 0x6a, 0x50, 0x56,
0x66, 0x6e, 0x44, 0x6b, 0x43, 0x70, 0x6c, 0x68, 0x74, 0x5a, 0x6b, 0x56,
0x56, 0x6d, 0x43, 0x53, 0x47, 0x63, 0x76, 0x32, 0x74, 0x5a, 0x73, 0x39,
0x77, 0x6a, 0x41, 0x62, 0x61, 0x31, 0x49, 0x74, 0x6e, 0x76, 0x35, 0x74,
0x30, 0x6e, 0x4e, 0x51, 0x34, 0x37, 0x74, 0x63, 0x4a, 0x4e, 0x74, 0x71,
0x48, 0x35, 0x42, 0x4f, 0x6a, 0x0a, 0x32, 0x66, 0x2b, 0x75, 0x2b, 0x6e,
0x35, 0x44, 0x51, 0x31, 0x33, 0x46, 0x4a, 0x74, 0x4b, 0x70, 0x37, 0x33,
0x73, 0x6a, 0x4a, 0x4c, 0x77, 0x54, 0x7a, 0x4a, 0x43, 0x4c, 0x6a, 0x46,
0x4f, 0x4b, 0x68, 0x66, 0x5a, 0x6d, 0x46, 0x51, 0x6f, 0x4f, 0x70, 0x54,
0x65, 0x75, 0x71, 0x53, 0x2f, 0x70, 0x53, 0x68, 0x56, 0x38, 0x50, 0x6c,
0x5a, 0x6a, 0x7a, 0x55, 0x79, 0x5a, 0x56, 0x62, 0x72, 0x70, 0x0a, 0x59,
0x35, 0x68, 0x64, 0x58, 0x48, 0x50, 0x32, 0x53, 0x35, 0x4b, 0x76, 0x4d,
0x76, 0x59, 0x67, 0x32, 0x77, 0x33, 0x44, 0x77, 0x38, 0x6b, 0x74, 0x2f,
0x53, 0x63, 0x69, 0x44, 0x57, 0x6a, 0x57, 0x47, 0x42, 0x69, 0x38, 0x6e,
0x33, 0x6a, 0x50, 0x77, 0x51, 0x4b, 0x42, 0x67, 0x51, 0x44, 0x2b, 0x36,
0x55, 0x47, 0x6d, 0x48, 0x31, 0x4a, 0x73, 0x31, 0x56, 0x68, 0x75, 0x48,
0x2b, 0x71, 0x4a, 0x0a, 0x56, 0x35, 0x53, 0x6f, 0x66, 0x31, 0x2b, 0x31,
0x6f, 0x6b, 0x48, 0x52, 0x33, 0x50, 0x53, 0x33, 0x75, 0x4c, 0x6e, 0x4a,
0x79, 0x33, 0x6a, 0x46, 0x31, 0x44, 0x73, 0x67, 0x51, 0x33, 0x48, 0x38,
0x75, 0x56, 0x51, 0x2b, 0x6d, 0x45, 0x33, 0x34, 0x79, 0x53, 0x69, 0x59,
0x52, 0x74, 0x6e, 0x6a, 0x4c, 0x6b, 0x6e, 0x63, 0x42, 0x71, 0x65, 0x79,
0x5a, 0x68, 0x56, 0x50, 0x6f, 0x52, 0x68, 0x79, 0x0a, 0x64, 0x64, 0x55,
0x47, 0x39, 0x56, 0x43, 0x75, 0x2f, 0x7a, 0x44, 0x52, 0x50, 0x6c, 0x49,
0x6d, 0x58, 0x64, 0x5a, 0x75, 0x39, 0x51, 0x4e, 0x56, 0x36, 0x32, 0x59,
0x43, 0x6d, 0x38, 0x2b, 0x73, 0x43, 0x6b, 0x4e, 0x57, 0x32, 0x49, 0x2f,
0x64, 0x52, 0x73, 0x6d, 0x2b, 0x71, 0x72, 0x54, 0x46, 0x70, 0x72, 0x6a,
0x35, 0x5a, 0x45, 0x66, 0x78, 0x45, 0x41, 0x39, 0x6f, 0x4e, 0x7a, 0x57,
0x6a, 0x0a, 0x4d, 0x50, 0x4d, 0x6d, 0x6c, 0x51, 0x59, 0x6c, 0x33, 0x38,
0x54, 0x74, 0x77, 0x70, 0x6f, 0x33, 0x2b, 0x6d, 0x6a, 0x46, 0x30, 0x6b,
0x70, 0x6c, 0x6f, 0x51, 0x4b, 0x42, 0x67, 0x51, 0x44, 0x33, 0x78, 0x30,
0x71, 0x51, 0x61, 0x4e, 0x57, 0x50, 0x67, 0x73, 0x65, 0x58, 0x55, 0x48,
0x42, 0x47, 0x66, 0x2b, 0x36, 0x4e, 0x34, 0x58, 0x54, 0x64, 0x79, 0x39,
0x55, 0x45, 0x73, 0x4a, 0x70, 0x47, 0x0a, 0x47, 0x42, 0x41, 0x5a, 0x79,
0x36, 0x34, 0x57, 0x42, 0x6a, 0x47, 0x34, 0x46, 0x4f, 0x6e, 0x50, 0x47,
0x4e, 0x4a, 0x71, 0x6c, 0x38, 0x34, 0x75, 0x39, 0x55, 0x45, 0x55, 0x6c,
0x78, 0x39, 0x6a, 0x69, 0x79, 0x75, 0x4b, 0x42, 0x57, 0x70, 0x57, 0x2f,
0x31, 0x6f, 0x6b, 0x44, 0x49, 0x48, 0x65, 0x70, 0x73, 0x42, 0x57, 0x52,
0x75, 0x45, 0x4d, 0x51, 0x67, 0x4a, 0x72, 0x6a, 0x59, 0x44, 0x33, 0x0a,
0x62, 0x37, 0x36, 0x77, 0x4a, 0x2b, 0x75, 0x42, 0x7a, 0x2f, 0x75, 0x6d,
0x47, 0x50, 0x6f, 0x50, 0x56, 0x4f, 0x32, 0x49, 0x2f, 0x79, 0x53, 0x54,
0x52, 0x47, 0x67, 0x66, 0x37, 0x5a, 0x70, 0x34, 0x47, 0x74, 0x50, 0x6f,
0x54, 0x67, 0x58, 0x68, 0x54, 0x65, 0x72, 0x37, 0x58, 0x79, 0x42, 0x73,
0x57, 0x49, 0x75, 0x78, 0x55, 0x78, 0x32, 0x2f, 0x48, 0x5a, 0x31, 0x58,
0x6f, 0x6a, 0x78, 0x65, 0x0a, 0x37, 0x75, 0x54, 0x37, 0x41, 0x6b, 0x70,
0x7a, 0x51, 0x51, 0x4b, 0x42, 0x67, 0x42, 0x46, 0x4b, 0x42, 0x73, 0x37,
0x61, 0x6e, 0x76, 0x2b, 0x4d, 0x74, 0x4e, 0x4f, 0x37, 0x54, 0x48, 0x41,
0x47, 0x52, 0x61, 0x6e, 0x73, 0x41, 0x62, 0x54, 0x54, 0x44, 0x58, 0x33,
0x4c, 0x61, 0x37, 0x6d, 0x75, 0x53, 0x4d, 0x4f, 0x63, 0x44, 0x6c, 0x50,
0x30, 0x6f, 0x68, 0x48, 0x39, 0x49, 0x52, 0x55, 0x51, 0x0a, 0x43, 0x4e,
0x75, 0x35, 0x2f, 0x73, 0x66, 0x5a, 0x39, 0x4f, 0x76, 0x6e, 0x47, 0x6b,
0x34, 0x6a, 0x54, 0x4a, 0x55, 0x6b, 0x79, 0x6d, 0x6a, 0x36, 0x4c, 0x59,
0x58, 0x61, 0x47, 0x6b, 0x74, 0x68, 0x48, 0x4a, 0x4b, 0x39, 0x50, 0x72,
0x79, 0x76, 0x79, 0x45, 0x4c, 0x59, 0x35, 0x44, 0x39, 0x2f, 0x36, 0x39,
0x52, 0x59, 0x76, 0x2b, 0x49, 0x71, 0x39, 0x68, 0x39, 0x46, 0x4c, 0x42,
0x2b, 0x79, 0x0a, 0x44, 0x6f, 0x45, 0x73, 0x62, 0x51, 0x32, 0x49, 0x43,
0x4a, 0x54, 0x72, 0x42, 0x52, 0x6e, 0x47, 0x78, 0x68, 0x4c, 0x38, 0x4c,
0x7a, 0x6a, 0x31, 0x61, 0x75, 0x59, 0x5a, 0x6f, 0x49, 0x53, 0x79, 0x42,
0x44, 0x76, 0x67, 0x72, 0x61, 0x73, 0x52, 0x38, 0x30, 0x78, 0x67, 0x2f,
0x34, 0x36, 0x2b, 0x61, 0x43, 0x37, 0x4b, 0x70, 0x59, 0x73, 0x68, 0x41,
0x6f, 0x47, 0x41, 0x47, 0x44, 0x52, 0x4e, 0x0a, 0x6f, 0x6d, 0x47, 0x37,
0x53, 0x76, 0x4f, 0x5a, 0x6a, 0x37, 0x78, 0x35, 0x32, 0x30, 0x6b, 0x77,
0x41, 0x6f, 0x67, 0x64, 0x70, 0x48, 0x54, 0x2b, 0x38, 0x43, 0x42, 0x59,
0x55, 0x62, 0x53, 0x55, 0x44, 0x68, 0x45, 0x4a, 0x68, 0x6e, 0x6c, 0x41,
0x62, 0x68, 0x30, 0x4d, 0x34, 0x67, 0x41, 0x6f, 0x76, 0x65, 0x54, 0x71,
0x62, 0x55, 0x66, 0x6a, 0x2f, 0x61, 0x44, 0x74, 0x6e, 0x67, 0x6e, 0x41,
0x0a, 0x54, 0x52, 0x46, 0x4f, 0x58, 0x41, 0x56, 0x42, 0x78, 0x76, 0x65,
0x35, 0x30, 0x41, 0x67, 0x32, 0x44, 0x62, 0x65, 0x4b, 0x30, 0x47, 0x6d,
0x36, 0x56, 0x73, 0x74, 0x52, 0x35, 0x39, 0x6e, 0x77, 0x70, 0x4d, 0x43,
0x68, 0x6a, 0x75, 0x4c, 0x45, 0x55, 0x47, 0x74, 0x73, 0x4d, 0x67, 0x63,
0x33, 0x31, 0x51, 0x51, 0x6e, 0x6a, 0x49, 0x4e, 0x49, 0x4d, 0x4b, 0x5a,
0x44, 0x53, 0x71, 0x78, 0x45, 0x0a, 0x4f, 0x78, 0x4d, 0x30, 0x47, 0x39,
0x68, 0x43, 0x74, 0x68, 0x2b, 0x4b, 0x79, 0x55, 0x71, 0x31, 0x43, 0x72,
0x4e, 0x31, 0x32, 0x6d, 0x2b, 0x49, 0x4b, 0x55, 0x46, 0x64, 0x36, 0x47,
0x41, 0x70, 0x32, 0x69, 0x4e, 0x56, 0x4a, 0x6f, 0x45, 0x43, 0x67, 0x59,
0x45, 0x41, 0x77, 0x34, 0x47, 0x6f, 0x44, 0x49, 0x77, 0x54, 0x59, 0x4e,
0x65, 0x63, 0x4e, 0x48, 0x5a, 0x45, 0x58, 0x6e, 0x36, 0x62, 0x0a, 0x76,
0x44, 0x51, 0x66, 0x73, 0x6e, 0x64, 0x34, 0x44, 0x30, 0x50, 0x58, 0x4c,
0x75, 0x52, 0x63, 0x35, 0x64, 0x70, 0x77, 0x46, 0x2f, 0x6a, 0x53, 0x33,
0x6d, 0x4a, 0x33, 0x6f, 0x74, 0x61, 0x6a, 0x7a, 0x79, 0x39, 0x59, 0x6a,
0x76, 0x4c, 0x6c, 0x7a, 0x75, 0x55, 0x38, 0x70, 0x43, 0x46, 0x36, 0x45,
0x45, 0x48, 0x70, 0x57, 0x6e, 0x71, 0x55, 0x54, 0x47, 0x69, 0x74, 0x51,
0x69, 0x58, 0x36, 0x0a, 0x33, 0x76, 0x69, 0x69, 0x79, 0x71, 0x6d, 0x34,
0x2f, 0x65, 0x30, 0x75, 0x36, 0x4a, 0x66, 0x30, 0x72, 0x55, 0x2f, 0x78,
0x71, 0x46, 0x49, 0x54, 0x65, 0x4a, 0x37, 0x6b, 0x43, 0x6a, 0x37, 0x73,
0x73, 0x32, 0x4e, 0x68, 0x53, 0x79, 0x54, 0x54, 0x34, 0x6a, 0x51, 0x30,
0x33, 0x36, 0x76, 0x39, 0x57, 0x65, 0x50, 0x55, 0x69, 0x70, 0x34, 0x44,
0x7a, 0x6c, 0x59, 0x6c, 0x65, 0x2f, 0x72, 0x79, 0x0a, 0x59, 0x43, 0x64,
0x56, 0x73, 0x63, 0x5a, 0x59, 0x31, 0x61, 0x38, 0x73, 0x46, 0x34, 0x73,
0x36, 0x74, 0x6e, 0x36, 0x64, 0x48, 0x75, 0x4d, 0x3d, 0x0a, 0x2d, 0x2d,
0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x50, 0x52, 0x49, 0x56, 0x41,
0x54, 0x45, 0x20, 0x4b, 0x45, 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a
};
unsigned int CAKeyLength = 1704;

View File

@ -0,0 +1,35 @@
#include <stdint.h>
/*
SEQUENCE (2 bytes)
OBJECT IDENTIFIER (2+5 bytes) 1.3.14.3.2.26 (sha1)
OCTET STRING (2+20 bytes) <SHA1 CDHash>
SEQUENCE (2 bytes)
OBJECT IDENTIFIER (2+9 bytes) 2.16.840.1.101.3.4.2.1 (sha256)
OCTET STRING (2+32 bytes) <SHA256 CDHash>
*/
uint8_t CDHashesDERTemplate[] = {
/* SEQUENCE (2 bytes) */
0x30, 0x1D,
/* OBJECT IDENTIFIER (2+5 bytes) */
0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A,
/* OCTET STRING (2+20 bytes) */
0x04, 0x14,
/* SHA1 CDHash goes here */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* SEQUENCE (2 bytes) */
0x30, 0x2D,
/* OBJECT IDENTIFIER (2+9 bytes) */
0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01,
/* OCTET STRING (2+32 bytes) */
0x04, 0x20,
/* SHA256 CDHash goes here */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
#define CDHASHES_DER_SIZE 78
#define CDHASHES_DER_SHA1_OFFSET 11
#define CDHASHES_DER_SHA256_OFFSET 46

View File

@ -1,8 +0,0 @@
unsigned char DecryptedSignature[] = {
0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20, 0xe2, 0x34, 0xf9, 0x25, 0x65,
0xa4, 0x33, 0xb7, 0x13, 0x67, 0xc8, 0x63, 0x93, 0xdc, 0x41, 0xaa, 0xc4,
0x0e, 0x76, 0xa0, 0x80, 0x29, 0x8b, 0x38, 0x9e, 0xc5, 0x6d, 0xd6, 0xba,
0xef, 0xbf, 0x0d
};
unsigned int DecryptedSignature_len = 51;

View File

@ -1,145 +0,0 @@
unsigned char CAKey[] = {
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x50,
0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x20, 0x4b, 0x45, 0x59, 0x2d, 0x2d,
0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x45, 0x76, 0x51, 0x49, 0x42,
0x41, 0x44, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47,
0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x45, 0x46, 0x41, 0x41, 0x53, 0x43,
0x42, 0x4b, 0x63, 0x77, 0x67, 0x67, 0x53, 0x6a, 0x41, 0x67, 0x45, 0x41,
0x41, 0x6f, 0x49, 0x42, 0x41, 0x51, 0x43, 0x2b, 0x45, 0x79, 0x35, 0x49,
0x69, 0x68, 0x4b, 0x59, 0x57, 0x55, 0x39, 0x50, 0x0a, 0x58, 0x31, 0x76,
0x52, 0x54, 0x35, 0x64, 0x63, 0x37, 0x65, 0x6a, 0x57, 0x51, 0x2b, 0x6b,
0x2b, 0x4a, 0x6f, 0x49, 0x34, 0x49, 0x68, 0x68, 0x57, 0x52, 0x53, 0x48,
0x32, 0x38, 0x4c, 0x6a, 0x50, 0x34, 0x32, 0x6f, 0x58, 0x33, 0x38, 0x35,
0x79, 0x62, 0x61, 0x32, 0x6f, 0x66, 0x54, 0x48, 0x35, 0x6f, 0x55, 0x70,
0x7a, 0x37, 0x67, 0x64, 0x4c, 0x6c, 0x61, 0x68, 0x59, 0x44, 0x67, 0x58,
0x5a, 0x0a, 0x42, 0x31, 0x73, 0x39, 0x52, 0x37, 0x76, 0x4f, 0x66, 0x58,
0x35, 0x4c, 0x4d, 0x48, 0x62, 0x6b, 0x35, 0x43, 0x71, 0x66, 0x53, 0x45,
0x59, 0x38, 0x36, 0x43, 0x50, 0x72, 0x61, 0x38, 0x65, 0x76, 0x31, 0x57,
0x51, 0x6a, 0x5a, 0x76, 0x38, 0x6c, 0x32, 0x6d, 0x70, 0x2b, 0x6c, 0x54,
0x37, 0x44, 0x44, 0x65, 0x62, 0x47, 0x42, 0x70, 0x44, 0x47, 0x69, 0x69,
0x38, 0x66, 0x79, 0x32, 0x4f, 0x49, 0x0a, 0x6f, 0x44, 0x79, 0x64, 0x79,
0x6f, 0x56, 0x6e, 0x67, 0x47, 0x37, 0x68, 0x54, 0x72, 0x64, 0x68, 0x2f,
0x6f, 0x47, 0x4c, 0x55, 0x77, 0x63, 0x30, 0x56, 0x6c, 0x69, 0x6d, 0x52,
0x6c, 0x68, 0x67, 0x4a, 0x45, 0x53, 0x73, 0x70, 0x31, 0x79, 0x36, 0x71,
0x38, 0x46, 0x30, 0x62, 0x56, 0x79, 0x42, 0x34, 0x68, 0x75, 0x34, 0x4f,
0x6f, 0x66, 0x73, 0x43, 0x49, 0x61, 0x64, 0x68, 0x76, 0x6e, 0x4a, 0x0a,
0x44, 0x46, 0x33, 0x30, 0x58, 0x4e, 0x6e, 0x34, 0x65, 0x6e, 0x34, 0x67,
0x70, 0x5a, 0x56, 0x53, 0x63, 0x45, 0x76, 0x30, 0x6c, 0x6e, 0x37, 0x6b,
0x4d, 0x42, 0x45, 0x76, 0x58, 0x42, 0x6b, 0x4f, 0x70, 0x6d, 0x75, 0x58,
0x55, 0x6d, 0x6a, 0x58, 0x31, 0x32, 0x66, 0x70, 0x6b, 0x64, 0x72, 0x71,
0x79, 0x39, 0x52, 0x77, 0x75, 0x68, 0x45, 0x49, 0x75, 0x46, 0x53, 0x34,
0x53, 0x47, 0x46, 0x43, 0x0a, 0x34, 0x4b, 0x35, 0x54, 0x49, 0x38, 0x41,
0x58, 0x76, 0x57, 0x32, 0x78, 0x70, 0x52, 0x4f, 0x67, 0x5a, 0x62, 0x58,
0x71, 0x6b, 0x5a, 0x71, 0x6c, 0x4c, 0x34, 0x37, 0x43, 0x4f, 0x35, 0x46,
0x77, 0x6e, 0x5a, 0x35, 0x75, 0x6e, 0x7a, 0x35, 0x6e, 0x30, 0x39, 0x64,
0x69, 0x4f, 0x39, 0x79, 0x57, 0x48, 0x76, 0x4d, 0x4c, 0x52, 0x36, 0x38,
0x6d, 0x50, 0x4e, 0x30, 0x4f, 0x41, 0x4c, 0x39, 0x76, 0x0a, 0x4a, 0x4a,
0x34, 0x48, 0x50, 0x4f, 0x56, 0x64, 0x41, 0x67, 0x4d, 0x42, 0x41, 0x41,
0x45, 0x43, 0x67, 0x67, 0x45, 0x41, 0x42, 0x33, 0x73, 0x44, 0x52, 0x51,
0x30, 0x55, 0x44, 0x73, 0x56, 0x6a, 0x43, 0x75, 0x31, 0x6d, 0x6c, 0x47,
0x34, 0x45, 0x74, 0x37, 0x35, 0x51, 0x50, 0x64, 0x43, 0x46, 0x35, 0x7a,
0x47, 0x47, 0x53, 0x66, 0x58, 0x44, 0x6a, 0x65, 0x2b, 0x69, 0x46, 0x74,
0x45, 0x69, 0x0a, 0x41, 0x4f, 0x4b, 0x44, 0x48, 0x43, 0x58, 0x74, 0x66,
0x74, 0x44, 0x6b, 0x74, 0x76, 0x38, 0x59, 0x58, 0x71, 0x6e, 0x7a, 0x6e,
0x32, 0x7a, 0x6b, 0x67, 0x68, 0x76, 0x46, 0x65, 0x4a, 0x4f, 0x79, 0x74,
0x4c, 0x67, 0x6d, 0x70, 0x64, 0x71, 0x44, 0x49, 0x47, 0x30, 0x4e, 0x63,
0x61, 0x47, 0x61, 0x61, 0x45, 0x63, 0x33, 0x69, 0x7a, 0x58, 0x42, 0x74,
0x2b, 0x64, 0x74, 0x39, 0x48, 0x65, 0x31, 0x0a, 0x4c, 0x2b, 0x30, 0x65,
0x79, 0x41, 0x72, 0x6e, 0x61, 0x30, 0x4b, 0x31, 0x6b, 0x72, 0x35, 0x47,
0x62, 0x6c, 0x42, 0x48, 0x66, 0x77, 0x38, 0x6d, 0x6c, 0x76, 0x32, 0x38,
0x76, 0x59, 0x78, 0x59, 0x59, 0x6a, 0x6e, 0x6d, 0x4d, 0x4e, 0x4b, 0x56,
0x33, 0x66, 0x30, 0x75, 0x76, 0x2f, 0x54, 0x45, 0x59, 0x46, 0x6d, 0x76,
0x47, 0x50, 0x2f, 0x66, 0x52, 0x6e, 0x62, 0x49, 0x66, 0x65, 0x43, 0x77,
0x0a, 0x2f, 0x2b, 0x57, 0x57, 0x71, 0x37, 0x7a, 0x4c, 0x45, 0x7a, 0x55,
0x62, 0x73, 0x6d, 0x53, 0x46, 0x46, 0x68, 0x37, 0x52, 0x35, 0x77, 0x6d,
0x70, 0x37, 0x61, 0x62, 0x64, 0x58, 0x4a, 0x49, 0x72, 0x55, 0x59, 0x61,
0x67, 0x38, 0x38, 0x79, 0x76, 0x32, 0x57, 0x4b, 0x31, 0x4b, 0x71, 0x70,
0x50, 0x6d, 0x6c, 0x32, 0x61, 0x63, 0x78, 0x56, 0x65, 0x73, 0x38, 0x42,
0x73, 0x69, 0x34, 0x4b, 0x75, 0x0a, 0x2f, 0x4c, 0x35, 0x62, 0x46, 0x66,
0x59, 0x66, 0x50, 0x33, 0x50, 0x37, 0x5a, 0x45, 0x7a, 0x7a, 0x31, 0x55,
0x5a, 0x68, 0x34, 0x75, 0x47, 0x68, 0x49, 0x57, 0x6c, 0x53, 0x75, 0x77,
0x67, 0x4e, 0x71, 0x79, 0x71, 0x79, 0x4b, 0x67, 0x65, 0x62, 0x34, 0x31,
0x43, 0x78, 0x50, 0x53, 0x71, 0x63, 0x4c, 0x54, 0x63, 0x61, 0x30, 0x59,
0x38, 0x55, 0x34, 0x31, 0x62, 0x75, 0x76, 0x71, 0x4d, 0x46, 0x0a, 0x56,
0x63, 0x2b, 0x75, 0x31, 0x55, 0x2f, 0x34, 0x67, 0x6d, 0x54, 0x45, 0x58,
0x6e, 0x5a, 0x79, 0x46, 0x6b, 0x79, 0x47, 0x30, 0x34, 0x68, 0x57, 0x38,
0x4f, 0x64, 0x49, 0x49, 0x58, 0x51, 0x77, 0x67, 0x6a, 0x49, 0x78, 0x64,
0x48, 0x58, 0x58, 0x32, 0x51, 0x4b, 0x42, 0x67, 0x51, 0x44, 0x66, 0x64,
0x77, 0x63, 0x52, 0x4a, 0x50, 0x43, 0x2f, 0x49, 0x46, 0x30, 0x65, 0x31,
0x53, 0x75, 0x53, 0x0a, 0x66, 0x55, 0x4c, 0x65, 0x63, 0x31, 0x48, 0x65,
0x51, 0x56, 0x6d, 0x52, 0x74, 0x4b, 0x71, 0x6c, 0x35, 0x69, 0x6a, 0x50,
0x42, 0x5a, 0x5a, 0x6a, 0x37, 0x78, 0x2b, 0x73, 0x47, 0x49, 0x6b, 0x2f,
0x4e, 0x4d, 0x6f, 0x7a, 0x61, 0x6b, 0x70, 0x65, 0x2b, 0x4f, 0x69, 0x54,
0x62, 0x4f, 0x52, 0x37, 0x37, 0x70, 0x30, 0x39, 0x52, 0x2f, 0x2b, 0x62,
0x52, 0x71, 0x2b, 0x6f, 0x73, 0x61, 0x6c, 0x5a, 0x0a, 0x30, 0x56, 0x46,
0x59, 0x52, 0x30, 0x62, 0x42, 0x77, 0x4a, 0x6e, 0x66, 0x43, 0x36, 0x30,
0x36, 0x35, 0x54, 0x45, 0x39, 0x35, 0x48, 0x2b, 0x33, 0x75, 0x30, 0x57,
0x4e, 0x2f, 0x55, 0x50, 0x39, 0x4e, 0x58, 0x4b, 0x70, 0x4e, 0x49, 0x59,
0x71, 0x73, 0x43, 0x69, 0x4c, 0x53, 0x33, 0x57, 0x48, 0x67, 0x73, 0x62,
0x4e, 0x30, 0x43, 0x56, 0x46, 0x53, 0x54, 0x35, 0x76, 0x62, 0x76, 0x71,
0x31, 0x0a, 0x4a, 0x33, 0x50, 0x30, 0x77, 0x42, 0x41, 0x75, 0x2b, 0x2f,
0x6f, 0x34, 0x46, 0x35, 0x70, 0x6b, 0x70, 0x5a, 0x62, 0x36, 0x38, 0x34,
0x79, 0x4e, 0x78, 0x51, 0x4b, 0x42, 0x67, 0x51, 0x44, 0x5a, 0x76, 0x36,
0x52, 0x67, 0x79, 0x45, 0x47, 0x77, 0x53, 0x59, 0x56, 0x31, 0x49, 0x35,
0x63, 0x5a, 0x68, 0x2f, 0x66, 0x2b, 0x6f, 0x53, 0x49, 0x37, 0x74, 0x6b,
0x52, 0x62, 0x58, 0x74, 0x37, 0x46, 0x0a, 0x4e, 0x75, 0x2f, 0x71, 0x35,
0x66, 0x6f, 0x37, 0x58, 0x74, 0x54, 0x53, 0x6f, 0x38, 0x72, 0x53, 0x6a,
0x2f, 0x66, 0x79, 0x35, 0x35, 0x42, 0x6f, 0x58, 0x4c, 0x61, 0x7a, 0x53,
0x65, 0x61, 0x6e, 0x62, 0x68, 0x43, 0x58, 0x6e, 0x48, 0x39, 0x53, 0x67,
0x6f, 0x52, 0x77, 0x77, 0x56, 0x44, 0x49, 0x4a, 0x48, 0x2f, 0x42, 0x46,
0x35, 0x75, 0x6e, 0x74, 0x6e, 0x47, 0x72, 0x64, 0x5a, 0x64, 0x69, 0x0a,
0x47, 0x45, 0x56, 0x55, 0x4f, 0x4d, 0x53, 0x2b, 0x73, 0x70, 0x7a, 0x4b,
0x64, 0x42, 0x70, 0x4a, 0x49, 0x51, 0x43, 0x59, 0x4b, 0x38, 0x74, 0x54,
0x49, 0x62, 0x76, 0x78, 0x30, 0x4a, 0x4a, 0x68, 0x53, 0x66, 0x67, 0x7a,
0x44, 0x65, 0x68, 0x38, 0x4a, 0x64, 0x4f, 0x57, 0x56, 0x42, 0x68, 0x49,
0x43, 0x61, 0x51, 0x6f, 0x50, 0x31, 0x62, 0x71, 0x77, 0x36, 0x4a, 0x2b,
0x78, 0x71, 0x30, 0x35, 0x0a, 0x75, 0x4f, 0x37, 0x64, 0x70, 0x57, 0x6e,
0x4b, 0x75, 0x51, 0x4b, 0x42, 0x67, 0x47, 0x74, 0x77, 0x2b, 0x53, 0x37,
0x66, 0x43, 0x66, 0x6c, 0x37, 0x41, 0x41, 0x72, 0x52, 0x42, 0x33, 0x41,
0x5a, 0x56, 0x63, 0x74, 0x4b, 0x75, 0x76, 0x51, 0x58, 0x69, 0x34, 0x38,
0x6f, 0x78, 0x46, 0x75, 0x62, 0x65, 0x38, 0x64, 0x39, 0x73, 0x6a, 0x38,
0x2b, 0x4f, 0x34, 0x59, 0x74, 0x44, 0x65, 0x41, 0x62, 0x0a, 0x36, 0x35,
0x51, 0x6f, 0x36, 0x4c, 0x55, 0x64, 0x44, 0x41, 0x58, 0x46, 0x39, 0x31,
0x30, 0x32, 0x37, 0x74, 0x63, 0x47, 0x42, 0x50, 0x6d, 0x4e, 0x56, 0x4f,
0x76, 0x51, 0x37, 0x39, 0x48, 0x46, 0x65, 0x45, 0x7a, 0x76, 0x69, 0x43,
0x2b, 0x6b, 0x41, 0x4e, 0x64, 0x69, 0x37, 0x39, 0x6b, 0x2f, 0x56, 0x52,
0x75, 0x69, 0x2f, 0x31, 0x31, 0x42, 0x5a, 0x30, 0x48, 0x4c, 0x6f, 0x61,
0x4c, 0x65, 0x0a, 0x7a, 0x64, 0x42, 0x59, 0x39, 0x71, 0x45, 0x54, 0x72,
0x59, 0x71, 0x37, 0x72, 0x7a, 0x69, 0x47, 0x51, 0x6a, 0x75, 0x32, 0x64,
0x68, 0x55, 0x49, 0x45, 0x45, 0x4c, 0x58, 0x6f, 0x79, 0x62, 0x79, 0x58,
0x79, 0x67, 0x77, 0x4b, 0x42, 0x66, 0x50, 0x41, 0x78, 0x46, 0x78, 0x46,
0x38, 0x53, 0x49, 0x63, 0x54, 0x30, 0x62, 0x57, 0x46, 0x72, 0x5a, 0x41,
0x6f, 0x47, 0x41, 0x55, 0x6d, 0x69, 0x67, 0x0a, 0x4b, 0x6d, 0x79, 0x2f,
0x78, 0x35, 0x73, 0x62, 0x6f, 0x69, 0x69, 0x56, 0x44, 0x2f, 0x6d, 0x51,
0x6c, 0x74, 0x4b, 0x65, 0x35, 0x53, 0x42, 0x6e, 0x49, 0x48, 0x6c, 0x34,
0x4d, 0x41, 0x56, 0x4a, 0x71, 0x59, 0x6e, 0x65, 0x4f, 0x55, 0x66, 0x37,
0x6e, 0x62, 0x69, 0x56, 0x6b, 0x7a, 0x6b, 0x66, 0x61, 0x74, 0x50, 0x4f,
0x71, 0x47, 0x43, 0x6d, 0x57, 0x4a, 0x5a, 0x59, 0x62, 0x2f, 0x64, 0x4d,
0x0a, 0x32, 0x6b, 0x52, 0x46, 0x50, 0x35, 0x48, 0x62, 0x30, 0x39, 0x79,
0x6c, 0x32, 0x51, 0x6c, 0x50, 0x50, 0x47, 0x48, 0x56, 0x37, 0x42, 0x51,
0x31, 0x55, 0x75, 0x48, 0x50, 0x4b, 0x44, 0x58, 0x74, 0x54, 0x79, 0x47,
0x6f, 0x2f, 0x45, 0x38, 0x57, 0x33, 0x64, 0x77, 0x77, 0x38, 0x6f, 0x70,
0x46, 0x38, 0x6c, 0x46, 0x6f, 0x77, 0x77, 0x36, 0x61, 0x56, 0x62, 0x74,
0x4e, 0x47, 0x76, 0x72, 0x6d, 0x0a, 0x72, 0x31, 0x50, 0x4e, 0x4c, 0x2b,
0x63, 0x55, 0x2b, 0x2b, 0x6a, 0x5a, 0x77, 0x37, 0x47, 0x36, 0x61, 0x65,
0x30, 0x47, 0x31, 0x52, 0x53, 0x7a, 0x55, 0x2b, 0x32, 0x58, 0x4d, 0x36,
0x68, 0x55, 0x35, 0x70, 0x65, 0x71, 0x77, 0x53, 0x6b, 0x43, 0x67, 0x59,
0x45, 0x41, 0x67, 0x37, 0x37, 0x2f, 0x6f, 0x31, 0x67, 0x5a, 0x66, 0x58,
0x69, 0x58, 0x56, 0x69, 0x58, 0x52, 0x75, 0x2b, 0x4a, 0x38, 0x0a, 0x41,
0x30, 0x45, 0x44, 0x52, 0x4d, 0x30, 0x41, 0x43, 0x32, 0x79, 0x39, 0x62,
0x42, 0x75, 0x64, 0x7a, 0x44, 0x46, 0x4a, 0x46, 0x42, 0x47, 0x6b, 0x65,
0x38, 0x44, 0x4d, 0x58, 0x6d, 0x55, 0x62, 0x78, 0x47, 0x63, 0x48, 0x43,
0x62, 0x67, 0x75, 0x6e, 0x31, 0x77, 0x6c, 0x69, 0x4d, 0x44, 0x37, 0x32,
0x48, 0x45, 0x54, 0x62, 0x52, 0x77, 0x2f, 0x38, 0x2b, 0x32, 0x42, 0x6d,
0x55, 0x44, 0x31, 0x0a, 0x77, 0x46, 0x32, 0x38, 0x75, 0x4d, 0x4b, 0x4e,
0x43, 0x51, 0x70, 0x31, 0x2b, 0x6d, 0x44, 0x57, 0x34, 0x77, 0x68, 0x63,
0x31, 0x75, 0x6d, 0x6b, 0x6f, 0x33, 0x43, 0x75, 0x4c, 0x42, 0x42, 0x44,
0x58, 0x7a, 0x41, 0x59, 0x38, 0x4c, 0x30, 0x6e, 0x4d, 0x44, 0x55, 0x52,
0x71, 0x4a, 0x46, 0x69, 0x46, 0x56, 0x45, 0x35, 0x41, 0x47, 0x75, 0x53,
0x4e, 0x52, 0x74, 0x53, 0x50, 0x55, 0x48, 0x46, 0x0a, 0x46, 0x46, 0x6a,
0x6b, 0x37, 0x31, 0x4e, 0x30, 0x47, 0x57, 0x74, 0x64, 0x51, 0x53, 0x6f,
0x76, 0x70, 0x52, 0x2b, 0x47, 0x52, 0x44, 0x45, 0x3d, 0x0a, 0x2d, 0x2d,
0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x50, 0x52, 0x49, 0x56, 0x41,
0x54, 0x45, 0x20, 0x4b, 0x45, 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a
};
unsigned int CAKeyLength = 1704;

View File

@ -1,10 +1,10 @@
unsigned char TemplateSignatureBlob[] = {
0xfa, 0xde, 0x0b, 0x01, 0x00, 0x00, 0x1a, 0xbd, 0x30, 0x80, 0x06, 0x09,
unsigned char AppStoreSignatureBlob[] = {
0xfa, 0xde, 0x0b, 0x01, 0x00, 0x00, 0x11, 0x2e, 0x30, 0x80, 0x06, 0x09,
0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x80, 0x30,
0x80, 0x02, 0x01, 0x01, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x30, 0x80, 0x06,
0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x00, 0x00,
0xa0, 0x82, 0x12, 0x53, 0x30, 0x82, 0x04, 0x24, 0x30, 0x82, 0x03, 0x0c,
0xa0, 0x82, 0x0d, 0x2f, 0x30, 0x82, 0x04, 0x24, 0x30, 0x82, 0x03, 0x0c,
0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x40, 0x60, 0x57, 0xb3, 0xc9,
0xbf, 0x9d, 0xf0, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x73, 0x31, 0x2d, 0x30, 0x2b,
@ -285,290 +285,86 @@ unsigned char TemplateSignatureBlob[] = {
0xfb, 0xd8, 0xd5, 0x71, 0x9e, 0x7e, 0xa1, 0x52, 0xb7, 0x1b, 0xbd, 0x93,
0x42, 0x24, 0x12, 0x2a, 0xc7, 0x0f, 0x1d, 0xb6, 0x4d, 0x9c, 0x5e, 0x63,
0xc8, 0x4b, 0x80, 0x17, 0x50, 0xaa, 0x8a, 0xd5, 0xda, 0xe4, 0xfc, 0xd0,
0x09, 0x07, 0x37, 0xb0, 0x75, 0x75, 0x21, 0x30, 0x82, 0x05, 0x20, 0x30,
0x82, 0x04, 0x08, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14, 0x18, 0xa5,
0xfe, 0xfd, 0x11, 0xd9, 0xc4, 0xcc, 0x28, 0xd6, 0xf8, 0xff, 0xcf, 0xf4,
0x58, 0x6e, 0xc6, 0xc8, 0x3e, 0xf3, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81, 0xfc,
0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a,
0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x12,
0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70,
0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x34, 0x30, 0x32, 0x06, 0x03,
0x55, 0x04, 0x0a, 0x0c, 0x2b, 0x54, 0x72, 0x6f, 0x6c, 0x6c, 0x53, 0x74,
0x6f, 0x72, 0x65, 0x20, 0x32, 0x20, 0x69, 0x50, 0x68, 0x6f, 0x6e, 0x65,
0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69,
0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79,
0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x2a, 0x54,
0x72, 0x6f, 0x6c, 0x6c, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x20, 0x32, 0x20,
0x69, 0x50, 0x68, 0x6f, 0x6e, 0x65, 0x20, 0x4f, 0x53, 0x20, 0x41, 0x70,
0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x53, 0x69,
0x67, 0x6e, 0x69, 0x6e, 0x67, 0x31, 0x34, 0x30, 0x32, 0x06, 0x03, 0x55,
0x04, 0x03, 0x0c, 0x2b, 0x54, 0x72, 0x6f, 0x6c, 0x6c, 0x53, 0x74, 0x6f,
0x72, 0x65, 0x20, 0x32, 0x20, 0x69, 0x50, 0x68, 0x6f, 0x6e, 0x65, 0x20,
0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31,
0x23, 0x30, 0x21, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
0x09, 0x01, 0x16, 0x14, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x40, 0x63, 0x6f,
0x72, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x68, 0x61, 0x78, 0x78,
0x30, 0x1e, 0x17, 0x0d, 0x32, 0x33, 0x31, 0x31, 0x32, 0x36, 0x32, 0x30,
0x31, 0x39, 0x32, 0x36, 0x5a, 0x17, 0x0d, 0x33, 0x33, 0x31, 0x31, 0x32,
0x33, 0x32, 0x30, 0x31, 0x39, 0x32, 0x36, 0x5a, 0x30, 0x81, 0xfc, 0x31,
0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x43,
0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x12, 0x30,
0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65,
0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x34, 0x30, 0x32, 0x06, 0x03, 0x55,
0x04, 0x0a, 0x0c, 0x2b, 0x54, 0x72, 0x6f, 0x6c, 0x6c, 0x53, 0x74, 0x6f,
0x72, 0x65, 0x20, 0x32, 0x20, 0x69, 0x50, 0x68, 0x6f, 0x6e, 0x65, 0x20,
0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31,
0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x2a, 0x54, 0x72,
0x6f, 0x6c, 0x6c, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x20, 0x32, 0x20, 0x69,
0x50, 0x68, 0x6f, 0x6e, 0x65, 0x20, 0x4f, 0x53, 0x20, 0x41, 0x70, 0x70,
0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x53, 0x69, 0x67,
0x6e, 0x69, 0x6e, 0x67, 0x31, 0x34, 0x30, 0x32, 0x06, 0x03, 0x55, 0x04,
0x03, 0x0c, 0x2b, 0x54, 0x72, 0x6f, 0x6c, 0x6c, 0x53, 0x74, 0x6f, 0x72,
0x65, 0x20, 0x32, 0x20, 0x69, 0x50, 0x68, 0x6f, 0x6e, 0x65, 0x20, 0x43,
0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x23,
0x30, 0x21, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09,
0x01, 0x16, 0x14, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x40, 0x63, 0x6f, 0x72,
0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x68, 0x61, 0x78, 0x78, 0x30,
0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30,
0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xbe, 0x13, 0x2e, 0x48,
0x8a, 0x12, 0x98, 0x59, 0x4f, 0x4f, 0x5f, 0x5b, 0xd1, 0x4f, 0x97, 0x5c,
0xed, 0xe8, 0xd6, 0x43, 0xe9, 0x3e, 0x26, 0x82, 0x38, 0x22, 0x18, 0x56,
0x45, 0x21, 0xf6, 0xf0, 0xb8, 0xcf, 0xe3, 0x6a, 0x17, 0xdf, 0xce, 0x72,
0x6d, 0xad, 0xa8, 0x7d, 0x31, 0xf9, 0xa1, 0x4a, 0x73, 0xee, 0x07, 0x4b,
0x95, 0xa8, 0x58, 0x0e, 0x05, 0xd9, 0x07, 0x5b, 0x3d, 0x47, 0xbb, 0xce,
0x7d, 0x7e, 0x4b, 0x30, 0x76, 0xe4, 0xe4, 0x2a, 0x9f, 0x48, 0x46, 0x3c,
0xe8, 0x23, 0xeb, 0x6b, 0xc7, 0xaf, 0xd5, 0x64, 0x23, 0x66, 0xff, 0x25,
0xda, 0x6a, 0x7e, 0x95, 0x3e, 0xc3, 0x0d, 0xe6, 0xc6, 0x06, 0x90, 0xc6,
0x8a, 0x2f, 0x1f, 0xcb, 0x63, 0x88, 0xa0, 0x3c, 0x9d, 0xca, 0x85, 0x67,
0x80, 0x6e, 0xe1, 0x4e, 0xb7, 0x61, 0xfe, 0x81, 0x8b, 0x53, 0x07, 0x34,
0x56, 0x58, 0xa6, 0x46, 0x58, 0x60, 0x24, 0x44, 0xac, 0xa7, 0x5c, 0xba,
0xab, 0xc1, 0x74, 0x6d, 0x5c, 0x81, 0xe2, 0x1b, 0xb8, 0x3a, 0x87, 0xec,
0x08, 0x86, 0x9d, 0x86, 0xf9, 0xc9, 0x0c, 0x5d, 0xf4, 0x5c, 0xd9, 0xf8,
0x7a, 0x7e, 0x20, 0xa5, 0x95, 0x52, 0x70, 0x4b, 0xf4, 0x96, 0x7e, 0xe4,
0x30, 0x11, 0x2f, 0x5c, 0x19, 0x0e, 0xa6, 0x6b, 0x97, 0x52, 0x68, 0xd7,
0xd7, 0x67, 0xe9, 0x91, 0xda, 0xea, 0xcb, 0xd4, 0x70, 0xba, 0x11, 0x08,
0xb8, 0x54, 0xb8, 0x48, 0x61, 0x42, 0xe0, 0xae, 0x53, 0x23, 0xc0, 0x17,
0xbd, 0x6d, 0xb1, 0xa5, 0x13, 0xa0, 0x65, 0xb5, 0xea, 0x91, 0x9a, 0xa5,
0x2f, 0x8e, 0xc2, 0x3b, 0x91, 0x70, 0x9d, 0x9e, 0x6e, 0x9f, 0x3e, 0x67,
0xd3, 0xd7, 0x62, 0x3b, 0xdc, 0x96, 0x1e, 0xf3, 0x0b, 0x47, 0xaf, 0x26,
0x3c, 0xdd, 0x0e, 0x00, 0xbf, 0x6f, 0x24, 0x9e, 0x07, 0x3c, 0xe5, 0x5d,
0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0x97, 0x30, 0x81, 0x94, 0x30,
0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30,
0x03, 0x01, 0x01, 0xff, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01,
0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x02, 0x84, 0x30, 0x13, 0x06, 0x03,
0x55, 0x1d, 0x25, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06, 0x01,
0x05, 0x05, 0x07, 0x03, 0x03, 0x30, 0x12, 0x06, 0x09, 0x2a, 0x86, 0x48,
0x86, 0xf7, 0x63, 0x64, 0x06, 0x16, 0x01, 0x01, 0xff, 0x04, 0x02, 0x05,
0x00, 0x30, 0x13, 0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64,
0x06, 0x01, 0x03, 0x01, 0x01, 0xff, 0x04, 0x02, 0x05, 0x00, 0x30, 0x14,
0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x06, 0x01, 0x19,
0x01, 0x01, 0x01, 0xff, 0x04, 0x02, 0x05, 0x00, 0x30, 0x1d, 0x06, 0x03,
0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x97, 0x90, 0xd2, 0x7e, 0x87,
0x35, 0x8a, 0x0b, 0xd1, 0x92, 0xf5, 0xcf, 0xe4, 0xac, 0xd2, 0x14, 0x35,
0x29, 0x08, 0xe2, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xaf,
0xec, 0x00, 0x5b, 0x9f, 0xd7, 0x13, 0x93, 0xed, 0x33, 0xed, 0x89, 0x31,
0xb5, 0x65, 0x98, 0x7d, 0xda, 0x9a, 0x64, 0x39, 0x1d, 0x57, 0x7c, 0x94,
0x15, 0x45, 0x72, 0x2a, 0xcd, 0xa2, 0x27, 0x64, 0xbf, 0xcd, 0x85, 0xfb,
0x31, 0x6f, 0x5c, 0x95, 0x7d, 0xda, 0xcf, 0x45, 0x42, 0x2f, 0x16, 0x1c,
0xcc, 0xbe, 0x04, 0x54, 0xe9, 0x2b, 0xf6, 0xa3, 0xed, 0x39, 0xbf, 0xa9,
0x07, 0x30, 0x2e, 0x7f, 0x7f, 0x4f, 0xf8, 0xe3, 0x57, 0x46, 0x14, 0x13,
0xf2, 0x63, 0xec, 0xeb, 0x6d, 0x45, 0x3e, 0x7b, 0xff, 0xac, 0x12, 0xb0,
0xc5, 0x88, 0x28, 0xd4, 0x90, 0x1f, 0xee, 0xff, 0xbc, 0x44, 0xd3, 0xed,
0x31, 0xb8, 0x9a, 0x97, 0xc9, 0x55, 0xcd, 0x8d, 0x3e, 0x1d, 0x7b, 0x2d,
0xb9, 0x3f, 0x22, 0xbc, 0xf5, 0x0a, 0x03, 0x97, 0x34, 0x5d, 0x7a, 0xc2,
0x76, 0xd6, 0xd9, 0x31, 0x83, 0x9a, 0x0e, 0x0b, 0x37, 0xbb, 0x5f, 0xd6,
0x51, 0xb0, 0xe7, 0x4e, 0xd9, 0x2c, 0xea, 0x1b, 0x09, 0x0f, 0x39, 0x82,
0x33, 0xd2, 0xda, 0x40, 0x1d, 0xce, 0x88, 0xe6, 0x38, 0xa4, 0xb9, 0x5b,
0x19, 0x4a, 0x81, 0x4c, 0xab, 0x5e, 0x26, 0xdf, 0x84, 0xc7, 0x32, 0x53,
0x48, 0x27, 0xce, 0x7e, 0x1c, 0xa8, 0x2d, 0xaa, 0xa9, 0x23, 0x65, 0x36,
0xcd, 0x47, 0x8e, 0x78, 0x2e, 0x50, 0x63, 0x1d, 0x1b, 0xeb, 0x67, 0xa6,
0x52, 0x25, 0x90, 0x17, 0x82, 0x2a, 0xce, 0xda, 0x28, 0x25, 0x81, 0x97,
0xce, 0x6c, 0x78, 0x95, 0x82, 0x61, 0x57, 0xf1, 0x51, 0x01, 0xfe, 0x4d,
0xfa, 0xd7, 0xff, 0xa7, 0xd1, 0x77, 0x95, 0x23, 0xf2, 0xf9, 0x96, 0xfc,
0xed, 0xf5, 0x91, 0x1a, 0x02, 0x6d, 0x73, 0x16, 0xd0, 0x29, 0xe5, 0xb4,
0xc8, 0x8f, 0xa1, 0x44, 0xbc, 0x67, 0x60, 0xf5, 0xac, 0xeb, 0x52, 0x4b,
0xa7, 0x44, 0xa7, 0x31, 0x82, 0x08, 0x20, 0x30, 0x82, 0x04, 0x67, 0x02,
0x01, 0x01, 0x30, 0x82, 0x01, 0x15, 0x30, 0x81, 0xfc, 0x31, 0x0b, 0x30,
0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13,
0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x43, 0x61, 0x6c,
0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x12, 0x30, 0x10, 0x06,
0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74,
0x69, 0x6e, 0x6f, 0x31, 0x34, 0x30, 0x32, 0x06, 0x03, 0x55, 0x04, 0x0a,
0x0c, 0x2b, 0x54, 0x72, 0x6f, 0x6c, 0x6c, 0x53, 0x74, 0x6f, 0x72, 0x65,
0x20, 0x32, 0x20, 0x69, 0x50, 0x68, 0x6f, 0x6e, 0x65, 0x20, 0x43, 0x65,
0x09, 0x07, 0x37, 0xb0, 0x75, 0x75, 0x21, 0x31, 0x82, 0x03, 0xb5, 0x30,
0x82, 0x03, 0xb1, 0x02, 0x01, 0x01, 0x30, 0x7f, 0x30, 0x73, 0x31, 0x2d,
0x30, 0x2b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x24, 0x41, 0x70, 0x70,
0x6c, 0x65, 0x20, 0x69, 0x50, 0x68, 0x6f, 0x6e, 0x65, 0x20, 0x43, 0x65,
0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20,
0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x33, 0x30,
0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x2a, 0x54, 0x72, 0x6f, 0x6c,
0x6c, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x20, 0x32, 0x20, 0x69, 0x50, 0x68,
0x6f, 0x6e, 0x65, 0x20, 0x4f, 0x53, 0x20, 0x41, 0x70, 0x70, 0x6c, 0x69,
0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x69,
0x6e, 0x67, 0x31, 0x34, 0x30, 0x32, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c,
0x2b, 0x54, 0x72, 0x6f, 0x6c, 0x6c, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x20,
0x32, 0x20, 0x69, 0x50, 0x68, 0x6f, 0x6e, 0x65, 0x20, 0x43, 0x65, 0x72,
0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41,
0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x23, 0x30, 0x21,
0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16,
0x14, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x40, 0x63, 0x6f, 0x72, 0x65, 0x74,
0x72, 0x75, 0x73, 0x74, 0x2e, 0x68, 0x61, 0x78, 0x78, 0x02, 0x14, 0x18,
0xa5, 0xfe, 0xfd, 0x11, 0xd9, 0xc4, 0xcc, 0x28, 0xd6, 0xf8, 0xff, 0xcf,
0xf4, 0x58, 0x6e, 0xc6, 0xc8, 0x3e, 0xf3, 0x30, 0x0d, 0x06, 0x09, 0x60,
0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0xa0, 0x82,
0x02, 0x25, 0x30, 0x18, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
0x01, 0x09, 0x03, 0x31, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
0x0d, 0x01, 0x07, 0x01, 0x30, 0x1c, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
0xf7, 0x0d, 0x01, 0x09, 0x05, 0x31, 0x0f, 0x17, 0x0d, 0x32, 0x33, 0x31,
0x31, 0x32, 0x36, 0x32, 0x30, 0x33, 0x34, 0x32, 0x39, 0x5a, 0x30, 0x2f,
0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x04, 0x31,
0x22, 0x04, 0x20, 0xc2, 0x96, 0x8f, 0x4a, 0x63, 0xc0, 0xcf, 0xb6, 0xcd,
0x82, 0xb8, 0x48, 0xe2, 0x04, 0x3d, 0xa0, 0x71, 0xfe, 0xa3, 0x66, 0x32,
0x8c, 0xb4, 0xe0, 0x94, 0x12, 0xdb, 0xb5, 0x73, 0x96, 0xc4, 0xc4, 0x30,
0x5b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x09, 0x02,
0x31, 0x4e, 0x30, 0x1d, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x04,
0x14, 0x51, 0xf9, 0xbc, 0xa2, 0x95, 0xbe, 0x9c, 0x2e, 0x1d, 0xee, 0x77,
0xd0, 0x93, 0xce, 0x0f, 0xcf, 0x3f, 0xc9, 0x34, 0x50, 0x30, 0x2d, 0x06,
0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x04, 0x20,
0xb8, 0xca, 0x7d, 0x9d, 0xef, 0xa9, 0xcf, 0xd2, 0x00, 0x90, 0x38, 0x28,
0x1d, 0x0a, 0xa7, 0x2f, 0xca, 0x77, 0xd7, 0xa4, 0x6b, 0xae, 0x73, 0x93,
0x60, 0xf8, 0x61, 0x98, 0xd2, 0x1a, 0x38, 0xe6, 0x30, 0x82, 0x01, 0x5b,
0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x09, 0x01, 0x31,
0x82, 0x01, 0x4c, 0x04, 0x82, 0x01, 0x48, 0x3c, 0x3f, 0x78, 0x6d, 0x6c,
0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x22, 0x31, 0x2e,
0x30, 0x22, 0x20, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x3d,
0x22, 0x55, 0x54, 0x46, 0x2d, 0x38, 0x22, 0x3f, 0x3e, 0x0a, 0x3c, 0x21,
0x44, 0x4f, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, 0x70, 0x6c, 0x69, 0x73,
0x74, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x20, 0x22, 0x2d, 0x2f,
0x2f, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2f, 0x2f, 0x44, 0x54, 0x44, 0x20,
0x50, 0x4c, 0x49, 0x53, 0x54, 0x20, 0x31, 0x2e, 0x30, 0x2f, 0x2f, 0x45,
0x4e, 0x22, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77,
0x77, 0x77, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d,
0x2f, 0x44, 0x54, 0x44, 0x73, 0x2f, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72,
0x74, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x2d, 0x31, 0x2e, 0x30, 0x2e, 0x64,
0x74, 0x64, 0x22, 0x3e, 0x0a, 0x3c, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x20,
0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x22, 0x31, 0x2e, 0x30,
0x22, 0x3e, 0x0a, 0x3c, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09, 0x3c,
0x6b, 0x65, 0x79, 0x3e, 0x63, 0x64, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73,
0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x3c, 0x61, 0x72, 0x72,
0x61, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x64, 0x61, 0x74, 0x61, 0x3e,
0x0a, 0x09, 0x09, 0x55, 0x66, 0x6d, 0x38, 0x6f, 0x70, 0x57, 0x2b, 0x6e,
0x43, 0x34, 0x64, 0x37, 0x6e, 0x66, 0x51, 0x6b, 0x38, 0x34, 0x50, 0x7a,
0x7a, 0x2f, 0x4a, 0x4e, 0x46, 0x41, 0x3d, 0x0a, 0x09, 0x09, 0x3c, 0x2f,
0x64, 0x61, 0x74, 0x61, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x64, 0x61, 0x74,
0x61, 0x3e, 0x0a, 0x09, 0x09, 0x75, 0x4d, 0x70, 0x39, 0x6e, 0x65, 0x2b,
0x70, 0x7a, 0x39, 0x49, 0x41, 0x6b, 0x44, 0x67, 0x6f, 0x48, 0x51, 0x71,
0x6e, 0x4c, 0x38, 0x70, 0x33, 0x31, 0x36, 0x51, 0x3d, 0x0a, 0x09, 0x09,
0x3c, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x3e, 0x0a, 0x09, 0x3c, 0x2f, 0x61,
0x72, 0x72, 0x61, 0x79, 0x3e, 0x0a, 0x3c, 0x2f, 0x64, 0x69, 0x63, 0x74,
0x3e, 0x0a, 0x3c, 0x2f, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x3e, 0x0a, 0x30,
0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
0x05, 0x00, 0x04, 0x82, 0x01, 0x00, 0x8a, 0x4f, 0xdd, 0xcf, 0x23, 0x66,
0x89, 0x82, 0x87, 0x09, 0x5e, 0x07, 0x11, 0x65, 0x40, 0xb9, 0xb3, 0x8d,
0x01, 0xe1, 0x4d, 0x1b, 0x8e, 0x62, 0x4a, 0x5b, 0x58, 0xeb, 0x47, 0xdc,
0x16, 0xcf, 0x38, 0x9e, 0x58, 0xa5, 0xd5, 0xf4, 0xc5, 0x4f, 0x29, 0x4f,
0x60, 0x33, 0xb0, 0x92, 0x37, 0xb8, 0x09, 0x57, 0x2b, 0x96, 0xac, 0x26,
0xff, 0x16, 0xea, 0x99, 0x5e, 0x59, 0x82, 0x6b, 0xdf, 0x30, 0x74, 0x56,
0x21, 0xf8, 0x74, 0xa7, 0x30, 0xc5, 0x39, 0x51, 0x3e, 0x9f, 0xb4, 0x72,
0x2b, 0xe4, 0x38, 0xba, 0xf7, 0x3e, 0xc4, 0x32, 0x44, 0x26, 0xd7, 0xf9,
0x2e, 0xd3, 0x1b, 0xae, 0x9b, 0x11, 0x53, 0x18, 0x30, 0x62, 0xd9, 0x2f,
0xcf, 0x75, 0x5d, 0x58, 0x96, 0xee, 0x25, 0x1e, 0x1c, 0x56, 0x0a, 0x73,
0xeb, 0x92, 0x36, 0x72, 0x9c, 0x50, 0x6f, 0x95, 0x52, 0xdc, 0xf7, 0xb1,
0xd3, 0xdb, 0x8a, 0x63, 0xa0, 0xaf, 0x92, 0x8a, 0xee, 0x6c, 0xf3, 0xda,
0xe7, 0x80, 0xb5, 0x91, 0x84, 0x44, 0x67, 0xa2, 0xf9, 0x57, 0x3e, 0x32,
0x32, 0x3d, 0xa7, 0x08, 0x49, 0xd2, 0x36, 0xce, 0xd6, 0x80, 0x05, 0x59,
0xe2, 0xa7, 0xc3, 0xcc, 0xa4, 0x03, 0xdd, 0xfd, 0x03, 0x43, 0xa6, 0x40,
0xa1, 0xe0, 0x13, 0x82, 0x00, 0xf9, 0x92, 0x0e, 0x10, 0x21, 0x32, 0xc8,
0x64, 0x04, 0x7d, 0x2c, 0x02, 0x00, 0x45, 0xf8, 0xf1, 0x51, 0x15, 0xc6,
0x5d, 0xed, 0x5b, 0xfa, 0x93, 0x66, 0x92, 0x56, 0xd6, 0xce, 0x71, 0x5b,
0xd3, 0x98, 0xad, 0x6d, 0x65, 0x09, 0xef, 0x4e, 0x32, 0xd7, 0x45, 0x67,
0xdb, 0x98, 0x15, 0x28, 0xfa, 0xa2, 0x1c, 0x10, 0xdb, 0x79, 0x78, 0x0b,
0x10, 0x4c, 0xf7, 0x0e, 0x2a, 0xb6, 0x4a, 0xfb, 0x58, 0x57, 0x5f, 0xd6,
0x06, 0x52, 0x0a, 0xe1, 0xd7, 0xbe, 0x4a, 0xb5, 0x63, 0x48, 0x30, 0x82,
0x03, 0xb1, 0x02, 0x01, 0x01, 0x30, 0x7f, 0x30, 0x73, 0x31, 0x2d, 0x30,
0x2b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x24, 0x41, 0x70, 0x70, 0x6c,
0x65, 0x20, 0x69, 0x50, 0x68, 0x6f, 0x6e, 0x65, 0x20, 0x43, 0x65, 0x72,
0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41,
0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x20, 0x30, 0x1e,
0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x17, 0x43, 0x65, 0x72, 0x74, 0x69,
0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74,
0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
0x55, 0x04, 0x0a, 0x0c, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49,
0x6e, 0x63, 0x2e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
0x13, 0x02, 0x55, 0x53, 0x02, 0x08, 0x40, 0x60, 0x57, 0xb3, 0xc9, 0xbf,
0x9d, 0xf0, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
0x04, 0x02, 0x01, 0x05, 0x00, 0xa0, 0x82, 0x02, 0x07, 0x30, 0x18, 0x06,
0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x03, 0x31, 0x0b,
0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x30,
0x2f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x04,
0x31, 0x22, 0x04, 0x20, 0xc2, 0x96, 0x8f, 0x4a, 0x63, 0xc0, 0xcf, 0xb6,
0xcd, 0x82, 0xb8, 0x48, 0xe2, 0x04, 0x3d, 0xa0, 0x71, 0xfe, 0xa3, 0x66,
0x32, 0x8c, 0xb4, 0xe0, 0x94, 0x12, 0xdb, 0xb5, 0x73, 0x96, 0xc4, 0xc4,
0x30, 0x5b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x09,
0x02, 0x31, 0x4e, 0x30, 0x1d, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a,
0x04, 0x14, 0x51, 0xf9, 0xbc, 0xa2, 0x95, 0xbe, 0x9c, 0x2e, 0x1d, 0xee,
0x77, 0xd0, 0x93, 0xce, 0x0f, 0xcf, 0x3f, 0xc9, 0x34, 0x50, 0x30, 0x2d,
0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x04,
0x20, 0x93, 0x72, 0x19, 0xc3, 0x98, 0x18, 0xd7, 0x7d, 0x0c, 0x7b, 0x93,
0x6c, 0xba, 0xd6, 0x2c, 0xa4, 0x4c, 0x44, 0xb7, 0xa4, 0xaa, 0x7c, 0x50,
0x40, 0x93, 0x6f, 0x30, 0xb3, 0xe1, 0x19, 0xb0, 0x40, 0x30, 0x82, 0x01,
0x5b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x09, 0x01,
0x31, 0x82, 0x01, 0x4c, 0x04, 0x82, 0x01, 0x48, 0x3c, 0x3f, 0x78, 0x6d,
0x6c, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x22, 0x31,
0x2e, 0x30, 0x22, 0x20, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67,
0x3d, 0x22, 0x55, 0x54, 0x46, 0x2d, 0x38, 0x22, 0x3f, 0x3e, 0x0a, 0x3c,
0x21, 0x44, 0x4f, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, 0x70, 0x6c, 0x69,
0x73, 0x74, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x20, 0x22, 0x2d,
0x2f, 0x2f, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2f, 0x2f, 0x44, 0x54, 0x44,
0x20, 0x50, 0x4c, 0x49, 0x53, 0x54, 0x20, 0x31, 0x2e, 0x30, 0x2f, 0x2f,
0x45, 0x4e, 0x22, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
0x77, 0x77, 0x77, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f,
0x6d, 0x2f, 0x44, 0x54, 0x44, 0x73, 0x2f, 0x50, 0x72, 0x6f, 0x70, 0x65,
0x72, 0x74, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x2d, 0x31, 0x2e, 0x30, 0x2e,
0x64, 0x74, 0x64, 0x22, 0x3e, 0x0a, 0x3c, 0x70, 0x6c, 0x69, 0x73, 0x74,
0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x22, 0x31, 0x2e,
0x30, 0x22, 0x3e, 0x0a, 0x3c, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09,
0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x64, 0x68, 0x61, 0x73, 0x68, 0x65,
0x73, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x3c, 0x61, 0x72,
0x72, 0x61, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x64, 0x61, 0x74, 0x61,
0x3e, 0x0a, 0x09, 0x09, 0x55, 0x66, 0x6d, 0x38, 0x6f, 0x70, 0x57, 0x2b,
0x6e, 0x43, 0x34, 0x64, 0x37, 0x6e, 0x66, 0x51, 0x6b, 0x38, 0x34, 0x50,
0x7a, 0x7a, 0x2f, 0x4a, 0x4e, 0x46, 0x41, 0x3d, 0x0a, 0x09, 0x09, 0x3c,
0x2f, 0x64, 0x61, 0x74, 0x61, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x64, 0x61,
0x74, 0x61, 0x3e, 0x0a, 0x09, 0x09, 0x6b, 0x33, 0x49, 0x5a, 0x77, 0x35,
0x67, 0x59, 0x31, 0x33, 0x30, 0x4d, 0x65, 0x35, 0x4e, 0x73, 0x75, 0x74,
0x59, 0x73, 0x70, 0x45, 0x78, 0x45, 0x74, 0x36, 0x51, 0x3d, 0x0a, 0x09,
0x09, 0x3c, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x3e, 0x0a, 0x09, 0x3c, 0x2f,
0x61, 0x72, 0x72, 0x61, 0x79, 0x3e, 0x0a, 0x3c, 0x2f, 0x64, 0x69, 0x63,
0x74, 0x3e, 0x0a, 0x3c, 0x2f, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x3e, 0x0a,
0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
0x0b, 0x05, 0x00, 0x04, 0x82, 0x01, 0x00, 0x3b, 0x3d, 0x60, 0x8d, 0xa2,
0x95, 0x1e, 0x5b, 0xa6, 0x02, 0xb4, 0x71, 0xc3, 0xfa, 0x01, 0xf0, 0x1c,
0x1f, 0x15, 0x8d, 0xf0, 0x15, 0xcb, 0x76, 0x6a, 0xfd, 0xb4, 0x95, 0x14,
0x6f, 0xea, 0x4c, 0x1b, 0xf1, 0x32, 0x80, 0xe7, 0x97, 0x04, 0x00, 0x07,
0x4d, 0x86, 0x73, 0xbe, 0x5c, 0xd4, 0x13, 0xe4, 0x31, 0xb7, 0x94, 0xc0,
0x6a, 0xf9, 0x4a, 0x48, 0x7a, 0x44, 0xde, 0x67, 0xc8, 0xb2, 0xcd, 0xed,
0x2c, 0xff, 0x80, 0xec, 0x96, 0xc1, 0x2e, 0x37, 0x13, 0x67, 0x1b, 0xa3,
0x54, 0x63, 0x88, 0x84, 0x5d, 0x1a, 0xca, 0xc9, 0x58, 0xec, 0xca, 0x82,
0x38, 0x8d, 0x29, 0x1c, 0xca, 0x58, 0x50, 0xc4, 0xd0, 0x91, 0xba, 0x22,
0x7e, 0x73, 0x00, 0x58, 0x48, 0x5d, 0x49, 0xbd, 0xe7, 0xde, 0x35, 0x23,
0xfa, 0x60, 0x93, 0x12, 0x98, 0x2f, 0xf6, 0x8b, 0x38, 0x54, 0x32, 0x75,
0x0a, 0x3b, 0xed, 0x7f, 0x6a, 0x78, 0xf7, 0x87, 0x30, 0x49, 0xf4, 0x1f,
0x0d, 0x0a, 0x8b, 0xb7, 0xa7, 0x7e, 0x69, 0x48, 0x34, 0x6c, 0x9b, 0x77,
0xce, 0x0e, 0x68, 0xd9, 0x30, 0xb2, 0xc6, 0xa3, 0x30, 0x8a, 0x87, 0xd9,
0x25, 0xd7, 0x58, 0xc1, 0xae, 0x33, 0x4f, 0xeb, 0x2c, 0xcb, 0xf2, 0xb2,
0xe8, 0x2d, 0xa9, 0x4c, 0xa8, 0xd8, 0x64, 0x8b, 0x91, 0xdc, 0xb6, 0x55,
0x69, 0x84, 0x43, 0x4b, 0x75, 0xe6, 0xba, 0xd6, 0x58, 0x5b, 0x5e, 0xe7,
0x91, 0x5a, 0x69, 0x9b, 0xb6, 0x45, 0x7f, 0x1a, 0x9f, 0x0b, 0x87, 0xac,
0x4c, 0xc8, 0x58, 0x59, 0x18, 0x25, 0x02, 0x6c, 0xb2, 0x66, 0xf1, 0x2c,
0xc7, 0xaf, 0x68, 0x7a, 0x0e, 0x82, 0x93, 0x27, 0xd8, 0x75, 0x01, 0xdf,
0xd4, 0xa7, 0xba, 0xa5, 0x6e, 0xb2, 0x16, 0x49, 0x9a, 0xef, 0xdf, 0xec,
0xa7, 0x15, 0x78, 0x05, 0x68, 0x37, 0xaf, 0xf6, 0xfb, 0xa9, 0x3b, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00
0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x20, 0x30,
0x1e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x17, 0x43, 0x65, 0x72, 0x74,
0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75,
0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x13, 0x30, 0x11, 0x06,
0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20,
0x49, 0x6e, 0x63, 0x2e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
0x06, 0x13, 0x02, 0x55, 0x53, 0x02, 0x08, 0x40, 0x60, 0x57, 0xb3, 0xc9,
0xbf, 0x9d, 0xf0, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65,
0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0xa0, 0x82, 0x02, 0x07, 0x30, 0x18,
0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x03, 0x31,
0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01,
0x30, 0x2f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09,
0x04, 0x31, 0x22, 0x04, 0x20, 0xc2, 0x96, 0x8f, 0x4a, 0x63, 0xc0, 0xcf,
0xb6, 0xcd, 0x82, 0xb8, 0x48, 0xe2, 0x04, 0x3d, 0xa0, 0x71, 0xfe, 0xa3,
0x66, 0x32, 0x8c, 0xb4, 0xe0, 0x94, 0x12, 0xdb, 0xb5, 0x73, 0x96, 0xc4,
0xc4, 0x30, 0x5b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64,
0x09, 0x02, 0x31, 0x4e, 0x30, 0x1d, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
0x1a, 0x04, 0x14, 0x51, 0xf9, 0xbc, 0xa2, 0x95, 0xbe, 0x9c, 0x2e, 0x1d,
0xee, 0x77, 0xd0, 0x93, 0xce, 0x0f, 0xcf, 0x3f, 0xc9, 0x34, 0x50, 0x30,
0x2d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01,
0x04, 0x20, 0x93, 0x72, 0x19, 0xc3, 0x98, 0x18, 0xd7, 0x7d, 0x0c, 0x7b,
0x93, 0x6c, 0xba, 0xd6, 0x2c, 0xa4, 0x4c, 0x44, 0xb7, 0xa4, 0xaa, 0x7c,
0x50, 0x40, 0x93, 0x6f, 0x30, 0xb3, 0xe1, 0x19, 0xb0, 0x40, 0x30, 0x82,
0x01, 0x5b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x09,
0x01, 0x31, 0x82, 0x01, 0x4c, 0x04, 0x82, 0x01, 0x48, 0x3c, 0x3f, 0x78,
0x6d, 0x6c, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x22,
0x31, 0x2e, 0x30, 0x22, 0x20, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e,
0x67, 0x3d, 0x22, 0x55, 0x54, 0x46, 0x2d, 0x38, 0x22, 0x3f, 0x3e, 0x0a,
0x3c, 0x21, 0x44, 0x4f, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, 0x70, 0x6c,
0x69, 0x73, 0x74, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x20, 0x22,
0x2d, 0x2f, 0x2f, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2f, 0x2f, 0x44, 0x54,
0x44, 0x20, 0x50, 0x4c, 0x49, 0x53, 0x54, 0x20, 0x31, 0x2e, 0x30, 0x2f,
0x2f, 0x45, 0x4e, 0x22, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
0x2f, 0x77, 0x77, 0x77, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63,
0x6f, 0x6d, 0x2f, 0x44, 0x54, 0x44, 0x73, 0x2f, 0x50, 0x72, 0x6f, 0x70,
0x65, 0x72, 0x74, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x2d, 0x31, 0x2e, 0x30,
0x2e, 0x64, 0x74, 0x64, 0x22, 0x3e, 0x0a, 0x3c, 0x70, 0x6c, 0x69, 0x73,
0x74, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x22, 0x31,
0x2e, 0x30, 0x22, 0x3e, 0x0a, 0x3c, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a,
0x09, 0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x64, 0x68, 0x61, 0x73, 0x68,
0x65, 0x73, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x3c, 0x61,
0x72, 0x72, 0x61, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x64, 0x61, 0x74,
0x61, 0x3e, 0x0a, 0x09, 0x09, 0x55, 0x66, 0x6d, 0x38, 0x6f, 0x70, 0x57,
0x2b, 0x6e, 0x43, 0x34, 0x64, 0x37, 0x6e, 0x66, 0x51, 0x6b, 0x38, 0x34,
0x50, 0x7a, 0x7a, 0x2f, 0x4a, 0x4e, 0x46, 0x41, 0x3d, 0x0a, 0x09, 0x09,
0x3c, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x64,
0x61, 0x74, 0x61, 0x3e, 0x0a, 0x09, 0x09, 0x6b, 0x33, 0x49, 0x5a, 0x77,
0x35, 0x67, 0x59, 0x31, 0x33, 0x30, 0x4d, 0x65, 0x35, 0x4e, 0x73, 0x75,
0x74, 0x59, 0x73, 0x70, 0x45, 0x78, 0x45, 0x74, 0x36, 0x51, 0x3d, 0x0a,
0x09, 0x09, 0x3c, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x3e, 0x0a, 0x09, 0x3c,
0x2f, 0x61, 0x72, 0x72, 0x61, 0x79, 0x3e, 0x0a, 0x3c, 0x2f, 0x64, 0x69,
0x63, 0x74, 0x3e, 0x0a, 0x3c, 0x2f, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x3e,
0x0a, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
0x01, 0x0b, 0x05, 0x00, 0x04, 0x82, 0x01, 0x00, 0x3b, 0x3d, 0x60, 0x8d,
0xa2, 0x95, 0x1e, 0x5b, 0xa6, 0x02, 0xb4, 0x71, 0xc3, 0xfa, 0x01, 0xf0,
0x1c, 0x1f, 0x15, 0x8d, 0xf0, 0x15, 0xcb, 0x76, 0x6a, 0xfd, 0xb4, 0x95,
0x14, 0x6f, 0xea, 0x4c, 0x1b, 0xf1, 0x32, 0x80, 0xe7, 0x97, 0x04, 0x00,
0x07, 0x4d, 0x86, 0x73, 0xbe, 0x5c, 0xd4, 0x13, 0xe4, 0x31, 0xb7, 0x94,
0xc0, 0x6a, 0xf9, 0x4a, 0x48, 0x7a, 0x44, 0xde, 0x67, 0xc8, 0xb2, 0xcd,
0xed, 0x2c, 0xff, 0x80, 0xec, 0x96, 0xc1, 0x2e, 0x37, 0x13, 0x67, 0x1b,
0xa3, 0x54, 0x63, 0x88, 0x84, 0x5d, 0x1a, 0xca, 0xc9, 0x58, 0xec, 0xca,
0x82, 0x38, 0x8d, 0x29, 0x1c, 0xca, 0x58, 0x50, 0xc4, 0xd0, 0x91, 0xba,
0x22, 0x7e, 0x73, 0x00, 0x58, 0x48, 0x5d, 0x49, 0xbd, 0xe7, 0xde, 0x35,
0x23, 0xfa, 0x60, 0x93, 0x12, 0x98, 0x2f, 0xf6, 0x8b, 0x38, 0x54, 0x32,
0x75, 0x0a, 0x3b, 0xed, 0x7f, 0x6a, 0x78, 0xf7, 0x87, 0x30, 0x49, 0xf4,
0x1f, 0x0d, 0x0a, 0x8b, 0xb7, 0xa7, 0x7e, 0x69, 0x48, 0x34, 0x6c, 0x9b,
0x77, 0xce, 0x0e, 0x68, 0xd9, 0x30, 0xb2, 0xc6, 0xa3, 0x30, 0x8a, 0x87,
0xd9, 0x25, 0xd7, 0x58, 0xc1, 0xae, 0x33, 0x4f, 0xeb, 0x2c, 0xcb, 0xf2,
0xb2, 0xe8, 0x2d, 0xa9, 0x4c, 0xa8, 0xd8, 0x64, 0x8b, 0x91, 0xdc, 0xb6,
0x55, 0x69, 0x84, 0x43, 0x4b, 0x75, 0xe6, 0xba, 0xd6, 0x58, 0x5b, 0x5e,
0xe7, 0x91, 0x5a, 0x69, 0x9b, 0xb6, 0x45, 0x7f, 0x1a, 0x9f, 0x0b, 0x87,
0xac, 0x4c, 0xc8, 0x58, 0x59, 0x18, 0x25, 0x02, 0x6c, 0xb2, 0x66, 0xf1,
0x2c, 0xc7, 0xaf, 0x68, 0x7a, 0x0e, 0x82, 0x93, 0x27, 0xd8, 0x75, 0x01,
0xdf, 0xd4, 0xa7, 0xba, 0xa5, 0x6e, 0xb2, 0x16, 0x49, 0x9a, 0xef, 0xdf,
0xec, 0xa7, 0x15, 0x78, 0x05, 0x68, 0x37, 0xaf, 0xf6, 0xfb, 0xa9, 0x3b,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
unsigned int TemplateSignatureBlob_len = 6845;
unsigned int AppStoreSignatureBlob_len = 4398;

View File

@ -1,127 +1,242 @@
#include <CoreFoundation/CoreFoundation.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <dirent.h>
#include <sys/stat.h>
#include <choma/CSBlob.h>
#include <choma/MachOByteOrder.h>
#include <choma/MachO.h>
#include <choma/Host.h>
#include <choma/MemoryStream.h>
#include <choma/FileStream.h>
#include <choma/BufferedStream.h>
#include <choma/Signing.h>
#include <choma/SignOSSL.h>
#include <choma/CodeDirectory.h>
#include <choma/Base64.h>
#include "CSBlob.h"
#include "MachOByteOrder.h"
#include "MachO.h"
#include "Host.h"
#include "MemoryStream.h"
#include "FileStream.h"
#include "BufferedStream.h"
#include "CodeDirectory.h"
#include "Base64.h"
#include "Templates/AppStoreCodeDirectory.h"
#include "Templates/SignatureBlob.h"
#include "Templates/DecryptedSignature.h"
#include "Templates/PrivateKey.h"
// We can use static offsets here because we use a template signature blob
#define SIGNED_ATTRS_OFFSET 0x13C6 // SignedAttributes sequence
#define HASHHASH_OFFSET 0x1470 // SHA256 hash SignedAttribute
#define BASEBASE_OFFSET 0x15AD // Base64 hash SignedAttribute
#define SIGNSIGN_OFFSET 0x1602 // Signature
#define DECRYPTED_SIGNATURE_HASH_OFFSET 0x13
#include "Templates/DERTemplate.h"
#include "Templates/TemplateSignatureBlob.h"
#include "Templates/CADetails.h"
#include <openssl/pem.h>
#include <openssl/err.h>
#include <copyfile.h>
#include <TargetConditionals.h>
#include <openssl/cms.h>
int update_signature_blob(CS_DecodedSuperBlob *superblob)
{
CS_DecodedBlob *sha1CD = csd_superblob_find_blob(superblob, CSSLOT_CODEDIRECTORY, NULL);
if (!sha1CD) {
printf("Could not find SHA1 CodeDirectory blob!\n");
return -1;
}
CS_DecodedBlob *sha256CD = csd_superblob_find_blob(superblob, CSSLOT_ALTERNATE_CODEDIRECTORIES, NULL);
if (!sha256CD) {
printf("Could not find CodeDirectory blob!\n");
return -1;
}
CS_DecodedBlob *signatureBlob = csd_superblob_find_blob(superblob, CSSLOT_SIGNATURESLOT, NULL);
if (!signatureBlob) {
printf("Could not find signature blob!\n");
printf("Could not find SHA256 CodeDirectory blob!\n");
return -1;
}
uint8_t fullHash[CC_SHA256_DIGEST_LENGTH];
size_t dataSizeToRead = csd_blob_get_size(sha256CD);
uint8_t *data = malloc(dataSizeToRead);
memset(data, 0, dataSizeToRead);
csd_blob_read(sha256CD, 0, dataSizeToRead, data);
CC_SHA256(data, (CC_LONG)dataSizeToRead, fullHash);
free(data);
uint8_t secondCDSHA256Hash[CC_SHA256_DIGEST_LENGTH];
memcpy(secondCDSHA256Hash, fullHash, CC_SHA256_DIGEST_LENGTH);
// Print the hash
printf("SHA256 hash: ");
for (int i = 0; i < CC_SHA256_DIGEST_LENGTH; i++) {
printf("%02x", secondCDSHA256Hash[i]);
}
printf("\n");
uint8_t sha1CDHash[CC_SHA1_DIGEST_LENGTH];
uint8_t sha256CDHash[CC_SHA256_DIGEST_LENGTH];
size_t base64OutLength = 0;
char *newBase64Hash = base64_encode(secondCDSHA256Hash, CC_SHA1_DIGEST_LENGTH, &base64OutLength);
if (!newBase64Hash) {
printf("Failed to base64 encode hash!\n");
{
size_t dataSizeToRead = csd_blob_get_size(sha1CD);
uint8_t *data = malloc(dataSizeToRead);
memset(data, 0, dataSizeToRead);
csd_blob_read(sha1CD, 0, dataSizeToRead, data);
CC_SHA1(data, (CC_LONG)dataSizeToRead, sha1CDHash);
free(data);
printf("SHA1 hash: ");
for (int i = 0; i < CC_SHA1_DIGEST_LENGTH; i++) {
printf("%02x", sha1CDHash[i]);
}
printf("\n");
}
{
size_t dataSizeToRead = csd_blob_get_size(sha256CD);
uint8_t *data = malloc(dataSizeToRead);
memset(data, 0, dataSizeToRead);
csd_blob_read(sha256CD, 0, dataSizeToRead, data);
CC_SHA256(data, (CC_LONG)dataSizeToRead, sha256CDHash);
free(data);
printf("SHA256 hash: ");
for (int i = 0; i < CC_SHA256_DIGEST_LENGTH; i++) {
printf("%02x", sha256CDHash[i]);
}
printf("\n");
}
const uint8_t *cmsDataPtr = AppStoreSignatureBlob + offsetof(CS_GenericBlob, data);
size_t cmsDataSize = AppStoreSignatureBlob_len - sizeof(CS_GenericBlob);
CMS_ContentInfo *cms = d2i_CMS_ContentInfo(NULL, (const unsigned char**)&cmsDataPtr, cmsDataSize);
if (!cms) {
printf("Failed to parse CMS blob: %s!\n", ERR_error_string(ERR_get_error(), NULL));
return -1;
}
// Print the base64 hash
printf("Base64 hash: %.*s\n", CC_SHA256_DIGEST_LENGTH, newBase64Hash);
int ret = csd_blob_write(signatureBlob, HASHHASH_OFFSET, CC_SHA256_DIGEST_LENGTH, secondCDSHA256Hash);
if (ret != 0) {
printf("Failed to write SHA256 hash to signature blob!\n");
free(newBase64Hash);
// Load private key
FILE* privateKeyFile = fmemopen(CAKey, CAKeyLength, "r");
if (!privateKeyFile) {
printf("Failed to open private key file!\n");
return -1;
}
EVP_PKEY* privateKey = PEM_read_PrivateKey(privateKeyFile, NULL, NULL, NULL);
fclose(privateKeyFile);
if (!privateKey) {
printf("Failed to read private key file!\n");
return -1;
}
// Load certificate
FILE* certificateFile = fmemopen(CACert, CACertLength, "r");
if (!certificateFile) {
printf("Failed to open certificate file!\n");
return -1;
}
X509* certificate = PEM_read_X509(certificateFile, NULL, NULL, NULL);
fclose(certificateFile);
if (!certificate) {
printf("Failed to read certificate file!\n");
return -1;
}
// Add signer
CMS_SignerInfo* newSigner = CMS_add1_signer(cms, certificate, privateKey, EVP_sha256(), CMS_PARTIAL | CMS_REUSE_DIGEST | CMS_NOSMIMECAP);
if (!newSigner) {
printf("Failed to add signer: %s!\n", ERR_error_string(ERR_get_error(), NULL));
return -1;
}
CFMutableArrayRef cdHashesArray = CFArrayCreateMutable(NULL, 2, &kCFTypeArrayCallBacks);
if (!cdHashesArray) {
printf("Failed to create CDHashes array!\n");
return -1;
}
CFDataRef sha1CDHashData = CFDataCreate(NULL, sha1CDHash, CC_SHA1_DIGEST_LENGTH);
if (!sha1CDHashData) {
printf("Failed to create CFData from SHA1 CDHash!\n");
CFRelease(cdHashesArray);
return -1;
}
CFArrayAppendValue(cdHashesArray, sha1CDHashData);
CFRelease(sha1CDHashData);
// In this plist, the SHA256 hash is truncated to SHA1 length
CFDataRef sha256CDHashData = CFDataCreate(NULL, sha256CDHash, CC_SHA1_DIGEST_LENGTH);
if (!sha256CDHashData) {
printf("Failed to create CFData from SHA256 CDHash!\n");
CFRelease(cdHashesArray);
return -1;
}
CFArrayAppendValue(cdHashesArray, sha256CDHashData);
CFRelease(sha256CDHashData);
ret = csd_blob_write(signatureBlob, BASEBASE_OFFSET, base64OutLength, newBase64Hash);
if (ret != 0) {
printf("Failed to write base64 hash to signature blob!\n");
free(newBase64Hash);
CFMutableDictionaryRef cdHashesDictionary = CFDictionaryCreateMutable(NULL, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
if (!cdHashesDictionary) {
printf("Failed to create CDHashes dictionary!\n");
CFRelease(cdHashesArray);
return -1;
}
CFDictionarySetValue(cdHashesDictionary, CFSTR("cdhashes"), cdHashesArray);
CFRelease(cdHashesArray);
CFErrorRef error = NULL;
CFDataRef cdHashesDictionaryData = CFPropertyListCreateData(NULL, cdHashesDictionary, kCFPropertyListXMLFormat_v1_0, 0, &error);
CFRelease(cdHashesDictionary);
if (!cdHashesDictionaryData) {
// CFStringGetCStringPtr, unfortunately, does not always work
CFStringRef errorString = CFErrorCopyDescription(error);
CFIndex maxSize = CFStringGetMaximumSizeForEncoding(CFStringGetLength(errorString), kCFStringEncodingUTF8) + 1;
char *buffer = (char *)malloc(maxSize);
if (CFStringGetCString(errorString, buffer, maxSize, kCFStringEncodingUTF8)) {
printf("Failed to encode CDHashes plist: %s\n", buffer);
} else {
printf("Failed to encode CDHashes plist: unserializable error\n");
}
free(buffer);
return -1;
}
free(newBase64Hash);
unsigned char *newSignature = NULL;
size_t newSignatureSize = 0;
unsigned char newDecryptedSignature[0x33];
memset(newDecryptedSignature, 0, 0x33);
memcpy(newDecryptedSignature, DecryptedSignature, 0x33);
// Get the signed attributes hash
unsigned char signedAttrs[0x229];
memset(signedAttrs, 0, 0x229);
csd_blob_read(signatureBlob, SIGNED_ATTRS_OFFSET, 0x229, signedAttrs);
signedAttrs[0] = 0x31;
// Hash
uint8_t fullAttributesHash[CC_SHA256_DIGEST_LENGTH];
CC_SHA256(signedAttrs, (CC_LONG)0x229, fullAttributesHash);
memcpy(newDecryptedSignature + DECRYPTED_SIGNATURE_HASH_OFFSET, fullAttributesHash, CC_SHA256_DIGEST_LENGTH);
newSignature = signWithRSA(newDecryptedSignature, DecryptedSignature_len, CAKey, CAKeyLength, &newSignatureSize);
if (!newSignature) {
printf("Failed to sign the decrypted signature!\n");
// Add text CDHashes attribute
if (!CMS_signed_add1_attr_by_txt(newSigner, "1.2.840.113635.100.9.1", V_ASN1_OCTET_STRING, CFDataGetBytePtr(cdHashesDictionaryData), CFDataGetLength(cdHashesDictionaryData))) {
printf("Failed to add text CDHashes attribute: %s!\n", ERR_error_string(ERR_get_error(), NULL));
return -1;
}
if (newSignatureSize != 0x100) {
printf("The new signature is not the correct size!\n");
free(newSignature);
// Create DER-encoded CDHashes (see DERTemplate.h for details)
uint8_t cdHashesDER[78];
memset(cdHashesDER, 0, sizeof(cdHashesDER));
memcpy(cdHashesDER, CDHashesDERTemplate, sizeof(CDHashesDERTemplate));
memcpy(cdHashesDER + CDHASHES_DER_SHA1_OFFSET, sha1CDHash, CC_SHA1_DIGEST_LENGTH);
memcpy(cdHashesDER + CDHASHES_DER_SHA256_OFFSET, sha256CDHash, CC_SHA256_DIGEST_LENGTH);
// Add DER CDHashes attribute
if (!CMS_signed_add1_attr_by_txt(newSigner, "1.2.840.113635.100.9.2", V_ASN1_SEQUENCE, cdHashesDER, sizeof(cdHashesDER))) {
printf("Failed to add CDHashes attribute: %s!\n", ERR_error_string(ERR_get_error(), NULL));
return -1;
}
ret = csd_blob_write(signatureBlob, SIGNSIGN_OFFSET, newSignatureSize, newSignature);
free(newSignature);
return ret;
// Sign the CMS structure
if (!CMS_SignerInfo_sign(newSigner)) {
printf("Failed to sign CMS structure: %s!\n", ERR_error_string(ERR_get_error(), NULL));
return -1;
}
// Encode the CMS structure into DER
uint8_t *newCMSData = NULL;
int newCMSDataSize = i2d_CMS_ContentInfo(cms, &newCMSData);
if (newCMSDataSize <= 0) {
printf("Failed to encode CMS structure: %s!\n", ERR_error_string(ERR_get_error(), NULL));
return -1;
}
// Copy CMS data into a new blob
uint32_t newCMSDataBlobSize = sizeof(CS_GenericBlob) + newCMSDataSize;
CS_GenericBlob *newCMSDataBlob = malloc(newCMSDataBlobSize);
newCMSDataBlob->magic = HOST_TO_BIG(CSMAGIC_BLOBWRAPPER);
newCMSDataBlob->length = HOST_TO_BIG(newCMSDataBlobSize);
memcpy(newCMSDataBlob->data, newCMSData, newCMSDataSize);
free(newCMSData);
// Remove old signature blob if it exists
CS_DecodedBlob *oldSignatureBlob = csd_superblob_find_blob(superblob, CSSLOT_SIGNATURESLOT, NULL);
if (oldSignatureBlob) {
csd_superblob_remove_blob(superblob, oldSignatureBlob);
csd_blob_free(oldSignatureBlob);
}
// Append new signature blob
CS_DecodedBlob *signatureBlob = csd_blob_init(CSSLOT_SIGNATURESLOT, newCMSDataBlob);
free(newCMSDataBlob);
// Append new signature blob
return csd_superblob_append_blob(superblob, signatureBlob);
}
int apply_coretrust_bypass(const char *machoPath)
{
MachO *macho = macho_init_for_writing(machoPath);
if (!macho) return -1;
if (macho_is_encrypted(macho)) {
printf("Error: MachO is encrypted, please use a decrypted app!\n");
macho_free(macho);
return 2;
}
if (macho->machHeader.filetype == MH_OBJECT) {
printf("Error: MachO is an object file, please use a MachO executable or dynamic library!\n");
macho_free(macho);
return 3;
}
if (macho->machHeader.filetype == MH_DSYM) {
printf("Error: MachO is a dSYM file, please use a MachO executable or dynamic library!\n");
macho_free(macho);
return 3;
}
CS_SuperBlob *superblob = macho_read_code_signature(macho);
if (!superblob) {
@ -137,8 +252,15 @@ int apply_coretrust_bypass(const char *machoPath)
CS_DecodedBlob *mainCodeDirBlob = csd_superblob_find_blob(decodedSuperblob, CSSLOT_CODEDIRECTORY, NULL);
CS_DecodedBlob *alternateCodeDirBlob = csd_superblob_find_blob(decodedSuperblob, CSSLOT_ALTERNATE_CODEDIRECTORIES, NULL);
CS_DecodedBlob *entitlementsBlob = csd_superblob_find_blob(decodedSuperblob, CSSLOT_ENTITLEMENTS, NULL);
CS_DecodedBlob *derEntitlementsBlob = csd_superblob_find_blob(decodedSuperblob, CSSLOT_DER_ENTITLEMENTS, NULL);
if (!entitlementsBlob && !derEntitlementsBlob && macho->machHeader.filetype == MH_EXECUTE) {
printf("Warning: Unable to find existing entitlements blobs in executable MachO.\n");
}
if (!mainCodeDirBlob) {
printf("Error: Unable to find code directory, make sure the input binary is ad-hoc signed?\n");
printf("Error: Unable to find code directory, make sure the input binary is ad-hoc signed.\n");
return -1;
}
@ -178,17 +300,12 @@ int apply_coretrust_bypass(const char *machoPath)
csd_blob_free(signatureBlob);
}
// Append new template blob
signatureBlob = csd_blob_init(CSSLOT_SIGNATURESLOT, (CS_GenericBlob *)TemplateSignatureBlob);
csd_superblob_append_blob(decodedSuperblob, signatureBlob);
// After Modification:
// 1. App Store CodeDirectory (SHA1)
// ?. Requirements
// ?. Entitlements
// ?. DER entitlements
// 5. Actual CodeDirectory (SHA256)
// 6. Signature blob
printf("Updating TeamID...\n");
@ -212,6 +329,16 @@ int apply_coretrust_bypass(const char *machoPath)
// Set flags to 0 to remove any problematic flags (such as the 'adhoc' flag in bit 2)
csd_code_directory_set_flags(realCodeDirBlob, 0);
int ret = 0;
// 6. Signature blob
printf("Doing initial signing to calculate size...\n");
ret = update_signature_blob(decodedSuperblob);
if(ret == -1) {
printf("Error: failed to create new signature blob!\n");
return -1;
}
printf("Encoding unsigned superblob...\n");
CS_SuperBlob *encodedSuperblobUnsigned = csd_superblob_encode(decodedSuperblob);
@ -225,7 +352,6 @@ int apply_coretrust_bypass(const char *machoPath)
printf("Updating code slot hashes...\n");
csd_code_directory_update(realCodeDirBlob, macho);
int ret = 0;
printf("Signing binary...\n");
ret = update_signature_blob(decodedSuperblob);
if(ret == -1) {

View File

@ -1,11 +0,0 @@
#ifndef BASE64_H
#define BASE64_H
#include <stdint.h>
#include <stdlib.h>
char *base64_encode(const unsigned char *data,
size_t input_length,
size_t *output_length);
#endif // BASE64_H

View File

@ -1,19 +0,0 @@
#ifndef BUFFERED_STREAM_H
#define BUFFERED_STREAM_H
#include "MemoryStream.h"
#include <stdbool.h>
#define BUFFERED_STREAM_FLAG_AUTO_EXPAND (1 << 0)
typedef struct BufferedStreamContext {
uint8_t *buffer;
size_t bufferSize;
uint32_t subBufferStart;
size_t subBufferSize;
} BufferedStreamContext;
MemoryStream *buffered_stream_init_from_buffer_nocopy(void *buffer, size_t bufferSize, uint32_t flags);
MemoryStream *buffered_stream_init_from_buffer(void *buffer, size_t bufferSize, uint32_t flags);
#endif // BUFFERED_STREAM_H

View File

@ -1,108 +0,0 @@
#ifndef CS_BLOB_H
#define CS_BLOB_H
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>
#include "FAT.h"
#include "MachO.h"
#include "MemoryStream.h"
// Blob index
typedef struct __BlobIndex {
uint32_t type;
uint32_t offset;
} CS_BlobIndex;
// CMS superblob
typedef struct __SuperBlob {
uint32_t magic;
uint32_t length;
uint32_t count;
CS_BlobIndex index[];
} CS_SuperBlob;
typedef struct __GenericBlob {
uint32_t magic; /* magic number */
uint32_t length; /* total length of blob */
char data[];
} CS_GenericBlob;
// CMS blob magic types
enum {
CSBLOB_REQUIREMENT = 0xfade0c00,
CSBLOB_REQUIREMENTS = 0xfade0c01,
CSBLOB_CODEDIRECTORY = 0xfade0c02,
CSBLOB_EMBEDDED_SIGNATURE = 0xfade0cc0,
CSBLOB_DETACHED_SIGNATURE = 0xfade0cc1,
CSBLOB_ENTITLEMENTS = 0xfade7171,
CSBLOB_DER_ENTITLEMENTS = 0xfade7172,
CSBLOB_SIGNATURE_BLOB = 0xfade0b01
} CS_BlobType;
enum {
CSSLOT_CODEDIRECTORY = 0,
CSSLOT_INFOSLOT = 1,
CSSLOT_REQUIREMENTS = 2,
CSSLOT_RESOURCEDIR = 3,
CSSLOT_APPLICATION = 4,
CSSLOT_ENTITLEMENTS = 5,
CSSLOT_DER_ENTITLEMENTS = 7,
CSSLOT_ALTERNATE_CODEDIRECTORIES = 0x1000,
CSSLOT_ALTERNATE_CODEDIRECTORY_MAX = 5,
CSSLOT_ALTERNATE_CODEDIRECTORY_LIMIT = CSSLOT_ALTERNATE_CODEDIRECTORIES + CSSLOT_ALTERNATE_CODEDIRECTORY_MAX,
CSSLOT_SIGNATURESLOT = 0x10000
} CS_SlotType;
typedef struct s_CS_DecodedBlob {
struct s_CS_DecodedBlob *next;
uint32_t type;
MemoryStream *stream;
} CS_DecodedBlob;
typedef struct s_CS_DecodedSuperBlob {
uint32_t magic;
struct s_CS_DecodedBlob *firstBlob;
} CS_DecodedSuperBlob;
// Convert blob magic to readable blob type string
char *cs_blob_magic_to_string(int magic);
// Extract Code Signature to file
int macho_extract_cs_to_file(MachO *macho, CS_SuperBlob *superblob);
int macho_find_code_signature_bounds(MachO *macho, uint32_t *offsetOut, uint32_t *sizeOut);
CS_SuperBlob *macho_read_code_signature(MachO *macho);
int macho_replace_code_signature(MachO *macho, CS_SuperBlob *superblob);
int update_load_commands(MachO *macho, CS_SuperBlob *superblob, uint64_t originalSize);
CS_DecodedBlob *csd_blob_init(uint32_t type, CS_GenericBlob *blobData);
int csd_blob_read(CS_DecodedBlob *blob, uint64_t offset, size_t size, void *outBuf);
int csd_blob_write(CS_DecodedBlob *blob, uint64_t offset, size_t size, const void *inBuf);
int csd_blob_insert(CS_DecodedBlob *blob, uint64_t offset, size_t size, const void *inBuf);
int csd_blob_delete(CS_DecodedBlob *blob, uint64_t offset, size_t size);
int csd_blob_read_string(CS_DecodedBlob *blob, uint64_t offset, char **outString);
int csd_blob_write_string(CS_DecodedBlob *blob, uint64_t offset, const char *string);
int csd_blob_get_size(CS_DecodedBlob *blob);
uint32_t csd_blob_get_type(CS_DecodedBlob *blob);
void csd_blob_set_type(CS_DecodedBlob *blob, uint32_t type);
void csd_blob_free(CS_DecodedBlob *blob);
CS_DecodedSuperBlob *csd_superblob_decode(CS_SuperBlob *superblob);
CS_SuperBlob *csd_superblob_encode(CS_DecodedSuperBlob *decodedSuperblob);
CS_DecodedBlob *csd_superblob_find_blob(CS_DecodedSuperBlob *superblob, uint32_t type, uint32_t *indexOut);
int csd_superblob_insert_blob_after_blob(CS_DecodedSuperBlob *superblob, CS_DecodedBlob *blobToInsert, CS_DecodedBlob *afterBlob);
int csd_superblob_insert_blob_at_index(CS_DecodedSuperBlob *superblob, CS_DecodedBlob *blobToInsert, uint32_t atIndex);
int csd_superblob_append_blob(CS_DecodedSuperBlob *superblob, CS_DecodedBlob *blobToAppend);
int csd_superblob_remove_blob(CS_DecodedSuperBlob *superblob, CS_DecodedBlob *blobToRemove); // <- Important: When calling this, caller is responsible for freeing blobToRemove
int csd_superblob_remove_blob_at_index(CS_DecodedSuperBlob *superblob, uint32_t atIndex);
int csd_superblob_print_content(CS_DecodedSuperBlob *decodedSuperblob, MachO *macho, bool printAllSlots, bool verifySlots);
void csd_superblob_free(CS_DecodedSuperBlob *decodedSuperblob);
#endif // CS_BLOB_H

View File

@ -1,53 +0,0 @@
#ifndef CODE_DIRECTORY_H
#define CODE_DIRECTORY_H
#include <stdint.h>
#include <math.h>
#include <CommonCrypto/CommonDigest.h>
#include "MachO.h"
#include "CSBlob.h"
#include "FAT.h"
#include "MachOByteOrder.h"
#include "MachOLoadCommand.h"
#include "MemoryStream.h"
// Code directory blob header
typedef struct __CodeDirectory {
uint32_t magic;
uint32_t length;
uint32_t version;
uint32_t flags;
uint32_t hashOffset;
uint32_t identOffset;
uint32_t nSpecialSlots;
uint32_t nCodeSlots;
uint32_t codeLimit;
uint8_t hashSize;
uint8_t hashType;
uint8_t spare1;
uint8_t pageSize;
uint32_t spare2;
uint32_t scatterOffset;
uint32_t teamOffset;
} CS_CodeDirectory;
enum CS_HashType {
CS_HASHTYPE_SHA160_160 = 1,
CS_HASHTYPE_SHA256_256 = 2,
CS_HASHTYPE_SHA256_160 = 3,
CS_HASHTYPE_SHA384_384 = 4,
};
char *csd_code_directory_copy_identity(CS_DecodedBlob *codeDirBlob, uint32_t *offsetOut);
char *csd_code_directory_copy_team_id(CS_DecodedBlob *codeDirBlob, uint32_t *offsetOut);
int csd_code_directory_set_team_id(CS_DecodedBlob *codeDirBlob, char *newTeamID);
uint32_t csd_code_directory_get_flags(CS_DecodedBlob *codeDirBlob);
void csd_code_directory_set_flags(CS_DecodedBlob *codeDirBlob, uint32_t flags);
uint8_t csd_code_directory_get_hash_type(CS_DecodedBlob *codeDirBlob);
void csd_code_directory_set_hash_type(CS_DecodedBlob *codeDirBlob, uint8_t hashType);
int csd_code_directory_print_content(CS_DecodedBlob *codeDirBlob, MachO *macho, bool printSlots, bool verifySlots);
void csd_code_directory_update(CS_DecodedBlob *codeDirBlob, MachO *macho);
#endif // CODE_DIRECTORY_H

View File

@ -1,41 +0,0 @@
#ifndef MACHO_H
#define MACHO_H
#include <stdio.h>
#include <libkern/OSByteOrder.h>
#include <mach/mach.h>
#include <mach-o/loader.h>
#include <mach-o/fat.h>
#include <sys/stat.h>
#include "MemoryStream.h"
typedef struct MachO MachO;
// A FAT structure can either represent a FAT file with multiple slices, in which the slices will be loaded into the slices attribute
// Or a single slice MachO, in which case it serves as a compatibility layer and the single slice will also be loaded into the slices attribute
typedef struct FAT
{
MemoryStream *stream;
MachO **slices;
uint32_t slicesCount;
int fileDescriptor;
} FAT;
int fat_read_at_offset(FAT *fat, uint64_t offset, size_t size, void *outBuf);
MemoryStream *fat_get_stream(FAT *fat);
// Initialise a FAT structure from a memory stream
FAT *fat_init_from_memory_stream(MemoryStream *stream);
// Initialise a FAT structure using the path to the file
FAT *fat_init_from_path(const char *filePath);
//FAT *fat_init_from_path_for_writing(const char *filePath);
// Find macho with cputype and cpusubtype in FAT, returns NULL if not found
MachO *fat_find_slice(FAT *fat, cpu_type_t cputype, cpu_subtype_t cpusubtype);
// Free all elements of the FAT structure
void fat_free(FAT *fat);
#endif // MACHO_H

View File

@ -1,21 +0,0 @@
#ifndef FILE_STREAM_H
#define FILE_STREAM_H
#include "MemoryStream.h"
#define FILE_STREAM_SIZE_AUTO 0
#define FILE_STREAM_FLAG_WRITABLE (1 << 0)
#define FILE_STREAM_FLAG_AUTO_EXPAND (1 << 1)
typedef struct FileStreamContext {
int fd;
size_t fileSize;
uint32_t bufferStart;
size_t bufferSize;
} FileStreamContext;
MemoryStream *file_stream_init_from_file_descriptor_nodup(int fd, uint32_t bufferStart, size_t bufferSize, uint32_t flags);
MemoryStream *file_stream_init_from_file_descriptor(int fd, uint32_t bufferStart, size_t bufferSize, uint32_t flags);
MemoryStream *file_stream_init_from_path(const char *path, uint32_t bufferStart, size_t bufferSize, uint32_t flags);
#endif // FILE_STREAM_H

View File

@ -1,10 +0,0 @@
#ifndef HOST_H
#define HOST_H
#include "FAT.h"
// Retrieve the preferred MachO slice from a FAT
// Preferred slice as in the slice that the kernel would use when loading the file
MachO *fat_find_preferred_slice(FAT *fat);
#endif // HOST_H

View File

@ -1,62 +0,0 @@
#ifndef MACHO_SLICE_H
#define MACHO_SLICE_H
#include <stdbool.h>
#include <mach-o/fat.h>
#include <mach-o/loader.h>
#include "MemoryStream.h"
#include "FAT.h"
typedef struct MachOSegment
{
struct segment_command_64 command;
struct section_64 sections[];
} __attribute__((__packed__)) MachOSegment;
typedef struct FilesetMachO {
char *entry_id;
uint64_t vmaddr;
uint64_t fileoff;
FAT *underlyingMachO;
} FilesetMachO;
typedef struct MachO {
MemoryStream *stream;
bool isSupported;
struct mach_header_64 machHeader;
struct fat_arch_64 archDescriptor;
uint32_t filesetCount;
FilesetMachO *filesetMachos;
uint32_t segmentCount;
MachOSegment **segments;
} MachO;
// Read data from a MachO at a specified offset
int macho_read_at_offset(MachO *macho, uint64_t offset, size_t size, void *outBuf);
// Write data from a MachO at a specified offset, auto expands, only works if opened via macho_init_for_writing
int macho_write_at_offset(MachO *macho, uint64_t offset, size_t size, void *inBuf);
MemoryStream *macho_get_stream(MachO *macho);
uint32_t macho_get_filetype(MachO *macho);
// Perform translation between file offsets and virtual addresses
int macho_translate_fileoff_to_vmaddr(MachO *macho, uint64_t fileoff, uint64_t *vmaddrOut, MachOSegment **segmentOut);
int macho_translate_vmaddr_to_fileoff(MachO *macho, uint64_t vmaddr, uint64_t *fileoffOut, MachOSegment **segmentOut);
// Read data from a MachO at a specified virtual address
int macho_read_at_vmaddr(MachO *macho, uint64_t vmaddr, size_t size, void *outBuf);
int macho_enumerate_load_commands(MachO *macho, void (^enumeratorBlock)(struct load_command loadCommand, uint64_t offset, void *cmd, bool *stop));
// Initialise a MachO object from a MemoryStream and it's corresponding FAT arch descriptor
MachO *macho_init(MemoryStream *stream, struct fat_arch_64 archDescriptor);
// Initialize a single slice macho for writing to it
MachO *macho_init_for_writing(const char *filePath);
void macho_free(MachO *macho);
#endif // MACHO_SLICE_H

View File

@ -1,164 +0,0 @@
#ifndef MACHO_BYTE_ORDER_H
#define MACHO_BYTE_ORDER_H
#include <stdio.h>
#include <stdlib.h>
// 8-bit integers needed for CodeDirectory
#define BIG_TO_HOST(n) _Generic((n), \
int8_t: n, \
uint8_t: n, \
int16_t: OSSwapBigToHostInt16(n), \
uint16_t: OSSwapBigToHostInt16(n), \
int32_t: OSSwapBigToHostInt32(n), \
uint32_t: OSSwapBigToHostInt32(n), \
int64_t: OSSwapBigToHostInt64(n), \
uint64_t: OSSwapBigToHostInt64(n) \
)
#define HOST_TO_BIG(n) _Generic((n), \
int8_t: n, \
uint8_t: n, \
uint16_t: OSSwapHostToBigInt16(n), \
int16_t: OSSwapHostToBigInt16(n), \
int32_t: OSSwapHostToBigInt32(n), \
uint32_t: OSSwapHostToBigInt32(n), \
int64_t: OSSwapHostToBigInt64(n), \
uint64_t: OSSwapHostToBigInt64(n) \
)
#define LITTLE_TO_HOST(n) _Generic((n), \
int8_t: n, \
uint8_t: n, \
int16_t: OSSwapLittleToHostInt16(n), \
uint16_t: OSSwapLittleToHostInt16(n), \
int32_t: OSSwapLittleToHostInt32(n), \
uint32_t: OSSwapLittleToHostInt32(n), \
int64_t: OSSwapLittleToHostInt64(n), \
uint64_t: OSSwapLittleToHostInt64(n) \
)
#define HOST_TO_LITTLE(n) _Generic((n), \
int8_t: n, \
uint8_t: n, \
int16_t: OSSwapHostToLittleInt16(n), \
uint16_t: OSSwapHostToLittleInt16(n), \
int32_t: OSSwapHostToLittleInt32(n), \
uint32_t: OSSwapHostToLittleInt32(n), \
int64_t: OSSwapHostToLittleInt64(n), \
uint64_t: OSSwapHostToLittleInt64(n) \
)
#define HOST_TO_LITTLE_APPLIER(instance, member) \
(instance)->member = HOST_TO_LITTLE((instance)->member)
#define HOST_TO_BIG_APPLIER(instance, member) \
(instance)->member = HOST_TO_BIG((instance)->member)
#define LITTLE_TO_HOST_APPLIER(instance, member) \
(instance)->member = LITTLE_TO_HOST((instance)->member)
#define BIG_TO_HOST_APPLIER(instance, member) \
(instance)->member = BIG_TO_HOST((instance)->member)
#define FAT_HEADER_APPLY_BYTE_ORDER(fh, applier) \
applier(fh, magic); \
applier(fh, nfat_arch);
#define FAT_ARCH_APPLY_BYTE_ORDER(arch, applier) \
applier(arch, cputype); \
applier(arch, cpusubtype); \
applier(arch, offset); \
applier(arch, size); \
applier(arch, align); \
#define FAT_ARCH_64_APPLY_BYTE_ORDER(arch, applier) \
applier(arch, cputype); \
applier(arch, cpusubtype); \
applier(arch, offset); \
applier(arch, size); \
applier(arch, align); \
applier(arch, reserved); \
#define MACH_HEADER_APPLY_BYTE_ORDER(mh, applier) \
applier(mh, magic); \
applier(mh, cputype); \
applier(mh, cpusubtype); \
applier(mh, filetype); \
applier(mh, ncmds); \
applier(mh, sizeofcmds); \
applier(mh, reserved);
#define LOAD_COMMAND_APPLY_BYTE_ORDER(lc, applier) \
applier(lc, cmd); \
applier(lc, cmdsize);
#define LINKEDIT_DATA_COMMAND_APPLY_BYTE_ORDER(lc, applier) \
applier(lc, cmd); \
applier(lc, cmdsize); \
applier(lc, dataoff); \
applier(lc, datasize);
#define BLOB_INDEX_APPLY_BYTE_ORDER(bi, applier) \
applier(bi, type); \
applier(bi, offset);
#define SUPERBLOB_APPLY_BYTE_ORDER(sb, applier) \
applier(sb, magic); \
applier(sb, length); \
applier(sb, count);
#define GENERIC_BLOB_APPLY_BYTE_ORDER(gb, applier) \
applier(gb, magic); \
applier(gb, length);
#define CODE_DIRECTORY_APPLY_BYTE_ORDER(cd, applier) \
applier(cd, magic); \
applier(cd, length); \
applier(cd, version); \
applier(cd, flags); \
applier(cd, hashOffset); \
applier(cd, identOffset); \
applier(cd, nSpecialSlots); \
applier(cd, nCodeSlots); \
applier(cd, codeLimit); \
applier(cd, hashSize); \
applier(cd, hashType); \
applier(cd, spare1); \
applier(cd, pageSize); \
applier(cd, spare2); \
applier(cd, scatterOffset); \
applier(cd, teamOffset);
#define SEGMENT_COMMAND_64_APPLY_BYTE_ORDER(sc64, applier) \
applier(sc64, cmd); \
applier(sc64, cmdsize); \
applier(sc64, fileoff); \
applier(sc64, filesize); \
applier(sc64, vmaddr); \
applier(sc64, vmsize); \
applier(sc64, flags); \
applier(sc64, initprot); \
applier(sc64, maxprot); \
applier(sc64, nsects);
#define SECTION_64_APPLY_BYTE_ORDER(sc64, applier) \
applier(sc64, addr); \
applier(sc64, align); \
applier(sc64, flags); \
applier(sc64, nreloc); \
applier(sc64, offset); \
applier(sc64, reserved1); \
applier(sc64, reserved2); \
applier(sc64, reserved3); \
applier(sc64, size);
#define FILESET_ENTRY_COMMAND_APPLY_BYTE_ORDER(fse, applier) \
applier(fse, cmd); \
applier(fse, cmdsize); \
applier(fse, vmaddr); \
applier(fse, fileoff); \
applier(fse, entry_id.offset); \
applier(fse, reserved); \
#endif // MACHO_BYTE_ORDER_H

View File

@ -1,16 +0,0 @@
#ifndef MACHO_LOAD_COMMAND_H
#define MACHO_LOAD_COMMAND_H
#include <mach-o/loader.h>
#include "MachO.h"
#include "CSBlob.h"
#include "FileStream.h"
#include "MachOByteOrder.h"
// Convert load command to load command name
char *load_command_to_string(int loadCommand);
void update_segment_command_64(MachO *macho, const char *segmentName, uint64_t vmaddr, uint64_t vmsize, uint64_t fileoff, uint64_t filesize);
void update_lc_code_signature(MachO *macho, uint64_t size);
int update_load_commands_for_coretrust_bypass(MachO *macho, CS_SuperBlob *superblob, uint64_t originalCodeSignatureSize, uint64_t originalMachOSize);
#endif // MACHO_LOAD_COMMAND_H

View File

@ -1,60 +0,0 @@
#ifndef MEMORY_STREAM_H
#define MEMORY_STREAM_H
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <stdbool.h>
#define MEMORY_STREAM_FLAG_OWNS_DATA (1 << 0)
#define MEMORY_STREAM_FLAG_MUTABLE (1 << 1)
#define MEMORY_STREAM_FLAG_AUTO_EXPAND (1 << 2)
#define MEMORY_STREAM_SIZE_INVALID (size_t)-1
// A generic memory IO interface that is used throughout this project
// Can be backed by anything, just the functions have to be implemented
typedef struct s_MemoryStream {
void *context;
uint32_t flags;
int (*read)(struct s_MemoryStream *stream, uint64_t offset, size_t size, void *outBuf);
int (*write)(struct s_MemoryStream *stream, uint64_t offset, size_t size, const void *inBuf);
int (*getSize)(struct s_MemoryStream *stream, size_t *sizeOut);
uint8_t *(*getRawPtr)(struct s_MemoryStream *stream);
int (*trim)(struct s_MemoryStream *stream, size_t trimAtStart, size_t trimAtEnd);
int (*expand)(struct s_MemoryStream *stream, size_t expandAtStart, size_t expandAtEnd);
struct s_MemoryStream *(*hardclone)(struct s_MemoryStream *stream);
struct s_MemoryStream *(*softclone)(struct s_MemoryStream *stream);
void (*free)(struct s_MemoryStream *stream);
} MemoryStream;
int memory_stream_read(MemoryStream *stream, uint64_t offset, size_t size, void *outBuf);
int memory_stream_write(MemoryStream *stream, uint64_t offset, size_t size, const void *inBuf);
int memory_stream_insert(MemoryStream *stream, uint64_t offset, size_t size, const void *inBuf);
int memory_stream_delete(MemoryStream *stream, uint64_t offset, size_t size);
int memory_stream_read_string(MemoryStream *stream, uint64_t offset, char **outString);
int memory_stream_write_string(MemoryStream *stream, uint64_t offset, const char *string);
size_t memory_stream_get_size(MemoryStream *stream);
uint8_t *memory_stream_get_raw_pointer(MemoryStream *stream);
uint32_t memory_stream_get_flags(MemoryStream *stream);
MemoryStream *memory_stream_softclone(MemoryStream *stream);
MemoryStream *memory_stream_hardclone(MemoryStream *stream);
int memory_stream_trim(MemoryStream *stream, size_t trimAtStart, size_t trimAtEnd);
int memory_stream_expand(MemoryStream *stream, size_t expandAtStart, size_t expandAtEnd);
void memory_stream_free(MemoryStream *stream);
int memory_stream_copy_data(MemoryStream *originStream, uint64_t originOffset, MemoryStream *targetStream, uint64_t targetOffset, size_t size);
int memory_stream_find_memory(MemoryStream *stream, uint64_t searchOffset, size_t searchSize, void *bytes, void *mask, size_t nbytes, uint16_t alignment, uint64_t *foundOffsetOut);
#endif // MEMORY_STREAM_H

View File

@ -1,44 +0,0 @@
#include <stdint.h>
#include "MachO.h"
#define METRIC_TYPE_PATTERN 1
#define METRIC_TYPE_STRING_XREF 2
#define METRIC_TYPE_FUNCTION_XREF 3
typedef struct PFSection {
uint64_t fileoff;
uint64_t vmaddr;
uint64_t size;
uint8_t *cache;
bool ownsCache;
} PFSection;
PFSection *macho_patchfinder_create_section(MachO *macho, const char *filesetEntryId, const char *segName, const char *sectName);
int macho_patchfinder_cache_section(PFSection *section, MachO *fromMacho);
void macho_patchfinder_section_free(PFSection *section);
typedef struct MetricShared {
uint32_t type;
PFSection *section;
} MetricShared;
typedef enum {
BYTE_PATTERN_ALIGN_8_BIT,
BYTE_PATTERN_ALIGN_16_BIT,
BYTE_PATTERN_ALIGN_32_BIT,
BYTE_PATTERN_ALIGN_64_BIT,
} BytePatternAlignment;
typedef struct BytePatternMetric {
MetricShared shared;
void *bytes;
void *mask;
size_t nbytes;
BytePatternAlignment alignment;
} BytePatternMetric;
BytePatternMetric *macho_patchfinder_create_byte_pattern_metric(PFSection *section, void *bytes, void *mask, size_t nbytes, BytePatternAlignment alignment);
void macho_patchfinder_run_metric(MachO *macho, void *metric, void (^matchBlock)(uint64_t vmaddr, bool *stop));

View File

@ -1,16 +0,0 @@
#ifndef SIGN_OSSL_H
#define SIGN_OSSL_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>
#include <openssl/sha.h>
#include <openssl/err.h>
unsigned char *signWithRSA(unsigned char *inputData, size_t inputDataLength, unsigned char *key, size_t key_len, size_t *outputDataLength);
#endif // SIGN_OSSL_H
// 0xA422

View File

@ -1,12 +0,0 @@
#ifndef SIGNING_H
#define SIGNING_H
#include <stdio.h>
#include <stdlib.h>
#include <CommonCrypto/CommonCrypto.h>
#include <Security/SecKey.h>
#include <Security/Security.h>
// int signWithRSA(const char *certificateFile, const char *inputFile, const char *outputFile);
#endif // SIGNING_H

View File

@ -1,6 +0,0 @@
#include <stdint.h>
#include <stdlib.h>
uint64_t align_to_size(int size, int alignment);
int count_digits(int64_t num);
void print_hash(uint8_t *hash, size_t size);

Binary file not shown.

View File

@ -1,17 +1,46 @@
#include "codesign.h"
#include "coretrust_bug.h"
#include <choma/FAT.h>
#include <choma/MachO.h>
#include <choma/FileStream.h>
#include <choma/Host.h>
#include "FAT.h"
#include "MachO.h"
#include "FileStream.h"
#include "Host.h"
#include <copyfile.h>
#define CPU_SUBTYPE_ARM64E_ABI_V2 0x80000000
char *extract_preferred_slice(const char *fatPath)
{
FAT *fat = fat_init_from_path(fatPath);
if (!fat) return NULL;
MachO *macho = fat_find_preferred_slice(fat);
if (!macho) return NULL;
#if TARGET_OS_MAC && !TARGET_OS_IPHONE
if (!macho) {
// Check for arm64v8 first
macho = fat_find_slice(fat, CPU_TYPE_ARM64, CPU_SUBTYPE_ARM64_V8);
if (!macho) {
// If that fails, check for regular arm64
macho = fat_find_slice(fat, CPU_TYPE_ARM64, CPU_SUBTYPE_ARM64_ALL);
if (!macho) {
// If that fails, check for arm64e with ABI v2
macho = fat_find_slice(fat, CPU_TYPE_ARM64, CPU_SUBTYPE_ARM64E | CPU_SUBTYPE_ARM64E_ABI_V2);
if (!macho) {
// If that fails, check for arm64e
macho = fat_find_slice(fat, CPU_TYPE_ARM64, CPU_SUBTYPE_ARM64E);
if (!macho) {
fat_free(fat);
return NULL;
}
}
}
}
}
#else
if (!macho) {
fat_free(fat);
return NULL;
}
#endif // TARGET_OS_MAC && !TARGET_OS_IPHONE
char *temp = strdup("/tmp/XXXXXX");
int fd = mkstemp(temp);
@ -26,30 +55,6 @@ char *extract_preferred_slice(const char *fatPath)
return temp;
}
int apply_coretrust_bypass_wrapper(const char *inputPath, const char *outputPath)
{
char *machoPath = extract_preferred_slice(inputPath);
printf("extracted best slice to %s\n", machoPath);
int r = apply_coretrust_bypass(machoPath);
if (r != 0) {
free(machoPath);
return r;
}
r = copyfile(machoPath, outputPath, 0, COPYFILE_ALL | COPYFILE_MOVE | COPYFILE_UNLINK);
if (r == 0) {
chmod(outputPath, 0755);
printf("Signed file! CoreTrust bypass eta now!!\n");
}
else {
perror("copyfile");
}
free(machoPath);
return r;
}
int main(int argc, char *argv[]) {
if (argc < 2) return -1;
@ -73,13 +78,19 @@ int main(int argc, char *argv[]) {
}
char *machoPath = extract_preferred_slice(input);
if (!machoPath) {
printf("Failed extracting best slice\n");
return -1;
}
printf("Extracted best slice to %s\n", machoPath);
printf("Applying CoreTrust bypass...\n");
if (apply_coretrust_bypass(machoPath) != 0) {
r = apply_coretrust_bypass(machoPath);
if (r != 0) {
printf("Failed applying CoreTrust bypass\n");
return -1;
return r;
}
if (copyfile(machoPath, input, 0, COPYFILE_ALL | COPYFILE_MOVE | COPYFILE_UNLINK) == 0) {

View File

@ -4,13 +4,13 @@ Upstream-Contact: opa334 <opa334@protonmail.com>
Source: https://github.com/opa334/TrollStore
Files: *
Copyright: 2022-2023 Lars Fröder
Copyright: 2022-2024 Lars Fröder
License: MIT
Files: RootHelper/uicache.m
Copyright: Copyright (c) 2019 CoolStar,
Modified work Copyright (c) 2020-2022 Procursus Team <team@procurs.us>
Modified work Copyright (c) 2022-2023 Lars Fröder <opa334@protonmail.com>
Modified work Copyright (c) 2022-2024 Lars Fröder <opa334@protonmail.com>
License: BSD-4-Clause
License: BSD-4-Clause

122
Makefile
View File

@ -1,77 +1,93 @@
TOPTARGETS := all clean
TOPTARGETS := all clean update
$(TOPTARGETS): pre_build make_fastPathSign make_roothelper make_trollstore make_trollhelper_embedded make_trollhelper_package assemble_trollstore build_installer15 build_installer64e
$(TOPTARGETS): pre_build make_fastPathSign make_roothelper make_trollstore make_trollhelper_embedded make_trollhelper_package assemble_trollstore build_installer15 build_installer64e make_trollstore_lite
pre_build:
@rm -rf ./_build 2>/dev/null || true
@mkdir -p ./_build
@rm -rf ./_build 2>/dev/null || true
@mkdir -p ./_build
make_fastPathSign:
@$(MAKE) -C ./Exploits/fastPathSign $(MAKECMDGOALS)
@$(MAKE) -C ./Exploits/fastPathSign $(MAKECMDGOALS)
make_roothelper:
@$(MAKE) -C ./RootHelper FINALPACKAGE=1 $(MAKECMDGOALS)
@$(MAKE) -C ./RootHelper DEBUG=0 $(MAKECMDGOALS)
make_trollstore:
@$(MAKE) -C ./TrollStore FINALPACKAGE=1 $(MAKECMDGOALS)
@$(MAKE) -C ./TrollStore FINALPACKAGE=1 $(MAKECMDGOALS)
ifneq ($(MAKECMDGOALS),clean)
make_trollhelper_package:
@$(MAKE) clean -C ./TrollHelper
@cp ./RootHelper/.theos/obj/trollstorehelper ./TrollHelper/Resources/trollstorehelper
@$(MAKE) -C ./TrollHelper FINALPACKAGE=1 package $(MAKECMDGOALS)
@$(MAKE) clean -C ./TrollHelper
@$(MAKE) -C ./TrollHelper THEOS_PACKAGE_SCHEME=rootless FINALPACKAGE=1 package $(MAKECMDGOALS)
@rm ./TrollHelper/Resources/trollstorehelper
@$(MAKE) clean -C ./TrollHelper
@cp ./RootHelper/.theos/obj/trollstorehelper ./TrollHelper/Resources/trollstorehelper
@$(MAKE) -C ./TrollHelper FINALPACKAGE=1 package $(MAKECMDGOALS)
@$(MAKE) clean -C ./TrollHelper
@$(MAKE) -C ./TrollHelper THEOS_PACKAGE_SCHEME=rootless FINALPACKAGE=1 package $(MAKECMDGOALS)
@rm ./TrollHelper/Resources/trollstorehelper
make_trollhelper_embedded:
@$(MAKE) clean -C ./TrollHelper
@$(MAKE) -C ./TrollHelper FINALPACKAGE=1 EMBEDDED_ROOT_HELPER=1 $(MAKECMDGOALS)
@cp ./TrollHelper/.theos/obj/TrollStorePersistenceHelper.app/TrollStorePersistenceHelper ./_build/PersistenceHelper_Embedded
@$(MAKE) clean -C ./TrollHelper
@$(MAKE) -C ./TrollHelper FINALPACKAGE=1 EMBEDDED_ROOT_HELPER=1 LEGACY_CT_BUG=1 $(MAKECMDGOALS)
@cp ./TrollHelper/.theos/obj/TrollStorePersistenceHelper.app/TrollStorePersistenceHelper ./_build/PersistenceHelper_Embedded_Legacy_arm64
@$(MAKE) clean -C ./TrollHelper
@$(MAKE) -C ./TrollHelper FINALPACKAGE=1 EMBEDDED_ROOT_HELPER=1 CUSTOM_ARCHS=arm64e $(MAKECMDGOALS)
@cp ./TrollHelper/.theos/obj/TrollStorePersistenceHelper.app/TrollStorePersistenceHelper ./_build/PersistenceHelper_Embedded_Legacy_arm64e
@$(MAKE) clean -C ./TrollHelper
@$(MAKE) clean -C ./TrollHelper
@$(MAKE) -C ./TrollHelper FINALPACKAGE=1 EMBEDDED_ROOT_HELPER=1 $(MAKECMDGOALS)
@cp ./TrollHelper/.theos/obj/TrollStorePersistenceHelper.app/TrollStorePersistenceHelper ./_build/PersistenceHelper_Embedded
@$(MAKE) clean -C ./TrollHelper
@$(MAKE) -C ./TrollHelper FINALPACKAGE=1 EMBEDDED_ROOT_HELPER=1 LEGACY_CT_BUG=1 $(MAKECMDGOALS)
@cp ./TrollHelper/.theos/obj/TrollStorePersistenceHelper.app/TrollStorePersistenceHelper ./_build/PersistenceHelper_Embedded_Legacy_arm64
@$(MAKE) clean -C ./TrollHelper
@$(MAKE) -C ./TrollHelper FINALPACKAGE=1 EMBEDDED_ROOT_HELPER=1 CUSTOM_ARCHS=arm64e $(MAKECMDGOALS)
@cp ./TrollHelper/.theos/obj/TrollStorePersistenceHelper.app/TrollStorePersistenceHelper ./_build/PersistenceHelper_Embedded_Legacy_arm64e
@$(MAKE) clean -C ./TrollHelper
assemble_trollstore:
@cp ./RootHelper/.theos/obj/trollstorehelper ./TrollStore/.theos/obj/TrollStore.app/trollstorehelper
@cp ./TrollHelper/.theos/obj/TrollStorePersistenceHelper.app/TrollStorePersistenceHelper ./TrollStore/.theos/obj/TrollStore.app/PersistenceHelper
@export COPYFILE_DISABLE=1
@tar -czvf ./_build/TrollStore.tar -C ./TrollStore/.theos/obj TrollStore.app
@cp ./RootHelper/.theos/obj/trollstorehelper ./TrollStore/.theos/obj/TrollStore.app/trollstorehelper
@cp ./TrollHelper/.theos/obj/TrollStorePersistenceHelper.app/TrollStorePersistenceHelper ./TrollStore/.theos/obj/TrollStore.app/PersistenceHelper
@export COPYFILE_DISABLE=1
@tar -czvf ./_build/TrollStore.tar -C ./TrollStore/.theos/obj TrollStore.app
build_installer15:
@mkdir -p ./_build/tmp15
@unzip ./Victim/InstallerVictim.ipa -d ./_build/tmp15
@cp ./_build/PersistenceHelper_Embedded_Legacy_arm64 ./_build/TrollStorePersistenceHelperToInject
@pwnify set-cpusubtype ./_build/TrollStorePersistenceHelperToInject 1
@ldid -s -K./Victim/victim.p12 ./_build/TrollStorePersistenceHelperToInject
APP_PATH=$$(find ./_build/tmp15/Payload -name "*" -depth 1) ; \
APP_NAME=$$(basename $$APP_PATH) ; \
BINARY_NAME=$$(echo "$$APP_NAME" | cut -f 1 -d '.') ; \
echo $$BINARY_NAME ; \
pwnify pwn ./_build/tmp15/Payload/$$APP_NAME/$$BINARY_NAME ./_build/TrollStorePersistenceHelperToInject
@pushd ./_build/tmp15 ; \
zip -vrD ../../_build/TrollHelper_iOS15.ipa * ; \
popd
@rm ./_build/TrollStorePersistenceHelperToInject
@rm -rf ./_build/tmp15
@mkdir -p ./_build/tmp15
@unzip ./Victim/InstallerVictim.ipa -d ./_build/tmp15
@cp ./_build/PersistenceHelper_Embedded_Legacy_arm64 ./_build/TrollStorePersistenceHelperToInject
@pwnify set-cpusubtype ./_build/TrollStorePersistenceHelperToInject 1
@ldid -s -K./Victim/victim.p12 ./_build/TrollStorePersistenceHelperToInject
APP_PATH=$$(find ./_build/tmp15/Payload -name "*" -depth 1) ; \
APP_NAME=$$(basename $$APP_PATH) ; \
BINARY_NAME=$$(echo "$$APP_NAME" | cut -f 1 -d '.') ; \
echo $$BINARY_NAME ; \
pwnify pwn ./_build/tmp15/Payload/$$APP_NAME/$$BINARY_NAME ./_build/TrollStorePersistenceHelperToInject
@pushd ./_build/tmp15 ; \
zip -vrD ../../_build/TrollHelper_iOS15.ipa * ; \
popd
@rm ./_build/TrollStorePersistenceHelperToInject
@rm -rf ./_build/tmp15
build_installer64e:
@mkdir -p ./_build/tmp64e
@unzip ./Victim/InstallerVictim.ipa -d ./_build/tmp64e
APP_PATH=$$(find ./_build/tmp64e/Payload -name "*" -depth 1) ; \
APP_NAME=$$(basename $$APP_PATH) ; \
BINARY_NAME=$$(echo "$$APP_NAME" | cut -f 1 -d '.') ; \
echo $$BINARY_NAME ; \
pwnify pwn64e ./_build/tmp64e/Payload/$$APP_NAME/$$BINARY_NAME ./_build/PersistenceHelper_Embedded_Legacy_arm64e
@pushd ./_build/tmp64e ; \
zip -vrD ../../_build/TrollHelper_arm64e.ipa * ; \
popd
@rm -rf ./_build/tmp64e
@mkdir -p ./_build/tmp64e
@unzip ./Victim/InstallerVictim.ipa -d ./_build/tmp64e
APP_PATH=$$(find ./_build/tmp64e/Payload -name "*" -depth 1) ; \
APP_NAME=$$(basename $$APP_PATH) ; \
BINARY_NAME=$$(echo "$$APP_NAME" | cut -f 1 -d '.') ; \
echo $$BINARY_NAME ; \
pwnify pwn64e ./_build/tmp64e/Payload/$$APP_NAME/$$BINARY_NAME ./_build/PersistenceHelper_Embedded_Legacy_arm64e
@pushd ./_build/tmp64e ; \
zip -vrD ../../_build/TrollHelper_arm64e.ipa * ; \
popd
@rm -rf ./_build/tmp64e
make_trollstore_lite:
@$(MAKE) -C ./RootHelper DEBUG=0 TROLLSTORE_LITE=1
@rm -rf ./TrollStoreLite/Resources/trollstorehelper
@cp ./RootHelper/.theos/obj/trollstorehelper_lite ./TrollStoreLite/Resources/trollstorehelper
@$(MAKE) -C ./TrollStoreLite package FINALPACKAGE=1
@$(MAKE) -C ./RootHelper TROLLSTORE_LITE=1 clean
@$(MAKE) -C ./TrollStoreLite clean
@$(MAKE) -C ./RootHelper DEBUG=0 TROLLSTORE_LITE=1 THEOS_PACKAGE_SCHEME=rootless
@rm -rf ./TrollStoreLite/Resources/trollstorehelper
@cp ./RootHelper/.theos/obj/trollstorehelper_lite ./TrollStoreLite/Resources/trollstorehelper
@$(MAKE) -C ./TrollStoreLite package FINALPACKAGE=1 THEOS_PACKAGE_SCHEME=rootless
else
make_trollstore_lite:
@$(MAKE) -C ./TrollStoreLite $(MAKECMDGOALS)
endif
.PHONY: $(TOPTARGETS) pre_build assemble_trollstore make_trollhelper_package make_trollhelper_embedded build_installer15 build_installer64e

View File

@ -2,27 +2,15 @@
TrollStore is a permasigned jailed app that can permanently install any IPA you open in it.
It works because of an AMFI/CoreTrust bug where iOS does not verify whether or not a root certificate used to sign a binary is legit.
It works because of an AMFI/CoreTrust bug where iOS does not correctly verify code signatures of binaries in which there are multiple signers.
Supported versions: 14.0 beta 2 - 16.6.1, 16.7 RC (20H18), 17.0
## Installing TrollStore
### Installation Guides
For installing TrollStore, refer to the guides at [ios.cfw.guide](https://ios.cfw.guide/installing-trollstore)
| Version / Device | arm64 (A8 - A11) | arm64e (A12 - A17, M1-M2) |
| --- | --- | --- |
| 13.7 and below | Not Supported (Both CT Bugs only got introduced in 14.0) | Not Supported (Both CT Bugs only got introduced in 14.0) |
| 14.0 - 14.8.1 | [checkra1n + TrollHelper](./install_trollhelper.md) | [TrollHelperOTA (arm64e)](./install_trollhelperota_arm64e.md) |
| 15.0 - 15.4.1 | [TrollHelperOTA (iOS 15+)](./install_trollhelperota_ios15.md) | [TrollHelperOTA (iOS 15+)](./install_trollhelperota_ios15.md) |
| 15.5 beta 1 - 4 | [TrollHelperOTA (iOS 15+)](./install_trollhelperota_ios15.md) | [TrollHelperOTA (iOS 15+)](./install_trollhelperota_ios15.md) |
| 15.5 | Coming Soon | Coming Soon |
| 15.6 beta 1 - 5 | [TrollHelperOTA (iOS 15+)](./install_trollhelperota_ios15.md) | [TrollHelperOTA (iOS 15+)](./install_trollhelperota_ios15.md) |
| 15.6 - 16.5 | Coming Soon | Coming Soon |
| 16.5.1 - 16.6.1 | Coming Soon | No Installation Method |
| 16.7 - 16.7.2 | Not Supported (Both CT Bugs fixed) | Not Supported (Both CT Bugs fixed) |
| 17.0 | Coming Soon | No Installation Method |
| 17.0.1 and newer | Not Supported (Both CT Bugs fixed) | Not Supported (Both CT Bugs fixed) |
Due to the discovery of a new CoreTrust vulnerability, support for 15.5 - 16.6.1 and 17.0 will be added in the future. Stay on these versions if you want TrollStore. 16.7 and 17.0.1+ will NEVER be supported (unless Apple fucks CoreTrust up a third time...).
16.7.x (excluding 16.7 RC) and 17.0.1+ will NEVER be supported (unless a third CoreTrust bug is discovered, which is unlikely).
## Updating TrollStore
@ -32,7 +20,7 @@ Alternatively (if anything goes wrong), you can download the TrollStore.tar file
## Uninstalling an app
Apps installed from TrollStore can only be uninstalled from TrollStore itself, tap an app or swipe it to the right in the 'Apps' tab to delete it.
Apps installed from TrollStore can only be uninstalled from TrollStore itself, tap an app or swipe it to the left in the 'Apps' tab to delete it.
## Persistence Helper
@ -44,9 +32,10 @@ On jailbroken iOS 14 when TrollHelper is used for installation, it is located in
## URL Scheme
As of version 1.3, TrollStore replaces the system URL scheme "apple-magnifier" (this is done so "jailbreak" detections can't detect TrollStore like they could if TrollStore had a unique URL scheme). This URL scheme can be used to install applications right from the browser, the format goes as follows:
As of version 1.3, TrollStore replaces the system URL scheme "apple-magnifier" (this is done so "jailbreak" detections can't detect TrollStore like they could if TrollStore had a unique URL scheme). This URL scheme can be used to install applications right from the browser, or to enable JIT from the app itself (only 2.0.12 and above), the format goes as follows:
`apple-magnifier://install?url=<URL_to_IPA>`
- `apple-magnifier://install?url=<URL_to_IPA>`
- `apple-magnifier://enable-jit?bundle-id=<Bundle_ID>`
On devices that don't have TrollStore (1.3+) installed, this will just open the magnifier app.
@ -112,7 +101,7 @@ When your app is not sandboxed, you can spawn other binaries using posix_spawn,
You can also add your own binaries into your app bundle.
Afterwards you can use the [spawnRoot function in TSUtil.m](./Shared/TSUtil.m#L77) to spawn the binary as root.
Afterwards you can use the [spawnRoot function in TSUtil.m](./Shared/TSUtil.m#L79) to spawn the binary as root.
### Things that are not possible using TrollStore
@ -120,10 +109,18 @@ Afterwards you can use the [spawnRoot function in TSUtil.m](./Shared/TSUtil.m#L7
- Spawning a launch daemon (Would need `CS_PLATFORMIZED`)
- Injecting a tweak into a system process (Would need `TF_PLATFORM`, a userland PAC bypass and a PMAP trust level bypass)
### Compilation
To compile TrollStore, ensure [theos](https://theos.dev/docs/installation) is installed. Additionaly ensure [brew](https://brew.sh/) is installed and install [libarchive](https://formulae.brew.sh/formula/libarchive) from brew.
## Credits and Further Reading
[@LinusHenze](https://twitter.com/LinusHenze/) - Found the CoreTrust bug that allows TrollStore to work.
[@alfiecg_dev](https://twitter.com/alfiecg_dev/) - Found the CoreTrust bug that allows TrollStore to work through patchdiffing and worked on automating the bypass.
Google Threat Analysis Group - Found the CoreTrust bug as part of an in-the-wild spyware chain and reported it to Apple.
[@LinusHenze](https://twitter.com/LinusHenze) - Found the installd bypass used to install TrollStore on iOS 14-15.6.1 via TrollHelperOTA, as well as the original CoreTrust bug used in TrollStore 1.0.
[Fugu15 Presentation](https://youtu.be/rPTifU1lG7Q)
[Write-Up on the CoreTrust bug with more information](https://worthdoingbadly.com/coretrust/).
[Write-Up on the first CoreTrust bug with more information](https://worthdoingbadly.com/coretrust/).

View File

View File

@ -1,18 +1,36 @@
TARGET := iphone:clang:16.4:14.0
TARGET := iphone:clang:16.5:14.0
ARCHS = arm64
ifdef TROLLSTORE_LITE
HELPER_NAME = trollstorehelper_lite
else
HELPER_NAME = trollstorehelper
TARGET_CODESIGN = ../Exploits/fastPathSign/fastPathSign
endif
include $(THEOS)/makefiles/common.mk
TOOL_NAME = trollstorehelper
TOOL_NAME = $(HELPER_NAME)
trollstorehelper_FILES = $(wildcard *.m) $(wildcard ../Shared/*.m) ../Exploits/fastPathSign/src/coretrust_bug.c ../Exploits/fastPathSign/src/codesign.m
trollstorehelper_CFLAGS = -fobjc-arc -I../Shared $(shell pkg-config --cflags libcrypto) -Iexternal/include -I../Exploits/fastPathSign/src
trollstorehelper_LDFLAGS = -Lexternal/lib -lcrypto -lchoma
trollstorehelper_CODESIGN_FLAGS = --entitlements entitlements.plist
trollstorehelper_INSTALL_PATH = /usr/local/bin
trollstorehelper_LIBRARIES = archive
trollstorehelper_PRIVATE_FRAMEWORKS = SpringBoardServices BackBoardServices MobileContainerManager
$(HELPER_NAME)_FILES = $(wildcard *.m) $(wildcard ../Shared/*.m) $(wildcard ../ChOma/src/*.c)
ifndef TROLLSTORE_LITE
$(HELPER_NAME)_FILES += ../Exploits/fastPathSign/src/coretrust_bug.c ../Exploits/fastPathSign/src/codesign.m
$(HELPER_NAME)_CODESIGN_FLAGS = --entitlements entitlements.plist
$(HELPER_NAME)_LDFLAGS = -L../ChOma/external/ios -lcrypto
else
$(HELPER_NAME)_CODESIGN_FLAGS = -Sentitlements.plist
endif
$(HELPER_NAME)_CFLAGS = -fobjc-arc -I../Shared $(shell pkg-config --cflags libcrypto) -I../ChOma/src -I../Exploits/fastPathSign/src -I$(shell brew --prefix)/opt/libarchive/include
$(HELPER_NAME)_INSTALL_PATH = /usr/local/bin
$(HELPER_NAME)_LIBRARIES = archive
$(HELPER_NAME)_FRAMEWORKS = CoreTelephony
$(HELPER_NAME)_PRIVATE_FRAMEWORKS = SpringBoardServices BackBoardServices MobileContainerManager FrontBoardServices RunningBoardServices
ifdef TROLLSTORE_LITE
$(HELPER_NAME)_CFLAGS += -DTROLLSTORE_LITE -DDISABLE_SIGNING=1
endif
include $(THEOS_MAKE_PATH)/tool.mk

View File

@ -1,6 +1,6 @@
Package: com.opa334.trollstoreroothelper
Name: trollstoreroothelper
Version: 2.0.3
Version: 2.1
Architecture: iphoneos-arm
Description: An awesome tool of some sort!!
Maintainer: opa334

4
RootHelper/devmode.h Normal file
View File

@ -0,0 +1,4 @@
#import <Foundation/Foundation.h>
BOOL checkDeveloperMode(void);
BOOL armDeveloperMode(BOOL* alreadyEnabled);

145
RootHelper/devmode.m Normal file
View File

@ -0,0 +1,145 @@
@import Foundation;
#ifndef __XPC_H__
// Types
typedef NSObject* xpc_object_t;
typedef xpc_object_t xpc_connection_t;
typedef void (^xpc_handler_t)(xpc_object_t object);
// Communication
extern xpc_connection_t xpc_connection_create_mach_service(const char* name, dispatch_queue_t targetq, uint64_t flags);
extern void xpc_connection_set_event_handler(xpc_connection_t connection, xpc_handler_t handler);
extern void xpc_connection_resume(xpc_connection_t connection);
extern void xpc_connection_send_message_with_reply(xpc_connection_t connection, xpc_object_t message, dispatch_queue_t replyq, xpc_handler_t handler);
extern xpc_object_t xpc_connection_send_message_with_reply_sync(xpc_connection_t connection, xpc_object_t message);
extern xpc_object_t xpc_dictionary_get_value(xpc_object_t xdict, const char *key);
#endif
// Serialization
extern CFTypeRef _CFXPCCreateCFObjectFromXPCObject(xpc_object_t xpcattrs);
extern xpc_object_t _CFXPCCreateXPCObjectFromCFObject(CFTypeRef attrs);
extern xpc_object_t _CFXPCCreateXPCMessageWithCFObject(CFTypeRef obj);
extern CFTypeRef _CFXPCCreateCFObjectFromXPCMessage(xpc_object_t obj);
typedef enum {
kAMFIActionArm = 0, // Trigger a prompt asking the user to enable developer mode on the next reboot
// (regardless of current state)
kAMFIActionDisable = 1, // Disable developer mode if it's currently enabled. Takes effect immediately.
kAMFIActionStatus = 2, // Returns a dict: {success: bool, status: bool, armed: bool}
} AMFIXPCAction;
xpc_connection_t startConnection(void) {
xpc_connection_t connection = xpc_connection_create_mach_service("com.apple.amfi.xpc", NULL, 0);
if (!connection) {
NSLog(@"[startXPCConnection] Failed to create XPC connection to amfid");
return nil;
}
xpc_connection_set_event_handler(connection, ^(xpc_object_t event) {
});
xpc_connection_resume(connection);
return connection;
}
NSDictionary* sendXPCRequest(xpc_connection_t connection, AMFIXPCAction action) {
xpc_object_t message = _CFXPCCreateXPCMessageWithCFObject((__bridge CFDictionaryRef) @{@"action": @(action)});
xpc_object_t replyMsg = xpc_connection_send_message_with_reply_sync(connection, message);
if (!replyMsg) {
NSLog(@"[sendXPCRequest] got no reply from amfid");
return nil;
}
xpc_object_t replyObj = xpc_dictionary_get_value(replyMsg, "cfreply");
if (!replyObj) {
NSLog(@"[sendXPCRequest] got reply but no cfreply");
return nil;
}
NSDictionary* asCF = (__bridge NSDictionary*)_CFXPCCreateCFObjectFromXPCMessage(replyObj);
return asCF;
}
BOOL getDeveloperModeState(xpc_connection_t connection) {
NSDictionary* reply = sendXPCRequest(connection, kAMFIActionStatus);
if (!reply) {
NSLog(@"[getDeveloperModeState] failed to get reply");
return NO;
}
NSLog(@"[getDeveloperModeState] got reply %@", reply);
NSObject* success = reply[@"success"];
if (!success || ![success isKindOfClass:[NSNumber class]] || ![(NSNumber*)success boolValue]) {
NSLog(@"[getDeveloperModeState] request failed with error %@", reply[@"error"]);
return NO;
}
NSObject* status = reply[@"status"];
if (!status || ![status isKindOfClass:[NSNumber class]]) {
NSLog(@"[getDeveloperModeState] request succeeded but no status");
return NO;
}
return [(NSNumber*)status boolValue];
}
BOOL setDeveloperModeState(xpc_connection_t connection, BOOL enable) {
NSDictionary* reply = sendXPCRequest(connection, enable ? kAMFIActionArm : kAMFIActionDisable);
if (!reply) {
NSLog(@"[setDeveloperModeState] failed to get reply");
return NO;
}
NSObject* success = reply[@"success"];
if (!success || ![success isKindOfClass:[NSNumber class]] || ![(NSNumber*)success boolValue]) {
NSLog(@"[setDeveloperModeState] request failed with error %@", reply[@"error"]);
return NO;
}
return YES;
}
BOOL checkDeveloperMode(void) {
// Developer mode does not exist before iOS 16
if (@available(iOS 16, *)) {
xpc_connection_t connection = startConnection();
if (!connection) {
NSLog(@"[checkDeveloperMode] failed to start connection");
// Assume it's disabled
return NO;
}
return getDeveloperModeState(connection);
} else {
return YES;
}
}
BOOL armDeveloperMode(BOOL* alreadyEnabled) {
// Developer mode does not exist before iOS 16
if (@available(iOS 16, *)) {
xpc_connection_t connection = startConnection();
if (!connection) {
NSLog(@"[armDeveloperMode] failed to start connection");
return NO;
}
BOOL enabled = getDeveloperModeState(connection);
if (alreadyEnabled) {
*alreadyEnabled = enabled;
}
if (enabled) {
// NSLog(@"[armDeveloperMode] already enabled");
return YES;
}
BOOL success = setDeveloperModeState(connection, YES);
if (!success) {
NSLog(@"[armDeveloperMode] failed to arm");
return NO;
}
}
return YES;
}

View File

@ -44,5 +44,11 @@
<string>Uninstall</string>
<string>UpdatePlaceholderMetadata</string>
</array>
<key>com.apple.private.amfi.developer-mode-control</key>
<true/>
<key>com.apple.frontboard.shutdown</key>
<true/>
<key>com.apple.runningboard.process-state</key>
<true/>
</dict>
</plist>

View File

@ -1,11 +0,0 @@
#ifndef BASE64_H
#define BASE64_H
#include <stdint.h>
#include <stdlib.h>
char *base64_encode(const unsigned char *data,
size_t input_length,
size_t *output_length);
#endif // BASE64_H

View File

@ -1,19 +0,0 @@
#ifndef BUFFERED_STREAM_H
#define BUFFERED_STREAM_H
#include "MemoryStream.h"
#include <stdbool.h>
#define BUFFERED_STREAM_FLAG_AUTO_EXPAND (1 << 0)
typedef struct BufferedStreamContext {
uint8_t *buffer;
size_t bufferSize;
uint32_t subBufferStart;
size_t subBufferSize;
} BufferedStreamContext;
MemoryStream *buffered_stream_init_from_buffer_nocopy(void *buffer, size_t bufferSize, uint32_t flags);
MemoryStream *buffered_stream_init_from_buffer(void *buffer, size_t bufferSize, uint32_t flags);
#endif // BUFFERED_STREAM_H

View File

@ -1,108 +0,0 @@
#ifndef CS_BLOB_H
#define CS_BLOB_H
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>
#include "FAT.h"
#include "MachO.h"
#include "MemoryStream.h"
// Blob index
typedef struct __BlobIndex {
uint32_t type;
uint32_t offset;
} CS_BlobIndex;
// CMS superblob
typedef struct __SuperBlob {
uint32_t magic;
uint32_t length;
uint32_t count;
CS_BlobIndex index[];
} CS_SuperBlob;
typedef struct __GenericBlob {
uint32_t magic; /* magic number */
uint32_t length; /* total length of blob */
char data[];
} CS_GenericBlob;
// CMS blob magic types
enum {
CSBLOB_REQUIREMENT = 0xfade0c00,
CSBLOB_REQUIREMENTS = 0xfade0c01,
CSBLOB_CODEDIRECTORY = 0xfade0c02,
CSBLOB_EMBEDDED_SIGNATURE = 0xfade0cc0,
CSBLOB_DETACHED_SIGNATURE = 0xfade0cc1,
CSBLOB_ENTITLEMENTS = 0xfade7171,
CSBLOB_DER_ENTITLEMENTS = 0xfade7172,
CSBLOB_SIGNATURE_BLOB = 0xfade0b01
} CS_BlobType;
enum {
CSSLOT_CODEDIRECTORY = 0,
CSSLOT_INFOSLOT = 1,
CSSLOT_REQUIREMENTS = 2,
CSSLOT_RESOURCEDIR = 3,
CSSLOT_APPLICATION = 4,
CSSLOT_ENTITLEMENTS = 5,
CSSLOT_DER_ENTITLEMENTS = 7,
CSSLOT_ALTERNATE_CODEDIRECTORIES = 0x1000,
CSSLOT_ALTERNATE_CODEDIRECTORY_MAX = 5,
CSSLOT_ALTERNATE_CODEDIRECTORY_LIMIT = CSSLOT_ALTERNATE_CODEDIRECTORIES + CSSLOT_ALTERNATE_CODEDIRECTORY_MAX,
CSSLOT_SIGNATURESLOT = 0x10000
} CS_SlotType;
typedef struct s_CS_DecodedBlob {
struct s_CS_DecodedBlob *next;
uint32_t type;
MemoryStream *stream;
} CS_DecodedBlob;
typedef struct s_CS_DecodedSuperBlob {
uint32_t magic;
struct s_CS_DecodedBlob *firstBlob;
} CS_DecodedSuperBlob;
// Convert blob magic to readable blob type string
char *cs_blob_magic_to_string(int magic);
// Extract Code Signature to file
int macho_extract_cs_to_file(MachO *macho, CS_SuperBlob *superblob);
int macho_find_code_signature_bounds(MachO *macho, uint32_t *offsetOut, uint32_t *sizeOut);
CS_SuperBlob *macho_read_code_signature(MachO *macho);
int macho_replace_code_signature(MachO *macho, CS_SuperBlob *superblob);
int update_load_commands(MachO *macho, CS_SuperBlob *superblob, uint64_t originalSize);
CS_DecodedBlob *csd_blob_init(uint32_t type, CS_GenericBlob *blobData);
int csd_blob_read(CS_DecodedBlob *blob, uint64_t offset, size_t size, void *outBuf);
int csd_blob_write(CS_DecodedBlob *blob, uint64_t offset, size_t size, const void *inBuf);
int csd_blob_insert(CS_DecodedBlob *blob, uint64_t offset, size_t size, const void *inBuf);
int csd_blob_delete(CS_DecodedBlob *blob, uint64_t offset, size_t size);
int csd_blob_read_string(CS_DecodedBlob *blob, uint64_t offset, char **outString);
int csd_blob_write_string(CS_DecodedBlob *blob, uint64_t offset, const char *string);
int csd_blob_get_size(CS_DecodedBlob *blob);
uint32_t csd_blob_get_type(CS_DecodedBlob *blob);
void csd_blob_set_type(CS_DecodedBlob *blob, uint32_t type);
void csd_blob_free(CS_DecodedBlob *blob);
CS_DecodedSuperBlob *csd_superblob_decode(CS_SuperBlob *superblob);
CS_SuperBlob *csd_superblob_encode(CS_DecodedSuperBlob *decodedSuperblob);
CS_DecodedBlob *csd_superblob_find_blob(CS_DecodedSuperBlob *superblob, uint32_t type, uint32_t *indexOut);
int csd_superblob_insert_blob_after_blob(CS_DecodedSuperBlob *superblob, CS_DecodedBlob *blobToInsert, CS_DecodedBlob *afterBlob);
int csd_superblob_insert_blob_at_index(CS_DecodedSuperBlob *superblob, CS_DecodedBlob *blobToInsert, uint32_t atIndex);
int csd_superblob_append_blob(CS_DecodedSuperBlob *superblob, CS_DecodedBlob *blobToAppend);
int csd_superblob_remove_blob(CS_DecodedSuperBlob *superblob, CS_DecodedBlob *blobToRemove); // <- Important: When calling this, caller is responsible for freeing blobToRemove
int csd_superblob_remove_blob_at_index(CS_DecodedSuperBlob *superblob, uint32_t atIndex);
int csd_superblob_print_content(CS_DecodedSuperBlob *decodedSuperblob, MachO *macho, bool printAllSlots, bool verifySlots);
void csd_superblob_free(CS_DecodedSuperBlob *decodedSuperblob);
#endif // CS_BLOB_H

View File

@ -1,53 +0,0 @@
#ifndef CODE_DIRECTORY_H
#define CODE_DIRECTORY_H
#include <stdint.h>
#include <math.h>
#include <CommonCrypto/CommonDigest.h>
#include "MachO.h"
#include "CSBlob.h"
#include "FAT.h"
#include "MachOByteOrder.h"
#include "MachOLoadCommand.h"
#include "MemoryStream.h"
// Code directory blob header
typedef struct __CodeDirectory {
uint32_t magic;
uint32_t length;
uint32_t version;
uint32_t flags;
uint32_t hashOffset;
uint32_t identOffset;
uint32_t nSpecialSlots;
uint32_t nCodeSlots;
uint32_t codeLimit;
uint8_t hashSize;
uint8_t hashType;
uint8_t spare1;
uint8_t pageSize;
uint32_t spare2;
uint32_t scatterOffset;
uint32_t teamOffset;
} CS_CodeDirectory;
enum CS_HashType {
CS_HASHTYPE_SHA160_160 = 1,
CS_HASHTYPE_SHA256_256 = 2,
CS_HASHTYPE_SHA256_160 = 3,
CS_HASHTYPE_SHA384_384 = 4,
};
char *csd_code_directory_copy_identity(CS_DecodedBlob *codeDirBlob, uint32_t *offsetOut);
char *csd_code_directory_copy_team_id(CS_DecodedBlob *codeDirBlob, uint32_t *offsetOut);
int csd_code_directory_set_team_id(CS_DecodedBlob *codeDirBlob, char *newTeamID);
uint32_t csd_code_directory_get_flags(CS_DecodedBlob *codeDirBlob);
void csd_code_directory_set_flags(CS_DecodedBlob *codeDirBlob, uint32_t flags);
uint8_t csd_code_directory_get_hash_type(CS_DecodedBlob *codeDirBlob);
void csd_code_directory_set_hash_type(CS_DecodedBlob *codeDirBlob, uint8_t hashType);
int csd_code_directory_print_content(CS_DecodedBlob *codeDirBlob, MachO *macho, bool printSlots, bool verifySlots);
void csd_code_directory_update(CS_DecodedBlob *codeDirBlob, MachO *macho);
#endif // CODE_DIRECTORY_H

View File

@ -1,41 +0,0 @@
#ifndef MACHO_H
#define MACHO_H
#include <stdio.h>
#include <libkern/OSByteOrder.h>
#include <mach/mach.h>
#include <mach-o/loader.h>
#include <mach-o/fat.h>
#include <sys/stat.h>
#include "MemoryStream.h"
typedef struct MachO MachO;
// A FAT structure can either represent a FAT file with multiple slices, in which the slices will be loaded into the slices attribute
// Or a single slice MachO, in which case it serves as a compatibility layer and the single slice will also be loaded into the slices attribute
typedef struct FAT
{
MemoryStream *stream;
MachO **slices;
uint32_t slicesCount;
int fileDescriptor;
} FAT;
int fat_read_at_offset(FAT *fat, uint64_t offset, size_t size, void *outBuf);
MemoryStream *fat_get_stream(FAT *fat);
// Initialise a FAT structure from a memory stream
FAT *fat_init_from_memory_stream(MemoryStream *stream);
// Initialise a FAT structure using the path to the file
FAT *fat_init_from_path(const char *filePath);
//FAT *fat_init_from_path_for_writing(const char *filePath);
// Find macho with cputype and cpusubtype in FAT, returns NULL if not found
MachO *fat_find_slice(FAT *fat, cpu_type_t cputype, cpu_subtype_t cpusubtype);
// Free all elements of the FAT structure
void fat_free(FAT *fat);
#endif // MACHO_H

View File

@ -1,21 +0,0 @@
#ifndef FILE_STREAM_H
#define FILE_STREAM_H
#include "MemoryStream.h"
#define FILE_STREAM_SIZE_AUTO 0
#define FILE_STREAM_FLAG_WRITABLE (1 << 0)
#define FILE_STREAM_FLAG_AUTO_EXPAND (1 << 1)
typedef struct FileStreamContext {
int fd;
size_t fileSize;
uint32_t bufferStart;
size_t bufferSize;
} FileStreamContext;
MemoryStream *file_stream_init_from_file_descriptor_nodup(int fd, uint32_t bufferStart, size_t bufferSize, uint32_t flags);
MemoryStream *file_stream_init_from_file_descriptor(int fd, uint32_t bufferStart, size_t bufferSize, uint32_t flags);
MemoryStream *file_stream_init_from_path(const char *path, uint32_t bufferStart, size_t bufferSize, uint32_t flags);
#endif // FILE_STREAM_H

View File

@ -1,10 +0,0 @@
#ifndef HOST_H
#define HOST_H
#include "FAT.h"
// Retrieve the preferred MachO slice from a FAT
// Preferred slice as in the slice that the kernel would use when loading the file
MachO *fat_find_preferred_slice(FAT *fat);
#endif // HOST_H

View File

@ -1,62 +0,0 @@
#ifndef MACHO_SLICE_H
#define MACHO_SLICE_H
#include <stdbool.h>
#include <mach-o/fat.h>
#include <mach-o/loader.h>
#include "MemoryStream.h"
#include "FAT.h"
typedef struct MachOSegment
{
struct segment_command_64 command;
struct section_64 sections[];
} __attribute__((__packed__)) MachOSegment;
typedef struct FilesetMachO {
char *entry_id;
uint64_t vmaddr;
uint64_t fileoff;
FAT *underlyingMachO;
} FilesetMachO;
typedef struct MachO {
MemoryStream *stream;
bool isSupported;
struct mach_header_64 machHeader;
struct fat_arch_64 archDescriptor;
uint32_t filesetCount;
FilesetMachO *filesetMachos;
uint32_t segmentCount;
MachOSegment **segments;
} MachO;
// Read data from a MachO at a specified offset
int macho_read_at_offset(MachO *macho, uint64_t offset, size_t size, void *outBuf);
// Write data from a MachO at a specified offset, auto expands, only works if opened via macho_init_for_writing
int macho_write_at_offset(MachO *macho, uint64_t offset, size_t size, void *inBuf);
MemoryStream *macho_get_stream(MachO *macho);
uint32_t macho_get_filetype(MachO *macho);
// Perform translation between file offsets and virtual addresses
int macho_translate_fileoff_to_vmaddr(MachO *macho, uint64_t fileoff, uint64_t *vmaddrOut, MachOSegment **segmentOut);
int macho_translate_vmaddr_to_fileoff(MachO *macho, uint64_t vmaddr, uint64_t *fileoffOut, MachOSegment **segmentOut);
// Read data from a MachO at a specified virtual address
int macho_read_at_vmaddr(MachO *macho, uint64_t vmaddr, size_t size, void *outBuf);
int macho_enumerate_load_commands(MachO *macho, void (^enumeratorBlock)(struct load_command loadCommand, uint64_t offset, void *cmd, bool *stop));
// Initialise a MachO object from a MemoryStream and it's corresponding FAT arch descriptor
MachO *macho_init(MemoryStream *stream, struct fat_arch_64 archDescriptor);
// Initialize a single slice macho for writing to it
MachO *macho_init_for_writing(const char *filePath);
void macho_free(MachO *macho);
#endif // MACHO_SLICE_H

View File

@ -1,164 +0,0 @@
#ifndef MACHO_BYTE_ORDER_H
#define MACHO_BYTE_ORDER_H
#include <stdio.h>
#include <stdlib.h>
// 8-bit integers needed for CodeDirectory
#define BIG_TO_HOST(n) _Generic((n), \
int8_t: n, \
uint8_t: n, \
int16_t: OSSwapBigToHostInt16(n), \
uint16_t: OSSwapBigToHostInt16(n), \
int32_t: OSSwapBigToHostInt32(n), \
uint32_t: OSSwapBigToHostInt32(n), \
int64_t: OSSwapBigToHostInt64(n), \
uint64_t: OSSwapBigToHostInt64(n) \
)
#define HOST_TO_BIG(n) _Generic((n), \
int8_t: n, \
uint8_t: n, \
uint16_t: OSSwapHostToBigInt16(n), \
int16_t: OSSwapHostToBigInt16(n), \
int32_t: OSSwapHostToBigInt32(n), \
uint32_t: OSSwapHostToBigInt32(n), \
int64_t: OSSwapHostToBigInt64(n), \
uint64_t: OSSwapHostToBigInt64(n) \
)
#define LITTLE_TO_HOST(n) _Generic((n), \
int8_t: n, \
uint8_t: n, \
int16_t: OSSwapLittleToHostInt16(n), \
uint16_t: OSSwapLittleToHostInt16(n), \
int32_t: OSSwapLittleToHostInt32(n), \
uint32_t: OSSwapLittleToHostInt32(n), \
int64_t: OSSwapLittleToHostInt64(n), \
uint64_t: OSSwapLittleToHostInt64(n) \
)
#define HOST_TO_LITTLE(n) _Generic((n), \
int8_t: n, \
uint8_t: n, \
int16_t: OSSwapHostToLittleInt16(n), \
uint16_t: OSSwapHostToLittleInt16(n), \
int32_t: OSSwapHostToLittleInt32(n), \
uint32_t: OSSwapHostToLittleInt32(n), \
int64_t: OSSwapHostToLittleInt64(n), \
uint64_t: OSSwapHostToLittleInt64(n) \
)
#define HOST_TO_LITTLE_APPLIER(instance, member) \
(instance)->member = HOST_TO_LITTLE((instance)->member)
#define HOST_TO_BIG_APPLIER(instance, member) \
(instance)->member = HOST_TO_BIG((instance)->member)
#define LITTLE_TO_HOST_APPLIER(instance, member) \
(instance)->member = LITTLE_TO_HOST((instance)->member)
#define BIG_TO_HOST_APPLIER(instance, member) \
(instance)->member = BIG_TO_HOST((instance)->member)
#define FAT_HEADER_APPLY_BYTE_ORDER(fh, applier) \
applier(fh, magic); \
applier(fh, nfat_arch);
#define FAT_ARCH_APPLY_BYTE_ORDER(arch, applier) \
applier(arch, cputype); \
applier(arch, cpusubtype); \
applier(arch, offset); \
applier(arch, size); \
applier(arch, align); \
#define FAT_ARCH_64_APPLY_BYTE_ORDER(arch, applier) \
applier(arch, cputype); \
applier(arch, cpusubtype); \
applier(arch, offset); \
applier(arch, size); \
applier(arch, align); \
applier(arch, reserved); \
#define MACH_HEADER_APPLY_BYTE_ORDER(mh, applier) \
applier(mh, magic); \
applier(mh, cputype); \
applier(mh, cpusubtype); \
applier(mh, filetype); \
applier(mh, ncmds); \
applier(mh, sizeofcmds); \
applier(mh, reserved);
#define LOAD_COMMAND_APPLY_BYTE_ORDER(lc, applier) \
applier(lc, cmd); \
applier(lc, cmdsize);
#define LINKEDIT_DATA_COMMAND_APPLY_BYTE_ORDER(lc, applier) \
applier(lc, cmd); \
applier(lc, cmdsize); \
applier(lc, dataoff); \
applier(lc, datasize);
#define BLOB_INDEX_APPLY_BYTE_ORDER(bi, applier) \
applier(bi, type); \
applier(bi, offset);
#define SUPERBLOB_APPLY_BYTE_ORDER(sb, applier) \
applier(sb, magic); \
applier(sb, length); \
applier(sb, count);
#define GENERIC_BLOB_APPLY_BYTE_ORDER(gb, applier) \
applier(gb, magic); \
applier(gb, length);
#define CODE_DIRECTORY_APPLY_BYTE_ORDER(cd, applier) \
applier(cd, magic); \
applier(cd, length); \
applier(cd, version); \
applier(cd, flags); \
applier(cd, hashOffset); \
applier(cd, identOffset); \
applier(cd, nSpecialSlots); \
applier(cd, nCodeSlots); \
applier(cd, codeLimit); \
applier(cd, hashSize); \
applier(cd, hashType); \
applier(cd, spare1); \
applier(cd, pageSize); \
applier(cd, spare2); \
applier(cd, scatterOffset); \
applier(cd, teamOffset);
#define SEGMENT_COMMAND_64_APPLY_BYTE_ORDER(sc64, applier) \
applier(sc64, cmd); \
applier(sc64, cmdsize); \
applier(sc64, fileoff); \
applier(sc64, filesize); \
applier(sc64, vmaddr); \
applier(sc64, vmsize); \
applier(sc64, flags); \
applier(sc64, initprot); \
applier(sc64, maxprot); \
applier(sc64, nsects);
#define SECTION_64_APPLY_BYTE_ORDER(sc64, applier) \
applier(sc64, addr); \
applier(sc64, align); \
applier(sc64, flags); \
applier(sc64, nreloc); \
applier(sc64, offset); \
applier(sc64, reserved1); \
applier(sc64, reserved2); \
applier(sc64, reserved3); \
applier(sc64, size);
#define FILESET_ENTRY_COMMAND_APPLY_BYTE_ORDER(fse, applier) \
applier(fse, cmd); \
applier(fse, cmdsize); \
applier(fse, vmaddr); \
applier(fse, fileoff); \
applier(fse, entry_id.offset); \
applier(fse, reserved); \
#endif // MACHO_BYTE_ORDER_H

View File

@ -1,16 +0,0 @@
#ifndef MACHO_LOAD_COMMAND_H
#define MACHO_LOAD_COMMAND_H
#include <mach-o/loader.h>
#include "MachO.h"
#include "CSBlob.h"
#include "FileStream.h"
#include "MachOByteOrder.h"
// Convert load command to load command name
char *load_command_to_string(int loadCommand);
void update_segment_command_64(MachO *macho, const char *segmentName, uint64_t vmaddr, uint64_t vmsize, uint64_t fileoff, uint64_t filesize);
void update_lc_code_signature(MachO *macho, uint64_t size);
int update_load_commands_for_coretrust_bypass(MachO *macho, CS_SuperBlob *superblob, uint64_t originalCodeSignatureSize, uint64_t originalMachOSize);
#endif // MACHO_LOAD_COMMAND_H

View File

@ -1,60 +0,0 @@
#ifndef MEMORY_STREAM_H
#define MEMORY_STREAM_H
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <stdbool.h>
#define MEMORY_STREAM_FLAG_OWNS_DATA (1 << 0)
#define MEMORY_STREAM_FLAG_MUTABLE (1 << 1)
#define MEMORY_STREAM_FLAG_AUTO_EXPAND (1 << 2)
#define MEMORY_STREAM_SIZE_INVALID (size_t)-1
// A generic memory IO interface that is used throughout this project
// Can be backed by anything, just the functions have to be implemented
typedef struct s_MemoryStream {
void *context;
uint32_t flags;
int (*read)(struct s_MemoryStream *stream, uint64_t offset, size_t size, void *outBuf);
int (*write)(struct s_MemoryStream *stream, uint64_t offset, size_t size, const void *inBuf);
int (*getSize)(struct s_MemoryStream *stream, size_t *sizeOut);
uint8_t *(*getRawPtr)(struct s_MemoryStream *stream);
int (*trim)(struct s_MemoryStream *stream, size_t trimAtStart, size_t trimAtEnd);
int (*expand)(struct s_MemoryStream *stream, size_t expandAtStart, size_t expandAtEnd);
struct s_MemoryStream *(*hardclone)(struct s_MemoryStream *stream);
struct s_MemoryStream *(*softclone)(struct s_MemoryStream *stream);
void (*free)(struct s_MemoryStream *stream);
} MemoryStream;
int memory_stream_read(MemoryStream *stream, uint64_t offset, size_t size, void *outBuf);
int memory_stream_write(MemoryStream *stream, uint64_t offset, size_t size, const void *inBuf);
int memory_stream_insert(MemoryStream *stream, uint64_t offset, size_t size, const void *inBuf);
int memory_stream_delete(MemoryStream *stream, uint64_t offset, size_t size);
int memory_stream_read_string(MemoryStream *stream, uint64_t offset, char **outString);
int memory_stream_write_string(MemoryStream *stream, uint64_t offset, const char *string);
size_t memory_stream_get_size(MemoryStream *stream);
uint8_t *memory_stream_get_raw_pointer(MemoryStream *stream);
uint32_t memory_stream_get_flags(MemoryStream *stream);
MemoryStream *memory_stream_softclone(MemoryStream *stream);
MemoryStream *memory_stream_hardclone(MemoryStream *stream);
int memory_stream_trim(MemoryStream *stream, size_t trimAtStart, size_t trimAtEnd);
int memory_stream_expand(MemoryStream *stream, size_t expandAtStart, size_t expandAtEnd);
void memory_stream_free(MemoryStream *stream);
int memory_stream_copy_data(MemoryStream *originStream, uint64_t originOffset, MemoryStream *targetStream, uint64_t targetOffset, size_t size);
int memory_stream_find_memory(MemoryStream *stream, uint64_t searchOffset, size_t searchSize, void *bytes, void *mask, size_t nbytes, uint16_t alignment, uint64_t *foundOffsetOut);
#endif // MEMORY_STREAM_H

View File

@ -1,44 +0,0 @@
#include <stdint.h>
#include "MachO.h"
#define METRIC_TYPE_PATTERN 1
#define METRIC_TYPE_STRING_XREF 2
#define METRIC_TYPE_FUNCTION_XREF 3
typedef struct PFSection {
uint64_t fileoff;
uint64_t vmaddr;
uint64_t size;
uint8_t *cache;
bool ownsCache;
} PFSection;
PFSection *macho_patchfinder_create_section(MachO *macho, const char *filesetEntryId, const char *segName, const char *sectName);
int macho_patchfinder_cache_section(PFSection *section, MachO *fromMacho);
void macho_patchfinder_section_free(PFSection *section);
typedef struct MetricShared {
uint32_t type;
PFSection *section;
} MetricShared;
typedef enum {
BYTE_PATTERN_ALIGN_8_BIT,
BYTE_PATTERN_ALIGN_16_BIT,
BYTE_PATTERN_ALIGN_32_BIT,
BYTE_PATTERN_ALIGN_64_BIT,
} BytePatternAlignment;
typedef struct BytePatternMetric {
MetricShared shared;
void *bytes;
void *mask;
size_t nbytes;
BytePatternAlignment alignment;
} BytePatternMetric;
BytePatternMetric *macho_patchfinder_create_byte_pattern_metric(PFSection *section, void *bytes, void *mask, size_t nbytes, BytePatternAlignment alignment);
void macho_patchfinder_run_metric(MachO *macho, void *metric, void (^matchBlock)(uint64_t vmaddr, bool *stop));

View File

@ -1,16 +0,0 @@
#ifndef SIGN_OSSL_H
#define SIGN_OSSL_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>
#include <openssl/sha.h>
#include <openssl/err.h>
unsigned char *signWithRSA(unsigned char *inputData, size_t inputDataLength, unsigned char *key, size_t key_len, size_t *outputDataLength);
#endif // SIGN_OSSL_H
// 0xA422

View File

@ -1,12 +0,0 @@
#ifndef SIGNING_H
#define SIGNING_H
#include <stdio.h>
#include <stdlib.h>
#include <CommonCrypto/CommonCrypto.h>
#include <Security/SecKey.h>
#include <Security/Security.h>
// int signWithRSA(const char *certificateFile, const char *inputFile, const char *outputFile);
#endif // SIGNING_H

View File

@ -1,6 +0,0 @@
#include <stdint.h>
#include <stdlib.h>
uint64_t align_to_size(int size, int alignment);
int count_digits(int64_t num);
void print_hash(uint8_t *hash, size_t size);

Binary file not shown.

Binary file not shown.

3
RootHelper/jit.h Normal file
View File

@ -0,0 +1,3 @@
#import <Foundation/Foundation.h>
int enableJIT(NSString *bundleID);

45
RootHelper/jit.m Normal file
View File

@ -0,0 +1,45 @@
@import Foundation;
@import Darwin;
@interface RBSProcessPredicate
+ (instancetype)predicateMatchingBundleIdentifier:(NSString *)bundleID;
@end
@interface RBSProcessHandle
+ (instancetype)handleForPredicate:(RBSProcessPredicate *)predicate error:(NSError **)error;
- (int)rbs_pid;
@end
#define PT_DETACH 11
#define PT_ATTACHEXC 14
int ptrace(int request, pid_t pid, caddr_t addr, int data);
int enableJIT(NSString *bundleID) {
#ifdef EMBEDDED_ROOT_HELPER
return -1;
#else
RBSProcessPredicate *predicate = [RBSProcessPredicate predicateMatchingBundleIdentifier:bundleID];
RBSProcessHandle* process = [RBSProcessHandle handleForPredicate:predicate error:nil];
int pid = process.rbs_pid;
if (!pid)
{
return ESRCH;
}
int ret = ptrace(PT_ATTACHEXC, pid, 0, 0);
if (ret == -1)
{
return errno;
}
usleep(100000);
ret = ptrace(PT_DETACH, pid, 0, 0);
if (ret == -1)
{
return errno;
}
return 0;
#endif
}

View File

@ -10,17 +10,21 @@
#import <sys/utsname.h>
#import <mach-o/loader.h>
#import <mach-o/fat.h>
#import "devmode.h"
#import "jit.h"
#ifndef EMBEDDED_ROOT_HELPER
#import "codesign.h"
#import "coretrust_bug.h"
#import <choma/FAT.h>
#import <choma/MachO.h>
#import <choma/FileStream.h>
#import <choma/Host.h>
#import "FAT.h"
#import "MachO.h"
#import "FileStream.h"
#import "Host.h"
#endif
#import <SpringBoardServices/SpringBoardServices.h>
#import <FrontBoardServices/FBSSystemService.h>
#import <Security/Security.h>
#import <libroot.h>
#ifdef EMBEDDED_ROOT_HELPER
#define MAIN_NAME rootHelperMain
@ -240,6 +244,21 @@ void setTSURLSchemeState(BOOL newState, NSString* customAppPath)
}
}
#ifdef TROLLSTORE_LITE
BOOL isLdidInstalled(void)
{
// Since TrollStore Lite depends on ldid, we assume it exists
return YES;
}
NSString *getLdidPath(void)
{
return JBROOT_PATH(@"/usr/bin/ldid");
}
#else
void installLdid(NSString* ldidToCopyPath, NSString* ldidVersion)
{
if(![[NSFileManager defaultManager] fileExistsAtPath:ldidToCopyPath]) return;
@ -267,9 +286,16 @@ BOOL isLdidInstalled(void)
return [[NSFileManager defaultManager] fileExistsAtPath:ldidPath];
}
NSString *getLdidPath(void)
{
return [trollStoreAppPath() stringByAppendingPathComponent:@"ldid"];
}
#endif
int runLdid(NSArray* args, NSString** output, NSString** errorOutput)
{
NSString* ldidPath = [trollStoreAppPath() stringByAppendingPathComponent:@"ldid"];
NSString* ldidPath = getLdidPath();
NSMutableArray* argsM = args.mutableCopy ?: [NSMutableArray new];
[argsM insertObject:ldidPath.lastPathComponent atIndex:0];
@ -297,6 +323,7 @@ int runLdid(NSArray* args, NSString** output, NSString** errorOutput)
pid_t task_pid;
int status = -200;
NSLog(@"About to spawn ldid (%@) with args %@", ldidPath, args);
int spawnError = posix_spawn(&task_pid, [ldidPath fileSystemRepresentation], &action, NULL, (char* const*)argsC, NULL);
for (NSUInteger i = 0; i < argCount; i++)
{
@ -306,7 +333,7 @@ int runLdid(NSArray* args, NSString** output, NSString** errorOutput)
if(spawnError != 0)
{
NSLog(@"posix_spawn error %d\n", spawnError);
NSLog(@"ldid failed to spawn with error %d (%s)\n", spawnError, strerror(spawnError));
return spawnError;
}
@ -478,7 +505,7 @@ int signApp(NSString* appPath)
#else
int signAdhoc(NSString *filePath, NSDictionary *entitlements)
{
//if (@available(iOS 15, *)) {
//if (@available(iOS 16, *)) {
// return codesign_sign_adhoc(filePath.fileSystemRepresentation, true, entitlements);
//}
// If iOS 14 is so great, how come there is no iOS 14 2?????
@ -531,60 +558,169 @@ int signApp(NSString* appPath)
if(!mainExecutablePath) return 176;
if(![[NSFileManager defaultManager] fileExistsAtPath:mainExecutablePath]) return 174;
NSObject *tsBundleIsPreSigned = appInfoDict[@"TSBundlePreSigned"];
if([tsBundleIsPreSigned isKindOfClass:[NSNumber class]])
#ifndef TROLLSTORE_LITE
// Check if the bundle has had a supported exploit pre-applied
EXPLOIT_TYPE declaredPreAppliedExploitType = getDeclaredExploitTypeFromInfoDictionary(appInfoDict);
if(isPlatformVulnerableToExploitType(declaredPreAppliedExploitType))
{
// if TSBundlePreSigned = YES, this bundle has been externally signed so we can skip over signing it now
NSNumber *tsBundleIsPreSignedNum = (NSNumber *)tsBundleIsPreSigned;
if([tsBundleIsPreSignedNum boolValue] == YES)
{
NSLog(@"[signApp] taking fast path for app which declares it has already been signed (%@)", mainExecutablePath);
return 0;
}
NSLog(@"[signApp] taking fast path for app which declares use of a supported pre-applied exploit (%@)", mainExecutablePath);
return 0;
}
else if (declaredPreAppliedExploitType != 0)
{
NSLog(@"[signApp] app (%@) declares use of a pre-applied exploit that is not supported on this device. Proceeding to re-sign...", mainExecutablePath);
}
// XXX: There used to be a check here whether the main binary was already signed with bypass
// In that case it would skip signing aswell, no clue if that's still needed
// With the new bypass adhoc signing should fail and reapplying the bypass should produce an identical binary
/*SecStaticCodeRef codeRef = getStaticCodeRef(mainExecutablePath);
if(codeRef != NULL)
// If the app doesn't declare a pre-applied exploit, and the host supports fake custom root certs,
// we can also skip doing any work here when that app is signed with fake roots
// If not, with the new bypass, a previously modified binary should failed to be adhoc signed, and
// reapplying the bypass should produce an identical binary
if(isPlatformVulnerableToExploitType(EXPLOIT_TYPE_CUSTOM_ROOT_CERTIFICATE_V1))
{
if(codeCertChainContainsFakeAppStoreExtensions(codeRef))
SecStaticCodeRef codeRef = getStaticCodeRef(mainExecutablePath);
if(codeRef != NULL)
{
NSLog(@"[signApp] taking fast path for app signed using a custom root certificate (%@)", mainExecutablePath);
if(codeCertChainContainsFakeAppStoreExtensions(codeRef))
{
NSLog(@"[signApp] taking fast path for app signed using a custom root certificate (%@)", mainExecutablePath);
CFRelease(codeRef);
return 0;
}
CFRelease(codeRef);
return 0;
}
}
else
{
NSLog(@"[signApp] failed to get static code, can't derive entitlements from %@, continuing anways...", mainExecutablePath);
}*/
int (^signFile)(NSString *, NSDictionary *) = ^(NSString *filePath, NSDictionary *entitlements) {
NSLog(@"Checking %@", filePath);
// On iOS 16+, binaries with certain entitlements requires developer mode to be enabled, so we'll check
// while we're fixing entitlements
BOOL requiresDevMode = NO;
#endif
// The majority of IPA decryption utilities only decrypt the main executable of the app bundle
// As a result, we cannot bail on the entire app if an additional binary is encrypted (e.g. app extensions)
// Instead, we will display a warning to the user, and warn them that the app may not work properly
BOOL hasAdditionalEncryptedBinaries = NO;
NSURL* fileURL;
NSDirectoryEnumerator *enumerator;
// Due to how the new CT bug works, in order for data containers to work properly we need to add the
// com.apple.private.security.container-required=<bundle-identifier> entitlement to every binary inside a bundle
// For this we will want to first collect info about all the bundles in the app by seeking for Info.plist files and adding the ent to the main binary
enumerator = [[NSFileManager defaultManager] enumeratorAtURL:[NSURL fileURLWithPath:appPath] includingPropertiesForKeys:nil options:0 errorHandler:nil];
while(fileURL = [enumerator nextObject])
{
NSString *filePath = fileURL.path;
if ([filePath.lastPathComponent isEqualToString:@"Info.plist"]) {
NSDictionary *infoDict = [NSDictionary dictionaryWithContentsOfFile:filePath];
if (!infoDict) continue;
NSString *bundleId = infoDict[@"CFBundleIdentifier"];
NSString *bundleExecutable = infoDict[@"CFBundleExecutable"];
if (!bundleId || !bundleExecutable) continue;
if ([bundleId isEqualToString:@""] || [bundleExecutable isEqualToString:@""]) continue;
NSString *bundleMainExecutablePath = [[filePath stringByDeletingLastPathComponent] stringByAppendingPathComponent:bundleExecutable];
if (![[NSFileManager defaultManager] fileExistsAtPath:bundleMainExecutablePath]) continue;
NSString *packageType = infoDict[@"CFBundlePackageType"];
// We don't care about frameworks (yet)
if ([packageType isEqualToString:@"FMWK"]) continue;
NSMutableDictionary *entitlementsToUse = dumpEntitlementsFromBinaryAtPath(bundleMainExecutablePath).mutableCopy;
if (isSameFile(bundleMainExecutablePath, mainExecutablePath)) {
// In the case where the main executable of the app currently has no entitlements at all
// We want to ensure it gets signed with fallback entitlements
// These mimic the entitlements that Xcodes gives every app it signs
if (!entitlementsToUse) {
entitlementsToUse = @{
@"application-identifier" : @"TROLLTROLL.*",
@"com.apple.developer.team-identifier" : @"TROLLTROLL",
@"get-task-allow" : (__bridge id)kCFBooleanTrue,
@"keychain-access-groups" : @[
@"TROLLTROLL.*",
@"com.apple.token"
],
}.mutableCopy;
}
}
if (!entitlementsToUse) entitlementsToUse = [NSMutableDictionary new];
#ifndef TROLLSTORE_LITE
// Developer mode does not exist before iOS 16
if (@available(iOS 16, *)){
if (!requiresDevMode) {
for (NSString* restrictedEntitlementKey in @[
@"get-task-allow",
@"task_for_pid-allow",
@"com.apple.system-task-ports",
@"com.apple.system-task-ports.control",
@"com.apple.system-task-ports.token.control",
@"com.apple.private.cs.debugger"
]) {
NSObject *restrictedEntitlement = entitlementsToUse[restrictedEntitlementKey];
if (restrictedEntitlement && [restrictedEntitlement isKindOfClass:[NSNumber class]] && [(NSNumber *)restrictedEntitlement boolValue]) {
requiresDevMode = YES;
}
}
}
}
NSObject *containerRequiredO = entitlementsToUse[@"com.apple.private.security.container-required"];
BOOL containerRequired = YES;
if (containerRequiredO && [containerRequiredO isKindOfClass:[NSNumber class]]) {
containerRequired = [(NSNumber *)containerRequiredO boolValue];
}
else if (containerRequiredO && [containerRequiredO isKindOfClass:[NSString class]]) {
// Keep whatever is in it if it's a string...
containerRequired = NO;
}
if (containerRequired) {
NSObject *noContainerO = entitlementsToUse[@"com.apple.private.security.no-container"];
BOOL noContainer = NO;
if (noContainerO && [noContainerO isKindOfClass:[NSNumber class]]) {
noContainer = [(NSNumber *)noContainerO boolValue];
}
NSObject *noSandboxO = entitlementsToUse[@"com.apple.private.security.no-sandbox"];
BOOL noSandbox = NO;
if (noSandboxO && [noSandboxO isKindOfClass:[NSNumber class]]) {
noSandbox = [(NSNumber *)noSandboxO boolValue];
}
if (!noContainer && !noSandbox) {
entitlementsToUse[@"com.apple.private.security.container-required"] = bundleId;
}
}
#else
// Since TrollStore Lite adhoc signs stuff, this means that on PMAP_CS devices, it will run with "PMAP_CS_IN_LOADED_TRUST_CACHE" trust level
// We need to overwrite it so that the app runs as expected (Dopamine 2.1.5+ feature)
entitlementsToUse[@"jb.pmap_cs_custom_trust"] = @"PMAP_CS_APP_STORE";
#endif
int r = signAdhoc(bundleMainExecutablePath, entitlementsToUse);
if (r != 0) return r;
}
}
// All entitlement related issues should be fixed at this point, so all we need to do is sign the entire bundle
// And then apply the CoreTrust bypass to all executables
// XXX: This only works because we're using ldid at the moment and that recursively signs everything
int r = signAdhoc(appPath, nil);
if (r != 0) return r;
#ifndef TROLLSTORE_LITE
// Apply CoreTrust bypass
enumerator = [[NSFileManager defaultManager] enumeratorAtURL:[NSURL fileURLWithPath:appPath] includingPropertiesForKeys:nil options:0 errorHandler:nil];
while(fileURL = [enumerator nextObject])
{
NSString *filePath = fileURL.path;
FAT *fat = fat_init_from_path(filePath.fileSystemRepresentation);
if (fat) {
NSLog(@"%@ is binary", filePath);
fat_free(fat);
// First attempt ad hoc signing
int r = signAdhoc(filePath, entitlements);
if (r != 0) {
// If it doesn't work it's not a big deal, that usually happens when the binary had the bypass applied already (Don't ask me why)
NSLog(@"[%@] Adhoc signing failed with error code %d, continuing anyways...\n", filePath, r);
}
else {
NSLog(@"[%@] Adhoc signing worked!\n", filePath);
}
fat = fat_init_from_path(filePath.fileSystemRepresentation);
if (!fat) return 175; // This should never happen, if it does then everything is fucked
// Now apply CoreTrust bypass to best slice
MachO *machoForExtraction = fat_find_preferred_slice(fat);
if (machoForExtraction) {
// Extract best slice
NSString *tmpPath = [NSTemporaryDirectory() stringByAppendingPathComponent:[NSUUID UUID].UUIDString];
MemoryStream *sliceStream = macho_get_stream(machoForExtraction);
MemoryStream *sliceOutStream = file_stream_init_from_path(tmpPath.fileSystemRepresentation, 0, 0, FILE_STREAM_FLAG_WRITABLE | FILE_STREAM_FLAG_AUTO_EXPAND);
@ -592,19 +728,32 @@ int signApp(NSString* appPath)
memory_stream_copy_data(sliceStream, 0, sliceOutStream, 0, memory_stream_get_size(sliceStream));
memory_stream_free(sliceOutStream);
// Now we have the single slice at tmpPath, which we will sign and apply the bypass, then copy over the original file
NSLog(@"[%@] Adhoc signing...", filePath);
// Now we have the best slice at tmpPath, which we will apply the bypass to, then copy it over the original file
// We loose all other slices doing that but they aren't a loss as they wouldn't run either way
NSLog(@"[%@] Applying CoreTrust bypass...", filePath);
r = apply_coretrust_bypass(tmpPath.fileSystemRepresentation);
int r = apply_coretrust_bypass(tmpPath.fileSystemRepresentation);
if (r == 0) {
NSLog(@"[%@] Applied CoreTrust bypass!", filePath);
}
else if (r == 2) {
NSLog(@"[%@] Cannot apply CoreTrust bypass on an encrypted binary!", filePath);
if (isSameFile(filePath, mainExecutablePath)) {
// If this is the main binary, this error is fatal
NSLog(@"[%@] Main binary is encrypted, cannot continue!", filePath);
fat_free(fat);
return 180;
}
else {
// If not, we can continue but want to show a warning after the app is installed
hasAdditionalEncryptedBinaries = YES;
}
} else if (r == 3) { // Non-fatal - unsupported MachO type
NSLog(@"[%@] Cannot apply CoreTrust bypass on an unsupported MachO type!", filePath);
}
else {
NSLog(@"[%@] CoreTrust bypass failed!!! :(", filePath);
fat_free(fat);
return 175;
return 185;
}
// tempFile is now signed, overwrite original file at filePath with it
@ -614,39 +763,47 @@ int signApp(NSString* appPath)
}
fat_free(fat);
}
return 0;
};
}
NSURL* fileURL;
NSDirectoryEnumerator *enumerator = [[NSFileManager defaultManager] enumeratorAtURL:[NSURL fileURLWithPath:appPath] includingPropertiesForKeys:nil options:0 errorHandler:nil];
if (requiresDevMode) {
// Postpone trying to enable dev mode until after the app is (successfully) installed
return 182;
}
#else // TROLLSTORE_LITE
// Just check for whether anything is fairplay encrypted
enumerator = [[NSFileManager defaultManager] enumeratorAtURL:[NSURL fileURLWithPath:appPath] includingPropertiesForKeys:nil options:0 errorHandler:nil];
while(fileURL = [enumerator nextObject])
{
NSString *filePath = fileURL.path;
if (isSameFile(filePath, mainExecutablePath)) {
// Skip main executable, we will sign it at the end
continue;
FAT *fat = fat_init_from_path(filePath.fileSystemRepresentation);
if (fat) {
NSLog(@"%@ is binary", filePath);
MachO *macho = fat_find_preferred_slice(fat);
if (macho) {
if (macho_is_encrypted(macho)) {
NSLog(@"[%@] Cannot apply CoreTrust bypass on an encrypted binary!", filePath);
if (isSameFile(filePath, mainExecutablePath)) {
// If this is the main binary, this error is fatal
NSLog(@"[%@] Main binary is encrypted, cannot continue!", filePath);
fat_free(fat);
return 180;
}
else {
// If not, we can continue but want to show a warning after the app is installed
hasAdditionalEncryptedBinaries = YES;
}
}
}
fat_free(fat);
}
int r = signFile(filePath, nil);
if (r != 0) return r;
}
#endif
if (hasAdditionalEncryptedBinaries) {
return 184;
}
// In the case where the main executable currently has no entitlements at all
// We want to ensure it gets signed with fallback entitlements
// These mimic the entitlements that Xcodes gives every app it signs
NSDictionary *entitlementsToUse = nil;
NSDictionary* mainExecutableEntitlements = dumpEntitlementsFromBinaryAtPath(mainExecutablePath);
if (!mainExecutableEntitlements) {
entitlementsToUse = @{
@"application-identifier" : @"TROLLTROLL.*",
@"com.apple.developer.team-identifier" : @"TROLLTROLL",
@"get-task-allow" : (__bridge id)kCFBooleanTrue,
@"keychain-access-groups" : @[
@"TROLLTROLL.*",
@"com.apple.token"
],
};
}
return signFile(mainExecutablePath, entitlementsToUse);
return 0;
}
#endif
@ -705,7 +862,10 @@ void applyPatchesToInfoDictionary(NSString* appPath)
// 172: no info.plist found in app
// 173: app is not signed and cannot be signed because ldid not installed or didn't work
// 174:
int installApp(NSString* appPackagePath, BOOL sign, BOOL force, BOOL isTSUpdate, BOOL useInstalldMethod)
// 180: tried to sign app where the main binary is encrypted
// 184: tried to sign app where an additional binary is encrypted
int installApp(NSString* appPackagePath, BOOL sign, BOOL force, BOOL isTSUpdate, BOOL useInstalldMethod, BOOL skipUICache)
{
NSLog(@"[installApp force = %d]", force);
@ -729,10 +889,23 @@ int installApp(NSString* appPackagePath, BOOL sign, BOOL force, BOOL isTSUpdate,
applyPatchesToInfoDictionary(appBundleToInstallPath);
}
BOOL requiresDevMode = NO;
BOOL hasAdditionalEncryptedBinaries = NO;
if(sign)
{
int signRet = signApp(appBundleToInstallPath);
if(signRet != 0) return signRet;
// 182: app requires developer mode; non-fatal
// 184: app has additional encrypted binaries; non-fatal
if(signRet != 0) {
if (signRet == 182) {
requiresDevMode = YES;
} else if (signRet == 184) {
hasAdditionalEncryptedBinaries = YES;
} else {
return signRet;
}
};
}
MCMAppContainer* appContainer = [MCMAppContainer containerWithIdentifier:appId createIfNecessary:NO existed:nil error:nil];
@ -746,12 +919,19 @@ int installApp(NSString* appPackagePath, BOOL sign, BOOL force, BOOL isTSUpdate,
NSURL* appBundleURL = findAppURLInBundleURL(bundleContainerURL);
// Make sure the installed app is a TrollStore app or the container is empty (or the force flag is set)
NSURL* trollStoreMarkURL = [bundleContainerURL URLByAppendingPathComponent:@"_TrollStore"];
NSURL* trollStoreMarkURL = [bundleContainerURL URLByAppendingPathComponent:TS_ACTIVE_MARKER];
if(appBundleURL && ![trollStoreMarkURL checkResourceIsReachableAndReturnError:nil] && !force)
{
NSLog(@"[installApp] already installed and not a TrollStore app... bailing out");
return 171;
}
else if (appBundleURL) {
// When overwriting an app that has been installed with a different TrollStore flavor, make sure to remove the marker of said flavor
NSURL *otherMarkerURL = [bundleContainerURL URLByAppendingPathComponent:TS_INACTIVE_MARKER];
if ([otherMarkerURL checkResourceIsReachableAndReturnError:nil]) {
[[NSFileManager defaultManager] removeItemAtURL:otherMarkerURL error:nil];
}
}
// Terminate app if it's still running
if(!isTSUpdate)
@ -857,7 +1037,7 @@ int installApp(NSString* appPackagePath, BOOL sign, BOOL force, BOOL isTSUpdate,
appContainer = [MCMAppContainer containerWithIdentifier:appId createIfNecessary:NO existed:nil error:nil];
// Mark app as TrollStore app
NSURL* trollStoreMarkURL = [appContainer.url URLByAppendingPathComponent:@"_TrollStore"];
NSURL* trollStoreMarkURL = [appContainer.url URLByAppendingPathComponent:TS_ACTIVE_MARKER];
if(![[NSFileManager defaultManager] fileExistsAtPath:trollStoreMarkURL.path])
{
NSError* creationError;
@ -874,7 +1054,36 @@ int installApp(NSString* appPackagePath, BOOL sign, BOOL force, BOOL isTSUpdate,
// Also permissions need to be fixed
NSURL* updatedAppURL = findAppURLInBundleURL(appContainer.url);
fixPermissionsOfAppBundle(updatedAppURL.path);
registerPath(updatedAppURL.path, 0, YES);
if (!skipUICache) {
if (!registerPath(updatedAppURL.path, 0, !shouldRegisterAsUserByDefault())) {
[[NSFileManager defaultManager] removeItemAtURL:appContainer.url error:nil];
return 181;
}
}
// Handle developer mode after installing and registering the app, to ensure that we
// don't arm developer mode but then fail to install the app
if (requiresDevMode) {
BOOL alreadyEnabled = NO;
if (armDeveloperMode(&alreadyEnabled)) {
if (!alreadyEnabled) {
NSLog(@"[installApp] app requires developer mode and we have successfully armed it");
// non-fatal
return 182;
}
} else {
NSLog(@"[installApp] failed to arm developer mode");
// fatal
return 183;
}
}
if (hasAdditionalEncryptedBinaries) {
NSLog(@"[installApp] app has additional encrypted binaries");
// non-fatal
return 184;
}
return 0;
}
@ -979,7 +1188,9 @@ int uninstallAppById(NSString* appId, BOOL useCustomMethod)
// 166: IPA does not exist or is not accessible
// 167: IPA does not appear to contain an app
int installIpa(NSString* ipaPath, BOOL force, BOOL useInstalldMethod)
// 180: IPA's main binary is encrypted
// 184: IPA contains additional encrypted binaries
int installIpa(NSString* ipaPath, BOOL force, BOOL useInstalldMethod, BOOL skipUICache)
{
cleanRestrictions();
@ -998,7 +1209,7 @@ int installIpa(NSString* ipaPath, BOOL force, BOOL useInstalldMethod)
return 168;
}
int ret = installApp(tmpPackagePath, YES, force, NO, useInstalldMethod);
int ret = installApp(tmpPackagePath, YES, force, NO, useInstalldMethod, skipUICache);
[[NSFileManager defaultManager] removeItemAtPath:tmpPackagePath error:nil];
@ -1051,7 +1262,7 @@ int installTrollStore(NSString* pathToTar)
NSString* tmpTrollStorePath = [tmpPayloadPath stringByAppendingPathComponent:@"TrollStore.app"];
if(![[NSFileManager defaultManager] fileExistsAtPath:tmpTrollStorePath]) return 1;
//if (@available(iOS 15, *)) {} else {
//if (@available(iOS 16, *)) {} else {
// Transfer existing ldid installation if it exists
// But only if the to-be-installed version of TrollStore is 1.5.0 or above
// This is to make it possible to downgrade to older versions still
@ -1101,7 +1312,7 @@ int installTrollStore(NSString* pathToTar)
_installPersistenceHelper(persistenceHelperApp, trollStorePersistenceHelper, trollStoreRootHelper);
}
int ret = installApp(tmpPackagePath, NO, YES, YES, YES);
int ret = installApp(tmpPackagePath, NO, YES, YES, YES, NO);
NSLog(@"[installTrollStore] installApp => %d", ret);
[[NSFileManager defaultManager] removeItemAtPath:tmpPackagePath error:nil];
return ret;
@ -1173,12 +1384,16 @@ BOOL _installPersistenceHelper(LSApplicationProxy* appProxy, NSString* sourcePer
return YES;
}
void installPersistenceHelper(NSString* systemAppId)
void installPersistenceHelper(NSString* systemAppId, NSString *persistenceHelperBinary, NSString *rootHelperBinary)
{
if(findPersistenceHelperApp(PERSISTENCE_HELPER_TYPE_ALL)) return;
NSString* persistenceHelperBinary = [trollStoreAppPath() stringByAppendingPathComponent:@"PersistenceHelper"];
NSString* rootHelperBinary = [trollStoreAppPath() stringByAppendingPathComponent:@"trollstorehelper"];
if (persistenceHelperBinary == nil) {
persistenceHelperBinary = [trollStoreAppPath() stringByAppendingPathComponent:@"PersistenceHelper"];
}
if (rootHelperBinary == nil) {
rootHelperBinary = [trollStoreAppPath() stringByAppendingPathComponent:@"trollstorehelper"];
}
LSApplicationProxy* appProxy = [LSApplicationProxy applicationProxyForIdentifier:systemAppId];
if(!appProxy || ![appProxy.bundleType isEqualToString:@"System"]) return;
@ -1331,8 +1546,9 @@ int MAIN_NAME(int argc, char *argv[], char *envp[])
// use system method when specified, otherwise use custom method
BOOL useInstalldMethod = [args containsObject:@"installd"];
BOOL force = [args containsObject:@"force"];
BOOL skipUICache = [args containsObject:@"skip-uicache"];
NSString* ipaPath = args.lastObject;
ret = installIpa(ipaPath, force, useInstalldMethod);
ret = installIpa(ipaPath, force, useInstalldMethod, skipUICache);
}
else if([cmd isEqualToString:@"uninstall"])
{
@ -1350,6 +1566,105 @@ int MAIN_NAME(int argc, char *argv[], char *envp[])
NSString* appPath = args.lastObject;
ret = uninstallAppByPath(appPath, useCustomMethod);
}
else if([cmd isEqualToString:@"refresh"])
{
refreshAppRegistrations(!shouldRegisterAsUserByDefault());
}
else if([cmd isEqualToString:@"refresh-all"])
{
cleanRestrictions();
//refreshAppRegistrations(NO); // <- fixes app permissions resetting, causes apps to move around on home screen, so I had to disable it
[[NSFileManager defaultManager] removeItemAtPath:@"/var/containers/Shared/SystemGroup/systemgroup.com.apple.lsd.iconscache/Library/Caches/com.apple.IconsCache" error:nil];
[[LSApplicationWorkspace defaultWorkspace] _LSPrivateRebuildApplicationDatabasesForSystemApps:YES internal:YES user:YES];
if (!shouldRegisterAsUserByDefault()) refreshAppRegistrations(YES);
killall(@"backboardd", YES);
}
else if([cmd isEqualToString:@"url-scheme"])
{
if(args.count < 2) return -3;
NSString* modifyArg = args.lastObject;
BOOL newState = [modifyArg isEqualToString:@"enable"];
if(newState == YES || [modifyArg isEqualToString:@"disable"])
{
setTSURLSchemeState(newState, nil);
}
}
else if([cmd isEqualToString:@"reboot"])
{
[[FBSSystemService sharedService] reboot];
// Give the system some time to reboot
sleep(1);
}
else if([cmd isEqualToString:@"enable-jit"])
{
if(args.count < 2) return -3;
NSString* userAppId = args.lastObject;
ret = enableJIT(userAppId);
}
else if([cmd isEqualToString:@"modify-registration"])
{
if(args.count < 3) return -3;
NSString* appPath = args[1];
NSString* newRegistration = args[2];
NSString* trollStoreMark = [[appPath stringByDeletingLastPathComponent] stringByAppendingPathComponent:TS_ACTIVE_MARKER];
if([[NSFileManager defaultManager] fileExistsAtPath:trollStoreMark])
{
registerPath(appPath, NO, [newRegistration isEqualToString:@"System"]);
}
}
else if ([cmd isEqualToString:@"transfer-apps"])
{
bool oneFailed = false;
for (NSString *appBundlePath in trollStoreInactiveInstalledAppBundlePaths()) {
NSLog(@"Transfering %@...", appBundlePath);
// Ldid lacks the entitlement to sign in place
// So copy to /tmp, resign, then replace >.<
NSString *tmpPath = [NSTemporaryDirectory() stringByAppendingPathComponent:[NSUUID UUID].UUIDString];
if (![[NSFileManager defaultManager] createDirectoryAtPath:tmpPath withIntermediateDirectories:YES attributes:nil error:nil]) return -3;
NSString *tmpAppPath = [tmpPath stringByAppendingPathComponent:appBundlePath.lastPathComponent];
if (![[NSFileManager defaultManager] copyItemAtPath:appBundlePath toPath:tmpAppPath error:nil]) {
[[NSFileManager defaultManager] removeItemAtPath:tmpPath error:nil];
oneFailed = true;
continue;
}
NSLog(@"Copied %@ to %@", appBundlePath, tmpAppPath);
int signRet = signApp(tmpAppPath);
NSLog(@"Signing %@ returned %d", tmpAppPath, signRet);
if (signRet == 0 || signRet == 182 || signRet == 184) { // Either 0 or non fatal error codes are fine
[[NSFileManager defaultManager] removeItemAtPath:appBundlePath error:nil];
[[NSFileManager defaultManager] moveItemAtPath:tmpAppPath toPath:appBundlePath error:nil];
[[NSFileManager defaultManager] removeItemAtPath:tmpPath error:nil];
}
else {
[[NSFileManager defaultManager] removeItemAtPath:tmpPath error:nil];
oneFailed = true;
continue;
}
fixPermissionsOfAppBundle(appBundlePath);
NSString *containerPath = [appBundlePath stringByDeletingLastPathComponent];
NSString *activeMarkerPath = [containerPath stringByAppendingPathComponent:TS_ACTIVE_MARKER];
NSString *inactiveMarkerPath = [containerPath stringByAppendingPathComponent:TS_INACTIVE_MARKER];
NSData* emptyData = [NSData data];
[emptyData writeToFile:activeMarkerPath options:0 error:nil];
[[NSFileManager defaultManager] removeItemAtPath:inactiveMarkerPath error:nil];
registerPath(appBundlePath, 0, !shouldRegisterAsUserByDefault());
NSLog(@"Transfered %@!", appBundlePath);
}
if (oneFailed) ret = -1;
}
#ifndef TROLLSTORE_LITE
else if([cmd isEqualToString:@"install-trollstore"])
{
if(args.count < 2) return -3;
@ -1367,31 +1682,25 @@ int MAIN_NAME(int argc, char *argv[], char *envp[])
}
else if([cmd isEqualToString:@"install-ldid"])
{
//if (@available(iOS 15, *)) {} else {
//if (@available(iOS 16, *)) {} else {
if(args.count < 3) return -3;
NSString* ldidPath = args[1];
NSString* ldidVersion = args[2];
installLdid(ldidPath, ldidVersion);
//}
}
else if([cmd isEqualToString:@"refresh"])
{
refreshAppRegistrations(YES);
}
else if([cmd isEqualToString:@"refresh-all"])
{
cleanRestrictions();
//refreshAppRegistrations(NO); // <- fixes app permissions resetting, causes apps to move around on home screen, so I had to disable it
[[NSFileManager defaultManager] removeItemAtPath:@"/var/containers/Shared/SystemGroup/systemgroup.com.apple.lsd.iconscache/Library/Caches/com.apple.IconsCache" error:nil];
[[LSApplicationWorkspace defaultWorkspace] _LSPrivateRebuildApplicationDatabasesForSystemApps:YES internal:YES user:YES];
refreshAppRegistrations(YES);
killall(@"backboardd", YES);
}
else if([cmd isEqualToString:@"install-persistence-helper"])
{
if(args.count < 2) return -3;
NSString* systemAppId = args.lastObject;
installPersistenceHelper(systemAppId);
NSString* systemAppId = args[1];
NSString* persistenceHelperBinary;
NSString* rootHelperBinary;
if (args.count == 4) {
persistenceHelperBinary = args[2];
rootHelperBinary = args[3];
}
installPersistenceHelper(systemAppId, persistenceHelperBinary, rootHelperBinary);
}
else if([cmd isEqualToString:@"uninstall-persistence-helper"])
{
@ -1403,28 +1712,17 @@ int MAIN_NAME(int argc, char *argv[], char *envp[])
NSString* userAppId = args.lastObject;
registerUserPersistenceHelper(userAppId);
}
else if([cmd isEqualToString:@"modify-registration"])
else if([cmd isEqualToString:@"check-dev-mode"])
{
if(args.count < 3) return -3;
NSString* appPath = args[1];
NSString* newRegistration = args[2];
NSString* trollStoreMark = [[appPath stringByDeletingLastPathComponent] stringByAppendingPathComponent:@"_TrollStore"];
if([[NSFileManager defaultManager] fileExistsAtPath:trollStoreMark])
{
registerPath(appPath, NO, [newRegistration isEqualToString:@"System"]);
}
// switch the result, so 0 is enabled, and 1 is disabled/error
ret = !checkDeveloperMode();
}
else if([cmd isEqualToString:@"url-scheme"])
else if([cmd isEqualToString:@"arm-dev-mode"])
{
if(args.count < 2) return -3;
NSString* modifyArg = args.lastObject;
BOOL newState = [modifyArg isEqualToString:@"enable"];
if(newState == YES || [modifyArg isEqualToString:@"disable"])
{
setTSURLSchemeState(newState, nil);
}
// assumes that checkDeveloperMode() has already been called
ret = !armDeveloperMode(NULL);
}
#endif
NSLog(@"trollstorehelper returning %d", ret);
return ret;

View File

@ -1 +1 @@
extern void registerPath(NSString* path, BOOL unregister, BOOL system);
extern bool registerPath(NSString *path, BOOL unregister, BOOL forceSystem);

View File

@ -11,33 +11,27 @@
extern NSSet<NSString*>* immutableAppBundleIdentifiers(void);
extern NSDictionary* dumpEntitlementsFromBinaryAtPath(NSString* binaryPath);
NSDictionary* constructGroupsContainersForEntitlements(NSDictionary* entitlements, BOOL systemGroups)
{
if(!entitlements) return nil;
NSDictionary *constructGroupsContainersForEntitlements(NSDictionary *entitlements, BOOL systemGroups) {
if (!entitlements) return nil;
NSString* entitlementForGroups;
NSString *entitlementForGroups;
Class mcmClass;
if(systemGroups)
{
if (systemGroups) {
entitlementForGroups = @"com.apple.security.system-groups";
mcmClass = [MCMSystemDataContainer class];
}
else
{
else {
entitlementForGroups = @"com.apple.security.application-groups";
mcmClass = [MCMSharedDataContainer class];
}
NSArray* groupIDs = entitlements[entitlementForGroups];
if(groupIDs && [groupIDs isKindOfClass:[NSArray class]])
{
NSMutableDictionary* groupContainers = [NSMutableDictionary new];
NSArray *groupIDs = entitlements[entitlementForGroups];
if (groupIDs && [groupIDs isKindOfClass:[NSArray class]]) {
NSMutableDictionary *groupContainers = [NSMutableDictionary new];
for(NSString* groupID in groupIDs)
{
MCMContainer* container = [mcmClass containerWithIdentifier:groupID createIfNecessary:YES existed:nil error:nil];
if(container.url)
{
for (NSString *groupID in groupIDs) {
MCMContainer *container = [mcmClass containerWithIdentifier:groupID createIfNecessary:YES existed:nil error:nil];
if (container.url) {
groupContainers[groupID] = container.url.path;
}
}
@ -48,100 +42,98 @@ NSDictionary* constructGroupsContainersForEntitlements(NSDictionary* entitlement
return nil;
}
BOOL constructContainerizationForEntitlements(NSDictionary* entitlements)
{
NSNumber* noContainer = entitlements[@"com.apple.private.security.no-container"];
if(noContainer && [noContainer isKindOfClass:[NSNumber class]])
{
if(noContainer.boolValue)
{
BOOL constructContainerizationForEntitlements(NSDictionary *entitlements, NSString **customContainerOut) {
NSNumber *noContainer = entitlements[@"com.apple.private.security.no-container"];
if (noContainer && [noContainer isKindOfClass:[NSNumber class]]) {
if (noContainer.boolValue) {
return NO;
}
}
NSNumber* containerRequired = entitlements[@"com.apple.private.security.container-required"];
if(containerRequired && [containerRequired isKindOfClass:[NSNumber class]])
{
if(!containerRequired.boolValue)
{
NSObject *containerRequired = entitlements[@"com.apple.private.security.container-required"];
if (containerRequired && [containerRequired isKindOfClass:[NSNumber class]]) {
if (!((NSNumber *)containerRequired).boolValue) {
return NO;
}
}
else if (containerRequired && [containerRequired isKindOfClass:[NSString class]]) {
*customContainerOut = (NSString *)containerRequired;
}
return YES;
}
NSString* constructTeamIdentifierForEntitlements(NSDictionary* entitlements)
{
NSString* teamIdentifier = entitlements[@"com.apple.developer.team-identifier"];
if(teamIdentifier && [teamIdentifier isKindOfClass:[NSString class]])
{
NSString *constructTeamIdentifierForEntitlements(NSDictionary *entitlements) {
NSString *teamIdentifier = entitlements[@"com.apple.developer.team-identifier"];
if (teamIdentifier && [teamIdentifier isKindOfClass:[NSString class]]) {
return teamIdentifier;
}
return nil;
}
NSDictionary* constructEnvironmentVariablesForContainerPath(NSString* containerPath)
{
NSString* tmpDir = [containerPath stringByAppendingPathComponent:@"tmp"];
NSDictionary *constructEnvironmentVariablesForContainerPath(NSString *containerPath, BOOL isContainerized) {
NSString *homeDir = isContainerized ? containerPath : @"/var/mobile";
NSString *tmpDir = isContainerized ? [containerPath stringByAppendingPathComponent:@"tmp"] : @"/var/tmp";
return @{
@"CFFIXED_USER_HOME" : containerPath,
@"HOME" : containerPath,
@"CFFIXED_USER_HOME" : homeDir,
@"HOME" : homeDir,
@"TMPDIR" : tmpDir
};
}
void registerPath(NSString* path, BOOL unregister, BOOL system)
{
if(!path) return;
bool registerPath(NSString *path, BOOL unregister, BOOL forceSystem) {
if (!path) return false;
LSApplicationWorkspace* workspace = [LSApplicationWorkspace defaultWorkspace];
if(unregister && ![[NSFileManager defaultManager] fileExistsAtPath:path])
{
LSApplicationProxy* app = [LSApplicationProxy applicationProxyForIdentifier:path];
if(app.bundleURL)
{
LSApplicationWorkspace *workspace = [LSApplicationWorkspace defaultWorkspace];
if (unregister && ![[NSFileManager defaultManager] fileExistsAtPath:path]) {
LSApplicationProxy *app = [LSApplicationProxy applicationProxyForIdentifier:path];
if (app.bundleURL) {
path = [app bundleURL].path;
}
}
path = [path stringByResolvingSymlinksInPath];
path = path.stringByResolvingSymlinksInPath.stringByStandardizingPath;
NSDictionary* appInfoPlist = [NSDictionary dictionaryWithContentsOfFile:[path stringByAppendingPathComponent:@"Info.plist"]];
NSString* appBundleID = [appInfoPlist objectForKey:@"CFBundleIdentifier"];
NSDictionary *appInfoPlist = [NSDictionary dictionaryWithContentsOfFile:[path stringByAppendingPathComponent:@"Info.plist"]];
NSString *appBundleID = [appInfoPlist objectForKey:@"CFBundleIdentifier"];
if([immutableAppBundleIdentifiers() containsObject:appBundleID.lowercaseString]) return;
if([immutableAppBundleIdentifiers() containsObject:appBundleID.lowercaseString]) return false;
if(appBundleID && !unregister)
{
MCMContainer* appContainer = [NSClassFromString(@"MCMAppDataContainer") containerWithIdentifier:appBundleID createIfNecessary:YES existed:nil error:nil];
NSString* containerPath = [appContainer url].path;
if (appBundleID && !unregister) {
NSString *appExecutablePath = [path stringByAppendingPathComponent:appInfoPlist[@"CFBundleExecutable"]];
NSDictionary *entitlements = dumpEntitlementsFromBinaryAtPath(appExecutablePath);
NSMutableDictionary* dictToRegister = [NSMutableDictionary dictionary];
NSString *appDataContainerID = appBundleID;
BOOL appContainerized = constructContainerizationForEntitlements(entitlements, &appDataContainerID);
MCMContainer *appDataContainer = [NSClassFromString(@"MCMAppDataContainer") containerWithIdentifier:appDataContainerID createIfNecessary:YES existed:nil error:nil];
NSString *containerPath = [appDataContainer url].path;
BOOL isRemovableSystemApp = [[NSFileManager defaultManager] fileExistsAtPath:[@"/System/Library/AppSignatures" stringByAppendingPathComponent:appBundleID]];
BOOL registerAsUser = [path hasPrefix:@"/var/containers"] && !isRemovableSystemApp && !forceSystem;
NSMutableDictionary *dictToRegister = [NSMutableDictionary dictionary];
// Add entitlements
NSString* appExecutablePath = [path stringByAppendingPathComponent:appInfoPlist[@"CFBundleExecutable"]];
NSDictionary* entitlements = dumpEntitlementsFromBinaryAtPath(appExecutablePath);
if(entitlements)
{
if (entitlements) {
dictToRegister[@"Entitlements"] = entitlements;
}
// Misc
dictToRegister[@"ApplicationType"] = system ? @"System" : @"User";
dictToRegister[@"ApplicationType"] = registerAsUser ? @"User" : @"System";
dictToRegister[@"CFBundleIdentifier"] = appBundleID;
dictToRegister[@"CodeInfoIdentifier"] = appBundleID;
dictToRegister[@"CompatibilityState"] = @0;
if(containerPath)
{
dictToRegister[@"IsContainerized"] = @(appContainerized);
if (containerPath) {
dictToRegister[@"Container"] = containerPath;
dictToRegister[@"EnvironmentVariables"] = constructEnvironmentVariablesForContainerPath(containerPath);
dictToRegister[@"EnvironmentVariables"] = constructEnvironmentVariablesForContainerPath(containerPath, appContainerized);
}
dictToRegister[@"IsDeletable"] = @(![appBundleID isEqualToString:@"com.opa334.TrollStore"] && kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_15_0);
dictToRegister[@"Path"] = path;
dictToRegister[@"IsContainerized"] = @(constructContainerizationForEntitlements(entitlements));
dictToRegister[@"SignerOrganization"] = @"Apple Inc.";
dictToRegister[@"SignatureVersion"] = @132352;
dictToRegister[@"SignerIdentity"] = @"Apple iPhone OS Application Signing";
@ -152,24 +144,21 @@ void registerPath(NSString* path, BOOL unregister, BOOL system)
dictToRegister[@"FamilyID"] = @0;
dictToRegister[@"IsOnDemandInstallCapable"] = @0;
NSString* teamIdentifier = constructTeamIdentifierForEntitlements(entitlements);
if(teamIdentifier) dictToRegister[@"TeamIdentifier"] = teamIdentifier;
NSString *teamIdentifier = constructTeamIdentifierForEntitlements(entitlements);
if (teamIdentifier) dictToRegister[@"TeamIdentifier"] = teamIdentifier;
// Add group containers
NSDictionary* appGroupContainers = constructGroupsContainersForEntitlements(entitlements, NO);
NSDictionary* systemGroupContainers = constructGroupsContainersForEntitlements(entitlements, YES);
NSMutableDictionary* groupContainers = [NSMutableDictionary new];
NSDictionary *appGroupContainers = constructGroupsContainersForEntitlements(entitlements, NO);
NSDictionary *systemGroupContainers = constructGroupsContainersForEntitlements(entitlements, YES);
NSMutableDictionary *groupContainers = [NSMutableDictionary new];
[groupContainers addEntriesFromDictionary:appGroupContainers];
[groupContainers addEntriesFromDictionary:systemGroupContainers];
if(groupContainers.count)
{
if(appGroupContainers.count)
{
if (groupContainers.count) {
if (appGroupContainers.count) {
dictToRegister[@"HasAppGroupContainers"] = @YES;
}
if(systemGroupContainers.count)
{
if (systemGroupContainers.count) {
dictToRegister[@"HasSystemGroupContainers"] = @YES;
}
dictToRegister[@"GroupContainers"] = groupContainers.copy;
@ -177,29 +166,29 @@ void registerPath(NSString* path, BOOL unregister, BOOL system)
// Add plugins
NSString* pluginsPath = [path stringByAppendingPathComponent:@"PlugIns"];
NSArray* plugins = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:pluginsPath error:nil];
NSString *pluginsPath = [path stringByAppendingPathComponent:@"PlugIns"];
NSArray *plugins = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:pluginsPath error:nil];
NSMutableDictionary* bundlePlugins = [NSMutableDictionary dictionary];
for (NSString* pluginName in plugins)
{
NSString* pluginPath = [pluginsPath stringByAppendingPathComponent:pluginName];
NSMutableDictionary *bundlePlugins = [NSMutableDictionary dictionary];
for (NSString *pluginName in plugins) {
NSString *pluginPath = [pluginsPath stringByAppendingPathComponent:pluginName];
NSDictionary* pluginInfoPlist = [NSDictionary dictionaryWithContentsOfFile:[pluginPath stringByAppendingPathComponent:@"Info.plist"]];
NSString* pluginBundleID = [pluginInfoPlist objectForKey:@"CFBundleIdentifier"];
NSDictionary *pluginInfoPlist = [NSDictionary dictionaryWithContentsOfFile:[pluginPath stringByAppendingPathComponent:@"Info.plist"]];
NSString *pluginBundleID = [pluginInfoPlist objectForKey:@"CFBundleIdentifier"];
if(!pluginBundleID) continue;
MCMContainer* pluginContainer = [NSClassFromString(@"MCMPluginKitPluginDataContainer") containerWithIdentifier:pluginBundleID createIfNecessary:YES existed:nil error:nil];
NSString* pluginContainerPath = [pluginContainer url].path;
if (!pluginBundleID) continue;
NSString *pluginExecutablePath = [pluginPath stringByAppendingPathComponent:pluginInfoPlist[@"CFBundleExecutable"]];
NSDictionary *pluginEntitlements = dumpEntitlementsFromBinaryAtPath(pluginExecutablePath);
NSString *pluginDataContainerID = pluginBundleID;
BOOL pluginContainerized = constructContainerizationForEntitlements(pluginEntitlements, &pluginDataContainerID);
NSMutableDictionary* pluginDict = [NSMutableDictionary dictionary];
MCMContainer *pluginContainer = [NSClassFromString(@"MCMPluginKitPluginDataContainer") containerWithIdentifier:pluginDataContainerID createIfNecessary:YES existed:nil error:nil];
NSString *pluginContainerPath = [pluginContainer url].path;
NSMutableDictionary *pluginDict = [NSMutableDictionary dictionary];
// Add entitlements
NSString* pluginExecutablePath = [pluginPath stringByAppendingPathComponent:pluginInfoPlist[@"CFBundleExecutable"]];
NSDictionary* pluginEntitlements = dumpEntitlementsFromBinaryAtPath(pluginExecutablePath);
if(pluginEntitlements)
{
if (pluginEntitlements) {
pluginDict[@"Entitlements"] = pluginEntitlements;
}
@ -209,36 +198,33 @@ void registerPath(NSString* path, BOOL unregister, BOOL system)
pluginDict[@"CFBundleIdentifier"] = pluginBundleID;
pluginDict[@"CodeInfoIdentifier"] = pluginBundleID;
pluginDict[@"CompatibilityState"] = @0;
if(pluginContainerPath)
{
pluginDict[@"IsContainerized"] = @(pluginContainerized);
if (pluginContainerPath) {
pluginDict[@"Container"] = pluginContainerPath;
pluginDict[@"EnvironmentVariables"] = constructEnvironmentVariablesForContainerPath(pluginContainerPath);
pluginDict[@"EnvironmentVariables"] = constructEnvironmentVariablesForContainerPath(pluginContainerPath, pluginContainerized);
}
pluginDict[@"Path"] = pluginPath;
pluginDict[@"PluginOwnerBundleID"] = appBundleID;
pluginDict[@"IsContainerized"] = @(constructContainerizationForEntitlements(pluginEntitlements));
pluginDict[@"SignerOrganization"] = @"Apple Inc.";
pluginDict[@"SignatureVersion"] = @132352;
pluginDict[@"SignerIdentity"] = @"Apple iPhone OS Application Signing";
NSString* pluginTeamIdentifier = constructTeamIdentifierForEntitlements(pluginEntitlements);
if(pluginTeamIdentifier) pluginDict[@"TeamIdentifier"] = pluginTeamIdentifier;
NSString *pluginTeamIdentifier = constructTeamIdentifierForEntitlements(pluginEntitlements);
if (pluginTeamIdentifier) pluginDict[@"TeamIdentifier"] = pluginTeamIdentifier;
// Add plugin group containers
NSDictionary* pluginAppGroupContainers = constructGroupsContainersForEntitlements(pluginEntitlements, NO);
NSDictionary* pluginSystemGroupContainers = constructGroupsContainersForEntitlements(pluginEntitlements, YES);
NSMutableDictionary* pluginGroupContainers = [NSMutableDictionary new];
NSDictionary *pluginAppGroupContainers = constructGroupsContainersForEntitlements(pluginEntitlements, NO);
NSDictionary *pluginSystemGroupContainers = constructGroupsContainersForEntitlements(pluginEntitlements, YES);
NSMutableDictionary *pluginGroupContainers = [NSMutableDictionary new];
[pluginGroupContainers addEntriesFromDictionary:pluginAppGroupContainers];
[pluginGroupContainers addEntriesFromDictionary:pluginSystemGroupContainers];
if(pluginGroupContainers.count)
{
if(pluginAppGroupContainers.count)
{
if (pluginGroupContainers.count) {
if (pluginAppGroupContainers.count) {
pluginDict[@"HasAppGroupContainers"] = @YES;
}
if(pluginSystemGroupContainers.count)
{
if (pluginSystemGroupContainers.count) {
pluginDict[@"HasSystemGroupContainers"] = @YES;
}
pluginDict[@"GroupContainers"] = pluginGroupContainers.copy;
@ -248,17 +234,21 @@ void registerPath(NSString* path, BOOL unregister, BOOL system)
}
[dictToRegister setObject:bundlePlugins forKey:@"_LSBundlePlugins"];
if(![workspace registerApplicationDictionary:dictToRegister])
{
if (![workspace registerApplicationDictionary:dictToRegister]) {
NSLog(@"Error: Unable to register %@", path);
NSLog(@"Used dictionary: {");
[dictToRegister enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSObject *obj, BOOL *stop) {
NSLog(@"%@ = %@", key, obj);
}];
NSLog(@"}");
return false;
}
} else {
NSURL *url = [NSURL fileURLWithPath:path];
if (![workspace unregisterApplication:url]) {
NSLog(@"Error: Unable to register %@", path);
return false;
}
}
else
{
NSURL* url = [NSURL fileURLWithPath:path];
if(![workspace unregisterApplication:url])
{
NSLog(@"Error: Unable to unregister %@", path);
}
}
return true;
}

View File

@ -1,7 +1,7 @@
#import "unarchive.h"
#include <libarchive/archive.h>
#include <libarchive/archive_entry.h>
#include <archive.h>
#include <archive_entry.h>
static int
copy_data(struct archive *ar, struct archive *aw)

View File

@ -37,8 +37,8 @@ extern NSString *LSInstallTypeKey;
@protocol LSApplicationWorkspaceObserverProtocol <NSObject>
@optional
-(void)applicationsDidInstall:(id)arg1;
-(void)applicationsDidUninstall:(id)arg1;
- (void)applicationsDidInstall:(NSArray <LSApplicationProxy *>*)apps;
- (void)applicationsDidUninstall:(NSArray <LSApplicationProxy *>*)apps;
@end
@interface LSEnumerator : NSEnumerator

View File

@ -3,8 +3,28 @@
#define TrollStoreErrorDomain @"TrollStoreErrorDomain"
#define TS_MARKER @"_TrollStore"
#define TS_LITE_MARKER @"_TrollStoreLite"
#define TS_NAME @"TrollStore"
#define TS_LITE_NAME @"Trollstore Lite"
#ifdef TROLLSTORE_LITE
#define TS_ACTIVE_MARKER TS_LITE_MARKER
#define TS_INACTIVE_MARKER TS_MARKER
#define APP_ID @"com.opa334.TrollStoreLite"
#define APP_NAME TS_LITE_NAME
#define OTHER_APP_NAME TS_NAME
#else
#define TS_ACTIVE_MARKER TS_MARKER
#define TS_INACTIVE_MARKER TS_LITE_MARKER
#define APP_ID @"com.opa334.TrollStore"
#define APP_NAME TS_NAME
#define OTHER_APP_NAME TS_LITE_NAME
#endif
extern void chineseWifiFixup(void);
extern NSString *getExecutablePath(void);
extern BOOL shouldRegisterAsUserByDefault(void);
extern NSString* rootHelperPath(void);
extern NSString* getNSStringFromFile(int fd);
extern void printMultilineNSString(NSString* stringToPrint);
@ -14,10 +34,11 @@ extern void respring(void);
extern void fetchLatestTrollStoreVersion(void (^completionHandler)(NSString* latestVersion));
extern void fetchLatestLdidVersion(void (^completionHandler)(NSString* latestVersion));
extern NSArray* trollStoreInstalledAppBundlePaths();
extern NSArray* trollStoreInstalledAppContainerPaths();
extern NSString* trollStorePath();
extern NSString* trollStoreAppPath();
extern NSArray* trollStoreInstalledAppBundlePaths(void);
extern NSArray* trollStoreInactiveInstalledAppBundlePaths(void);
extern NSArray* trollStoreInstalledAppContainerPaths(void);
extern NSString* trollStorePath(void);
extern NSString* trollStoreAppPath(void);
extern BOOL isRemovableSystemApp(NSString* appId);
@ -36,6 +57,22 @@ typedef enum
PERSISTENCE_HELPER_TYPE_ALL = PERSISTENCE_HELPER_TYPE_USER | PERSISTENCE_HELPER_TYPE_SYSTEM
} PERSISTENCE_HELPER_TYPE;
// EXPLOIT_TYPE is defined as a bitmask as some devices are vulnerable to multiple exploits
//
// An app that has had one of these exploits applied ahead of time can declare which exploit
// was used via the TSPreAppliedExploitType Info.plist key. The corresponding value should be
// (number of bits to left-shift + 1).
typedef enum
{
// CVE-2022-26766
// TSPreAppliedExploitType = 1
EXPLOIT_TYPE_CUSTOM_ROOT_CERTIFICATE_V1 = 1 << 0,
// CVE-2023-41991
// TSPreAppliedExploitType = 2
EXPLOIT_TYPE_CMS_SIGNERINFO_V1 = 1 << 1
} EXPLOIT_TYPE;
extern LSApplicationProxy* findPersistenceHelperApp(PERSISTENCE_HELPER_TYPE allowedTypes);
typedef struct __SecCode const *SecStaticCodeRef;
@ -60,4 +97,7 @@ extern CFStringRef kSecPolicyLeafMarkerOid;
extern SecStaticCodeRef getStaticCodeRef(NSString *binaryPath);
extern NSDictionary* dumpEntitlements(SecStaticCodeRef codeRef);
extern NSDictionary* dumpEntitlementsFromBinaryAtPath(NSString *binaryPath);
extern NSDictionary* dumpEntitlementsFromBinaryData(NSData* binaryData);
extern NSDictionary* dumpEntitlementsFromBinaryData(NSData* binaryData);
extern EXPLOIT_TYPE getDeclaredExploitTypeFromInfoDictionary(NSDictionary *infoDict);
extern bool isPlatformVulnerableToExploitType(EXPLOIT_TYPE exploitType);

View File

@ -4,11 +4,12 @@
#import <spawn.h>
#import <sys/sysctl.h>
#import <mach-o/dyld.h>
#import <libroot.h>
@interface PSAppDataUsagePolicyCache : NSObject
+ (instancetype)sharedInstance;
- (void)setUsagePoliciesForBundle:(NSString*)bundleId cellular:(BOOL)cellular wifi:(BOOL)wifi;
@end
static EXPLOIT_TYPE gPlatformVulnerabilities;
void* _CTServerConnectionCreate(CFAllocatorRef, void *, void *);
int64_t _CTServerConnectionSetCellularUsagePolicy(CFTypeRef* ct, NSString* identifier, NSDictionary* policies);
#define POSIX_SPAWN_PERSONA_FLAGS_OVERRIDE 1
extern int posix_spawnattr_set_persona_np(const posix_spawnattr_t* __restrict, uid_t, uint32_t);
@ -17,14 +18,14 @@ extern int posix_spawnattr_set_persona_gid_np(const posix_spawnattr_t* __restric
void chineseWifiFixup(void)
{
NSBundle *bundle = [NSBundle bundleWithPath:@"/System/Library/PrivateFrameworks/SettingsCellular.framework"];
[bundle load];
PSAppDataUsagePolicyCache* policyCache = [NSClassFromString(@"PSAppDataUsagePolicyCache") sharedInstance];
if([policyCache respondsToSelector:@selector(setUsagePoliciesForBundle:cellular:wifi:)])
{
[policyCache setUsagePoliciesForBundle:NSBundle.mainBundle.bundleIdentifier cellular:true wifi:true];
}
_CTServerConnectionSetCellularUsagePolicy(
_CTServerConnectionCreate(kCFAllocatorDefault, NULL, NULL),
NSBundle.mainBundle.bundleIdentifier,
@{
@"kCTCellularDataUsagePolicy" : @"kCTCellularDataUsagePolicyAlwaysAllow",
@"kCTWiFiDataUsagePolicy" : @"kCTCellularDataUsagePolicyAlwaysAllow"
}
);
}
NSString *getExecutablePath(void)
@ -35,6 +36,25 @@ NSString *getExecutablePath(void)
return [NSString stringWithUTF8String:selfPath];
}
#ifdef TROLLSTORE_LITE
BOOL shouldRegisterAsUserByDefault(void)
{
if ([[NSFileManager defaultManager] fileExistsAtPath:JBROOT_PATH(@"/Library/MobileSubstrate/DynamicLibraries/AppSyncUnified-FrontBoard.dylib")]) {
return YES;
}
return NO;
}
#else
BOOL shouldRegisterAsUserByDefault(void)
{
return NO;
}
#endif
#ifdef EMBEDDED_ROOT_HELPER
NSString* rootHelperPath(void)
{
@ -315,7 +335,7 @@ void fetchLatestLdidVersion(void (^completionHandler)(NSString* latestVersion))
github_fetchLatestVersion(@"opa334/ldid", completionHandler);
}
NSArray* trollStoreInstalledAppContainerPaths()
NSArray* trollStoreInstalledAppContainerPathsInternal(NSString *marker)
{
NSMutableArray* appContainerPaths = [NSMutableArray new];
@ -336,11 +356,12 @@ NSArray* trollStoreInstalledAppContainerPaths()
BOOL exists = [[NSFileManager defaultManager] fileExistsAtPath:containerPath isDirectory:&isDirectory];
if(exists && isDirectory)
{
NSString* trollStoreMark = [containerPath stringByAppendingPathComponent:@"_TrollStore"];
NSString* trollStoreMark = [containerPath stringByAppendingPathComponent:marker];
if([[NSFileManager defaultManager] fileExistsAtPath:trollStoreMark])
{
NSString* trollStoreApp = [containerPath stringByAppendingPathComponent:@"TrollStore.app"];
if(![[NSFileManager defaultManager] fileExistsAtPath:trollStoreApp])
NSString* trollStoreLiteApp = [containerPath stringByAppendingPathComponent:@"TrollStoreLite.app"];
if(![[NSFileManager defaultManager] fileExistsAtPath:trollStoreApp] && ![[NSFileManager defaultManager] fileExistsAtPath:trollStoreLiteApp])
{
[appContainerPaths addObject:containerPath];
}
@ -351,10 +372,15 @@ NSArray* trollStoreInstalledAppContainerPaths()
return appContainerPaths.copy;
}
NSArray* trollStoreInstalledAppBundlePaths()
NSArray *trollStoreInstalledAppContainerPaths(void)
{
return trollStoreInstalledAppContainerPathsInternal(TS_ACTIVE_MARKER);
}
NSArray* trollStoreInstalledAppBundlePathsInternal(NSString *marker)
{
NSMutableArray* appPaths = [NSMutableArray new];
for(NSString* containerPath in trollStoreInstalledAppContainerPaths())
for(NSString* containerPath in trollStoreInstalledAppContainerPathsInternal(marker))
{
NSArray* items = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:containerPath error:nil];
if(!items) return nil;
@ -370,10 +396,20 @@ NSArray* trollStoreInstalledAppBundlePaths()
return appPaths.copy;
}
NSArray *trollStoreInstalledAppBundlePaths(void)
{
return trollStoreInstalledAppBundlePathsInternal(TS_ACTIVE_MARKER);
}
NSArray *trollStoreInactiveInstalledAppBundlePaths(void)
{
return trollStoreInstalledAppBundlePathsInternal(TS_INACTIVE_MARKER);
}
NSString* trollStorePath()
{
NSError* mcmError;
MCMAppContainer* appContainer = [MCMAppContainer containerWithIdentifier:@"com.opa334.TrollStore" createIfNecessary:NO existed:NULL error:&mcmError];
MCMAppContainer* appContainer = [MCMAppContainer containerWithIdentifier:APP_ID createIfNecessary:NO existed:NULL error:&mcmError];
if(!appContainer) return nil;
return appContainer.url.path;
}
@ -521,4 +557,106 @@ NSDictionary* dumpEntitlementsFromBinaryData(NSData* binaryData)
[[NSFileManager defaultManager] removeItemAtURL:tmpURL error:nil];
}
return entitlements;
}
}
EXPLOIT_TYPE getDeclaredExploitTypeFromInfoDictionary(NSDictionary *infoDict)
{
NSObject *tsPreAppliedExploitType = infoDict[@"TSPreAppliedExploitType"];
if([tsPreAppliedExploitType isKindOfClass:[NSNumber class]])
{
NSNumber *tsPreAppliedExploitTypeNum = (NSNumber *)tsPreAppliedExploitType;
int exploitTypeInt = [tsPreAppliedExploitTypeNum intValue];
if(exploitTypeInt > 0)
{
// Convert versions 1, 2, etc... for use with bitmasking
return (1 << (exploitTypeInt - 1));
}
else
{
NSLog(@"[getDeclaredExploitTypeFromInfoDictionary] rejecting TSPreAppliedExploitType Info.plist value (%i) which is out of range", exploitTypeInt);
}
}
// Legacy Info.plist flag - now deprecated, but we treat it as a custom root cert if present
NSObject *tsBundleIsPreSigned = infoDict[@"TSBundlePreSigned"];
if([tsBundleIsPreSigned isKindOfClass:[NSNumber class]])
{
NSNumber *tsBundleIsPreSignedNum = (NSNumber *)tsBundleIsPreSigned;
if([tsBundleIsPreSignedNum boolValue] == YES)
{
return EXPLOIT_TYPE_CUSTOM_ROOT_CERTIFICATE_V1;
}
}
// No declarations
return 0;
}
void determinePlatformVulnerableExploitTypes(void *context) {
size_t size = 0;
// Get the current build number
int mib[2] = {CTL_KERN, KERN_OSVERSION};
// Get size of buffer
sysctl(mib, 2, NULL, &size, NULL, 0);
// Get the actual value
char *os_build = malloc(size);
if(!os_build)
{
// malloc failed
perror("malloc buffer for KERN_OSVERSION");
return;
}
if (sysctl(mib, 2, os_build, &size, NULL, 0) != 0)
{
// sysctl failed
perror("sysctl KERN_OSVERSION");
free(os_build);
return;
}
if(strncmp(os_build, "18A5319i", 8) < 0) {
// Below iOS 14.0 beta 2
gPlatformVulnerabilities = 0;
}
else if(strncmp(os_build, "21A326", 6) >= 0 && strncmp(os_build, "21A331", 6) <= 0)
{
// iOS 17.0 final
gPlatformVulnerabilities = EXPLOIT_TYPE_CMS_SIGNERINFO_V1;
}
else if(strncmp(os_build, "21A5248v", 8) >= 0 && strncmp(os_build, "21A5326a", 8) <= 0)
{
// iOS 17.0 beta 1 - 8
gPlatformVulnerabilities = EXPLOIT_TYPE_CMS_SIGNERINFO_V1;
}
else if(strncmp(os_build, "19G5027e", 8) >= 0 && strncmp(os_build, "19G5063a", 8) <= 0)
{
// iOS 15.6 beta 1 - 5
gPlatformVulnerabilities = (EXPLOIT_TYPE_CUSTOM_ROOT_CERTIFICATE_V1 | EXPLOIT_TYPE_CMS_SIGNERINFO_V1);
}
else if(strncmp(os_build, "19F5070b", 8) <= 0)
{
// iOS 14.0 beta 2 - 15.5 beta 4
gPlatformVulnerabilities = (EXPLOIT_TYPE_CUSTOM_ROOT_CERTIFICATE_V1 | EXPLOIT_TYPE_CMS_SIGNERINFO_V1);
}
else if(strncmp(os_build, "20H18", 5) <= 0)
{
// iOS 14.0 - 16.6.1, 16.7 RC (if CUSTOM_ROOT_CERTIFICATE_V1 not supported)
gPlatformVulnerabilities = EXPLOIT_TYPE_CMS_SIGNERINFO_V1;
}
free(os_build);
}
bool isPlatformVulnerableToExploitType(EXPLOIT_TYPE exploitType) {
// Find out what we are vulnerable to
static dispatch_once_t once;
dispatch_once_f(&once, NULL, determinePlatformVulnerableExploitTypes);
return (exploitType & gPlatformVulnerabilities) != 0;
}

View File

@ -1,7 +1,7 @@
export EMBEDDED_ROOT_HELPER ?= 0
export LEGACY_CT_BUG ?= 0
TARGET := iphone:clang:16.4:14.0
TARGET := iphone:clang:16.5:14.0
INSTALL_TARGET_PROCESSES = TrollStorePersistenceHelper
ifdef CUSTOM_ARCHS
@ -19,9 +19,9 @@ include $(THEOS)/makefiles/common.mk
APPLICATION_NAME = TrollStorePersistenceHelper
TrollStorePersistenceHelper_FILES = $(wildcard *.m) $(wildcard ../Shared/*.m)
TrollStorePersistenceHelper_FRAMEWORKS = UIKit CoreGraphics CoreServices
TrollStorePersistenceHelper_FRAMEWORKS = UIKit CoreGraphics CoreServices CoreTelephony
TrollStorePersistenceHelper_PRIVATE_FRAMEWORKS = Preferences MobileContainerManager
TrollStorePersistenceHelper_CFLAGS = -fobjc-arc -I../Shared
TrollStorePersistenceHelper_CFLAGS = -fobjc-arc -I../Shared -I$(shell brew --prefix)/opt/libarchive/include
ifeq ($(LEGACY_CT_BUG),1)
TrollStorePersistenceHelper_CODESIGN_FLAGS = -Sentitlements.plist -K../legacy.p12
@ -34,7 +34,7 @@ ifeq ($(EMBEDDED_ROOT_HELPER),1)
TrollStorePersistenceHelper_CFLAGS += -DEMBEDDED_ROOT_HELPER=1
TrollStorePersistenceHelper_FILES += $(wildcard ../RootHelper/*.m)
TrollStorePersistenceHelper_LIBRARIES += archive
TrollStorePersistenceHelper_PRIVATE_FRAMEWORKS += SpringBoardServices BackBoardServices
TrollStorePersistenceHelper_PRIVATE_FRAMEWORKS += SpringBoardServices BackBoardServices FrontBoardServices
endif
include $(THEOS_MAKE_PATH)/application.mk

View File

@ -52,7 +52,7 @@
<string>iPhoneOS</string>
</array>
<key>CFBundleVersion</key>
<string>2.0.3</string>
<string>2.1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UIDeviceFamily</key>
@ -62,83 +62,10 @@
</array>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UILaunchImageFile</key>
<string>LaunchImage</string>
<key>UILaunchImages</key>
<array>
<dict>
<key>UILaunchImageMinimumOSVersion</key>
<string>7.0</string>
<key>UILaunchImageName</key>
<string>LaunchImage</string>
<key>UILaunchImageOrientation</key>
<string>Portrait</string>
<key>UILaunchImageSize</key>
<string>{320, 480}</string>
</dict>
<dict>
<key>UILaunchImageMinimumOSVersion</key>
<string>7.0</string>
<key>UILaunchImageName</key>
<string>LaunchImage-700-568h</string>
<key>UILaunchImageOrientation</key>
<string>Portrait</string>
<key>UILaunchImageSize</key>
<string>{320, 568}</string>
</dict>
<dict>
<key>UILaunchImageMinimumOSVersion</key>
<string>7.0</string>
<key>UILaunchImageName</key>
<string>LaunchImage-Portrait</string>
<key>UILaunchImageOrientation</key>
<string>Portrait</string>
<key>UILaunchImageSize</key>
<string>{768, 1024}</string>
</dict>
<dict>
<key>UILaunchImageMinimumOSVersion</key>
<string>7.0</string>
<key>UILaunchImageName</key>
<string>LaunchImage-Landscape</string>
<key>UILaunchImageOrientation</key>
<string>Landscape</string>
<key>UILaunchImageSize</key>
<string>{768, 1024}</string>
</dict>
<dict>
<key>UILaunchImageMinimumOSVersion</key>
<string>8.0</string>
<key>UILaunchImageName</key>
<string>LaunchImage-800-667h</string>
<key>UILaunchImageOrientation</key>
<string>Portrait</string>
<key>UILaunchImageSize</key>
<string>{375, 667}</string>
</dict>
<dict>
<key>UILaunchImageMinimumOSVersion</key>
<string>8.0</string>
<key>UILaunchImageName</key>
<string>LaunchImage-800-Portrait-736h</string>
<key>UILaunchImageOrientation</key>
<string>Portrait</string>
<key>UILaunchImageSize</key>
<string>{414, 736}</string>
</dict>
<dict>
<key>UILaunchImageMinimumOSVersion</key>
<string>8.0</string>
<key>UILaunchImageName</key>
<string>LaunchImage-800-Landscape-736h</string>
<key>UILaunchImageOrientation</key>
<string>Landscape</string>
<key>UILaunchImageSize</key>
<string>{414, 736}</string>
</dict>
<string>arm64</string>
</array>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>

View File

@ -38,9 +38,9 @@
_specifiers = [NSMutableArray new];
#ifdef LEGACY_CT_BUG
NSString* credits = @"Powered by Fugu15 CoreTrust & installd bugs, thanks to @LinusHenze\n\n© 2022-2023 Lars Fröder (opa334)";
NSString* credits = @"Powered by Fugu15 CoreTrust & installd bugs, thanks to @LinusHenze\n\n© 2022-2024 Lars Fröder (opa334)";
#else
NSString* credits = @"Powered by CVE-2023-41991, originally discovered by Google TAG, rediscovered via patchdiffing by @alfiecg_dev\n\n© 2022-2023 Lars Fröder (opa334)";
NSString* credits = @"Powered by CVE-2023-41991, originally discovered by Google TAG, rediscovered via patchdiffing by @alfiecg_dev\n\n© 2022-2024 Lars Fröder (opa334)";
#endif
PSSpecifier* infoGroupSpecifier = [PSSpecifier emptyGroupSpecifier];

View File

@ -1,6 +1,6 @@
Package: com.opa334.trollstorehelper
Name: TrollStore Helper
Version: 2.0.3
Version: 2.1
Architecture: iphoneos-arm
Description: Helper utility to install and manage TrollStore!
Maintainer: opa334

View File

@ -6,10 +6,7 @@
<string>com.opa334.trollstorepersistencehelper</string>
<key>com.apple.CommCenter.fine-grained</key>
<array>
<string>cellular-plan</string>
<string>data-usage</string>
<string>data-allowed-write</string>
<string>preferences-write</string>
</array>
<key>com.apple.private.persona-mgmt</key>
<true/>

View File

@ -1,4 +1,4 @@
TARGET := iphone:clang:16.4:14.0
TARGET := iphone:clang:16.5:14.0
INSTALL_TARGET_PROCESSES = TrollStore
ARCHS = arm64
@ -9,10 +9,10 @@ include $(THEOS)/makefiles/common.mk
APPLICATION_NAME = TrollStore
TrollStore_FILES = $(wildcard *.m) $(wildcard ../Shared/*.m)
TrollStore_FRAMEWORKS = UIKit CoreGraphics CoreServices
TrollStore_FRAMEWORKS = UIKit CoreGraphics CoreServices CoreTelephony
TrollStore_PRIVATE_FRAMEWORKS = Preferences MobileIcons MobileContainerManager
TrollStore_LIBRARIES = archive
TrollStore_CFLAGS = -fobjc-arc -I../Shared
TrollStore_CFLAGS = -fobjc-arc -I../Shared -I$(shell brew --prefix)/opt/libarchive/include
TrollStore_CODESIGN_FLAGS = --entitlements entitlements.plist
include $(THEOS_MAKE_PATH)/application.mk

View File

@ -50,7 +50,7 @@
<string>iPhoneOS</string>
</array>
<key>CFBundleVersion</key>
<string>2.0.3</string>
<string>2.1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UIDeviceFamily</key>
@ -154,7 +154,7 @@
</dict>
</array>
<key>UTExportedTypeDeclarations</key>
<array>
<array>
<dict>
<key>UTTypeIdentifier</key>
<string>com.opa334.trollstore.tipa</string>

View File

@ -6,8 +6,8 @@
//
#import <Foundation/Foundation.h>
#import <libarchive/archive.h>
#import <libarchive/archive_entry.h>
#import <archive.h>
#import <archive_entry.h>
@import UIKit;
@interface TSAppInfo : NSObject
@ -50,6 +50,7 @@
- (NSAttributedString*)detailedInfoTitle;
- (NSAttributedString*)detailedInfoDescription;
//- (UIImage*)image;
- (BOOL)isDebuggable;
- (void)log;
@end

View File

@ -849,17 +849,38 @@ extern UIImage* imageWithSize(UIImage* image, CGSize size);
__block NSMutableArray* accessibleContainers = [NSMutableArray new]; //array by design, should be ordered
if(!unrestrictedContainerAccess)
{
[self enumerateAllInfoDictionaries:^(NSString *key, NSObject *value, BOOL *stop) {
if([key isEqualToString:@"CFBundleIdentifier"])
__block NSString *dataContainer = nil;
// If com.apple.private.security.container-required Entitlement is a string, prefer it to CFBundleIdentifier
[self enumerateAllEntitlements:^(NSString *key, NSObject *value, BOOL *stop) {
if([key isEqualToString:@"com.apple.private.security.container-required"])
{
NSString* valueStr = (NSString*)value;
if([valueStr isKindOfClass:NSString.class])
NSString* valueString = (NSString*)value;
if(valueString && [valueString isKindOfClass:NSString.class])
{
[accessibleContainers addObject:valueStr];
dataContainer = valueString;
}
}
}];
// Else take CFBundleIdentifier
if (!dataContainer) {
[self enumerateAllInfoDictionaries:^(NSString *key, NSObject *value, BOOL *stop) {
if([key isEqualToString:@"CFBundleIdentifier"])
{
NSString* valueStr = (NSString*)value;
if([valueStr isKindOfClass:NSString.class])
{
dataContainer = valueStr;
}
}
}];
}
if (dataContainer) {
[accessibleContainers addObject:dataContainer];
}
[self enumerateAllEntitlements:^(NSString *key, NSObject *value, BOOL *stop)
{
if([key isEqualToString:@"com.apple.developer.icloud-container-identifiers"] || [key isEqualToString:@"com.apple.security.application-groups"] || [key isEqualToString:@"com.apple.security.system-groups"])
@ -1065,7 +1086,7 @@ extern UIImage* imageWithSize(UIImage* image, CGSize size);
}
else if(isPlatformApplication && isUnsandboxed)
{
[description appendAttributedString:[[NSAttributedString alloc] initWithString:@"\nThe app can spawn arbitary binaries as the mobile user." attributes:bodyWarningAttributes]];
[description appendAttributedString:[[NSAttributedString alloc] initWithString:@"\nThe app can spawn arbitrary binaries as the mobile user." attributes:bodyWarningAttributes]];
}
else
{
@ -1144,5 +1165,23 @@ extern UIImage* imageWithSize(UIImage* image, CGSize size);
}];
}
- (BOOL)isDebuggable
{
[self loadEntitlements];
__block BOOL debuggable = NO;
[self enumerateAllEntitlements:^(NSString *key, NSObject *value, BOOL *stop)
{
if([key isEqualToString:@"get-task-allow"])
{
NSNumber* valueNum = (NSNumber*)value;
if(valueNum && [valueNum isKindOfClass:NSNumber.class])
{
debuggable = valueNum.boolValue;
*stop = YES;
}
}
}];
return debuggable;
}
@end

View File

@ -104,7 +104,8 @@ UIImage* imageWithSize(UIImage* image, CGSize size)
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reloadTable) name:@"ApplicationsChanged" object:nil];
}
- (void)viewDidLoad {
- (void)viewDidLoad
{
[super viewDidLoad];
self.tableView.allowsMultipleSelectionDuringEditing = NO;
@ -187,7 +188,7 @@ UIImage* imageWithSize(UIImage* image, CGSize size)
[TSInstallationController presentInstallationAlertIfEnabledForFile:pathToIPA isRemoteInstall:NO completion:nil];
}
- (void)openAppPressedForRowAtIndexPath:(NSIndexPath*)indexPath
- (void)openAppPressedForRowAtIndexPath:(NSIndexPath*)indexPath enableJIT:(BOOL)enableJIT
{
TSApplicationsManager* appsManager = [TSApplicationsManager sharedInstance];
@ -211,6 +212,17 @@ UIImage* imageWithSize(UIImage* image, CGSize size)
[didFailController addAction:cancelAction];
[TSPresentationDelegate presentViewController:didFailController animated:YES completion:nil];
}
else if (enableJIT)
{
int ret = [appsManager enableJITForBundleID:appId];
if (ret != 0)
{
UIAlertController* errorAlert = [UIAlertController alertControllerWithTitle:@"Error" message:[NSString stringWithFormat:@"Error enabling JIT: trollstorehelper returned %d", ret] preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* closeAction = [UIAlertAction actionWithTitle:@"Close" style:UIAlertActionStyleDefault handler:nil];
[errorAlert addAction:closeAction];
[TSPresentationDelegate presentViewController:errorAlert animated:YES completion:nil];
}
}
}
- (void)showDetailsPressedForRowAtIndexPath:(NSIndexPath*)indexPath
@ -329,11 +341,13 @@ UIImage* imageWithSize(UIImage* image, CGSize size)
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return _cachedAppInfos.count;
}
@ -342,7 +356,8 @@ UIImage* imageWithSize(UIImage* image, CGSize size)
[self reloadTable];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ApplicationCell"];
if(!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"ApplicationCell"];
@ -375,14 +390,15 @@ UIImage* imageWithSize(UIImage* image, CGSize size)
cell.imageView.image = _placeholderIcon;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^
{
//usleep(1000 * 5000); // (test delay for debugging)
UIImage* iconImage = imageWithSize([UIImage _applicationIconImageForBundleIdentifier:appId format:iconFormatToUse() scale:[UIScreen mainScreen].scale], _placeholderIcon.size);
_cachedIcons[appId] = iconImage;
dispatch_async(dispatch_get_main_queue(), ^{
if([tableView.indexPathsForVisibleRows containsObject:indexPath])
NSIndexPath *curIndexPath = [NSIndexPath indexPathForRow:[_cachedAppInfos indexOfObject:appInfo] inSection:0];
UITableViewCell *curCell = [tableView cellForRowAtIndexPath:curIndexPath];
if(curCell)
{
cell.imageView.image = iconImage;
[cell setNeedsLayout];
curCell.imageView.image = iconImage;
[curCell setNeedsLayout];
}
});
});
@ -400,7 +416,8 @@ UIImage* imageWithSize(UIImage* image, CGSize size)
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 80.0f;
}
@ -423,11 +440,21 @@ UIImage* imageWithSize(UIImage* image, CGSize size)
UIAlertAction* openAction = [UIAlertAction actionWithTitle:@"Open" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action)
{
[self openAppPressedForRowAtIndexPath:indexPath];
[self openAppPressedForRowAtIndexPath:indexPath enableJIT:NO];
[self deselectRow];
}];
[appSelectAlert addAction:openAction];
if ([appInfo isDebuggable])
{
UIAlertAction* openWithJITAction = [UIAlertAction actionWithTitle:@"Open with JIT" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action)
{
[self openAppPressedForRowAtIndexPath:indexPath enableJIT:YES];
[self deselectRow];
}];
[appSelectAlert addAction:openWithJITAction];
}
UIAlertAction* showDetailsAction = [UIAlertAction actionWithTitle:@"Show Details" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action)
{
[self showDetailsPressedForRowAtIndexPath:indexPath];
@ -475,14 +502,26 @@ UIImage* imageWithSize(UIImage* image, CGSize size)
[TSPresentationDelegate presentViewController:appSelectAlert animated:YES completion:nil];
}
- (void)applicationsDidInstall:(id)arg1
- (void)purgeCachedIconsForApps:(NSArray <LSApplicationProxy *>*)apps
{
for (LSApplicationProxy *appProxy in apps) {
NSString *appId = appProxy.bundleIdentifier;
if (_cachedIcons[appId]) {
[_cachedIcons removeObjectForKey:appId];
}
}
}
- (void)applicationsDidInstall:(NSArray <LSApplicationProxy *>*)apps
{
[self purgeCachedIconsForApps:apps];
[self reloadTable];
}
- (void)applicationsDidUninstall:(id)arg1
- (void)applicationsDidUninstall:(NSArray <LSApplicationProxy *>*)apps
{
[self purgeCachedIconsForApps:apps];
[self reloadTable];
}
@end
@end

View File

@ -16,6 +16,7 @@
- (int)uninstallApp:(NSString*)appId;
- (int)uninstallAppByPath:(NSString*)path;
- (BOOL)openApplicationWithBundleID:(NSString *)appID;
- (int)enableJITForBundleID:(NSString *)appID;
- (int)changeAppRegistration:(NSString*)appPath toState:(NSString*)newState;
@end

View File

@ -42,7 +42,7 @@ extern NSUserDefaults* trollStoreUserDefaults();
errorDescription = @"Failed to create container for app bundle.";
break;
case 171:
errorDescription = @"A non-TrollStore app with the same identifier is already installed. If you are absolutely sure it is not, you can force install it.";
errorDescription = @"A non "APP_NAME@" or a "OTHER_APP_NAME@" app with the same identifier is already installed. If you are absolutely sure it is not, you can force install it.";
break;
case 172:
errorDescription = @"The app does not contain an Info.plist file.";
@ -54,7 +54,7 @@ extern NSUserDefaults* trollStoreUserDefaults();
errorDescription = @"The app's main executable does not exist.";
break;
case 175: {
//if (@available(iOS 15, *)) {
//if (@available(iOS 16, *)) {
// errorDescription = @"Failed to sign the app.";
//}
//else {
@ -74,6 +74,23 @@ extern NSUserDefaults* trollStoreUserDefaults();
case 179:
errorDescription = @"The app you tried to install has the same identifier as a system app already installed on the device. The installation has been prevented to protect you from possible bootloops or other issues.";
break;
case 180:
errorDescription = @"The app you tried to install has an encrypted main binary, which cannot have the CoreTrust bypass applied to it. Please ensure you install decrypted apps.";
break;
case 181:
errorDescription = @"Failed to add app to icon cache.";
break;
case 182:
errorDescription = @"The app was installed successfully, but requires developer mode to be enabled to run. After rebooting, select \"Turn On\" to enable developer mode.";
break;
case 183:
errorDescription = @"Failed to enable developer mode.";
break;
case 184:
errorDescription = @"The app was installed successfully, but has additional binaries that are encrypted (e.g. extensions, plugins). The app itself should work, but you may experience broken functionality as a result.";
break;
case 185:
errorDescription = @"Failed to sign the app. The CoreTrust bypass returned a non zero status code.";
}
NSError* error = [NSError errorWithDomain:TrollStoreErrorDomain code:code userInfo:@{NSLocalizedDescriptionKey : errorDescription}];
@ -165,6 +182,11 @@ extern NSUserDefaults* trollStoreUserDefaults();
return [[LSApplicationWorkspace defaultWorkspace] openApplicationWithBundleID:appId];
}
- (int)enableJITForBundleID:(NSString *)appId
{
return spawnRoot(rootHelperPath(), @[@"enable-jit", appId], nil, nil);
}
- (int)changeAppRegistration:(NSString*)appPath toState:(NSString*)newState
{
if(!appPath || !newState) return -200;

View File

@ -32,42 +32,68 @@ extern NSUserDefaults* trollStoreUserDefaults(void);
{
[TSPresentationDelegate stopActivityWithCompletion:^
{
if(ret != 0)
{
if (ret == 0) {
// success
if(completionBlock) completionBlock(YES, nil);
} else if (ret == 171) {
// recoverable error
UIAlertController* errorAlert = [UIAlertController alertControllerWithTitle:[NSString stringWithFormat:@"Install Error %d", ret] message:[error localizedDescription] preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* closeAction = [UIAlertAction actionWithTitle:@"Close" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action)
{
if(ret == 171)
{
if(completionBlock) completionBlock(NO, error);
}
if(completionBlock) completionBlock(NO, error);
}];
[errorAlert addAction:closeAction];
if(ret == 171)
UIAlertAction* forceInstallAction = [UIAlertAction actionWithTitle:@"Force Installation" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action)
{
UIAlertAction* forceInstallAction = [UIAlertAction actionWithTitle:@"Force Installation" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action)
{
[self handleAppInstallFromFile:pathToIPA forceInstall:YES completion:completionBlock];
}];
[errorAlert addAction:forceInstallAction];
}
else
{
UIAlertAction* copyLogAction = [UIAlertAction actionWithTitle:@"Copy Debug Log" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action)
{
UIPasteboard* pasteboard = [UIPasteboard generalPasteboard];
pasteboard.string = log;
}];
[errorAlert addAction:copyLogAction];
}
[self handleAppInstallFromFile:pathToIPA forceInstall:YES completion:completionBlock];
}];
[errorAlert addAction:forceInstallAction];
[TSPresentationDelegate presentViewController:errorAlert animated:YES completion:nil];
}
} else if (ret == 182) {
// non-fatal informative message
UIAlertController* rebootNotification = [UIAlertController alertControllerWithTitle:@"Reboot Required" message:[error localizedDescription] preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* closeAction = [UIAlertAction actionWithTitle:@"Close" style:UIAlertActionStyleCancel handler:^(UIAlertAction* action)
{
if(completionBlock) completionBlock(YES, nil);
}];
[rebootNotification addAction:closeAction];
if(ret != 171)
{
if(completionBlock) completionBlock((BOOL)error, error);
UIAlertAction* rebootAction = [UIAlertAction actionWithTitle:@"Reboot Now" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action)
{
if(completionBlock) completionBlock(YES, nil);
spawnRoot(rootHelperPath(), @[@"reboot"], nil, nil);
}];
[rebootNotification addAction:rebootAction];
[TSPresentationDelegate presentViewController:rebootNotification animated:YES completion:nil];
} else if (ret == 184) {
// warning
UIAlertController* warningAlert = [UIAlertController alertControllerWithTitle:@"Warning" message:[error localizedDescription] preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* closeAction = [UIAlertAction actionWithTitle:@"Close" style:UIAlertActionStyleCancel handler:^(UIAlertAction* action)
{
if(completionBlock) completionBlock(YES, nil);
}];
[warningAlert addAction:closeAction];
[TSPresentationDelegate presentViewController:warningAlert animated:YES completion:nil];
} else {
// unrecoverable error
UIAlertController* errorAlert = [UIAlertController alertControllerWithTitle:[NSString stringWithFormat:@"Install Error %d", ret] message:[error localizedDescription] preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* closeAction = [UIAlertAction actionWithTitle:@"Close" style:UIAlertActionStyleDefault handler:nil];
[errorAlert addAction:closeAction];
UIAlertAction* copyLogAction = [UIAlertAction actionWithTitle:@"Copy Debug Log" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action)
{
UIPasteboard* pasteboard = [UIPasteboard generalPasteboard];
pasteboard.string = log;
}];
[errorAlert addAction:copyLogAction];
[TSPresentationDelegate presentViewController:errorAlert animated:YES completion:nil];
if(completionBlock) completionBlock(NO, error);
}
}];
});

View File

@ -1,6 +1,7 @@
#import "TSSceneDelegate.h"
#import "TSRootViewController.h"
#import "TSUtil.h"
#import "TSApplicationsManager.h"
#import "TSInstallationController.h"
#import <TSPresentationDelegate.h>
@ -67,16 +68,70 @@
[TSInstallationController handleAppInstallFromRemoteURL:URLToInstall completion:nil];
}
}
else if([components.host isEqualToString:@"enable-jit"])
{
NSString* BundleIDToEnableJIT;
for(NSURLQueryItem* queryItem in components.queryItems)
{
if([queryItem.name isEqualToString:@"bundle-id"])
{
BundleIDToEnableJIT = queryItem.value;
break;
}
}
if(BundleIDToEnableJIT && [BundleIDToEnableJIT isKindOfClass:NSString.class])
{
dispatch_async(dispatch_get_main_queue(), ^
{
[self handleEnableJITForBundleID:BundleIDToEnableJIT];
});
}
}
}
}
}
}
- (void)handleEnableJITForBundleID:(NSString *)appId
{
TSApplicationsManager* appsManager = [TSApplicationsManager sharedInstance];
BOOL didOpen = [appsManager openApplicationWithBundleID:appId];
// if we failed to open the app, show an alert
if(!didOpen)
{
NSString* failMessage = @"";
// we don't have TSAppInfo here so we cannot check the registration state
NSString* failTitle = [NSString stringWithFormat:@"Failed to open %@", appId];
UIAlertController* didFailController = [UIAlertController alertControllerWithTitle:failTitle message:failMessage preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil];
[didFailController addAction:cancelAction];
[TSPresentationDelegate presentViewController:didFailController animated:YES completion:nil];
}
else
{
int ret = [appsManager enableJITForBundleID:appId];
if (ret != 0)
{
UIAlertController* errorAlert = [UIAlertController alertControllerWithTitle:@"Error" message:[NSString stringWithFormat:@"Error enabling JIT: trollstorehelper returned %d", ret] preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* closeAction = [UIAlertAction actionWithTitle:@"Close" style:UIAlertActionStyleDefault handler:nil];
[errorAlert addAction:closeAction];
[TSPresentationDelegate presentViewController:errorAlert animated:YES completion:nil];
}
}
}
// We want to auto install ldid if either it doesn't exist
// or if it's the one from an old TrollStore version that's no longer supported
- (void)handleLdidCheck
{
//if (@available(iOS 15, *)) {} else {
#ifndef TROLLSTORE_LITE
//if (@available(iOS 16, *)) {} else {
NSString* tsAppPath = [NSBundle mainBundle].bundlePath;
NSString* ldidPath = [tsAppPath stringByAppendingPathComponent:@"ldid"];
@ -87,6 +142,7 @@
[TSInstallationController installLdid];
}
//}
#endif
}
- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {

View File

@ -1,4 +1,5 @@
#import "TSSettingsAdvancedListController.h"
#import "TSUtil.h"
#import <Preferences/PSSpecifier.h>
extern NSUserDefaults* trollStoreUserDefaults();
@ -39,7 +40,7 @@ extern NSUserDefaults* trollStoreUserDefaults();
edit:nil];
[installationMethodSegmentSpecifier setProperty:@YES forKey:@"enabled"];
installationMethodSegmentSpecifier.identifier = @"installationMethodSegment";
[installationMethodSegmentSpecifier setProperty:@"com.opa334.TrollStore" forKey:@"defaults"];
[installationMethodSegmentSpecifier setProperty:APP_ID forKey:@"defaults"];
[installationMethodSegmentSpecifier setProperty:@"installationMethod" forKey:@"key"];
installationMethodSegmentSpecifier.values = @[@0, @1];
installationMethodSegmentSpecifier.titleDictionary = @{@0 : @"installd", @1 : @"Custom"};
@ -71,7 +72,7 @@ extern NSUserDefaults* trollStoreUserDefaults();
edit:nil];
[uninstallationMethodSegmentSpecifier setProperty:@YES forKey:@"enabled"];
uninstallationMethodSegmentSpecifier.identifier = @"uninstallationMethodSegment";
[uninstallationMethodSegmentSpecifier setProperty:@"com.opa334.TrollStore" forKey:@"defaults"];
[uninstallationMethodSegmentSpecifier setProperty:APP_ID forKey:@"defaults"];
[uninstallationMethodSegmentSpecifier setProperty:@"uninstallationMethod" forKey:@"key"];
uninstallationMethodSegmentSpecifier.values = @[@0, @1];
uninstallationMethodSegmentSpecifier.titleDictionary = @{@0 : @"installd", @1 : @"Custom"};

View File

@ -5,5 +5,6 @@
PSSpecifier* _installPersistenceHelperSpecifier;
NSString* _newerVersion;
NSString* _newerLdidVersion;
BOOL _devModeEnabled;
}
@end

View File

@ -20,6 +20,7 @@ extern NSUserDefaults* trollStoreUserDefaults(void);
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reloadSpecifiers) name:UIApplicationWillEnterForegroundNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reloadSpecifiers) name:@"TrollStoreReloadSettingsNotification" object:nil];
#ifndef TROLLSTORE_LITE
fetchLatestTrollStoreVersion(^(NSString* latestVersion)
{
NSString* currentVersion = [self getTrollStoreVersion];
@ -34,7 +35,7 @@ extern NSUserDefaults* trollStoreUserDefaults(void);
}
});
//if (@available(iOS 15, *)) {} else {
//if (@available(iOS 16, *)) {} else {
fetchLatestLdidVersion(^(NSString* latestVersion)
{
NSString* ldidVersionPath = [NSBundle.mainBundle.bundlePath stringByAppendingPathComponent:@"ldid.version"];
@ -55,6 +56,17 @@ extern NSUserDefaults* trollStoreUserDefaults(void);
}
});
//}
if (@available(iOS 16, *))
{
_devModeEnabled = spawnRoot(rootHelperPath(), @[@"check-dev-mode"], nil, nil) == 0;
}
else
{
_devModeEnabled = YES;
}
#endif
[self reloadSpecifiers];
}
- (NSMutableArray*)specifiers
@ -63,6 +75,7 @@ extern NSUserDefaults* trollStoreUserDefaults(void);
{
_specifiers = [NSMutableArray new];
#ifndef TROLLSTORE_LITE
if(_newerVersion)
{
PSSpecifier* updateTrollStoreGroupSpecifier = [PSSpecifier emptyGroupSpecifier];
@ -82,9 +95,42 @@ extern NSUserDefaults* trollStoreUserDefaults(void);
[_specifiers addObject:updateTrollStoreSpecifier];
}
if(!_devModeEnabled)
{
PSSpecifier* enableDevModeGroupSpecifier = [PSSpecifier emptyGroupSpecifier];
enableDevModeGroupSpecifier.name = @"Developer Mode";
[enableDevModeGroupSpecifier setProperty:@"Some apps require developer mode enabled to launch. This requires a reboot to take effect." forKey:@"footerText"];
[_specifiers addObject:enableDevModeGroupSpecifier];
PSSpecifier* enableDevModeSpecifier = [PSSpecifier preferenceSpecifierNamed:@"Enable Developer Mode"
target:self
set:nil
get:nil
detail:nil
cell:PSButtonCell
edit:nil];
enableDevModeSpecifier.identifier = @"enableDevMode";
[enableDevModeSpecifier setProperty:@YES forKey:@"enabled"];
enableDevModeSpecifier.buttonAction = @selector(enableDevModePressed);
[_specifiers addObject:enableDevModeSpecifier];
}
#endif
PSSpecifier* utilitiesGroupSpecifier = [PSSpecifier emptyGroupSpecifier];
utilitiesGroupSpecifier.name = @"Utilities";
[utilitiesGroupSpecifier setProperty:@"If an app does not immediately appear after installation, respring here and it should appear afterwards." forKey:@"footerText"];
NSString *utilitiesDescription = @"";
#ifdef TROLLSTORE_LITE
if (shouldRegisterAsUserByDefault()) {
utilitiesDescription = @"Apps will be registered as User by default since AppSync Unified is installed.\n\n";
}
else {
utilitiesDescription = @"Apps will be registered as System by default since AppSync Unified is not installed. When apps loose their System registration and stop working, press \"Refresh App Registrations\" here to fix them.\n\n";
}
#endif
utilitiesDescription = [utilitiesDescription stringByAppendingString:@"If an app does not immediately appear after installation, respring here and it should appear afterwards."];
[utilitiesGroupSpecifier setProperty:utilitiesDescription forKey:@"footerText"];
[_specifiers addObject:utilitiesGroupSpecifier];
PSSpecifier* respringButtonSpecifier = [PSSpecifier preferenceSpecifierNamed:@"Respring"
@ -100,6 +146,19 @@ extern NSUserDefaults* trollStoreUserDefaults(void);
[_specifiers addObject:respringButtonSpecifier];
PSSpecifier* refreshAppRegistrationsSpecifier = [PSSpecifier preferenceSpecifierNamed:@"Refresh App Registrations"
target:self
set:nil
get:nil
detail:nil
cell:PSButtonCell
edit:nil];
refreshAppRegistrationsSpecifier.identifier = @"refreshAppRegistrations";
[refreshAppRegistrationsSpecifier setProperty:@YES forKey:@"enabled"];
refreshAppRegistrationsSpecifier.buttonAction = @selector(refreshAppRegistrationsPressed);
[_specifiers addObject:refreshAppRegistrationsSpecifier];
PSSpecifier* rebuildIconCacheSpecifier = [PSSpecifier preferenceSpecifierNamed:@"Rebuild Icon Cache"
target:self
set:nil
@ -113,7 +172,24 @@ extern NSUserDefaults* trollStoreUserDefaults(void);
[_specifiers addObject:rebuildIconCacheSpecifier];
//if (@available(iOS 15, *)) { } else {
NSArray *inactiveBundlePaths = trollStoreInactiveInstalledAppBundlePaths();
if (inactiveBundlePaths.count > 0) {
PSSpecifier* transferAppsSpecifier = [PSSpecifier preferenceSpecifierNamed:[NSString stringWithFormat:@"Transfer %zu "OTHER_APP_NAME@" %@", inactiveBundlePaths.count, inactiveBundlePaths.count > 1 ? @"Apps" : @"App"]
target:self
set:nil
get:nil
detail:nil
cell:PSButtonCell
edit:nil];
transferAppsSpecifier.identifier = @"transferApps";
[transferAppsSpecifier setProperty:@YES forKey:@"enabled"];
transferAppsSpecifier.buttonAction = @selector(transferAppsPressed);
[_specifiers addObject:transferAppsSpecifier];
}
#ifndef TROLLSTORE_LITE
//if (@available(iOS 16, *)) { } else {
NSString* ldidPath = [NSBundle.mainBundle.bundlePath stringByAppendingPathComponent:@"ldid"];
NSString* ldidVersionPath = [NSBundle.mainBundle.bundlePath stringByAppendingPathComponent:@"ldid.version"];
BOOL ldidInstalled = [[NSFileManager defaultManager] fileExistsAtPath:ldidPath];
@ -258,10 +334,11 @@ extern NSUserDefaults* trollStoreUserDefaults(void);
[_specifiers addObject:_installPersistenceHelperSpecifier];
}
}
#endif
PSSpecifier* installationSettingsGroupSpecifier = [PSSpecifier emptyGroupSpecifier];
installationSettingsGroupSpecifier.name = @"Security";
[installationSettingsGroupSpecifier setProperty:@"The URL Scheme, when enabled, will allow apps and websites to trigger TrollStore installations through the apple-magnifier://install?url=<IPA_URL> URL scheme." forKey:@"footerText"];
[installationSettingsGroupSpecifier setProperty:@"The URL Scheme, when enabled, will allow apps and websites to trigger TrollStore installations through the apple-magnifier://install?url=<IPA_URL> URL scheme and enable JIT through the apple-magnifier://enable-jit?bundle-id=<BUNDLE_ID> URL scheme." forKey:@"footerText"];
[_specifiers addObject:installationSettingsGroupSpecifier];
@ -286,14 +363,14 @@ extern NSUserDefaults* trollStoreUserDefaults(void);
installAlertConfigurationSpecifier.detailControllerClass = [PSListItemsController class];
[installAlertConfigurationSpecifier setProperty:@"installationConfirmationValues" forKey:@"valuesDataSource"];
[installAlertConfigurationSpecifier setProperty:@"installationConfirmationNames" forKey:@"titlesDataSource"];
[installAlertConfigurationSpecifier setProperty:@"com.opa334.TrollStore" forKey:@"defaults"];
[installAlertConfigurationSpecifier setProperty:APP_ID forKey:@"defaults"];
[installAlertConfigurationSpecifier setProperty:@"installAlertConfiguration" forKey:@"key"];
[installAlertConfigurationSpecifier setProperty:@0 forKey:@"default"];
[_specifiers addObject:installAlertConfigurationSpecifier];
PSSpecifier* otherGroupSpecifier = [PSSpecifier emptyGroupSpecifier];
[otherGroupSpecifier setProperty:[NSString stringWithFormat:@"TrollStore %@\n\n© 2022-2023 Lars Fröder (opa334)\n\nTrollStore is NOT for piracy!\n\nCredits:\nGoogle TAG, @alfiecg_dev: CoreTrust bug\n@lunotech11, @SerenaKit, @tylinux, @TheRealClarity: Various contributions\n@ProcursusTeam: uicache, ldid\n@cstar_ow: uicache\n@saurik: ldid", [self getTrollStoreVersion]] forKey:@"footerText"];
[otherGroupSpecifier setProperty:[NSString stringWithFormat:@"%@ %@\n\n© 2022-2024 Lars Fröder (opa334)\n\nTrollStore is NOT for piracy!\n\nCredits:\nGoogle TAG, @alfiecg_dev: CoreTrust bug\n@lunotech11, @SerenaKit, @tylinux, @TheRealClarity, @dhinakg, @khanhduytran0: Various contributions\n@ProcursusTeam: uicache, ldid\n@cstar_ow: uicache\n@saurik: ldid", APP_NAME, [self getTrollStoreVersion]] forKey:@"footerText"];
[_specifiers addObject:otherGroupSpecifier];
PSSpecifier* advancedLinkSpecifier = [PSSpecifier preferenceSpecifierNamed:@"Advanced"
@ -318,6 +395,7 @@ extern NSUserDefaults* trollStoreUserDefaults(void);
[donateSpecifier setProperty:@YES forKey:@"enabled"];
[_specifiers addObject:donateSpecifier];
#ifndef TROLLSTORE_LITE
// Uninstall TrollStore
PSSpecifier* uninstallTrollStoreSpecifier = [PSSpecifier preferenceSpecifierNamed:@"Uninstall TrollStore"
target:self
@ -331,7 +409,7 @@ extern NSUserDefaults* trollStoreUserDefaults(void);
[uninstallTrollStoreSpecifier setProperty:NSClassFromString(@"PSDeleteButtonCell") forKey:@"cellClass"];
uninstallTrollStoreSpecifier.buttonAction = @selector(uninstallTrollStorePressed);
[_specifiers addObject:uninstallTrollStoreSpecifier];
#endif
/*PSSpecifier* doTheDashSpecifier = [PSSpecifier preferenceSpecifierNamed:@"Do the Dash"
target:self
set:nil
@ -369,6 +447,37 @@ extern NSUserDefaults* trollStoreUserDefaults(void);
[TSInstallationController installLdid];
}
- (void)enableDevModePressed
{
int ret = spawnRoot(rootHelperPath(), @[@"arm-dev-mode"], nil, nil);
if (ret == 0) {
UIAlertController* rebootNotification = [UIAlertController alertControllerWithTitle:@"Reboot Required"
message:@"After rebooting, select \"Turn On\" to enable developer mode."
preferredStyle:UIAlertControllerStyleAlert
];
UIAlertAction* closeAction = [UIAlertAction actionWithTitle:@"Close" style:UIAlertActionStyleCancel handler:^(UIAlertAction* action)
{
[self reloadSpecifiers];
}];
[rebootNotification addAction:closeAction];
UIAlertAction* rebootAction = [UIAlertAction actionWithTitle:@"Reboot Now" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action)
{
spawnRoot(rootHelperPath(), @[@"reboot"], nil, nil);
}];
[rebootNotification addAction:rebootAction];
[TSPresentationDelegate presentViewController:rebootNotification animated:YES completion:nil];
} else {
UIAlertController* errorAlert = [UIAlertController alertControllerWithTitle:[NSString stringWithFormat:@"Error %d", ret] message:@"Failed to enable developer mode." preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* closeAction = [UIAlertAction actionWithTitle:@"Close" style:UIAlertActionStyleDefault handler:nil];
[errorAlert addAction:closeAction];
[TSPresentationDelegate presentViewController:errorAlert animated:YES completion:nil];
}
}
- (void)installPersistenceHelperPressed
{
NSMutableArray* appCandidates = [NSMutableArray new];
@ -378,7 +487,7 @@ extern NSUserDefaults* trollStoreUserDefaults(void);
{
if([[NSFileManager defaultManager] fileExistsAtPath:[@"/System/Library/AppSignatures" stringByAppendingPathComponent:appProxy.bundleIdentifier]])
{
NSURL* trollStoreMarkURL = [appProxy.bundleURL.URLByDeletingLastPathComponent URLByAppendingPathComponent:@"_TrollStore"];
NSURL* trollStoreMarkURL = [appProxy.bundleURL.URLByDeletingLastPathComponent URLByAppendingPathComponent:TS_ACTIVE_MARKER];
if(![trollStoreMarkURL checkResourceIsReachableAndReturnError:nil])
{
[appCandidates addObject:appProxy];
@ -410,6 +519,52 @@ extern NSUserDefaults* trollStoreUserDefaults(void);
[TSPresentationDelegate presentViewController:selectAppAlert animated:YES completion:nil];
}
- (void)transferAppsPressed
{
UIAlertController *confirmationAlert = [UIAlertController alertControllerWithTitle:@"Transfer Apps" message:[NSString stringWithFormat:@"This option will transfer %zu apps from "OTHER_APP_NAME@" to "APP_NAME@". Continue?", trollStoreInactiveInstalledAppBundlePaths().count] preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* transferAction = [UIAlertAction actionWithTitle:@"Transfer" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action)
{
[TSPresentationDelegate startActivity:@"Transfering"];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^
{
NSString *log;
int transferRet = spawnRoot(rootHelperPath(), @[@"transfer-apps"], nil, &log);
dispatch_async(dispatch_get_main_queue(), ^
{
[TSPresentationDelegate stopActivityWithCompletion:^
{
[self reloadSpecifiers];
if (transferRet != 0) {
NSArray *remainingApps = trollStoreInactiveInstalledAppBundlePaths();
UIAlertController *errorAlert = [UIAlertController alertControllerWithTitle:@"Transfer Failed" message:[NSString stringWithFormat:@"Failed to transfer %zu %@", remainingApps.count, remainingApps.count > 1 ? @"apps" : @"app"] preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* copyLogAction = [UIAlertAction actionWithTitle:@"Copy Debug Log" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action)
{
UIPasteboard* pasteboard = [UIPasteboard generalPasteboard];
pasteboard.string = log;
}];
[errorAlert addAction:copyLogAction];
UIAlertAction* closeAction = [UIAlertAction actionWithTitle:@"Close" style:UIAlertActionStyleDefault handler:nil];
[errorAlert addAction:closeAction];
[TSPresentationDelegate presentViewController:errorAlert animated:YES completion:nil];
}
}];
});
});
}];
[confirmationAlert addAction:transferAction];
UIAlertAction* cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil];
[confirmationAlert addAction:cancelAction];
[TSPresentationDelegate presentViewController:confirmationAlert animated:YES completion:nil];
}
- (id)getURLSchemeEnabledForSpecifier:(PSSpecifier*)specifier
{
BOOL URLSchemeActive = (BOOL)[NSBundle.mainBundle objectForInfoDictionaryKey:@"CFBundleURLTypes"];

View File

@ -1,6 +1,6 @@
Package: com.opa334.trollstore
Name: TrollStore
Version: 2.0.3
Version: 2.1
Architecture: iphoneos-arm
Description: An awesome application!
Maintainer: opa334

View File

@ -37,10 +37,7 @@
<true/>
<key>com.apple.CommCenter.fine-grained</key>
<array>
<string>cellular-plan</string>
<string>data-usage</string>
<string>data-allowed-write</string>
<string>preferences-write</string>
</array>
<key>com.apple.springboard.opensensitiveurl</key>
<true/>

View File

@ -4,7 +4,7 @@
NSUserDefaults* trollStoreUserDefaults(void)
{
return [[NSUserDefaults alloc] initWithSuiteName:[NSHomeDirectory() stringByAppendingPathComponent:@"Library/Preferences/com.opa334.TrollStore.plist"]];
return [[NSUserDefaults alloc] initWithSuiteName:[NSHomeDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"Library/Preferences/%@.plist", APP_ID]]];
}
int main(int argc, char *argv[]) {

1
TrollStoreLite/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
Resources/trollstorehelper

16
TrollStoreLite/Makefile Normal file
View File

@ -0,0 +1,16 @@
TARGET := iphone:clang:16.5:14.0
INSTALL_TARGET_PROCESSES = TrollStoreLite
ARCHS = arm64
include $(THEOS)/makefiles/common.mk
APPLICATION_NAME = TrollStoreLite
TrollStoreLite_FILES = $(wildcard ../TrollStore/*.m) $(wildcard ../Shared/*.m)
TrollStoreLite_FRAMEWORKS = UIKit CoreGraphics CoreServices CoreTelephony
TrollStoreLite_PRIVATE_FRAMEWORKS = Preferences MobileIcons MobileContainerManager
TrollStoreLite_LIBRARIES = archive
TrollStoreLite_CFLAGS = -fobjc-arc -I../Shared -I$(shell brew --prefix)/opt/libarchive/include -DTROLLSTORE_LITE
TrollStoreLite_CODESIGN_FLAGS = -Sentitlements.plist
include $(THEOS_MAKE_PATH)/application.mk

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Some files were not shown because too many files have changed in this diff Show More