Skip to content

Commit 7863a67

Browse files
2.0.1
1 parent d01dc33 commit 7863a67

File tree

18 files changed

+446
-158
lines changed

18 files changed

+446
-158
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
build
2+
RootHelper/.theos

RootHelper/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@ trolltoolsroothelper_FILES = $(wildcard *.m)
99
trolltoolsroothelper_CFLAGS = -fobjc-arc
1010
trolltoolsroothelper_CODESIGN_FLAGS = -Sentitlements.plist
1111
trolltoolsroothelper_INSTALL_PATH = /usr/local/bin
12-
trolltoolsroothelper_PRIVATE_FRAMEWORKS = SpringBoardServices BackBoardServices
12+
trolltoolsroothelper_PRIVATE_FRAMEWORKS = SpringBoardServices BackBoardServices MobileCoreServices
1313

1414
include $(THEOS_MAKE_PATH)/tool.mk

RootHelper/RootHelper.swift

Lines changed: 0 additions & 42 deletions
This file was deleted.

RootHelper/entitlements.plist

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,23 @@
1111
</array>
1212
<key>com.apple.private.security.container-manager</key>
1313
<true/>
14+
<key>com.apple.private.coreservices.canmaplsdatabase</key>
15+
<true/>
16+
<key>com.apple.lsapplicationworkspace.rebuildappdatabases</key>
17+
<true/>
1418
<key>com.apple.private.security.storage.AppBundles</key>
1519
<true/>
1620
<key>com.apple.private.MobileContainerManager.allowed</key>
1721
<true/>
18-
<key>com.apple.private.security.storage.AppDataContainers</key>
22+
<key>com.apple.private.MobileInstallationHelperService.InstallDaemonOpsEnabled</key>
23+
<true/>
24+
<key>com.apple.private.MobileInstallationHelperService.allowed</key>
25+
<true/>
26+
<key>com.apple.private.uninstall.deletion</key>
27+
<true/>
28+
<key>com.apple.backboardd.launchapplications</key>
29+
<true/>
30+
<key>com.apple.multitasking.termination</key>
1931
<true/>
2032
</dict>
21-
</plist>
33+
</plist>

RootHelper/main.m

