Skip to content

Commit

Permalink
fix: loader config and rebase upstream (#7)
Browse files Browse the repository at this point in the history
  • Loading branch information
PalmDevs authored Nov 15, 2024
2 parents 24d61d8 + bf11700 commit 35ad28b
Show file tree
Hide file tree
Showing 6 changed files with 184 additions and 20 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ jobs:
if: env.DEB_DOWNLOADED == 'false'
uses: Randomblock1/theos-action@v1

- name: Set GNU Make path
run: |
echo "PATH=$(brew --prefix make)/libexec/gnubin:$PATH" >> $GITHUB_ENV
- name: Build packages
if: env.DEB_DOWNLOADED == 'false'
run: make package FINALPACKAGE=1 && make package FINALPACKAGE=1 THEOS_PACKAGE_SCHEME=rootless
Expand Down
2 changes: 2 additions & 0 deletions Headers/LoaderConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@
@property (nonatomic, strong) NSURL *customLoadUrl;
+ (instancetype)defaultConfig;
+ (instancetype)getLoaderConfig;
- (instancetype)init;
- (BOOL)loadConfig;
@end
86 changes: 86 additions & 0 deletions Sources/LoaderConfig.m
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,92 @@

@implementation LoaderConfig

- (instancetype)init {
self = [super init];
if (self) {
self.customLoadUrlEnabled = NO;
self.customLoadUrl = [NSURL URLWithString:@"http://localhost:4040/revenge.js"];
}
return self;
}

- (BOOL)loadConfig {
NSURL *loaderConfigUrl = [getPyoncordDirectory() URLByAppendingPathComponent:@"loader.json"];
RevengeLog(@"Attempting to load config from: %@", loaderConfigUrl.path);

if ([[NSFileManager defaultManager] fileExistsAtPath:loaderConfigUrl.path]) {
NSError *error = nil;
NSData *data = [NSData dataWithContentsOfURL:loaderConfigUrl];
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];

if (error) {
RevengeLog(@"Error parsing loader config: %@", error);
return NO;
}

if (json) {
NSDictionary *customLoadUrl = json[@"customLoadUrl"];
if (customLoadUrl) {
self.customLoadUrlEnabled = [customLoadUrl[@"enabled"] boolValue];
NSString *urlString = customLoadUrl[@"url"];
if (urlString) {
self.customLoadUrl = [NSURL URLWithString:urlString];
}
}

RevengeLog(@"Loader config loaded - Custom URL %@: %@",
self.customLoadUrlEnabled ? @"enabled" : @"disabled",
self.customLoadUrl.absoluteString);
return YES;
}
}

RevengeLog(@"Using default loader config: %@", self.customLoadUrl.absoluteString);
return NO;
}

+ (instancetype)defaultConfig {
LoaderConfig *config = [[LoaderConfig alloc] init];
config.customLoadUrlEnabled = NO;
config.customLoadUrl = [NSURL URLWithString:@"http://localhost:4040/revenge.js"];
return config;
}

- (BOOL)loadConfig {
NSURL *loaderConfigUrl = [getPyoncordDirectory() URLByAppendingPathComponent:@"loader.json"];
RevengeLog(@"Attempting to load config from: %@", loaderConfigUrl.path);

if ([[NSFileManager defaultManager] fileExistsAtPath:loaderConfigUrl.path]) {
NSError *error = nil;
NSData *data = [NSData dataWithContentsOfURL:loaderConfigUrl];
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];

if (error) {
RevengeLog(@"Error parsing loader config: %@", error);
return NO;
}

if (json) {
NSDictionary *customLoadUrl = json[@"customLoadUrl"];
if (customLoadUrl) {
self.customLoadUrlEnabled = [customLoadUrl[@"enabled"] boolValue];
NSString *urlString = customLoadUrl[@"url"];
if (urlString) {
self.customLoadUrl = [NSURL URLWithString:urlString];
}
}

RevengeLog(@"Loader config loaded - Custom URL %@: %@",
self.customLoadUrlEnabled ? @"enabled" : @"disabled",
self.customLoadUrl.absoluteString);
return YES;
}
}

RevengeLog(@"Using default loader config: %@", self.customLoadUrl.absoluteString);
return NO;
}

