2022-09-02 23:19:48 +08:00
|
|
|
#import "TSUtil.h"
|
|
|
|
|
|
|
|
#import <Foundation/Foundation.h>
|
|
|
|
#import <spawn.h>
|
|
|
|
#import <sys/sysctl.h>
|
|
|
|
|
2022-09-30 03:00:11 +08:00
|
|
|
@interface PSAppDataUsagePolicyCache : NSObject
|
|
|
|
+ (instancetype)sharedInstance;
|
|
|
|
- (void)setUsagePoliciesForBundle:(NSString*)bundleId cellular:(BOOL)cellular wifi:(BOOL)wifi;
|
|
|
|
@end
|
|
|
|
|
2022-09-02 23:19:48 +08:00
|
|
|
#define POSIX_SPAWN_PERSONA_FLAGS_OVERRIDE 1
|
|
|
|
extern int posix_spawnattr_set_persona_np(const posix_spawnattr_t* __restrict, uid_t, uint32_t);
|
|
|
|
extern int posix_spawnattr_set_persona_uid_np(const posix_spawnattr_t* __restrict, uid_t);
|
|
|
|
extern int posix_spawnattr_set_persona_gid_np(const posix_spawnattr_t* __restrict, uid_t);
|
|
|
|
|
2022-09-30 03:00:11 +08:00
|
|
|
void chineseWifiFixup(void)
|
|
|
|
{
|
|
|
|
Class K_PSAppDataUsagePolicyCache = NSClassFromString(@"PSAppDataUsagePolicyCache");
|
|
|
|
PSAppDataUsagePolicyCache* cache = [K_PSAppDataUsagePolicyCache sharedInstance];
|
|
|
|
[cache setUsagePoliciesForBundle:NSBundle.mainBundle.bundleIdentifier cellular:true wifi:true];
|
|
|
|
}
|
|
|
|
|
2022-09-02 23:19:48 +08:00
|
|
|
NSString* helperPath(void)
|
|
|
|
{
|
|
|
|
return [[NSBundle mainBundle].bundlePath stringByAppendingPathComponent:@"trollstorehelper"];
|
|
|
|
}
|
|
|
|
|
2022-09-10 02:22:34 +08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
void printMultilineNSString(NSString* stringToPrint)
|
|
|
|
{
|
|
|
|
NSCharacterSet *separator = [NSCharacterSet newlineCharacterSet];
|
|
|
|
NSArray* lines = [stringToPrint componentsSeparatedByCharactersInSet:separator];
|
|
|
|
for(NSString* line in lines)
|
|
|
|
{
|
|
|
|
NSLog(@"%@", line);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int spawnRoot(NSString* path, NSArray* args, NSString** stdOut, NSString** stdErr)
|
2022-09-02 23:19:48 +08:00
|
|
|
{
|
|
|
|
NSMutableArray* argsM = args.mutableCopy ?: [NSMutableArray new];
|
|
|
|
[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;
|
|
|
|
|
|
|
|
posix_spawnattr_t attr;
|
2022-09-10 02:22:34 +08:00
|
|
|
posix_spawnattr_init(&attr);
|
2022-09-02 23:19:48 +08:00
|
|
|
|
|
|
|
posix_spawnattr_set_persona_np(&attr, 99, POSIX_SPAWN_PERSONA_FLAGS_OVERRIDE);
|
|
|
|
posix_spawnattr_set_persona_uid_np(&attr, 0);
|
|
|
|
posix_spawnattr_set_persona_gid_np(&attr, 0);
|
2022-09-10 02:22:34 +08:00
|
|
|
|
|
|
|
posix_spawn_file_actions_t action;
|
|
|
|
posix_spawn_file_actions_init(&action);
|
|
|
|
|
|
|
|
int outErr[2];
|
|
|
|
if(stdErr)
|
|
|
|
{
|
|
|
|
pipe(outErr);
|
|
|
|
posix_spawn_file_actions_adddup2(&action, outErr[1], STDERR_FILENO);
|
|
|
|
posix_spawn_file_actions_addclose(&action, outErr[0]);
|
|
|
|
}
|
|
|
|
|
|
|
|
int out[2];
|
|
|
|
if(stdOut)
|
|
|
|
{
|
|
|
|
pipe(out);
|
|
|
|
posix_spawn_file_actions_adddup2(&action, out[1], STDOUT_FILENO);
|
|
|
|
posix_spawn_file_actions_addclose(&action, out[0]);
|
|
|
|
}
|
2022-09-02 23:19:48 +08:00
|
|
|
|
|
|
|
pid_t task_pid;
|
|
|
|
int status = -200;
|
2022-09-10 02:22:34 +08:00
|
|
|
int spawnError = posix_spawn(&task_pid, [path UTF8String], &action, &attr, (char* const*)argsC, NULL);
|
2022-09-02 23:19:48 +08:00
|
|
|
posix_spawnattr_destroy(&attr);
|
|
|
|
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) {
|
2022-09-03 09:08:59 +08:00
|
|
|
NSLog(@"Child status %d", WEXITSTATUS(status));
|
2022-09-02 23:19:48 +08:00
|
|
|
} else
|
|
|
|
{
|
|
|
|
perror("waitpid");
|
|
|
|
return -222;
|
|
|
|
}
|
|
|
|
} while (!WIFEXITED(status) && !WIFSIGNALED(status));
|
2022-09-10 02:22:34 +08:00
|
|
|
|
|
|
|
if(stdOut)
|
|
|
|
{
|
|
|
|
close(out[1]);
|
|
|
|
NSString* output = getNSStringFromFile(out[0]);
|
|
|
|
*stdOut = output;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(stdErr)
|
|
|
|
{
|
|
|
|
close(outErr[1]);
|
|
|
|
NSString* errorOutput = getNSStringFromFile(outErr[0]);
|
|
|
|
*stdErr = errorOutput;
|
|
|
|
}
|
2022-09-02 23:19:48 +08:00
|
|
|
|
|
|
|
return WEXITSTATUS(status);
|
|
|
|
}
|
|
|
|
|
|
|
|
void enumerateProcessesUsingBlock(void (^enumerator)(pid_t pid, NSString* executablePath, BOOL* stop))
|
|
|
|
{
|
|
|
|
static int maxArgumentSize = 0;
|
|
|
|
if (maxArgumentSize == 0) {
|
|
|
|
size_t size = sizeof(maxArgumentSize);
|
|
|
|
if (sysctl((int[]){ CTL_KERN, KERN_ARGMAX }, 2, &maxArgumentSize, &size, NULL, 0) == -1) {
|
|
|
|
perror("sysctl argument size");
|
|
|
|
maxArgumentSize = 4096; // Default
|
|
|
|
}
|
|
|
|
}
|
|
|
|
int mib[3] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL};
|
|
|
|
struct kinfo_proc *info;
|
|
|
|
size_t length;
|
|
|
|
int count;
|
|
|
|
|
|
|
|
if (sysctl(mib, 3, NULL, &length, NULL, 0) < 0)
|
|
|
|
return;
|
|
|
|
if (!(info = malloc(length)))
|
|
|
|
return;
|
|
|
|
if (sysctl(mib, 3, info, &length, NULL, 0) < 0) {
|
|
|
|
free(info);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
count = length / sizeof(struct kinfo_proc);
|
|
|
|
for (int i = 0; i < count; i++) {
|
|
|
|
@autoreleasepool {
|
|
|
|
pid_t pid = info[i].kp_proc.p_pid;
|
|
|
|
if (pid == 0) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
size_t size = maxArgumentSize;
|
|
|
|
char* buffer = (char *)malloc(length);
|
|
|
|
if (sysctl((int[]){ CTL_KERN, KERN_PROCARGS2, pid }, 3, buffer, &size, NULL, 0) == 0) {
|
|
|
|
NSString* executablePath = [NSString stringWithCString:(buffer+sizeof(int)) encoding:NSUTF8StringEncoding];
|
|
|
|
|
|
|
|
BOOL stop = NO;
|
|
|
|
enumerator(pid, executablePath, &stop);
|
|
|
|
if(stop)
|
|
|
|
{
|
|
|
|
free(buffer);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
free(buffer);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
free(info);
|
|
|
|
}
|
|
|
|
|
|
|
|
void killall(NSString* processName)
|
|
|
|
{
|
|
|
|
enumerateProcessesUsingBlock(^(pid_t pid, NSString* executablePath, BOOL* stop)
|
|
|
|
{
|
|
|
|
if([executablePath.lastPathComponent isEqualToString:processName])
|
|
|
|
{
|
|
|
|
kill(pid, SIGTERM);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
void respring(void)
|
|
|
|
{
|
|
|
|
killall(@"SpringBoard");
|
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
|
2022-09-22 23:38:58 +08:00
|
|
|
void fetchLatestTrollStoreVersion(void (^completionHandler)(NSString* latestVersion))
|
2022-09-02 23:19:48 +08:00
|
|
|
{
|
2022-09-22 23:38:58 +08:00
|
|
|
NSURL* githubLatestAPIURL = [NSURL URLWithString:@"https://api.github.com/repos/opa334/TrollStore/releases/latest"];
|
|
|
|
|
|
|
|
NSURLSessionDataTask* task = [NSURLSession.sharedSession dataTaskWithURL:githubLatestAPIURL completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
|
|
|
|
{
|
|
|
|
if(!error)
|
|
|
|
{
|
|
|
|
if ([response isKindOfClass:[NSHTTPURLResponse class]])
|
|
|
|
{
|
|
|
|
NSError *jsonError;
|
|
|
|
NSDictionary *jsonResponse = [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonError];
|
|
|
|
|
|
|
|
if (!jsonError)
|
|
|
|
{
|
|
|
|
completionHandler(jsonResponse[@"tag_name"]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}];
|
|
|
|
|
|
|
|
[task resume];
|
|
|
|
}
|