From e60633c758b60fd527645e3e2ae85a52aa9b29dd Mon Sep 17 00:00:00 2001 From: Jeremy Agostino Date: Thu, 1 Dec 2016 16:49:11 -0500 Subject: [PATCH 1/2] Check whether the app is running under Translocation on macOS Sierra and uses the original application path instead of the path the app is running from. This fixes DMG and Download folder detection, which is broken when running from a Translocated path. --- PFMoveApplication.m | 48 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/PFMoveApplication.m b/PFMoveApplication.m index 12e84c1..5583454 100644 --- a/PFMoveApplication.m +++ b/PFMoveApplication.m @@ -42,6 +42,7 @@ // Helper functions +static NSURL * GetOriginalBundleURL(void); static NSString *PreferredInstallLocation(BOOL *isUserDirectory); static BOOL IsInApplicationsFolder(NSString *path); static BOOL IsInDownloadsFolder(NSString *path); @@ -61,7 +62,7 @@ void PFMoveToApplicationsFolderIfNecessary(void) { if ([[NSUserDefaults standardUserDefaults] boolForKey:AlertSuppressKey]) return; // Path of the bundle - NSString *bundlePath = [[NSBundle mainBundle] bundlePath]; + NSString *bundlePath = GetOriginalBundleURL().path; // Check if the bundle is embedded in another application BOOL isNestedApplication = IsApplicationAtPathNested(bundlePath); @@ -210,6 +211,51 @@ void PFMoveToApplicationsFolderIfNecessary(void) { #pragma mark - #pragma mark Helper Functions +/// Gets the real bundle path of the application, not the Translocated one if applicable +static NSURL * GetOriginalBundleURL(void) { + + NSURL * bundleURL = [NSBundle mainBundle].bundleURL; + NSLog(@"%s: Foundation says bundle URL is %@", __FUNCTION__, bundleURL); + + // #define NSAppKitVersionNumber10_11 1404 + if (floor(NSAppKitVersionNumber) <= 1404) { + return bundleURL; + } + + void * handle = dlopen("/System/Library/Frameworks/Security.framework/Security", RTLD_LAZY); + if (handle == NULL) { + return bundleURL; + } + + bool isTranslocated = false; + + // Get (undocumented?) function symbols for looking up app translocation info + // Note: was available in the macOS 10.12 beta SDKs but seems to have been removed as of Xcode 8.1 + Boolean(*mySecTranslocateIsTranslocatedURL)(CFURLRef path, bool *isTranslocated, CFErrorRef * __nullable error) = dlsym(handle, "SecTranslocateIsTranslocatedURL"); + CFURLRef __nullable(*mySecTranslocateCreateOriginalPathForURL)(CFURLRef translocatedPath, CFErrorRef * __nullable error) = dlsym(handle, "SecTranslocateCreateOriginalPathForURL"); + + dlclose(handle); + + if (mySecTranslocateIsTranslocatedURL == NULL || mySecTranslocateCreateOriginalPathForURL == NULL) { + NSLog(@"%s: We're running on macOS >= 10.12 but the SecTranslocate functions are not available", __FUNCTION__); + return bundleURL; + } + + if (mySecTranslocateIsTranslocatedURL((__bridge CFURLRef)bundleURL, &isTranslocated, NULL) && isTranslocated) + { + CFURLRef originalURL = mySecTranslocateCreateOriginalPathForURL((__bridge CFURLRef)bundleURL, NULL); + if (originalURL != NULL) + { + NSURL * result = CFBridgingRelease(originalURL); + NSLog(@"%s: Security says bundle is Translocated from %@", __FUNCTION__, result); + return result; + } + } + + NSLog(@"%s: Translocation not in effect", __FUNCTION__); + return bundleURL; +} + static NSString *PreferredInstallLocation(BOOL *isUserDirectory) { // Return the preferred install location. // Assume that if the user has a ~/Applications folder, they'd prefer their From 87142929cbed799ceb4d4c0c9457ec35591ef9b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Va=CC=81clav=20Slavi=CC=81k?= Date: Thu, 8 Sep 2022 16:20:03 +0200 Subject: [PATCH 2/2] Fix compilation warnings for dlsym() calls --- PFMoveApplication.m | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/PFMoveApplication.m b/PFMoveApplication.m index 5583454..9a8831b 100644 --- a/PFMoveApplication.m +++ b/PFMoveApplication.m @@ -231,8 +231,13 @@ void PFMoveToApplicationsFolderIfNecessary(void) { // Get (undocumented?) function symbols for looking up app translocation info // Note: was available in the macOS 10.12 beta SDKs but seems to have been removed as of Xcode 8.1 - Boolean(*mySecTranslocateIsTranslocatedURL)(CFURLRef path, bool *isTranslocated, CFErrorRef * __nullable error) = dlsym(handle, "SecTranslocateIsTranslocatedURL"); - CFURLRef __nullable(*mySecTranslocateCreateOriginalPathForURL)(CFURLRef translocatedPath, CFErrorRef * __nullable error) = dlsym(handle, "SecTranslocateCreateOriginalPathForURL"); + // see https://opensource.apple.com/source/Security/Security-58286.70.7/OSX/libsecurity_translocate/lib/SecTranslocate.h.auto.html + + typedef Boolean (*SecTranslocateIsTranslocatedURL_t)(CFURLRef path, bool *isTranslocated, CFErrorRef * __nullable error); + SecTranslocateIsTranslocatedURL_t mySecTranslocateIsTranslocatedURL = (SecTranslocateIsTranslocatedURL_t)dlsym(handle, "SecTranslocateIsTranslocatedURL"); + + typedef CFURLRef __nullable(*SecTranslocateCreateOriginalPathForURL_t)(CFURLRef translocatedPath, CFErrorRef * __nullable error); + SecTranslocateCreateOriginalPathForURL_t mySecTranslocateCreateOriginalPathForURL = (SecTranslocateCreateOriginalPathForURL_t)dlsym(handle, "SecTranslocateCreateOriginalPathForURL"); dlclose(handle);