Lines changed: 225 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,230 @@
1+
#import <stdio.h>
12
@import Foundation;
3+
#import "uicache.h"
4+
#import <sys/stat.h>
5+
#import <dlfcn.h>
6+
#import <spawn.h>
7+
#import <objc/runtime.h>
8+
#import "TSUtil.h"
9+
#import <sys/utsname.h>
10+
11+
#import <SpringBoardServices/SpringBoardServices.h>
12+
#import <Security/Security.h>
13+
14+
typedef CF_OPTIONS(uint32_t, SecCSFlags) {
15+
kSecCSDefaultFlags = 0
16+
};
17+
#define kSecCSRequirementInformation 1 << 2
18+
extern CFStringRef kSecCodeInfoEntitlementsDict;
19+
20+
typedef struct __SecCode const *SecStaticCodeRef;
21+
OSStatus SecStaticCodeCreateWithPathAndAttributes(CFURLRef path, SecCSFlags flags, CFDictionaryRef attributes, SecStaticCodeRef *staticCode);
22+
OSStatus SecCodeCopySigningInformation(SecStaticCodeRef code, SecCSFlags flags, CFDictionaryRef *information);
23+
24+
NSDictionary* dumpEntitlements(SecStaticCodeRef codeRef)
25+
{
26+
if(codeRef == NULL)
27+
{
28+
NSLog(@"[dumpEntitlements] attempting to dump entitlements without a StaticCodeRef");
29+
return nil;
30+
}
31+
32+
CFDictionaryRef signingInfo = NULL;
33+
OSStatus result;
34+
35+
result = SecCodeCopySigningInformation(codeRef, kSecCSRequirementInformation, &signingInfo);
36+
37+
if(result != errSecSuccess)
38+
{
39+
NSLog(@"[dumpEntitlements] failed to copy signing info from static code");
40+
return nil;
41+
}
42+
43+
NSDictionary *entitlementsNSDict = nil;
44+
45+
CFDictionaryRef entitlements = CFDictionaryGetValue(signingInfo, kSecCodeInfoEntitlementsDict);
46+
if(entitlements == NULL)
47+
{
48+
NSLog(@"[dumpEntitlements] no entitlements specified");
49+
}
50+
else if(CFGetTypeID(entitlements) != CFDictionaryGetTypeID())
51+
{
52+
NSLog(@"[dumpEntitlements] invalid entitlements");
53+
}
54+
else
55+
{
56+
entitlementsNSDict = (__bridge NSDictionary *)(entitlements);
57+
NSLog(@"[dumpEntitlements] dumped %@", entitlementsNSDict);
58+
}
59+
60+
CFRelease(signingInfo);
61+
return entitlementsNSDict;
62+
}
63+
SecStaticCodeRef getStaticCodeRef(NSString *binaryPath)
64+
{
65+
if(binaryPath == nil)
66+
{
67+
return NULL;
68+
}
69+
70+
CFURLRef binaryURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, (__bridge CFStringRef)binaryPath, kCFURLPOSIXPathStyle, false);
71+
if(binaryURL == NULL)
72+
{
73+
NSLog(@"[getStaticCodeRef] failed to get URL to binary %@", binaryPath);
74+
return NULL;
75+
}
76+
77+
SecStaticCodeRef codeRef = NULL;
78+
OSStatus result;
79+
80+
result = SecStaticCodeCreateWithPathAndAttributes(binaryURL, kSecCSDefaultFlags, NULL, &codeRef);
81+
82+
CFRelease(binaryURL);
83+
84+
if(result != errSecSuccess)
85+
{
86+
NSLog(@"[getStaticCodeRef] failed to create static code for binary %@", binaryPath);
87+
return NULL;
88+
}
89+
90+
return codeRef;
91+
}
92+
NSSet<NSString*>* immutableAppBundleIdentifiers(void)
93+
{
94+
NSMutableSet* systemAppIdentifiers = [NSMutableSet new];
95+
96+
LSEnumerator* enumerator = [LSEnumerator enumeratorForApplicationProxiesWithOptions:0];
97+
LSApplicationProxy* appProxy;
98+
while(appProxy = [enumerator nextObject])
99+
{
100+
if(appProxy.installed)
101+
{
102+
if(![appProxy.bundleURL.path hasPrefix:@"/private/var/containers"])
103+
{
104+
[systemAppIdentifiers addObject:appProxy.bundleIdentifier.lowercaseString];
105+
}
106+
}
107+
}
108+
109+
return systemAppIdentifiers.copy;
110+
}
111+
NSDictionary* dumpEntitlementsFromBinaryAtPath(NSString *binaryPath)
112+
{
113+
// This function is intended for one-shot checks. Main-event functions should retain/release their own SecStaticCodeRefs
114+
115+
if(binaryPath == nil)
116+
{
117+
return nil;
118+
}
119+
120+
SecStaticCodeRef codeRef = getStaticCodeRef(binaryPath);
121+
if(codeRef == NULL)
122+
{
123+
return nil;
124+
}
125+
126+
NSDictionary *entitlements = dumpEntitlements(codeRef);
127+
CFRelease(codeRef);
128+
129+
return entitlements;
130+
}
131+
132+
void refreshAppRegistrations()
133+
{
134+
//registerPath((char*)trollStoreAppPath().UTF8String, 1);
135+
registerPath((char*)trollStoreAppPath().UTF8String, 0);
136+
137+
for(NSString* appPath in trollStoreInstalledAppBundlePaths())
138+
{
139+
//registerPath((char*)appPath.UTF8String, 1);
140+
registerPath((char*)appPath.UTF8String, 0);
141+
}
142+
}
143+
144+
BOOL _installPersistenceHelper(LSApplicationProxy* appProxy, NSString* sourcePersistenceHelper, NSString* sourceRootHelper)
145+
{
146+
NSLog(@"_installPersistenceHelper(%@, %@, %@)", appProxy, sourcePersistenceHelper, sourceRootHelper);
147+
148+
NSString* executablePath = appProxy.canonicalExecutablePath;
149+
NSString* bundlePath = appProxy.bundleURL.path;
150+
if(!executablePath)
151+
{
152+
NSBundle* appBundle = [NSBundle bundleWithPath:bundlePath];
153+
executablePath = [bundlePath stringByAppendingPathComponent:[appBundle objectForInfoDictionaryKey:@"CFBundleExecutable"]];
154+
}
155+
156+
NSString* markPath = [bundlePath stringByAppendingPathComponent:@".TrollStorePersistenceHelper"];
157+
NSString* rootHelperPath = [bundlePath stringByAppendingPathComponent:@"trollstorehelper"];
158+
159+
// remove existing persistence helper binary if exists
160+
if([[NSFileManager defaultManager] fileExistsAtPath:markPath] && [[NSFileManager defaultManager] fileExistsAtPath:executablePath])
161+
{
162+
[[NSFileManager defaultManager] removeItemAtPath:executablePath error:nil];
163+
}
164+
165+
// remove existing root helper binary if exists
166+
if([[NSFileManager defaultManager] fileExistsAtPath:rootHelperPath])
167+
{
168+
[[NSFileManager defaultManager] removeItemAtPath:rootHelperPath error:nil];
169+
}
170+
171+
// install new persistence helper binary
172+
if(![[NSFileManager defaultManager] copyItemAtPath:sourcePersistenceHelper toPath:executablePath error:nil])
173+
{
174+
return NO;
175+
}
176+
177+
chmod(executablePath.UTF8String, 0755);
178+
chown(executablePath.UTF8String, 33, 33);
179+
180+
NSError* error;
181+
if(![[NSFileManager defaultManager] copyItemAtPath:sourceRootHelper toPath:rootHelperPath error:&error])
182+
{
183+
NSLog(@"error copying root helper: %@", error);
184+
}
185+
186+
chmod(rootHelperPath.UTF8String, 0755);
187+
chown(rootHelperPath.UTF8String, 0, 0);
188+
189+
// mark system app as persistence helper
190+
if(![[NSFileManager defaultManager] fileExistsAtPath:markPath])
191+
{
192+
[[NSFileManager defaultManager] createFileAtPath:markPath contents:[NSData data] attributes:nil];
193+
}
194+
195+
return YES;
196+
}
197+
2198