+ (instancetype)defaultConfig {
LoaderConfig *config = [[LoaderConfig alloc] init];
config.customLoadUrlEnabled = NO;
Expand Down
88 changes: 88 additions & 0 deletions Sources/Sideloading.x
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <dlfcn.h>
#import "Logger.h"

#define DISCORD_BUNDLE_ID @"com.hammerandchisel.discord"
#define DISCORD_NAME @"Discord"

static NSString *getAccessGroupID(void) {
NSDictionary *query = @{
(__bridge NSString *)kSecClass: (__bridge NSString *)kSecClassGenericPassword,
(__bridge NSString *)kSecAttrAccount: @"bundleSeedID",
(__bridge NSString *)kSecAttrService: @"",
(__bridge NSString *)kSecReturnAttributes: @YES
};

CFDictionaryRef result = NULL;
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, (CFTypeRef *)&result);

if (status == errSecItemNotFound) {
status = SecItemAdd((__bridge CFDictionaryRef)query, (CFTypeRef *)&result);
}

if (status != errSecSuccess) return nil;

NSString *accessGroup = [(__bridge NSDictionary *)result objectForKey:(__bridge NSString *)kSecAttrAccessGroup];
if (result) CFRelease(result);

return accessGroup;
}

static BOOL isSelfCall(void) {
NSArray *address = [NSThread callStackReturnAddresses];
Dl_info info = {0};
if (dladdr((void *)[address[2] longLongValue], &info) == 0) return NO;
NSString *path = [NSString stringWithUTF8String:info.dli_fname];
return [path hasPrefix:NSBundle.mainBundle.bundlePath];
}

%group Sideloading

%hook NSBundle
- (NSString *)bundleIdentifier {
return isSelfCall() ? DISCORD_BUNDLE_ID : %orig;
}

- (NSDictionary *)infoDictionary {
if (!isSelfCall()) return %orig;

NSMutableDictionary *info = [%orig mutableCopy];
info[@"CFBundleIdentifier"] = DISCORD_BUNDLE_ID;
info[@"CFBundleDisplayName"] = DISCORD_NAME;
info[@"CFBundleName"] = DISCORD_NAME;
return info;
}

- (id)objectForInfoDictionaryKey:(NSString *)key {
if (!isSelfCall()) return %orig;

if ([key isEqualToString:@"CFBundleIdentifier"]) return DISCORD_BUNDLE_ID;
if ([key isEqualToString:@"CFBundleDisplayName"] ||
[key isEqualToString:@"CFBundleName"]) return DISCORD_NAME;
return %orig;
}
%end

%hook NSFileManager
- (NSURL *)containerURLForSecurityApplicationGroupIdentifier:(NSString *)groupIdentifier {
BunnyLog(@"containerURLForSecurityApplicationGroupIdentifier called! %@", groupIdentifier ?: @"nil");

NSArray *paths = [self URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask];
NSURL *lastPath = [paths lastObject];
return [lastPath URLByAppendingPathComponent:@"AppGroup"];
}
%end

%hook UIPasteboard
- (NSString *)_accessGroup {
return getAccessGroupID();
}
%end

%end

%ctor {
BOOL isAppStoreApp = [[NSFileManager defaultManager] fileExistsAtPath:[[NSBundle mainBundle] appStoreReceiptURL].path];
if (!isAppStoreApp) %init(Sideloading);
}
22 changes: 3 additions & 19 deletions Sources/Tweak.x
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,6 @@ static NSString *revengePatchesBundlePath;
static NSURL *pyoncordDirectory;
static LoaderConfig *loaderConfig;

%hook NSFileManager

- (NSURL *)containerURLForSecurityApplicationGroupIdentifier:(NSString *)groupIdentifier {
RevengeLog(@"containerURLForSecurityApplicationGroupIdentifier called! %@",
groupIdentifier ?: @"nil");

if (isJailbroken) {
return %orig(groupIdentifier);
}

NSArray *paths = [self URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask];
NSURL *lastPath = [paths lastObject];
return [lastPath URLByAppendingPathComponent:@"AppGroup"];
}

%end

%hook RCTCxxBridge

- (void)executeApplicationScript:(NSData *)script url:(NSURL *)url async:(BOOL)async {
Expand Down Expand Up @@ -179,9 +162,10 @@ static LoaderConfig *loaderConfig;
RevengeLog(@"Bundle contents: %@", bundleContents);
}

pyoncordDirectory = getPyoncordDirectory();
pyoncordDirectory = getPyoncordDirectory();
loaderConfig = [[LoaderConfig alloc] init];

[loaderConfig loadConfig];

%init;
}
}
2 changes: 1 addition & 1 deletion control
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: io.github.revenge-mod.app
Name: Revenge
Version: 2.0.0
Version: 2.0.1
Architecture: iphoneos-arm
Description: A mod for Discord's mobile apps.
Maintainer: Cristiandis
Expand Down

0 comments on commit 35ad28b

Please sign in to comment.