3199
int main(int argc, char *argv[], char *envp[]) {
4-
NSString* action = [NSString stringWithUTF8String:argv[1]];
5-
NSString* source = [NSString stringWithUTF8String:argv[2]];
6-
NSString* destination = [NSString stringWithUTF8String:argv[3]];
7-
// NSBundle* bundle = [NSBundle bundleWithPath:@"/System/Library/PrivateFrameworks/MobileContainerManager.framework"];
8-
// [bundle load];
9-
10-
if ([action isEqual: @"filemove"]) {
11-
[[NSFileManager defaultManager] moveItemAtPath:source toPath:destination error:nil];
12-
} else if ([action isEqual: @"filecopy"]) {
13-
[[NSFileManager defaultManager] copyItemAtPath:source toPath:destination error:nil];
14-
} else if ([action isEqual: @"makedirectory"]) {
15-
[[NSFileManager defaultManager] createDirectoryAtPath:source withIntermediateDirectories:true attributes:nil error:nil];
16-
} else if ([action isEqual: @"removeitem"]) {
17-
[[NSFileManager defaultManager] removeItemAtPath:source error:nil];
18-
} else if ([action isEqual: @"permissionset"]) {
19-
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
20-
[dict setObject:[NSNumber numberWithInt:511] forKey:NSFilePosixPermissions];
21-
[[NSFileManager defaultManager] setAttributes:dict ofItemAtPath:source error:nil];
22-
}
200+
@autoreleasepool {
201+
[[NSFileManager defaultManager] createDirectoryAtPath:@"/var/mobile/testrebuild" withIntermediateDirectories:true attributes:nil error:nil];
202+
203+
loadMCMFramework();
204+
NSString* action = [NSString stringWithUTF8String:argv[1]];
205+
NSString* source = [NSString stringWithUTF8String:argv[2]];
206+
NSString* destination = [NSString stringWithUTF8String:argv[3]];
23207

24-
// NSLog(@"%s", getuid() == 0 ? "root" : "user");
25-
return 1;
208+
209+
if ([action isEqual: @"filemove"]) {
210+
[[NSFileManager defaultManager] moveItemAtPath:source toPath:destination error:nil];
211+
} else if ([action isEqual: @"filecopy"]) {
212+
[[NSFileManager defaultManager] copyItemAtPath:source toPath:destination error:nil];
213+
} else if ([action isEqual: @"makedirectory"]) {
214+
[[NSFileManager defaultManager] createDirectoryAtPath:source withIntermediateDirectories:true attributes:nil error:nil];
215+
} else if ([action isEqual: @"removeitem"]) {
216+
[[NSFileManager defaultManager] removeItemAtPath:source error:nil];
217+
} else if ([action isEqual: @"permissionset"]) {
218+
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
219+
[dict setObject:[NSNumber numberWithInt:511] forKey:NSFilePosixPermissions];
220+
[[NSFileManager defaultManager] setAttributes:dict ofItemAtPath:source error:nil];
221+
} else if ([action isEqual: @"rebuildiconcache"]) {
222+
[[LSApplicationWorkspace defaultWorkspace] _LSPrivateRebuildApplicationDatabasesForSystemApps:YES internal:YES user:YES];
223+
refreshAppRegistrations(); // needed for trollstore apps still working after rebuilding, otherwise they won't launch
224+
respring();
225+
}
226+
227+
// NSLog(@"%s", getuid() == 0 ? "root" : "user");
228+
return 0;
229+
}
26230
}

0 commit comments

Comments
 (0)