├── .gitignore ├── Dump ├── 10.8.txt └── 10.9.txt ├── FinderExt ├── Finder.h ├── FinderExt-Info.plist ├── FinderExt-Prefix.pch ├── FinderExt.h ├── FinderExt.m ├── ILClassOverrideUtils.h ├── ILClassOverrideUtils.m ├── ILFinderMenu.h ├── ILFinderMenu.m ├── ILPathMenuDelegate.h ├── ILPathMenuDelegate.m ├── ILSimpleMenuDelegate.h ├── ILSimpleMenuDelegate.m ├── ILTFENodeUtils.h ├── ILTFENodeUtils.mm └── en.lproj │ └── InfoPlist.strings ├── FinderMenu.xcodeproj └── project.pbxproj ├── FinderMenu ├── FinderMenu-Prefix.pch ├── FinderMenu.1 └── main.m ├── LICENSE ├── README.md ├── mach_inject ├── .gitignore ├── DisposeWindow+Beep │ ├── DisposeWindow+Beep.c │ ├── DisposeWindow+Beep.xcodeproj │ │ └── project.pbxproj │ ├── DisposeWindow+Beep_Prefix.pch │ ├── English.lproj │ │ └── InfoPlist.strings │ ├── Info.plist │ └── version.plist ├── DisposeWindow+Beep_Injector │ ├── DisposeWindow+Beep_Injector.xcodeproj │ │ └── project.pbxproj │ ├── DisposeWindow+Beep_Injector_Prefix.pch │ ├── English.lproj │ │ ├── InfoPlist.strings │ │ └── MainMenu.nib │ │ │ ├── classes.nib │ │ │ ├── info.nib │ │ │ └── objects.nib │ ├── Info.plist │ ├── InjectorAppDelegate.h │ ├── InjectorAppDelegate.m │ ├── main.m │ └── version.plist ├── README.markdown ├── mach_inject │ ├── mach_inject.c │ ├── mach_inject.h │ ├── mach_inject.xcodeproj │ │ └── project.pbxproj │ └── main.c ├── mach_inject_bundle │ ├── English.lproj │ │ └── InfoPlist.strings │ ├── Info.plist │ ├── mach_inject_bundle.c │ ├── mach_inject_bundle.h │ ├── mach_inject_bundle.xcodeproj │ │ └── project.pbxproj │ ├── mach_inject_bundle_Prefix.pch │ ├── main.c │ └── version.plist ├── mach_inject_bundle_stub │ ├── English.lproj │ │ └── InfoPlist.strings │ ├── Info.plist │ ├── load_bundle.c │ ├── load_bundle.h │ ├── mach_inject_bundle_stub.c │ ├── mach_inject_bundle_stub.h │ ├── mach_inject_bundle_stub.xcodeproj │ │ └── project.pbxproj │ ├── mach_inject_bundle_stub_Prefix.pch │ └── version.plist ├── mach_inject_example │ ├── Injector │ │ ├── DKInjector.h │ │ ├── DKInjector.m │ │ ├── Injector-Info.plist │ │ ├── Injector-Launchd.plist │ │ ├── Injector-Prefix.pch │ │ └── main.m │ ├── Installer │ │ ├── DKFrameworkInstaller.h │ │ ├── DKFrameworkInstaller.m │ │ ├── Installer-Info.plist │ │ ├── Installer-Launchd.plist │ │ ├── Installer-Prefix.pch │ │ └── main.m │ ├── LICENSE │ ├── MachInjectSample.xcodeproj │ │ └── project.pbxproj │ ├── MachInjectSample │ │ ├── DKAppDelegate.h │ │ ├── DKAppDelegate.m │ │ ├── DKConstant.h │ │ ├── DKConstant.m │ │ ├── DKInjectorProxy.h │ │ ├── DKInjectorProxy.m │ │ ├── DKInstaller.h │ │ ├── DKInstaller.m │ │ ├── MachInjectSample-Info.plist │ │ ├── MachInjectSample-Prefix.pch │ │ ├── en.lproj │ │ │ ├── InfoPlist.strings │ │ │ └── MainMenu.xib │ │ └── main.m │ ├── Payload │ │ ├── Payload-Info.plist │ │ ├── Payload-Prefix.pch │ │ ├── en.lproj │ │ │ └── InfoPlist.strings │ │ └── main.m │ └── README.md ├── mach_inject_sandbox │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── English.lproj │ │ ├── InfoPlist.strings │ │ └── MainMenu.nib │ │ │ ├── classes.nib │ │ │ ├── info.nib │ │ │ └── keyedobjects.nib │ ├── Info.plist │ ├── InjectedBundleClass.h │ ├── InjectedBundleClass.m │ ├── Japanese.lproj │ │ ├── InfoPlist.strings │ │ └── MainMenu.nib │ │ │ ├── classes.nib │ │ │ ├── info.nib │ │ │ └── keyedobjects.nib │ ├── mach_inject_sandbox.xcodeproj │ │ └── project.pbxproj │ ├── mach_inject_sandbox_Prefix.pch │ ├── mach_inject_sandbox_bundle-Info.plist │ └── main.m └── mach_inject_test │ ├── English.lproj │ ├── injectee-InfoPlist.strings │ ├── injectee-MainMenu.nib │ │ ├── classes.nib │ │ ├── info.nib │ │ └── keyedobjects.nib │ ├── injector-InfoPlist.strings │ └── injector-MainMenu.nib │ │ ├── classes.nib │ │ ├── designable.nib │ │ ├── info.nib │ │ └── keyedobjects.nib │ ├── injected-Info.plist │ ├── injected-PrincipalClass.h │ ├── injected-PrincipalClass.m │ ├── injectee-AppDelegate.h │ ├── injectee-AppDelegate.m │ ├── injectee-Info.plist │ ├── injector-AppDelegate.h │ ├── injector-AppDelegate.m │ ├── injector-Info.plist │ ├── mach_inject_test.xcodeproj │ └── project.pbxproj │ ├── mach_inject_test_Prefix.pch │ └── main.m └── run.sh /.gitignore: -------------------------------------------------------------------------------- 1 | # Exclude the build directory 2 | build/* 3 | 4 | # Exclude temp nibs and swap files 5 | *~.nib 6 | *.swp 7 | 8 | # Exclude OS X folder attributes 9 | .DS_Store 10 | 11 | # Exclude user-specific XCode 3 and 4 files 12 | *.mode1 13 | *.mode1v3 14 | *.mode2v3 15 | *.perspective 16 | *.perspectivev3 17 | *.pbxuser 18 | *.xcworkspace 19 | xcuserdata 20 | 21 | -------------------------------------------------------------------------------- /FinderExt/Finder.h: -------------------------------------------------------------------------------- 1 | // 2 | // Finder.h 3 | // FinderMenu 4 | // 5 | // Required Finder's interface declarations 6 | // Obtained using 'class_dump' tool ( http://www.codethecode.com/projects/class-dump/ ) 7 | // 8 | // Created by Alexey Zhuchkov on 11/4/12. 9 | // Copyright (c) 2012 InfiniteLabs. All rights reserved. 10 | // 11 | 12 | struct OpaqueNodeRef; 13 | 14 | struct TFENode { 15 | struct OpaqueNodeRef *fNodeRef; 16 | }; 17 | 18 | #ifdef __cplusplus 19 | #include 20 | class TFENodeVector : public std::vector { }; 21 | #else // !__cplusplus 22 | struct TFENodeVector; 23 | #endif 24 | 25 | 26 | @interface FINode : NSObject 27 | 28 | // Lion & Mountain Lion 29 | + (id)nodeFromNodeRef:(struct OpaqueNodeRef *)nodeRef; 30 | @property(readonly) NSURL *previewItemURL; 31 | 32 | // Snow Leopard 33 | + (id)nodeWithFENode:(const struct TFENode *)node; 34 | @property(readonly) NSString *fullPath; 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /FinderExt/FinderExt-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | com.infinitelabs.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | BNDL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | NSHumanReadableCopyright 26 | Copyright © 2012 InfiniteLabs. All rights reserved. 27 | NSPrincipalClass 28 | FinderExt 29 | 30 | 31 | -------------------------------------------------------------------------------- /FinderExt/FinderExt-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'FinderExt' target in the 'FinderExt' project 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | -------------------------------------------------------------------------------- /FinderExt/FinderExt.h: -------------------------------------------------------------------------------- 1 | // 2 | // FinderInj.h 3 | // FinderMenu 4 | // 5 | // Created by Alexey Zhuchkov on 10/21/12. 6 | // Copyright (c) 2012 InfiniteLabs. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface FinderExt : NSObject 12 | + (void)load; 13 | @end 14 | -------------------------------------------------------------------------------- /FinderExt/FinderExt.m: -------------------------------------------------------------------------------- 1 | // 2 | // FinderInj.m 3 | // FinderMenu 4 | // 5 | // Created by Alexey Zhuchkov on 10/21/12. 6 | // Copyright (c) 2012 InfiniteLabs. All rights reserved. 7 | // 8 | 9 | #import "FinderExt.h" 10 | 11 | #import "ILFinderMenu.h" 12 | #import "ILPathMenuDelegate.h" 13 | 14 | @implementation FinderExt 15 | 16 | static FinderExt *_instance = nil; 17 | 18 | + (void)load { 19 | 20 | NSLog(@"Main bundle: %@", [[NSBundle mainBundle] bundleIdentifier]); 21 | if (!_instance) { 22 | _instance = [[FinderExt alloc] init]; 23 | } 24 | NSLog(@"FinderExt load is complete"); 25 | } 26 | 27 | - (id)init 28 | { 29 | self = [super init]; 30 | if (self) { 31 | [self setupLogging]; 32 | 33 | NSMenuItem *menuItem = [self createMenuItem]; 34 | [self injectMenuItem:menuItem]; 35 | } 36 | return self; 37 | } 38 | 39 | - (void)setupLogging 40 | { 41 | // Write log file to ~/FinderExt.log 42 | const char* logFilePath = [[NSHomeDirectory() stringByAppendingPathComponent:@"FinderExt.log"] UTF8String]; 43 | freopen(logFilePath, "a", stdout); 44 | freopen(logFilePath, "a", stderr); 45 | } 46 | 47 | - (NSMenuItem *)createMenuItem 48 | { 49 | NSMenuItem *menuItem = [[NSMenuItem alloc] initWithTitle:@"Test menu" 50 | action:nil 51 | keyEquivalent:@""]; 52 | NSMenu *submenu = [[NSMenu alloc] initWithTitle:@"My menu"]; 53 | [submenu setAutoenablesItems:NO]; 54 | [[submenu addItemWithTitle:@"Item 1" 55 | action:@selector(itemClicked:) 56 | keyEquivalent:@""] 57 | setTarget:self]; 58 | [[submenu addItemWithTitle:@"Item 2" 59 | action:@selector(itemClicked:) 60 | keyEquivalent:@""] 61 | setTarget:self]; 62 | [menuItem setSubmenu:submenu]; 63 | return menuItem; 64 | } 65 | 66 | - (void)injectMenuItem:(NSMenuItem *)menuItem 67 | { 68 | // Create menu only in User's home directory 69 | ILSimpleMenuDelegate *simpleDelegate = [[[ILPathMenuDelegate alloc] 70 | initWithPath:NSHomeDirectory() 71 | menuItem:menuItem 72 | index:4] 73 | autorelease]; 74 | [[ILFinderMenu sharedInstance] setDelegate:simpleDelegate]; 75 | } 76 | 77 | - (void)itemClicked:(id)sender 78 | { 79 | NSMenuItem *item = (NSMenuItem *)sender; 80 | [[NSAlert alertWithMessageText:[NSString stringWithFormat:@"%@ clicked", [item title]] 81 | defaultButton:nil 82 | alternateButton:nil 83 | otherButton:nil 84 | informativeTextWithFormat:@"Selected files: %@", [[ILFinderMenu sharedInstance] selectedItems]] 85 | runModal]; 86 | } 87 | 88 | @end 89 | -------------------------------------------------------------------------------- /FinderExt/ILClassOverrideUtils.h: -------------------------------------------------------------------------------- 1 | // 2 | // ILClassOverrideHelper.h 3 | // FinderMenu 4 | // 5 | // Created by Alexey Zhuchkov on 3/23/13. 6 | // Copyright (c) 2013 InfiniteLabs. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | void overrideClassMethod(Class origClass, SEL origSEL, Class overrideClass, SEL overrideSEL); 16 | void overrideInstanceMethod(Class origClass, SEL origSEL, Class overrideClass, SEL overrideSEL); 17 | 18 | #ifdef __cplusplus 19 | } 20 | #endif 21 | -------------------------------------------------------------------------------- /FinderExt/ILClassOverrideUtils.m: -------------------------------------------------------------------------------- 1 | // 2 | // ILClassOverrideHelper.m 3 | // FinderMenu 4 | // 5 | // Created by Alexey Zhuchkov on 3/23/13. 6 | // Copyright (c) 2013 InfiniteLabs. All rights reserved. 7 | // 8 | 9 | #import "ILClassOverrideUtils.h" 10 | 11 | #import 12 | 13 | void overrideClassMethod(Class origClass, SEL origSEL, Class overrideClass, SEL overrideSEL) 14 | { 15 | Method origMethod, overrideMethod; 16 | 17 | overrideMethod = class_getClassMethod(overrideClass, overrideSEL); 18 | Class metaClass = object_getClass(origClass); 19 | class_addMethod(metaClass, // add method to meta class 20 | overrideSEL, 21 | method_getImplementation(overrideMethod), 22 | method_getTypeEncoding(overrideMethod)); 23 | 24 | origMethod = class_getClassMethod(origClass, origSEL); 25 | overrideMethod = class_getClassMethod(origClass, overrideSEL); 26 | method_exchangeImplementations(origMethod, overrideMethod); 27 | } 28 | 29 | void overrideInstanceMethod(Class origClass, SEL origSEL, Class overrideClass, SEL overrideSEL) 30 | { 31 | Method origMethod, overrideMethod; 32 | 33 | overrideMethod = class_getInstanceMethod(overrideClass, overrideSEL); 34 | class_addMethod(origClass, 35 | overrideSEL, 36 | method_getImplementation(overrideMethod), 37 | method_getTypeEncoding(overrideMethod)); 38 | 39 | origMethod = class_getInstanceMethod(origClass, origSEL); 40 | overrideMethod = class_getInstanceMethod(origClass, overrideSEL); 41 | method_exchangeImplementations(origMethod, overrideMethod); 42 | } 43 | -------------------------------------------------------------------------------- /FinderExt/ILFinderMenu.h: -------------------------------------------------------------------------------- 1 | // 2 | // ILFinderMenu.h 3 | // FinderMenu 4 | // 5 | // Created by Alexey Zhuchkov on 3/23/13. 6 | // Copyright (c) 2013 InfiniteLabs. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @protocol ILFinderMenuDelegate 12 | - (void)finderWillShowContextMenu:(NSMenu *)menu; 13 | @end 14 | 15 | @interface ILFinderMenu : NSObject { 16 | @private 17 | id _delegate; 18 | NSArray *_selectedItems; 19 | } 20 | 21 | @property (readwrite, nonatomic, retain) id delegate; 22 | @property (readonly, nonatomic) NSArray *selectedItems; 23 | 24 | + (ILFinderMenu *)sharedInstance; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /FinderExt/ILFinderMenu.m: -------------------------------------------------------------------------------- 1 | // 2 | // ILFinderMenu.m 3 | // FinderMenu 4 | // 5 | // Created by Alexey Zhuchkov on 3/23/13. 6 | // Copyright (c) 2013 InfiniteLabs. All rights reserved. 7 | // 8 | 9 | #import "ILFinderMenu.h" 10 | 11 | #import "Finder.h" 12 | #import "ILClassOverrideUtils.h" 13 | #import "ILTFENodeUtils.h" 14 | 15 | static int osxMajorVersion() 16 | { 17 | NSDictionary *sv = [NSDictionary dictionaryWithContentsOfFile:@"/System/Library/CoreServices/SystemVersion.plist"]; 18 | NSArray *versionComponents = [[sv objectForKey:@"ProductVersion"] componentsSeparatedByString:@"."]; 19 | return [[versionComponents objectAtIndex:1] intValue]; 20 | } 21 | 22 | @interface ILFinderMenu () 23 | @property (readwrite, nonatomic, retain) NSArray *selectedItems; 24 | @end 25 | 26 | @implementation ILFinderMenu 27 | 28 | @synthesize delegate = _delegate; 29 | @synthesize selectedItems = _selectedItems; 30 | 31 | static ILFinderMenu *_sharedInstance = nil; 32 | 33 | + (ILFinderMenu *)sharedInstance 34 | { 35 | @synchronized (self) { 36 | if (!_sharedInstance) { 37 | _sharedInstance = [[ILFinderMenu alloc] init]; 38 | } 39 | } 40 | return _sharedInstance; 41 | } 42 | 43 | - (id)init 44 | { 45 | self = [super init]; 46 | if (self) { 47 | int versionMajor = osxMajorVersion(); 48 | if (versionMajor < 6) { 49 | // Versions earlier Snow Leopard is not supported 50 | [self release]; 51 | return nil; 52 | } 53 | 54 | Class menuClass = NSClassFromString(@"TContextMenu"); 55 | if (!menuClass) { 56 | [self release]; 57 | return nil; 58 | } 59 | 60 | if (versionMajor >= 9) { 61 | // Mavericks and greater 62 | overrideClassMethod(menuClass, 63 | @selector(handleContextMenuCommon:nodes:event:clickedView:browserViewController:addPlugIns:), 64 | [self class], 65 | @selector(override_TContextMenu_handleContextMenuCommon:nodes:event:clickedView:browserViewController:addPlugIns:)); 66 | overrideInstanceMethod(menuClass, 67 | @selector(configureFromMenuNeedsUpdate:clickedView:container:event:selectedNodes:), 68 | [self class], 69 | @selector(override_TContextMenu_configureFromMenuNeedsUpdate:clickedView:container:event:selectedNodes:)); 70 | overrideClassMethod(menuClass, 71 | @selector(addViewSpecificStuffToMenu:clickedView:browserViewController:context:), 72 | [self class], 73 | @selector(override_TContextMenu_addViewSpecificStuffToMenu:clickedView:browserViewController:context:)); 74 | } else if (versionMajor == 8) { 75 | // Mountain Lion 76 | overrideClassMethod(menuClass, 77 | @selector(handleContextMenuCommon:nodes:event:view:browserController:addPlugIns:), 78 | [self class], 79 | @selector(override_TContextMenu_handleContextMenuCommon:nodes:event:view:browserController:addPlugIns:)); 80 | overrideInstanceMethod(menuClass, 81 | @selector(configureWithNodes:browserController:container:), 82 | [self class], 83 | @selector(override_TContextMenu_configureWithNodes:browserController:container:)); 84 | overrideClassMethod(menuClass, 85 | @selector(addViewSpecificStuffToMenu:browserViewController:context:), 86 | [self class], 87 | @selector(override_TContextMenu_addViewSpecificStuffToMenu:browserViewController:context:)); 88 | } else { 89 | // Snow Leopard & Lion 90 | overrideClassMethod(menuClass, 91 | @selector(handleContextMenuCommon:nodes:event:view:windowController:addPlugIns:), 92 | [self class], 93 | @selector(override_TContextMenu_handleContextMenuCommon:nodes:event:view:windowController:addPlugIns:)); 94 | overrideInstanceMethod(menuClass, 95 | @selector(configureWithNodes:windowController:container:), 96 | [self class], 97 | @selector(override_TContextMenu_configureWithNodes:windowController:container:)); 98 | overrideClassMethod(menuClass, 99 | @selector(addViewSpecificStuffToMenu:browserViewController:context:), 100 | [self class], 101 | @selector(override_TContextMenu_addViewSpecificStuffToMenu:browserViewController:context:)); 102 | } 103 | } 104 | return self; 105 | } 106 | 107 | + (void)finderWillShowContextMenu:(id)menu 108 | { 109 | [[[self sharedInstance] delegate] finderWillShowContextMenu:menu]; 110 | } 111 | 112 | + (void)setSelectedItemsFromNodes:(const struct TFENodeVector *)nodes 113 | { 114 | [[self sharedInstance] setSelectedItems:pathsForNodes(nodes)]; 115 | } 116 | 117 | #pragma mark Override methods for icons and desktop views 118 | // Snow Leopard & Lion 119 | + (void)override_TContextMenu_handleContextMenuCommon:(unsigned int)context 120 | nodes:(const struct TFENodeVector *)nodes 121 | event:(id)event 122 | view:(id)view 123 | windowController:(id)windowController 124 | addPlugIns:(BOOL)flag 125 | { 126 | [ILFinderMenu setSelectedItemsFromNodes:nodes]; 127 | [self override_TContextMenu_handleContextMenuCommon:context 128 | nodes:nodes 129 | event:event 130 | view:view 131 | windowController:windowController 132 | addPlugIns:flag]; 133 | } 134 | 135 | // Mountain Lion 136 | + (void)override_TContextMenu_handleContextMenuCommon:(unsigned int)context 137 | nodes:(const struct TFENodeVector *)nodes 138 | event:(id)event 139 | view:(id)view 140 | browserController:(id)browserController 141 | addPlugIns:(BOOL)flag 142 | { 143 | [ILFinderMenu setSelectedItemsFromNodes:nodes]; 144 | [self override_TContextMenu_handleContextMenuCommon:context 145 | nodes:nodes 146 | event:event 147 | view:view 148 | browserController:browserController 149 | addPlugIns:flag]; 150 | } 151 | 152 | // Mavericks 153 | + (void)override_TContextMenu_handleContextMenuCommon:(unsigned int)context 154 | nodes:(const struct TFENodeVector *)nodes 155 | event:(id)event 156 | clickedView:(id)view 157 | browserViewController:(id)browserViewController 158 | addPlugIns:(BOOL)flag 159 | { 160 | [ILFinderMenu setSelectedItemsFromNodes:nodes]; 161 | [self override_TContextMenu_handleContextMenuCommon:context 162 | nodes:nodes 163 | event:event 164 | clickedView:view 165 | browserViewController:browserViewController 166 | addPlugIns:flag]; 167 | } 168 | 169 | // Snow Leopard, Lion & Mountain Lion 170 | + (void)override_TContextMenu_addViewSpecificStuffToMenu:(id)menu 171 | browserViewController:(id)browserViewController 172 | context:(unsigned int)context 173 | { 174 | [self override_TContextMenu_addViewSpecificStuffToMenu:menu 175 | browserViewController:browserViewController 176 | context:context]; 177 | 178 | // Update menu only for Desktop and Icon views 179 | if ([browserViewController isKindOfClass:NSClassFromString(@"TIconViewController")] 180 | || [browserViewController isKindOfClass:NSClassFromString(@"TDesktopViewController")]) { 181 | [ILFinderMenu finderWillShowContextMenu:menu]; 182 | } 183 | } 184 | 185 | // Mavericks 186 | + (void)override_TContextMenu_addViewSpecificStuffToMenu:(id)menu 187 | clickedView:(id)view 188 | browserViewController:(id)browserViewController 189 | context:(unsigned int)context 190 | { 191 | [self override_TContextMenu_addViewSpecificStuffToMenu:menu 192 | clickedView:view 193 | browserViewController:browserViewController 194 | context:context]; 195 | // Update menu only for Desktop and Icon views 196 | if ([browserViewController isKindOfClass:NSClassFromString(@"TIconViewController")] 197 | || [browserViewController isKindOfClass:NSClassFromString(@"TDesktopViewController")]) { 198 | [ILFinderMenu finderWillShowContextMenu:menu]; 199 | } 200 | } 201 | 202 | #pragma mark Override methods for list, columns and cover flow views 203 | // Snow Leopard & Lion 204 | - (void)override_TContextMenu_configureWithNodes:(const struct TFENodeVector *)nodes 205 | windowController:(id)windowController 206 | container:(BOOL)container 207 | { 208 | [self override_TContextMenu_configureWithNodes:nodes 209 | windowController:windowController 210 | container:container]; 211 | 212 | [ILFinderMenu setSelectedItemsFromNodes:nodes]; 213 | [ILFinderMenu finderWillShowContextMenu:self]; 214 | } 215 | 216 | // Mountain Lion 217 | - (void)override_TContextMenu_configureWithNodes:(const struct TFENodeVector *)nodes 218 | browserController:(id)browserController 219 | container:(BOOL)container 220 | { 221 | [self override_TContextMenu_configureWithNodes:nodes 222 | browserController:browserController 223 | container:container]; 224 | 225 | [ILFinderMenu setSelectedItemsFromNodes:nodes]; 226 | [ILFinderMenu finderWillShowContextMenu:self]; 227 | } 228 | 229 | // Mavericks 230 | - (void)override_TContextMenu_configureFromMenuNeedsUpdate:(id)controller 231 | clickedView:(id)view 232 | container:(BOOL)container 233 | event:(id)event 234 | selectedNodes:(const struct TFENodeVector *)nodes 235 | { 236 | [self override_TContextMenu_configureFromMenuNeedsUpdate:controller 237 | clickedView:view 238 | container:container 239 | event:event 240 | selectedNodes:nodes]; 241 | [ILFinderMenu setSelectedItemsFromNodes:nodes]; 242 | [ILFinderMenu finderWillShowContextMenu:self]; 243 | } 244 | 245 | @end 246 | -------------------------------------------------------------------------------- /FinderExt/ILPathMenuDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // ILPathMenuDelegate.h 3 | // FinderMenu 4 | // 5 | // Created by Alexey Zhuchkov on 3/24/13. 6 | // Copyright (c) 2013 InfiniteLabs. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "ILSimpleMenuDelegate.h" 12 | 13 | @interface ILPathMenuDelegate : ILSimpleMenuDelegate { 14 | @private 15 | NSString *_path; 16 | } 17 | 18 | - (id)initWithPath:(NSString *)path 19 | menuItem:(NSMenuItem *)menuItem 20 | index:(NSInteger)index; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /FinderExt/ILPathMenuDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // ILPathMenuDelegate.m 3 | // FinderMenu 4 | // 5 | // Created by Alexey Zhuchkov on 3/24/13. 6 | // Copyright (c) 2013 InfiniteLabs. All rights reserved. 7 | // 8 | 9 | #import "ILPathMenuDelegate.h" 10 | 11 | #import "ILFinderMenu.h" 12 | 13 | @implementation ILPathMenuDelegate 14 | 15 | - (id)initWithPath:(NSString *)path 16 | menuItem:(NSMenuItem *)menuItem 17 | index:(NSInteger)index 18 | { 19 | self = [super initWithMenuItem:menuItem atIndex:index]; 20 | if (self) { 21 | _path = [path retain]; 22 | } 23 | return self; 24 | } 25 | 26 | - (void)dealloc 27 | { 28 | [_path release]; 29 | [super dealloc]; 30 | } 31 | 32 | - (void)finderWillShowContextMenu:(NSMenu *)menu 33 | { 34 | NSArray *selectedItems = [[ILFinderMenu sharedInstance] selectedItems]; 35 | if (selectedItems 36 | && ([selectedItems count] > 0) 37 | && [[selectedItems objectAtIndex:0] hasPrefix:_path]) { 38 | // Show menu only for specified directory 39 | [super finderWillShowContextMenu:menu]; 40 | } 41 | } 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /FinderExt/ILSimpleMenuDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // ILSimpleMenuDelegate.h 3 | // FinderMenu 4 | // 5 | // Created by Alexey Zhuchkov on 3/24/13. 6 | // Copyright (c) 2013 InfiniteLabs. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "ILFinderMenu.h" 12 | 13 | @interface ILSimpleMenuDelegate : NSObject { 14 | @private 15 | NSMenuItem *_menuItem; 16 | NSInteger _index; 17 | } 18 | 19 | - (id)initWithMenuItem:(NSMenuItem *)menuItem atIndex:(NSInteger)index; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /FinderExt/ILSimpleMenuDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // ILSimpleMenuDelegate.m 3 | // FinderMenu 4 | // 5 | // Created by Alexey Zhuchkov on 3/24/13. 6 | // Copyright (c) 2013 InfiniteLabs. All rights reserved. 7 | // 8 | 9 | #import "ILSimpleMenuDelegate.h" 10 | 11 | @implementation ILSimpleMenuDelegate 12 | 13 | - (id)initWithMenuItem:(NSMenuItem *)menuItem atIndex:(NSInteger)index 14 | { 15 | self = [super init]; 16 | if (self) { 17 | _menuItem = [menuItem retain]; 18 | _index = index; 19 | } 20 | return self; 21 | } 22 | 23 | - (void)dealloc 24 | { 25 | [_menuItem release]; 26 | [super dealloc]; 27 | } 28 | 29 | - (void)finderWillShowContextMenu:(NSMenu *)menu 30 | { 31 | if ([_menuItem menu]) { 32 | // Detach from previous menu 33 | [[_menuItem menu] removeItem:_menuItem]; 34 | } 35 | [menu insertItem:_menuItem atIndex:_index]; 36 | } 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /FinderExt/ILTFENodeUtils.h: -------------------------------------------------------------------------------- 1 | // 2 | // ILTFENodeUtils.h 3 | // FinderMenu 4 | // 5 | // Created by Alexey Zhuchkov on 3/24/13. 6 | // Copyright (c) 2013 InfiniteLabs. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "Finder.h" 12 | 13 | #ifdef __cplusplus 14 | extern "C" { 15 | #endif 16 | 17 | NSString *pathForNode(const struct TFENode *node); 18 | NSArray *pathsForNodes(const struct TFENodeVector *nodes); 19 | 20 | #ifdef __cplusplus 21 | } 22 | #endif 23 | -------------------------------------------------------------------------------- /FinderExt/ILTFENodeUtils.mm: -------------------------------------------------------------------------------- 1 | // 2 | // ILTFENodeUtils.m 3 | // FinderMenu 4 | // 5 | // Created by Alexey Zhuchkov on 3/24/13. 6 | // Copyright (c) 2013 InfiniteLabs. All rights reserved. 7 | // 8 | 9 | #import "ILTFENodeUtils.h" 10 | 11 | #import 12 | 13 | typedef enum { 14 | PathForNodeImplUndefined = 0, 15 | PathForNodeImplUnknown = 1, 16 | PathForNodeImplNodeWithFENode = 2, 17 | PathForNodeImplNodeFromNodeRef = 3 18 | } PathForNodeImpl; 19 | 20 | NSString *pathForNode(const struct TFENode *node) 21 | { 22 | static Class FINode_class = NSClassFromString(@"FINode"); 23 | static PathForNodeImpl impl = PathForNodeImplUndefined; 24 | 25 | if (!FINode_class) { 26 | // Key class not found 27 | return nil; 28 | } 29 | 30 | // Select implementation 31 | if (impl == PathForNodeImplUndefined) { 32 | if (class_getClassMethod(FINode_class, @selector(nodeWithFENode:)) 33 | && class_getInstanceMethod(FINode_class, @selector(fullPath))) { 34 | impl = PathForNodeImplNodeWithFENode; 35 | } else if (class_getClassMethod(FINode_class, @selector(nodeFromNodeRef:)) 36 | && class_getInstanceMethod(FINode_class, @selector(previewItemURL))) { 37 | impl = PathForNodeImplNodeFromNodeRef; 38 | } else { 39 | impl = PathForNodeImplUnknown; 40 | } 41 | } 42 | 43 | // Get path 44 | NSString *path = nil; 45 | FINode *fiNode; 46 | switch (impl) { 47 | case PathForNodeImplNodeWithFENode: 48 | fiNode = [FINode_class nodeWithFENode:node]; 49 | path = [fiNode fullPath]; 50 | break; 51 | case PathForNodeImplNodeFromNodeRef: 52 | fiNode = [FINode_class nodeFromNodeRef:node->fNodeRef]; 53 | path = [[fiNode previewItemURL] path]; 54 | break; 55 | default: 56 | break; 57 | } 58 | 59 | return path; 60 | } 61 | 62 | NSArray *pathsForNodes(const struct TFENodeVector *nodes) 63 | { 64 | NSMutableArray *paths = [NSMutableArray arrayWithCapacity:nodes->size()]; 65 | for (TFENodeVector::const_iterator it = nodes->begin(); it != nodes->end(); ++it) { 66 | NSString *filePath = pathForNode(&*it); 67 | if (filePath) { 68 | [paths addObject:filePath]; 69 | } 70 | } 71 | return paths; 72 | } -------------------------------------------------------------------------------- /FinderExt/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /FinderMenu/FinderMenu-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'FinderMenu' target in the 'FinderMenu' project 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | -------------------------------------------------------------------------------- /FinderMenu/FinderMenu.1: -------------------------------------------------------------------------------- 1 | .\"Modified from man(1) of FreeBSD, the NetBSD mdoc.template, and mdoc.samples. 2 | .\"See Also: 3 | .\"man mdoc.samples for a complete listing of options 4 | .\"man mdoc for the short list of editing options 5 | .\"/usr/share/misc/mdoc.template 6 | .Dd 10/21/12 \" DATE 7 | .Dt FinderMenu 1 \" Program name and manual section number 8 | .Os Darwin 9 | .Sh NAME \" Section Header - required - don't modify 10 | .Nm FinderMenu, 11 | .\" The following lines are read in generating the apropos(man -k) database. Use only key 12 | .\" words here as the database is built based on the words here and in the .ND line. 13 | .Nm Other_name_for_same_program(), 14 | .Nm Yet another name for the same program. 15 | .\" Use .Nm macro to designate other names for the documented program. 16 | .Nd This line parsed for whatis database. 17 | .Sh SYNOPSIS \" Section Header - required - don't modify 18 | .Nm 19 | .Op Fl abcd \" [-abcd] 20 | .Op Fl a Ar path \" [-a path] 21 | .Op Ar file \" [file] 22 | .Op Ar \" [file ...] 23 | .Ar arg0 \" Underlined argument - use .Ar anywhere to underline 24 | arg2 ... \" Arguments 25 | .Sh DESCRIPTION \" Section Header - required - don't modify 26 | Use the .Nm macro to refer to your program throughout the man page like such: 27 | .Nm 28 | Underlining is accomplished with the .Ar macro like this: 29 | .Ar underlined text . 30 | .Pp \" Inserts a space 31 | A list of items with descriptions: 32 | .Bl -tag -width -indent \" Begins a tagged list 33 | .It item a \" Each item preceded by .It macro 34 | Description of item a 35 | .It item b 36 | Description of item b 37 | .El \" Ends the list 38 | .Pp 39 | A list of flags and their descriptions: 40 | .Bl -tag -width -indent \" Differs from above in tag removed 41 | .It Fl a \"-a flag as a list item 42 | Description of -a flag 43 | .It Fl b 44 | Description of -b flag 45 | .El \" Ends the list 46 | .Pp 47 | .\" .Sh ENVIRONMENT \" May not be needed 48 | .\" .Bl -tag -width "ENV_VAR_1" -indent \" ENV_VAR_1 is width of the string ENV_VAR_1 49 | .\" .It Ev ENV_VAR_1 50 | .\" Description of ENV_VAR_1 51 | .\" .It Ev ENV_VAR_2 52 | .\" Description of ENV_VAR_2 53 | .\" .El 54 | .Sh FILES \" File used or created by the topic of the man page 55 | .Bl -tag -width "/Users/joeuser/Library/really_long_file_name" -compact 56 | .It Pa /usr/share/file_name 57 | FILE_1 description 58 | .It Pa /Users/joeuser/Library/really_long_file_name 59 | FILE_2 description 60 | .El \" Ends the list 61 | .\" .Sh DIAGNOSTICS \" May not be needed 62 | .\" .Bl -diag 63 | .\" .It Diagnostic Tag 64 | .\" Diagnostic informtion here. 65 | .\" .It Diagnostic Tag 66 | .\" Diagnostic informtion here. 67 | .\" .El 68 | .Sh SEE ALSO 69 | .\" List links in ascending order by section, alphabetically within a section. 70 | .\" Please do not reference files that do not exist without filing a bug report 71 | .Xr a 1 , 72 | .Xr b 1 , 73 | .Xr c 1 , 74 | .Xr a 2 , 75 | .Xr b 2 , 76 | .Xr a 3 , 77 | .Xr b 3 78 | .\" .Sh BUGS \" Document known, unremedied bugs 79 | .\" .Sh HISTORY \" Document history if command behaves in a unique manner -------------------------------------------------------------------------------- /FinderMenu/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // FinderMenu 4 | // 5 | // Created by Alexey Zhuchkov on 10/21/12. 6 | // Copyright (c) 2012 InfiniteLabs. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | #import "mach_inject_bundle/mach_inject_bundle.h" 13 | 14 | int main(int argc, const char * argv[]) 15 | { 16 | @autoreleasepool { 17 | NSArray *apps = [NSRunningApplication runningApplicationsWithBundleIdentifier:@"com.apple.finder"]; 18 | if ([apps count] < 1) { 19 | NSLog(@"Finder not found"); 20 | return -1; 21 | } 22 | 23 | // Use first found app 24 | pid_t pid = [[apps objectAtIndex:0] processIdentifier]; 25 | 26 | NSString *bundlePath = [[NSBundle mainBundle] pathForResource:@"FinderExt" ofType:@"bundle"]; 27 | 28 | NSLog(@"Bundle path: %@", bundlePath); 29 | NSLog(@"PID: %d", pid); 30 | 31 | mach_error_t err; 32 | err = mach_inject_bundle_pid([bundlePath fileSystemRepresentation], pid); 33 | if (err == err_none) { 34 | NSLog(@"Inject successful!"); 35 | } else { 36 | NSLog(@"Inject error: %d", err); 37 | } 38 | } 39 | return 0; 40 | } 41 | 42 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Alexey Zhuchkov 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FinderMenu 2 | 3 | Adds submenu to the context menu of Mac OS X Finder. Submenu has two items, clicking on them the window with the selected items is displayed. 4 | 5 | ## Description 6 | 7 | The method `configureWithNodes:browserController:container:` of class `TContextMenu` is called, when Finder is going to show context menu on files. This method is replaced, using the [*MethodSwizzle*](http://www.mikeash.com/pyblog/friday-qa-2010-01-29-method-replacement-for-fun-and-profit.html) technique. 8 | 9 | `mach_inject` is used to inject code into the Finder process. 10 | 11 | The application consists of the following components: 12 | 13 | * *FinderMenu* - the injector app, that loads bundle into Finder 14 | * *FinderExt.bundle* - injectee bundle, that overrides code inside Finder process 15 | * *mach_inject_bundle.framework* (and *mach_inject_bundle_stub.bundle* which is part of this framework) - mach inject bundle framework, which used by *FinderMenu* 16 | 17 | Application has been tested on OS X versions 10.8 and 10.9. I will be grateful if you test it in earlier versions. Theoretically it should work on OS X versions >= 10.6 (in 10.6 Finder has been rewritten from Carbon to Cocoa and this hack is Cocoa-specific). 18 | 19 | ## Building & running 20 | 21 | Application is required `procmod` group permssion, so you can not just run it in Xcode. To build it in Terminal you can use `xcodebuild` tool. After building you can just run it with `sudo`, or change executable group to `procmod` and `setgid` bit on it. 22 | -------------------------------------------------------------------------------- /mach_inject/.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | 3 | *.pbxuser 4 | *.perspectivev3 5 | *.mode1v3 6 | *.mode2v3 7 | !default.pbxuser 8 | !default.perspectivev3 9 | !default.mode1v3 10 | !default.mode2v3 11 | xcuserdata 12 | 13 | *~.nib 14 | *~.xib 15 | 16 | .DS_Store 17 | -------------------------------------------------------------------------------- /mach_inject/DisposeWindow+Beep/DisposeWindow+Beep.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "mach_override.h" 4 | 5 | // Override type & global. 6 | typedef void (*DisposeWindowProc)( WindowRef window ); 7 | DisposeWindowProc gDisposeWindow; 8 | 9 | // Funky Protos. 10 | void DisposeWindowOverride( WindowRef window ); 11 | 12 | __attribute__((constructor)) 13 | void load() 14 | { 15 | printf( "DisposeWindow+Beep loaded\n" ); 16 | if (mach_override( "_DisposeWindow", NULL, DisposeWindowOverride, (void**) &gDisposeWindow ) != 0) { 17 | printf("Override failed!\n"); 18 | } 19 | } 20 | 21 | void DisposeWindowOverride( WindowRef window ) { 22 | printf( "beep!\n" ); 23 | fflush(0); 24 | AudioServicesPlayAlertSound(kSystemSoundID_UserPreferredAlert); 25 | gDisposeWindow( window ); 26 | } -------------------------------------------------------------------------------- /mach_inject/DisposeWindow+Beep/DisposeWindow+Beep.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 42; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 10246EDB0FE737AD00EA5607 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 10246EDA0FE737AD00EA5607 /* AudioToolbox.framework */; }; 11 | 79ACC9A607FD4A8A00D4147B /* mach_override.c in Sources */ = {isa = PBXBuildFile; fileRef = 79ACC9A407FD4A8A00D4147B /* mach_override.c */; }; 12 | 79ACC9A707FD4A8A00D4147B /* mach_override.h in Headers */ = {isa = PBXBuildFile; fileRef = 79ACC9A507FD4A8A00D4147B /* mach_override.h */; }; 13 | 8D01CCC80486CAD60068D4B7 /* DisposeWindow+Beep_Prefix.pch in Headers */ = {isa = PBXBuildFile; fileRef = 32BAE0B30371A71500C91783 /* DisposeWindow+Beep_Prefix.pch */; }; 14 | 8D01CCCA0486CAD60068D4B7 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C167DFE841241C02AAC07 /* InfoPlist.strings */; }; 15 | 8D01CCCC0486CAD60068D4B7 /* DisposeWindow+Beep.c in Sources */ = {isa = PBXBuildFile; fileRef = 08FB77B2FE8417CDC02AAC07 /* DisposeWindow+Beep.c */; settings = {ATTRIBUTES = (); }; }; 16 | 8D01CCCE0486CAD60068D4B7 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 08EA7FFBFE8413EDC02AAC07 /* Carbon.framework */; }; 17 | /* End PBXBuildFile section */ 18 | 19 | /* Begin PBXFileReference section */ 20 | 089C167EFE841241C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = ""; }; 21 | 08EA7FFBFE8413EDC02AAC07 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = ""; }; 22 | 08FB77B2FE8417CDC02AAC07 /* DisposeWindow+Beep.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = "DisposeWindow+Beep.c"; sourceTree = ""; }; 23 | 10246EDA0FE737AD00EA5607 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = /System/Library/Frameworks/AudioToolbox.framework; sourceTree = ""; }; 24 | 32BAE0B30371A71500C91783 /* DisposeWindow+Beep_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "DisposeWindow+Beep_Prefix.pch"; sourceTree = ""; }; 25 | 79ACC9A407FD4A8A00D4147B /* mach_override.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = mach_override.c; path = ../mach_override/mach_override.c; sourceTree = SOURCE_ROOT; }; 26 | 79ACC9A507FD4A8A00D4147B /* mach_override.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = mach_override.h; path = ../mach_override/mach_override.h; sourceTree = SOURCE_ROOT; }; 27 | 8D01CCD10486CAD60068D4B7 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; 28 | 8D01CCD20486CAD60068D4B7 /* DisposeWindow+Beep.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "DisposeWindow+Beep.bundle"; sourceTree = BUILT_PRODUCTS_DIR; }; 29 | /* End PBXFileReference section */ 30 | 31 | /* Begin PBXFrameworksBuildPhase section */ 32 | 8D01CCCD0486CAD60068D4B7 /* Frameworks */ = { 33 | isa = PBXFrameworksBuildPhase; 34 | buildActionMask = 2147483647; 35 | files = ( 36 | 8D01CCCE0486CAD60068D4B7 /* Carbon.framework in Frameworks */, 37 | 10246EDB0FE737AD00EA5607 /* AudioToolbox.framework in Frameworks */, 38 | ); 39 | runOnlyForDeploymentPostprocessing = 0; 40 | }; 41 | /* End PBXFrameworksBuildPhase section */ 42 | 43 | /* Begin PBXGroup section */ 44 | 089C166AFE841209C02AAC07 /* DisposeWindow+Beep */ = { 45 | isa = PBXGroup; 46 | children = ( 47 | 08FB77ADFE841716C02AAC07 /* Source */, 48 | 089C167CFE841241C02AAC07 /* Resources */, 49 | 089C1671FE841209C02AAC07 /* External Frameworks and Libraries */, 50 | 19C28FB4FE9D528D11CA2CBB /* Products */, 51 | ); 52 | name = "DisposeWindow+Beep"; 53 | sourceTree = ""; 54 | }; 55 | 089C1671FE841209C02AAC07 /* External Frameworks and Libraries */ = { 56 | isa = PBXGroup; 57 | children = ( 58 | 08EA7FFBFE8413EDC02AAC07 /* Carbon.framework */, 59 | 10246EDA0FE737AD00EA5607 /* AudioToolbox.framework */, 60 | ); 61 | name = "External Frameworks and Libraries"; 62 | sourceTree = ""; 63 | }; 64 | 089C167CFE841241C02AAC07 /* Resources */ = { 65 | isa = PBXGroup; 66 | children = ( 67 | 8D01CCD10486CAD60068D4B7 /* Info.plist */, 68 | 089C167DFE841241C02AAC07 /* InfoPlist.strings */, 69 | ); 70 | name = Resources; 71 | sourceTree = ""; 72 | }; 73 | 08FB77ADFE841716C02AAC07 /* Source */ = { 74 | isa = PBXGroup; 75 | children = ( 76 | 08FB77B2FE8417CDC02AAC07 /* DisposeWindow+Beep.c */, 77 | 79ACC9A407FD4A8A00D4147B /* mach_override.c */, 78 | 79ACC9A507FD4A8A00D4147B /* mach_override.h */, 79 | 32BAE0B30371A71500C91783 /* DisposeWindow+Beep_Prefix.pch */, 80 | ); 81 | name = Source; 82 | sourceTree = ""; 83 | }; 84 | 19C28FB4FE9D528D11CA2CBB /* Products */ = { 85 | isa = PBXGroup; 86 | children = ( 87 | 8D01CCD20486CAD60068D4B7 /* DisposeWindow+Beep.bundle */, 88 | ); 89 | name = Products; 90 | sourceTree = ""; 91 | }; 92 | /* End PBXGroup section */ 93 | 94 | /* Begin PBXHeadersBuildPhase section */ 95 | 8D01CCC70486CAD60068D4B7 /* Headers */ = { 96 | isa = PBXHeadersBuildPhase; 97 | buildActionMask = 2147483647; 98 | files = ( 99 | 8D01CCC80486CAD60068D4B7 /* DisposeWindow+Beep_Prefix.pch in Headers */, 100 | 79ACC9A707FD4A8A00D4147B /* mach_override.h in Headers */, 101 | ); 102 | runOnlyForDeploymentPostprocessing = 0; 103 | }; 104 | /* End PBXHeadersBuildPhase section */ 105 | 106 | /* Begin PBXNativeTarget section */ 107 | 8D01CCC60486CAD60068D4B7 /* DisposeWindow+Beep */ = { 108 | isa = PBXNativeTarget; 109 | buildConfigurationList = 33B2ACCA092857D7004B1632 /* Build configuration list for PBXNativeTarget "DisposeWindow+Beep" */; 110 | buildPhases = ( 111 | 8D01CCC70486CAD60068D4B7 /* Headers */, 112 | 8D01CCC90486CAD60068D4B7 /* Resources */, 113 | 8D01CCCB0486CAD60068D4B7 /* Sources */, 114 | 8D01CCCD0486CAD60068D4B7 /* Frameworks */, 115 | 8D01CCCF0486CAD60068D4B7 /* Rez */, 116 | ); 117 | buildRules = ( 118 | ); 119 | dependencies = ( 120 | ); 121 | name = "DisposeWindow+Beep"; 122 | productInstallPath = "$(HOME)/Library/Bundles"; 123 | productName = "DisposeWindow+Beep"; 124 | productReference = 8D01CCD20486CAD60068D4B7 /* DisposeWindow+Beep.bundle */; 125 | productType = "com.apple.product-type.bundle"; 126 | }; 127 | /* End PBXNativeTarget section */ 128 | 129 | /* Begin PBXProject section */ 130 | 089C1669FE841209C02AAC07 /* Project object */ = { 131 | isa = PBXProject; 132 | buildConfigurationList = 33B2ACCE092857D7004B1632 /* Build configuration list for PBXProject "DisposeWindow+Beep" */; 133 | compatibilityVersion = "Xcode 2.4"; 134 | hasScannedForEncodings = 1; 135 | mainGroup = 089C166AFE841209C02AAC07 /* DisposeWindow+Beep */; 136 | projectDirPath = ""; 137 | projectRoot = ""; 138 | targets = ( 139 | 8D01CCC60486CAD60068D4B7 /* DisposeWindow+Beep */, 140 | ); 141 | }; 142 | /* End PBXProject section */ 143 | 144 | /* Begin PBXResourcesBuildPhase section */ 145 | 8D01CCC90486CAD60068D4B7 /* Resources */ = { 146 | isa = PBXResourcesBuildPhase; 147 | buildActionMask = 2147483647; 148 | files = ( 149 | 8D01CCCA0486CAD60068D4B7 /* InfoPlist.strings in Resources */, 150 | ); 151 | runOnlyForDeploymentPostprocessing = 0; 152 | }; 153 | /* End PBXResourcesBuildPhase section */ 154 | 155 | /* Begin PBXRezBuildPhase section */ 156 | 8D01CCCF0486CAD60068D4B7 /* Rez */ = { 157 | isa = PBXRezBuildPhase; 158 | buildActionMask = 2147483647; 159 | files = ( 160 | ); 161 | runOnlyForDeploymentPostprocessing = 0; 162 | }; 163 | /* End PBXRezBuildPhase section */ 164 | 165 | /* Begin PBXSourcesBuildPhase section */ 166 | 8D01CCCB0486CAD60068D4B7 /* Sources */ = { 167 | isa = PBXSourcesBuildPhase; 168 | buildActionMask = 2147483647; 169 | files = ( 170 | 8D01CCCC0486CAD60068D4B7 /* DisposeWindow+Beep.c in Sources */, 171 | 79ACC9A607FD4A8A00D4147B /* mach_override.c in Sources */, 172 | ); 173 | runOnlyForDeploymentPostprocessing = 0; 174 | }; 175 | /* End PBXSourcesBuildPhase section */ 176 | 177 | /* Begin PBXVariantGroup section */ 178 | 089C167DFE841241C02AAC07 /* InfoPlist.strings */ = { 179 | isa = PBXVariantGroup; 180 | children = ( 181 | 089C167EFE841241C02AAC07 /* English */, 182 | ); 183 | name = InfoPlist.strings; 184 | sourceTree = ""; 185 | }; 186 | /* End PBXVariantGroup section */ 187 | 188 | /* Begin XCBuildConfiguration section */ 189 | 33B2ACCB092857D7004B1632 /* Development */ = { 190 | isa = XCBuildConfiguration; 191 | buildSettings = { 192 | ARCHS = "$(ARCHS_STANDARD_64_BIT_PRE_XCODE_3_1)"; 193 | ARCHS_STANDARD_64_BIT_PRE_XCODE_3_1 = x86_64; 194 | COPY_PHASE_STRIP = NO; 195 | DEBUGGING_SYMBOLS = YES; 196 | FRAMEWORK_SEARCH_PATHS = ""; 197 | GCC_DYNAMIC_NO_PIC = NO; 198 | GCC_ENABLE_FIX_AND_CONTINUE = YES; 199 | GCC_ENABLE_TRIGRAPHS = NO; 200 | GCC_GENERATE_DEBUGGING_SYMBOLS = YES; 201 | GCC_OPTIMIZATION_LEVEL = 0; 202 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 203 | GCC_PREFIX_HEADER = "DisposeWindow+Beep_Prefix.pch"; 204 | GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO; 205 | GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; 206 | GCC_WARN_UNKNOWN_PRAGMAS = NO; 207 | HEADER_SEARCH_PATHS = ""; 208 | INFOPLIST_FILE = Info.plist; 209 | INSTALL_PATH = "$(HOME)/Library/Bundles"; 210 | LIBRARY_SEARCH_PATHS = ""; 211 | LIBRARY_STYLE = Bundle; 212 | OTHER_CFLAGS = ""; 213 | OTHER_LDFLAGS = ""; 214 | OTHER_REZFLAGS = ""; 215 | PRODUCT_NAME = "DisposeWindow+Beep"; 216 | SECTORDER_FLAGS = ""; 217 | WARNING_CFLAGS = ( 218 | "-Wmost", 219 | "-Wno-four-char-constants", 220 | "-Wno-unknown-pragmas", 221 | ); 222 | WRAPPER_EXTENSION = bundle; 223 | ZERO_LINK = YES; 224 | }; 225 | name = Development; 226 | }; 227 | 33B2ACCC092857D7004B1632 /* Deployment */ = { 228 | isa = XCBuildConfiguration; 229 | buildSettings = { 230 | ARCHS = "$(ARCHS_STANDARD_64_BIT_PRE_XCODE_3_1)"; 231 | ARCHS_STANDARD_64_BIT_PRE_XCODE_3_1 = x86_64; 232 | COPY_PHASE_STRIP = YES; 233 | FRAMEWORK_SEARCH_PATHS = ""; 234 | GCC_ENABLE_FIX_AND_CONTINUE = NO; 235 | GCC_ENABLE_TRIGRAPHS = NO; 236 | GCC_GENERATE_DEBUGGING_SYMBOLS = NO; 237 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 238 | GCC_PREFIX_HEADER = "DisposeWindow+Beep_Prefix.pch"; 239 | GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO; 240 | GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; 241 | GCC_WARN_UNKNOWN_PRAGMAS = NO; 242 | HEADER_SEARCH_PATHS = ""; 243 | INFOPLIST_FILE = Info.plist; 244 | INSTALL_PATH = "$(HOME)/Library/Bundles"; 245 | LIBRARY_SEARCH_PATHS = ""; 246 | LIBRARY_STYLE = Bundle; 247 | OTHER_CFLAGS = ""; 248 | OTHER_LDFLAGS = ""; 249 | OTHER_REZFLAGS = ""; 250 | PRODUCT_NAME = "DisposeWindow+Beep"; 251 | SECTORDER_FLAGS = ""; 252 | WARNING_CFLAGS = ( 253 | "-Wmost", 254 | "-Wno-four-char-constants", 255 | "-Wno-unknown-pragmas", 256 | ); 257 | WRAPPER_EXTENSION = bundle; 258 | ZERO_LINK = NO; 259 | }; 260 | name = Deployment; 261 | }; 262 | 33B2ACCD092857D7004B1632 /* Default */ = { 263 | isa = XCBuildConfiguration; 264 | buildSettings = { 265 | FRAMEWORK_SEARCH_PATHS = ""; 266 | GCC_ENABLE_TRIGRAPHS = NO; 267 | GCC_GENERATE_DEBUGGING_SYMBOLS = NO; 268 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 269 | GCC_PREFIX_HEADER = "DisposeWindow+Beep_Prefix.pch"; 270 | GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO; 271 | GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; 272 | GCC_WARN_UNKNOWN_PRAGMAS = NO; 273 | HEADER_SEARCH_PATHS = ""; 274 | INFOPLIST_FILE = Info.plist; 275 | INSTALL_PATH = "$(HOME)/Library/Bundles"; 276 | LIBRARY_SEARCH_PATHS = ""; 277 | LIBRARY_STYLE = Bundle; 278 | OTHER_CFLAGS = ""; 279 | OTHER_LDFLAGS = ""; 280 | OTHER_REZFLAGS = ""; 281 | PRODUCT_NAME = "DisposeWindow+Beep"; 282 | SECTORDER_FLAGS = ""; 283 | WARNING_CFLAGS = ( 284 | "-Wmost", 285 | "-Wno-four-char-constants", 286 | "-Wno-unknown-pragmas", 287 | ); 288 | WRAPPER_EXTENSION = bundle; 289 | }; 290 | name = Default; 291 | }; 292 | 33B2ACCF092857D7004B1632 /* Development */ = { 293 | isa = XCBuildConfiguration; 294 | buildSettings = { 295 | }; 296 | name = Development; 297 | }; 298 | 33B2ACD0092857D7004B1632 /* Deployment */ = { 299 | isa = XCBuildConfiguration; 300 | buildSettings = { 301 | }; 302 | name = Deployment; 303 | }; 304 | 33B2ACD1092857D7004B1632 /* Default */ = { 305 | isa = XCBuildConfiguration; 306 | buildSettings = { 307 | }; 308 | name = Default; 309 | }; 310 | /* End XCBuildConfiguration section */ 311 | 312 | /* Begin XCConfigurationList section */ 313 | 33B2ACCA092857D7004B1632 /* Build configuration list for PBXNativeTarget "DisposeWindow+Beep" */ = { 314 | isa = XCConfigurationList; 315 | buildConfigurations = ( 316 | 33B2ACCB092857D7004B1632 /* Development */, 317 | 33B2ACCC092857D7004B1632 /* Deployment */, 318 | 33B2ACCD092857D7004B1632 /* Default */, 319 | ); 320 | defaultConfigurationIsVisible = 0; 321 | defaultConfigurationName = Default; 322 | }; 323 | 33B2ACCE092857D7004B1632 /* Build configuration list for PBXProject "DisposeWindow+Beep" */ = { 324 | isa = XCConfigurationList; 325 | buildConfigurations = ( 326 | 33B2ACCF092857D7004B1632 /* Development */, 327 | 33B2ACD0092857D7004B1632 /* Deployment */, 328 | 33B2ACD1092857D7004B1632 /* Default */, 329 | ); 330 | defaultConfigurationIsVisible = 0; 331 | defaultConfigurationName = Default; 332 | }; 333 | /* End XCConfigurationList section */ 334 | }; 335 | rootObject = 089C1669FE841209C02AAC07 /* Project object */; 336 | } 337 | -------------------------------------------------------------------------------- /mach_inject/DisposeWindow+Beep/DisposeWindow+Beep_Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'DisposeWindow+Beep' target in the 'DisposeWindow+Beep' project. 3 | // 4 | 5 | #include 6 | -------------------------------------------------------------------------------- /mach_inject/DisposeWindow+Beep/English.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zerodivisi0n/FinderMenu/d65aac3e98e75924c9efa0fae48b02bbc0928e53/mach_inject/DisposeWindow+Beep/English.lproj/InfoPlist.strings -------------------------------------------------------------------------------- /mach_inject/DisposeWindow+Beep/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | DisposeWindow+Beep 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | com.apple.carbonbundletemplate 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1.0 21 | CSResourcesFileMapped 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /mach_inject/DisposeWindow+Beep/version.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildVersion 6 | 317 7 | CFBundleShortVersionString 8 | 1.0 9 | CFBundleVersion 10 | 1.0 11 | ProductBuildVersion 12 | 7K571 13 | ProjectName 14 | CarbonProjectTemplates 15 | SourceVersion 16 | 140000 17 | 18 | 19 | -------------------------------------------------------------------------------- /mach_inject/DisposeWindow+Beep_Injector/DisposeWindow+Beep_Injector.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 42; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 33635B07095492BE002C5F77 /* mach_inject_bundle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 33635B06095492BE002C5F77 /* mach_inject_bundle.framework */; }; 11 | 33635B2F09549461002C5F77 /* mach_inject_bundle.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 33635B06095492BE002C5F77 /* mach_inject_bundle.framework */; }; 12 | 79ACCB1B07FD4D6300D4147B /* DisposeWindow+Beep.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 79ACCB1A07FD4D6300D4147B /* DisposeWindow+Beep.bundle */; }; 13 | 79ACCB3007FD4DD100D4147B /* InjectorAppDelegate.h in Resources */ = {isa = PBXBuildFile; fileRef = 79ACCB2E07FD4DD100D4147B /* InjectorAppDelegate.h */; }; 14 | 79ACCB3107FD4DD100D4147B /* InjectorAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 79ACCB2F07FD4DD100D4147B /* InjectorAppDelegate.m */; }; 15 | 8D11072A0486CEB800E47090 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 29B97318FDCFA39411CA2CEA /* MainMenu.nib */; }; 16 | 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; }; 17 | 8D11072D0486CEB800E47090 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; }; 18 | 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; }; 19 | /* End PBXBuildFile section */ 20 | 21 | /* Begin PBXContainerItemProxy section */ 22 | 33635B18095493BA002C5F77 /* PBXContainerItemProxy */ = { 23 | isa = PBXContainerItemProxy; 24 | containerPortal = 33635B14095493BA002C5F77 /* mach_inject_bundle.xcodeproj */; 25 | proxyType = 2; 26 | remoteGlobalIDString = 8DC2EF5B0486A6940098B216; 27 | remoteInfo = mach_inject_bundle; 28 | }; 29 | 33635B1A095493C0002C5F77 /* PBXContainerItemProxy */ = { 30 | isa = PBXContainerItemProxy; 31 | containerPortal = 33635B14095493BA002C5F77 /* mach_inject_bundle.xcodeproj */; 32 | proxyType = 1; 33 | remoteGlobalIDString = 8DC2EF4F0486A6940098B216; 34 | remoteInfo = mach_inject_bundle; 35 | }; 36 | 33635B20095493CB002C5F77 /* PBXContainerItemProxy */ = { 37 | isa = PBXContainerItemProxy; 38 | containerPortal = 33635B1C095493CB002C5F77 /* DisposeWindow+Beep.xcodeproj */; 39 | proxyType = 2; 40 | remoteGlobalIDString = 8D01CCD20486CAD60068D4B7; 41 | remoteInfo = "DisposeWindow+Beep"; 42 | }; 43 | 33635B22095493D4002C5F77 /* PBXContainerItemProxy */ = { 44 | isa = PBXContainerItemProxy; 45 | containerPortal = 33635B1C095493CB002C5F77 /* DisposeWindow+Beep.xcodeproj */; 46 | proxyType = 1; 47 | remoteGlobalIDString = 8D01CCC60486CAD60068D4B7; 48 | remoteInfo = "DisposeWindow+Beep"; 49 | }; 50 | /* End PBXContainerItemProxy section */ 51 | 52 | /* Begin PBXCopyFilesBuildPhase section */ 53 | 79ACCB1607FD4D4000D4147B /* CopyFiles */ = { 54 | isa = PBXCopyFilesBuildPhase; 55 | buildActionMask = 2147483647; 56 | dstPath = ""; 57 | dstSubfolderSpec = 10; 58 | files = ( 59 | 33635B2F09549461002C5F77 /* mach_inject_bundle.framework in CopyFiles */, 60 | ); 61 | runOnlyForDeploymentPostprocessing = 0; 62 | }; 63 | /* End PBXCopyFilesBuildPhase section */ 64 | 65 | /* Begin PBXFileReference section */ 66 | 089C165DFE840E0CC02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = ""; }; 67 | 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; 68 | 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 69 | 29B97319FDCFA39411CA2CEA /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/MainMenu.nib; sourceTree = ""; }; 70 | 29B97324FDCFA39411CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; 71 | 29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; 72 | 32CA4F630368D1EE00C91783 /* DisposeWindow+Beep_Injector_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "DisposeWindow+Beep_Injector_Prefix.pch"; sourceTree = ""; }; 73 | 33635B06095492BE002C5F77 /* mach_inject_bundle.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = mach_inject_bundle.framework; path = ../mach_inject_bundle/build/Development/mach_inject_bundle.framework; sourceTree = SOURCE_ROOT; }; 74 | 33635B14095493BA002C5F77 /* mach_inject_bundle.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = mach_inject_bundle.xcodeproj; path = ../mach_inject_bundle/mach_inject_bundle.xcodeproj; sourceTree = SOURCE_ROOT; }; 75 | 33635B1C095493CB002C5F77 /* DisposeWindow+Beep.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = "DisposeWindow+Beep.xcodeproj"; path = "../DisposeWindow+Beep/DisposeWindow+Beep.xcodeproj"; sourceTree = SOURCE_ROOT; }; 76 | 79ACCB1A07FD4D6300D4147B /* DisposeWindow+Beep.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; name = "DisposeWindow+Beep.bundle"; path = "../DisposeWindow+Beep/build/Development/DisposeWindow+Beep.bundle"; sourceTree = SOURCE_ROOT; }; 77 | 79ACCB2E07FD4DD100D4147B /* InjectorAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InjectorAppDelegate.h; sourceTree = ""; }; 78 | 79ACCB2F07FD4DD100D4147B /* InjectorAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InjectorAppDelegate.m; sourceTree = ""; }; 79 | 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; 80 | 8D1107320486CEB800E47090 /* DisposeWindow+Beep_Injector.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "DisposeWindow+Beep_Injector.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 81 | /* End PBXFileReference section */ 82 | 83 | /* Begin PBXFrameworksBuildPhase section */ 84 | 8D11072E0486CEB800E47090 /* Frameworks */ = { 85 | isa = PBXFrameworksBuildPhase; 86 | buildActionMask = 2147483647; 87 | files = ( 88 | 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */, 89 | 33635B07095492BE002C5F77 /* mach_inject_bundle.framework in Frameworks */, 90 | ); 91 | runOnlyForDeploymentPostprocessing = 0; 92 | }; 93 | /* End PBXFrameworksBuildPhase section */ 94 | 95 | /* Begin PBXGroup section */ 96 | 080E96DDFE201D6D7F000001 /* Classes */ = { 97 | isa = PBXGroup; 98 | children = ( 99 | 79ACCB2E07FD4DD100D4147B /* InjectorAppDelegate.h */, 100 | 79ACCB2F07FD4DD100D4147B /* InjectorAppDelegate.m */, 101 | ); 102 | name = Classes; 103 | sourceTree = ""; 104 | }; 105 | 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = { 106 | isa = PBXGroup; 107 | children = ( 108 | 33635B06095492BE002C5F77 /* mach_inject_bundle.framework */, 109 | 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */, 110 | ); 111 | name = "Linked Frameworks"; 112 | sourceTree = ""; 113 | }; 114 | 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */ = { 115 | isa = PBXGroup; 116 | children = ( 117 | 29B97325FDCFA39411CA2CEA /* Foundation.framework */, 118 | 29B97324FDCFA39411CA2CEA /* AppKit.framework */, 119 | ); 120 | name = "Other Frameworks"; 121 | sourceTree = ""; 122 | }; 123 | 19C28FACFE9D520D11CA2CBB /* Products */ = { 124 | isa = PBXGroup; 125 | children = ( 126 | 8D1107320486CEB800E47090 /* DisposeWindow+Beep_Injector.app */, 127 | ); 128 | name = Products; 129 | sourceTree = ""; 130 | }; 131 | 29B97314FDCFA39411CA2CEA /* DisposeWindow+Beep_Injector */ = { 132 | isa = PBXGroup; 133 | children = ( 134 | 33635B14095493BA002C5F77 /* mach_inject_bundle.xcodeproj */, 135 | 33635B1C095493CB002C5F77 /* DisposeWindow+Beep.xcodeproj */, 136 | 080E96DDFE201D6D7F000001 /* Classes */, 137 | 29B97315FDCFA39411CA2CEA /* Other Sources */, 138 | 29B97317FDCFA39411CA2CEA /* Resources */, 139 | 29B97323FDCFA39411CA2CEA /* Frameworks */, 140 | 19C28FACFE9D520D11CA2CBB /* Products */, 141 | ); 142 | name = "DisposeWindow+Beep_Injector"; 143 | sourceTree = ""; 144 | }; 145 | 29B97315FDCFA39411CA2CEA /* Other Sources */ = { 146 | isa = PBXGroup; 147 | children = ( 148 | 32CA4F630368D1EE00C91783 /* DisposeWindow+Beep_Injector_Prefix.pch */, 149 | 29B97316FDCFA39411CA2CEA /* main.m */, 150 | ); 151 | name = "Other Sources"; 152 | sourceTree = ""; 153 | }; 154 | 29B97317FDCFA39411CA2CEA /* Resources */ = { 155 | isa = PBXGroup; 156 | children = ( 157 | 79ACCB1A07FD4D6300D4147B /* DisposeWindow+Beep.bundle */, 158 | 8D1107310486CEB800E47090 /* Info.plist */, 159 | 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */, 160 | 29B97318FDCFA39411CA2CEA /* MainMenu.nib */, 161 | ); 162 | name = Resources; 163 | sourceTree = ""; 164 | }; 165 | 29B97323FDCFA39411CA2CEA /* Frameworks */ = { 166 | isa = PBXGroup; 167 | children = ( 168 | 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */, 169 | 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */, 170 | ); 171 | name = Frameworks; 172 | sourceTree = ""; 173 | }; 174 | 33635B15095493BA002C5F77 /* Products */ = { 175 | isa = PBXGroup; 176 | children = ( 177 | 33635B19095493BA002C5F77 /* mach_inject_bundle.framework */, 178 | ); 179 | name = Products; 180 | sourceTree = ""; 181 | }; 182 | 33635B1D095493CB002C5F77 /* Products */ = { 183 | isa = PBXGroup; 184 | children = ( 185 | 33635B21095493CB002C5F77 /* DisposeWindow+Beep.bundle */, 186 | ); 187 | name = Products; 188 | sourceTree = ""; 189 | }; 190 | /* End PBXGroup section */ 191 | 192 | /* Begin PBXNativeTarget section */ 193 | 8D1107260486CEB800E47090 /* DisposeWindow+Beep_Injector */ = { 194 | isa = PBXNativeTarget; 195 | buildConfigurationList = 33A73B340928584700F6FEA5 /* Build configuration list for PBXNativeTarget "DisposeWindow+Beep_Injector" */; 196 | buildPhases = ( 197 | 8D1107290486CEB800E47090 /* Resources */, 198 | 8D11072C0486CEB800E47090 /* Sources */, 199 | 8D11072E0486CEB800E47090 /* Frameworks */, 200 | 79ACCB1607FD4D4000D4147B /* CopyFiles */, 201 | ); 202 | buildRules = ( 203 | ); 204 | dependencies = ( 205 | 33635B1B095493C0002C5F77 /* PBXTargetDependency */, 206 | 33635B23095493D4002C5F77 /* PBXTargetDependency */, 207 | ); 208 | name = "DisposeWindow+Beep_Injector"; 209 | productInstallPath = "$(HOME)/Applications"; 210 | productName = "DisposeWindow+Beep_Injector"; 211 | productReference = 8D1107320486CEB800E47090 /* DisposeWindow+Beep_Injector.app */; 212 | productType = "com.apple.product-type.application"; 213 | }; 214 | /* End PBXNativeTarget section */ 215 | 216 | /* Begin PBXProject section */ 217 | 29B97313FDCFA39411CA2CEA /* Project object */ = { 218 | isa = PBXProject; 219 | buildConfigurationList = 33A73B380928584700F6FEA5 /* Build configuration list for PBXProject "DisposeWindow+Beep_Injector" */; 220 | compatibilityVersion = "Xcode 2.4"; 221 | developmentRegion = English; 222 | hasScannedForEncodings = 1; 223 | knownRegions = ( 224 | en, 225 | ); 226 | mainGroup = 29B97314FDCFA39411CA2CEA /* DisposeWindow+Beep_Injector */; 227 | projectDirPath = ""; 228 | projectReferences = ( 229 | { 230 | ProductGroup = 33635B1D095493CB002C5F77 /* Products */; 231 | ProjectRef = 33635B1C095493CB002C5F77 /* DisposeWindow+Beep.xcodeproj */; 232 | }, 233 | { 234 | ProductGroup = 33635B15095493BA002C5F77 /* Products */; 235 | ProjectRef = 33635B14095493BA002C5F77 /* mach_inject_bundle.xcodeproj */; 236 | }, 237 | ); 238 | projectRoot = ""; 239 | targets = ( 240 | 8D1107260486CEB800E47090 /* DisposeWindow+Beep_Injector */, 241 | ); 242 | }; 243 | /* End PBXProject section */ 244 | 245 | /* Begin PBXReferenceProxy section */ 246 | 33635B19095493BA002C5F77 /* mach_inject_bundle.framework */ = { 247 | isa = PBXReferenceProxy; 248 | fileType = wrapper.framework; 249 | path = mach_inject_bundle.framework; 250 | remoteRef = 33635B18095493BA002C5F77 /* PBXContainerItemProxy */; 251 | sourceTree = BUILT_PRODUCTS_DIR; 252 | }; 253 | 33635B21095493CB002C5F77 /* DisposeWindow+Beep.bundle */ = { 254 | isa = PBXReferenceProxy; 255 | fileType = wrapper.cfbundle; 256 | path = "DisposeWindow+Beep.bundle"; 257 | remoteRef = 33635B20095493CB002C5F77 /* PBXContainerItemProxy */; 258 | sourceTree = BUILT_PRODUCTS_DIR; 259 | }; 260 | /* End PBXReferenceProxy section */ 261 | 262 | /* Begin PBXResourcesBuildPhase section */ 263 | 8D1107290486CEB800E47090 /* Resources */ = { 264 | isa = PBXResourcesBuildPhase; 265 | buildActionMask = 2147483647; 266 | files = ( 267 | 8D11072A0486CEB800E47090 /* MainMenu.nib in Resources */, 268 | 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */, 269 | 79ACCB1B07FD4D6300D4147B /* DisposeWindow+Beep.bundle in Resources */, 270 | 79ACCB3007FD4DD100D4147B /* InjectorAppDelegate.h in Resources */, 271 | ); 272 | runOnlyForDeploymentPostprocessing = 0; 273 | }; 274 | /* End PBXResourcesBuildPhase section */ 275 | 276 | /* Begin PBXSourcesBuildPhase section */ 277 | 8D11072C0486CEB800E47090 /* Sources */ = { 278 | isa = PBXSourcesBuildPhase; 279 | buildActionMask = 2147483647; 280 | files = ( 281 | 8D11072D0486CEB800E47090 /* main.m in Sources */, 282 | 79ACCB3107FD4DD100D4147B /* InjectorAppDelegate.m in Sources */, 283 | ); 284 | runOnlyForDeploymentPostprocessing = 0; 285 | }; 286 | /* End PBXSourcesBuildPhase section */ 287 | 288 | /* Begin PBXTargetDependency section */ 289 | 33635B1B095493C0002C5F77 /* PBXTargetDependency */ = { 290 | isa = PBXTargetDependency; 291 | name = mach_inject_bundle; 292 | targetProxy = 33635B1A095493C0002C5F77 /* PBXContainerItemProxy */; 293 | }; 294 | 33635B23095493D4002C5F77 /* PBXTargetDependency */ = { 295 | isa = PBXTargetDependency; 296 | name = "DisposeWindow+Beep"; 297 | targetProxy = 33635B22095493D4002C5F77 /* PBXContainerItemProxy */; 298 | }; 299 | /* End PBXTargetDependency section */ 300 | 301 | /* Begin PBXVariantGroup section */ 302 | 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */ = { 303 | isa = PBXVariantGroup; 304 | children = ( 305 | 089C165DFE840E0CC02AAC07 /* English */, 306 | ); 307 | name = InfoPlist.strings; 308 | sourceTree = ""; 309 | }; 310 | 29B97318FDCFA39411CA2CEA /* MainMenu.nib */ = { 311 | isa = PBXVariantGroup; 312 | children = ( 313 | 29B97319FDCFA39411CA2CEA /* English */, 314 | ); 315 | name = MainMenu.nib; 316 | sourceTree = ""; 317 | }; 318 | /* End PBXVariantGroup section */ 319 | 320 | /* Begin XCBuildConfiguration section */ 321 | 33A73B350928584700F6FEA5 /* Development */ = { 322 | isa = XCBuildConfiguration; 323 | buildSettings = { 324 | ARCHS = "$(ARCHS_STANDARD_64_BIT_PRE_XCODE_3_1)"; 325 | ARCHS_STANDARD_64_BIT_PRE_XCODE_3_1 = x86_64; 326 | COPY_PHASE_STRIP = NO; 327 | FRAMEWORK_SEARCH_PATHS = ( 328 | "$(SRCROOT)/../mach_inject_bundle/build/Development", 329 | "$(SRCROOT)/../mach_inject_bundle/build/Deployment", 330 | ); 331 | GCC_DYNAMIC_NO_PIC = NO; 332 | GCC_ENABLE_FIX_AND_CONTINUE = YES; 333 | GCC_GENERATE_DEBUGGING_SYMBOLS = YES; 334 | GCC_OPTIMIZATION_LEVEL = 0; 335 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 336 | GCC_PREFIX_HEADER = "DisposeWindow+Beep_Injector_Prefix.pch"; 337 | INFOPLIST_FILE = Info.plist; 338 | INSTALL_PATH = "$(HOME)/Applications"; 339 | PRODUCT_NAME = "DisposeWindow+Beep_Injector"; 340 | WRAPPER_EXTENSION = app; 341 | ZERO_LINK = YES; 342 | }; 343 | name = Development; 344 | }; 345 | 33A73B360928584700F6FEA5 /* Deployment */ = { 346 | isa = XCBuildConfiguration; 347 | buildSettings = { 348 | COPY_PHASE_STRIP = YES; 349 | FRAMEWORK_SEARCH_PATHS = ( 350 | "$(SRCROOT)/../mach_inject_bundle/build/Development", 351 | "$(SRCROOT)/../mach_inject_bundle/build/Deployment", 352 | ); 353 | GCC_ENABLE_FIX_AND_CONTINUE = NO; 354 | GCC_GENERATE_DEBUGGING_SYMBOLS = NO; 355 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 356 | GCC_PREFIX_HEADER = "DisposeWindow+Beep_Injector_Prefix.pch"; 357 | INFOPLIST_FILE = Info.plist; 358 | INSTALL_PATH = "$(HOME)/Applications"; 359 | PRODUCT_NAME = "DisposeWindow+Beep_Injector"; 360 | WRAPPER_EXTENSION = app; 361 | ZERO_LINK = NO; 362 | }; 363 | name = Deployment; 364 | }; 365 | 33A73B370928584700F6FEA5 /* Default */ = { 366 | isa = XCBuildConfiguration; 367 | buildSettings = { 368 | FRAMEWORK_SEARCH_PATHS = ( 369 | "$(SRCROOT)/../mach_inject_bundle/build/Development", 370 | "$(SRCROOT)/../mach_inject_bundle/build/Deployment", 371 | ); 372 | GCC_GENERATE_DEBUGGING_SYMBOLS = NO; 373 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 374 | GCC_PREFIX_HEADER = "DisposeWindow+Beep_Injector_Prefix.pch"; 375 | INFOPLIST_FILE = Info.plist; 376 | INSTALL_PATH = "$(HOME)/Applications"; 377 | PRODUCT_NAME = "DisposeWindow+Beep_Injector"; 378 | WRAPPER_EXTENSION = app; 379 | }; 380 | name = Default; 381 | }; 382 | 33A73B390928584700F6FEA5 /* Development */ = { 383 | isa = XCBuildConfiguration; 384 | buildSettings = { 385 | }; 386 | name = Development; 387 | }; 388 | 33A73B3A0928584700F6FEA5 /* Deployment */ = { 389 | isa = XCBuildConfiguration; 390 | buildSettings = { 391 | }; 392 | name = Deployment; 393 | }; 394 | 33A73B3B0928584700F6FEA5 /* Default */ = { 395 | isa = XCBuildConfiguration; 396 | buildSettings = { 397 | }; 398 | name = Default; 399 | }; 400 | /* End XCBuildConfiguration section */ 401 | 402 | /* Begin XCConfigurationList section */ 403 | 33A73B340928584700F6FEA5 /* Build configuration list for PBXNativeTarget "DisposeWindow+Beep_Injector" */ = { 404 | isa = XCConfigurationList; 405 | buildConfigurations = ( 406 | 33A73B350928584700F6FEA5 /* Development */, 407 | 33A73B360928584700F6FEA5 /* Deployment */, 408 | 33A73B370928584700F6FEA5 /* Default */, 409 | ); 410 | defaultConfigurationIsVisible = 0; 411 | defaultConfigurationName = Default; 412 | }; 413 | 33A73B380928584700F6FEA5 /* Build configuration list for PBXProject "DisposeWindow+Beep_Injector" */ = { 414 | isa = XCConfigurationList; 415 | buildConfigurations = ( 416 | 33A73B390928584700F6FEA5 /* Development */, 417 | 33A73B3A0928584700F6FEA5 /* Deployment */, 418 | 33A73B3B0928584700F6FEA5 /* Default */, 419 | ); 420 | defaultConfigurationIsVisible = 0; 421 | defaultConfigurationName = Default; 422 | }; 423 | /* End XCConfigurationList section */ 424 | }; 425 | rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; 426 | } 427 | -------------------------------------------------------------------------------- /mach_inject/DisposeWindow+Beep_Injector/DisposeWindow+Beep_Injector_Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'DisposeWindow+Beep_Injector' target in the 'DisposeWindow+Beep_Injector' project 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | -------------------------------------------------------------------------------- /mach_inject/DisposeWindow+Beep_Injector/English.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zerodivisi0n/FinderMenu/d65aac3e98e75924c9efa0fae48b02bbc0928e53/mach_inject/DisposeWindow+Beep_Injector/English.lproj/InfoPlist.strings -------------------------------------------------------------------------------- /mach_inject/DisposeWindow+Beep_Injector/English.lproj/MainMenu.nib/classes.nib: -------------------------------------------------------------------------------- 1 | { 2 | IBClasses = ( 3 | {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, 4 | {CLASS = Injector; LANGUAGE = ObjC; SUPERCLASS = NSObject; } 5 | ); 6 | IBVersion = 1; 7 | } -------------------------------------------------------------------------------- /mach_inject/DisposeWindow+Beep_Injector/English.lproj/MainMenu.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBDocumentLocation 6 | 25 67 356 240 0 0 1280 832 7 | IBEditorPositions 8 | 9 | 29 10 | 27 318 318 44 0 0 1280 832 11 | 12 | IBFramework Version 13 | 364.0 14 | IBOpenObjects 15 | 16 | 29 17 | 18 | IBSystem Version 19 | 7S215 20 | 21 | 22 | -------------------------------------------------------------------------------- /mach_inject/DisposeWindow+Beep_Injector/English.lproj/MainMenu.nib/objects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zerodivisi0n/FinderMenu/d65aac3e98e75924c9efa0fae48b02bbc0928e53/mach_inject/DisposeWindow+Beep_Injector/English.lproj/MainMenu.nib/objects.nib -------------------------------------------------------------------------------- /mach_inject/DisposeWindow+Beep_Injector/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | DisposeWindow+Beep_Injector 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | com.apple.myCocoaApp 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundlePackageType 16 | APPL 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1.0 21 | NSMainNibFile 22 | MainMenu 23 | NSPrincipalClass 24 | NSApplication 25 | 26 | 27 | -------------------------------------------------------------------------------- /mach_inject/DisposeWindow+Beep_Injector/InjectorAppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface Injector : NSObject {} 4 | @end 5 | -------------------------------------------------------------------------------- /mach_inject/DisposeWindow+Beep_Injector/InjectorAppDelegate.m: -------------------------------------------------------------------------------- 1 | #import "InjectorAppDelegate.h" 2 | #import 3 | 4 | @implementation Injector 5 | 6 | static 7 | OSErr 8 | FindProcessBySignature( 9 | OSType type, 10 | OSType creator, 11 | ProcessSerialNumber *psn ) 12 | { 13 | ProcessSerialNumber tempPSN = { 0, kNoProcess }; 14 | ProcessInfoRec procInfo; 15 | OSErr err = noErr; 16 | 17 | procInfo.processInfoLength = sizeof( ProcessInfoRec ); 18 | procInfo.processName = nil; 19 | //procInfo.processAppSpec = nil; 20 | 21 | while( !err ) { 22 | err = GetNextProcess( &tempPSN ); 23 | if( !err ) 24 | err = GetProcessInformation( &tempPSN, &procInfo ); 25 | if( !err 26 | && procInfo.processType == type 27 | && procInfo.processSignature == creator ) { 28 | *psn = tempPSN; 29 | return noErr; 30 | } 31 | } 32 | 33 | return err; 34 | } 35 | 36 | - (void)applicationDidFinishLaunching:(NSNotification*)notification_ { 37 | NSString *bundlePath = [[NSBundle mainBundle] 38 | pathForResource:@"DisposeWindow+Beep" ofType:@"bundle"]; 39 | 40 | // Find target by signature. 41 | ProcessSerialNumber psn; 42 | FindProcessBySignature( 'FNDR', 'MACS', &psn ); 43 | 44 | // Convert PSN to PID. 45 | pid_t pid; 46 | GetProcessPID( &psn, &pid ); 47 | 48 | printf("pid %d\n", pid); 49 | mach_error_t err = mach_inject_bundle_pid( 50 | [bundlePath fileSystemRepresentation], pid ); 51 | mach_error("shit", err); 52 | NSLog( @"err = %d", err ); 53 | [NSApp terminate:nil]; 54 | } 55 | 56 | @end -------------------------------------------------------------------------------- /mach_inject/DisposeWindow+Beep_Injector/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // DisposeWindow+Beep_Injector 4 | // 5 | // Created by Jonathan 'Wolf' Rentzsch on 4/1/05. 6 | // Copyright __MyCompanyName__ 2005. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, char *argv[]) 12 | { 13 | return NSApplicationMain(argc, (const char **) argv); 14 | } 15 | -------------------------------------------------------------------------------- /mach_inject/DisposeWindow+Beep_Injector/version.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildVersion 6 | 92 7 | CFBundleVersion 8 | 1.0 9 | ProductBuildVersion 10 | 7K571 11 | ProjectName 12 | NibPBTemplates 13 | SourceVersion 14 | 1200000 15 | 16 | 17 | -------------------------------------------------------------------------------- /mach_inject/README.markdown: -------------------------------------------------------------------------------- 1 | ## Description 2 | 3 | mach_inject enables you to "inject" code into an arbitrary process on Mac OS X. "Injection" means both 1) copying over the necessary code into the target's address space and 2) remotely creating a new thread to execute the code. 4 | 5 | ## Must Be This Tall To Ride 6 | 7 | Code injection is tricky business. You should be familiar with assembly and runtime calling conventions (ABIs) before using mach_inject. 8 | 9 | mach_inject is certainly not bug free and patches are extremely welcome, but the onus is on you when things don't work. Please don't file a bug report stating mach_inject is crashing for you when you try to use it -- you have to be hard-core enough to debug the problem yourself. 10 | 11 | ## Contributing 12 | 13 | Please base your work off the unstable branch. Then submit your Pull Request. 14 | 15 | ## Version History 16 | 17 | ### mach_inject 1.2: Aug 10 2012 18 | 19 | * [NEW] i386 and x86_64 support. 20 | 21 | * [CHANGE] Decoupled from mach_star. Most of folks were just using the side or the other of mach_star and this simplifies things (docs, tests). 22 | 23 | ### mach_star 1.1.1 Dec 18 2005 24 | 25 | * General Xcode 2.2 project cleanup. mach_star now includes `.xcodeproj` Xcode 2.2 project files for all of its projects. The old `.xcode` project files have been left in place, but they aren't maintained and may not work. Xcode 2.2 is the recommended mach_star development environment -- Xcode 2.1 had a bug with inter-project dependancies which would cause compilation failure. It works now again in Xcode 2.2. 26 | 27 | * Inter-project dependancies should working under Xcode 2.2. Any project you pick, you should just be able to hit the "Build" button and everything should Just Work™. 28 | 29 | * There was a stray reference to my username in one of the project, which causes compilation headaches for some folks. 30 | 31 | * Bug fix: in `mach_inject_bundle.c`'s `mach_inject_bundle_pid()` I no longer call `CFRelease()` on the framework bundle reference. Reported by Scott Kevill. 32 | 33 | * Added some explicit casts now required by gcc 4. 34 | 35 | * Added this document. 36 | 37 | ### mach_star 1.1: Apr 06 2005 38 | 39 | * New package added: `mach_inject_bundle`. It has a private subproject: `mach_inject_bundle_stub`. The stub is a generic reusable implementation of the code that gets squirted across the address spaces, which was always tricky to write. `mach_inject_bundle` is an embeddable framework that wraps `mach_inject` and the stub with a simple fire-and-forget API. 40 | 41 | * The "DisposeWindowBeeperOverride" example is replaced by "DisposeWindow+Beep". 42 | 43 | * The "FinderDisposeWindowBeeperInjector" is replaced by "DisposeWindow+Beep_Injector". 44 | 45 | * All the text is now wrapped to 80 chars wide. Done to print nicely in Scott Knaster's [Hacking Mac OS X Tiger](http://www.amazon.com/exec/obidos/ASIN/076458345X). Probably will undo this word-wrap in the future. We all have widescreens nowadays, right? ;-) 46 | 47 | * Thanks to Jon Gotow for letting me peek at `SCPatch`, which I used as a guide for `mach_inject_bundle`. It saved me a bunch of time. Also thanks to Bob Ippolito for `CALL_ON_LOAD` assistance. 48 | 49 | ### mach_star 1.0: Jun 18 2003 50 | 51 | * Initial release at MacHack 2003. -------------------------------------------------------------------------------- /mach_inject/mach_inject/mach_inject.c: -------------------------------------------------------------------------------- 1 | // mach_inject.c semver:1.2.0 2 | // Copyright (c) 2003-2012 Jonathan 'Wolf' Rentzsch: http://rentzsch.com 3 | // Some rights reserved: http://opensource.org/licenses/mit 4 | // https://github.com/rentzsch/mach_inject 5 | 6 | #include "mach_inject.h" 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include // for malloc() 15 | #include // for printf() 16 | #include // for fat structure decoding 17 | #include // to know which is local arch 18 | #include // for open/close 19 | // for mmap() 20 | #include 21 | #include 22 | 23 | #ifndef COMPILE_TIME_ASSERT( exp ) 24 | #define COMPILE_TIME_ASSERT( exp ) { switch (0) { case 0: case (exp):; } } 25 | #endif 26 | #define ASSERT_CAST( CAST_TO, CAST_FROM ) \ 27 | COMPILE_TIME_ASSERT( sizeof(CAST_TO)==sizeof(CAST_FROM) ) 28 | 29 | #if defined(__i386__) 30 | void* fixedUpImageFromImage ( 31 | const void *image, 32 | unsigned long imageSize, 33 | unsigned int jumpTableOffset, 34 | unsigned int jumpTableSize, 35 | ptrdiff_t fixUpOffset); 36 | #endif /* __i386__ */ 37 | 38 | #include 39 | #define MACH_ERROR(msg, err) { if(err != err_none) mach_error(msg, err); } 40 | 41 | /******************************************************************************* 42 | * 43 | * Interface 44 | * 45 | *******************************************************************************/ 46 | #pragma mark - 47 | #pragma mark (Interface) 48 | 49 | mach_error_t 50 | mach_inject( 51 | const mach_inject_entry threadEntry, 52 | const void *paramBlock, 53 | size_t paramSize, 54 | pid_t targetProcess, 55 | vm_size_t stackSize ) 56 | { 57 | assert( threadEntry ); 58 | assert( targetProcess > 0 ); 59 | assert( stackSize == 0 || stackSize > 1024 ); 60 | 61 | // Find the image. 62 | const void *image; 63 | unsigned long imageSize; 64 | unsigned int jumpTableOffset; 65 | unsigned int jumpTableSize; 66 | mach_error_t err = machImageForPointer( threadEntry, &image, &imageSize, &jumpTableOffset, &jumpTableSize ); 67 | //fprintf(stderr, "mach_inject: found threadEntry image at: %p with size: %lu\n", image, imageSize); 68 | 69 | // Initialize stackSize to default if requested. 70 | if( stackSize == 0 ) 71 | /** @bug 72 | We only want an 8K default, fix the plop-in-the-middle code below. 73 | */ 74 | stackSize = 16 * 1024; 75 | 76 | // Convert PID to Mach Task ref. 77 | mach_port_t remoteTask = 0; 78 | if( !err ) { 79 | err = task_for_pid( mach_task_self(), targetProcess, &remoteTask ); 80 | #if defined(__i386__) || defined(__x86_64__) 81 | if (err == 5) fprintf(stderr, "Could not access task for pid %d. You probably need to add user to procmod group\n", targetProcess); 82 | #endif 83 | } 84 | 85 | /** @todo 86 | Would be nice to just allocate one block for both the remote stack 87 | *and* the remoteCode (including the parameter data block once that's 88 | written. 89 | */ 90 | 91 | // Allocate the remoteStack. 92 | vm_address_t remoteStack = (vm_address_t)NULL; 93 | if( !err ) 94 | err = vm_allocate( remoteTask, &remoteStack, stackSize, 1 ); 95 | 96 | 97 | // Allocate the code. 98 | vm_address_t remoteCode = (vm_address_t)NULL; 99 | if( !err ) 100 | err = vm_allocate( remoteTask, &remoteCode, imageSize, 1 ); 101 | err = vm_protect(remoteTask, remoteCode, imageSize, 0, VM_PROT_EXECUTE | VM_PROT_WRITE | VM_PROT_READ); 102 | if( !err ) { 103 | ASSERT_CAST( pointer_t, image ); 104 | #if defined (__ppc__) || defined (__ppc64__) || defined(__x86_64__) 105 | err = vm_write( remoteTask, remoteCode, (pointer_t) image, imageSize ); 106 | #elif defined (__i386__) 107 | // on x86, jump table use relative jump instructions (jmp), which means 108 | // the offset needs to be corrected. We thus copy the image and fix the offset by hand. 109 | ptrdiff_t fixUpOffset = (ptrdiff_t) (image - remoteCode); 110 | void * fixedUpImage = fixedUpImageFromImage(image, imageSize, jumpTableOffset, jumpTableSize, fixUpOffset); 111 | err = vm_write( remoteTask, remoteCode, (pointer_t) fixedUpImage, imageSize ); 112 | free(fixedUpImage); 113 | #endif 114 | } 115 | 116 | // Allocate the paramBlock if specified. 117 | vm_address_t remoteParamBlock = (vm_address_t)NULL; 118 | if( !err && paramBlock != NULL && paramSize ) { 119 | err = vm_allocate( remoteTask, &remoteParamBlock, paramSize, 1 ); 120 | if( !err ) { 121 | ASSERT_CAST( pointer_t, paramBlock ); 122 | err = vm_write( remoteTask, remoteParamBlock, 123 | (pointer_t) paramBlock, paramSize ); 124 | } 125 | } 126 | 127 | // Calculate offsets. 128 | ptrdiff_t threadEntryOffset, imageOffset; 129 | if( !err ) { 130 | //assert( (void*)threadEntry >= image && (void*)threadEntry <= (image+imageSize) ); 131 | ASSERT_CAST( void*, threadEntry ); 132 | threadEntryOffset = ((void*) threadEntry) - image; 133 | 134 | #if defined(__x86_64__) 135 | imageOffset = 0; // RIP-relative addressing 136 | #else 137 | //ASSERT_CAST( void*, remoteCode ); 138 | //imageOffset = ((void*) remoteCode) - image; 139 | // WARNING: See bug https://github.com/rentzsch/mach_star/issues/11 . Not sure about this. 140 | imageOffset = 0; 141 | #endif 142 | } 143 | 144 | // Allocate the thread. 145 | thread_act_t remoteThread; 146 | #if defined (__ppc__) || defined (__ppc64__) 147 | if( !err ) { 148 | ppc_thread_state_t remoteThreadState; 149 | 150 | /** @bug 151 | Stack math should be more sophisticated than this (ala redzone). 152 | */ 153 | remoteStack += stackSize / 2; 154 | 155 | bzero( &remoteThreadState, sizeof(remoteThreadState) ); 156 | 157 | ASSERT_CAST( unsigned int, remoteCode ); 158 | remoteThreadState.__srr0 = (unsigned int) remoteCode; 159 | remoteThreadState.__srr0 += threadEntryOffset; 160 | assert( remoteThreadState.__srr0 < (remoteCode + imageSize) ); 161 | 162 | ASSERT_CAST( unsigned int, remoteStack ); 163 | remoteThreadState.__r1 = (unsigned int) remoteStack; 164 | 165 | ASSERT_CAST( unsigned int, imageOffset ); 166 | remoteThreadState.__r3 = (unsigned int) imageOffset; 167 | 168 | ASSERT_CAST( unsigned int, remoteParamBlock ); 169 | remoteThreadState.__r4 = (unsigned int) remoteParamBlock; 170 | 171 | ASSERT_CAST( unsigned int, paramSize ); 172 | remoteThreadState.__r5 = (unsigned int) paramSize; 173 | 174 | ASSERT_CAST( unsigned int, 0xDEADBEEF ); 175 | remoteThreadState.__lr = (unsigned int) 0xDEADBEEF; 176 | 177 | #if 0 178 | printf( "remoteCode start: %p\n", (void*) remoteCode ); 179 | printf( "remoteCode size: %ld\n", imageSize ); 180 | printf( "remoteCode pc: %p\n", (void*) remoteThreadState.srr0 ); 181 | printf( "remoteCode end: %p\n", 182 | (void*) (((char*)remoteCode)+imageSize) ); 183 | fflush(0); 184 | #endif 185 | 186 | err = thread_create_running( remoteTask, PPC_THREAD_STATE, 187 | (thread_state_t) &remoteThreadState, PPC_THREAD_STATE_COUNT, 188 | &remoteThread ); 189 | } 190 | #elif defined (__i386__) 191 | if( !err ) { 192 | 193 | i386_thread_state_t remoteThreadState; 194 | bzero( &remoteThreadState, sizeof(remoteThreadState) ); 195 | 196 | vm_address_t dummy_thread_struct = remoteStack; 197 | remoteStack += (stackSize / 2); // this is the real stack 198 | // (*) increase the stack, since we're simulating a CALL instruction, which normally pushes return address on the stack 199 | remoteStack -= 4; 200 | 201 | #define PARAM_COUNT 4 202 | #define STACK_CONTENTS_SIZE ((1+PARAM_COUNT) * sizeof(unsigned int)) 203 | unsigned int stackContents[1 + PARAM_COUNT]; // 1 for the return address and 1 for each param 204 | // first entry is return address (see above *) 205 | stackContents[0] = 0xDEADBEEF; // invalid return address. 206 | // then we push function parameters one by one. 207 | stackContents[1] = imageOffset; 208 | stackContents[2] = remoteParamBlock; 209 | stackContents[3] = paramSize; 210 | // We use the remote stack we allocated as the fake thread struct. We should probably use a dedicated memory zone. 211 | // We don't fill it with 0, vm_allocate did it for us 212 | stackContents[4] = dummy_thread_struct; 213 | 214 | // push stackContents 215 | err = vm_write( remoteTask, remoteStack, 216 | (pointer_t) stackContents, STACK_CONTENTS_SIZE); 217 | 218 | // set remote Program Counter 219 | remoteThreadState.__eip = (unsigned int) (remoteCode); 220 | remoteThreadState.__eip += threadEntryOffset; 221 | 222 | // set remote Stack Pointer 223 | ASSERT_CAST( unsigned int, remoteStack ); 224 | remoteThreadState.__esp = (unsigned int) remoteStack; 225 | 226 | // create thread and launch it 227 | err = thread_create_running( remoteTask, i386_THREAD_STATE, 228 | (thread_state_t) &remoteThreadState, i386_THREAD_STATE_COUNT, 229 | &remoteThread ); 230 | } 231 | #elif defined(__x86_64__) 232 | if( !err ) { 233 | 234 | x86_thread_state64_t remoteThreadState; 235 | bzero( &remoteThreadState, sizeof(remoteThreadState) ); 236 | 237 | vm_address_t dummy_thread_struct = remoteStack; 238 | remoteStack += (stackSize / 2); // this is the real stack 239 | // (*) increase the stack, since we're simulating a CALL instruction, which normally pushes return address on the stack 240 | remoteStack -= 8; 241 | 242 | #define PARAM_COUNT 0 243 | #define STACK_CONTENTS_SIZE ((1+PARAM_COUNT) * sizeof(unsigned long long)) 244 | unsigned long long stackContents[1 + PARAM_COUNT]; // 1 for the return address and 1 for each param 245 | // first entry is return address (see above *) 246 | stackContents[0] = 0x00000DEADBEA7DAD; // invalid return address. 247 | 248 | // push stackContents 249 | err = vm_write( remoteTask, remoteStack, 250 | (pointer_t) stackContents, STACK_CONTENTS_SIZE); 251 | 252 | remoteThreadState.__rdi = (unsigned long long) (imageOffset); 253 | remoteThreadState.__rsi = (unsigned long long) (remoteParamBlock); 254 | remoteThreadState.__rdx = (unsigned long long) (paramSize); 255 | remoteThreadState.__rcx = (unsigned long long) (dummy_thread_struct); 256 | 257 | // set remote Program Counter 258 | remoteThreadState.__rip = (unsigned long long) (remoteCode); 259 | remoteThreadState.__rip += threadEntryOffset; 260 | 261 | // set remote Stack Pointer 262 | ASSERT_CAST( unsigned long long, remoteStack ); 263 | remoteThreadState.__rsp = (unsigned long long) remoteStack; 264 | 265 | // create thread and launch it 266 | err = thread_create_running( remoteTask, x86_THREAD_STATE64, 267 | (thread_state_t) &remoteThreadState, x86_THREAD_STATE64_COUNT, 268 | &remoteThread ); 269 | } 270 | #else 271 | #error architecture not supported 272 | #endif 273 | 274 | if( err ) { 275 | MACH_ERROR("mach_inject failing..", err); 276 | if( remoteParamBlock ) 277 | vm_deallocate( remoteTask, remoteParamBlock, paramSize ); 278 | if( remoteCode ) 279 | vm_deallocate( remoteTask, remoteCode, imageSize ); 280 | if( remoteStack ) 281 | vm_deallocate( remoteTask, remoteStack, stackSize ); 282 | } 283 | 284 | return err; 285 | } 286 | 287 | mach_error_t 288 | machImageForPointer( 289 | const void *pointer, 290 | const void **image, 291 | unsigned long *size, 292 | unsigned int *jumpTableOffset, 293 | unsigned int *jumpTableSize ) 294 | { 295 | assert( pointer ); 296 | assert( image ); 297 | assert( size ); 298 | 299 | unsigned long p = (unsigned long) pointer; 300 | 301 | if (jumpTableOffset && jumpTableSize) { 302 | *jumpTableOffset = 0; 303 | *jumpTableSize = 0; 304 | } 305 | 306 | unsigned long imageIndex, imageCount = _dyld_image_count(); 307 | for( imageIndex = 0; imageIndex < imageCount; imageIndex++ ) { 308 | #if defined(__x86_64__) 309 | const struct mach_header_64 *header = (const struct mach_header_64 *)_dyld_get_image_header( imageIndex ); // why no function that returns mach_header_64 310 | const struct section_64 *section = getsectbynamefromheader_64( header, SEG_TEXT, SECT_TEXT ); 311 | #else 312 | const struct mach_header *header = (const struct mach_header *)_dyld_get_image_header( imageIndex ); 313 | const struct section *section = getsectbynamefromheader( header, SEG_TEXT, SECT_TEXT ); 314 | #endif 315 | if (section == 0) continue; 316 | long start = section->addr + _dyld_get_image_vmaddr_slide( imageIndex ); 317 | long stop = start + section->size; 318 | //printf("start %ld %p %s b\n", start, header, _dyld_get_image_name(imageIndex)); 319 | if( p >= start && p <= stop ) { 320 | // It is truely insane we have to stat() the file system in order 321 | // to discover the size of an in-memory data structure. 322 | const char *imageName = _dyld_get_image_name( imageIndex ); 323 | assert( imageName ); 324 | struct stat sb; 325 | if( stat( imageName, &sb ) ) 326 | return unix_err( errno ); 327 | if( image ) { 328 | ASSERT_CAST( void*, header ); 329 | *image = (void*) header; 330 | } 331 | if( size ) { 332 | ;//assertUInt32( st_size ); 333 | *size = sb.st_size; 334 | 335 | // needed for Universal binaries. Check if file is fat and get image size from there. 336 | int fd = open (imageName, O_RDONLY); 337 | size_t mapSize = *size; 338 | char * fileImage = mmap (NULL, mapSize, PROT_READ, MAP_FILE|MAP_SHARED, fd, 0); 339 | 340 | assert(fileImage != MAP_FAILED); 341 | struct fat_header* fatHeader = (struct fat_header *)fileImage; 342 | if (fatHeader->magic == OSSwapBigToHostInt32(FAT_MAGIC)) { 343 | //printf("This is a fat binary\n"); 344 | uint32_t archCount = OSSwapBigToHostInt32(fatHeader->nfat_arch); 345 | 346 | NXArchInfo const *localArchInfo = NXGetLocalArchInfo(); 347 | 348 | struct fat_arch* arch = (struct fat_arch *)(fileImage + sizeof(struct fat_header)); 349 | struct fat_arch* matchingArch = NULL; 350 | 351 | int archIndex = 0; 352 | for (archIndex = 0; archIndex < archCount; archIndex++) { 353 | cpu_type_t cpuType = OSSwapBigToHostInt32(arch[archIndex].cputype); 354 | cpu_subtype_t cpuSubtype = OSSwapBigToHostInt32(arch[archIndex].cpusubtype); 355 | 356 | if (localArchInfo->cputype == cpuType) { 357 | matchingArch = arch + archIndex; 358 | if (localArchInfo->cpusubtype == cpuSubtype) break; 359 | } 360 | } 361 | 362 | if (matchingArch) { 363 | *size = OSSwapBigToHostInt32(matchingArch->size); 364 | //printf ("found arch-specific size : %p\n", *size); 365 | } 366 | } 367 | 368 | munmap (fileImage, mapSize); 369 | close (fd); 370 | } 371 | #if defined(__i386__) // this segment is only available on IA-32 372 | if (jumpTableOffset && jumpTableSize) { 373 | const struct section * jumpTableSection = getsectbynamefromheader( header, SEG_IMPORT, "__jump_table" ); 374 | 375 | if (!jumpTableSection) { 376 | unsigned char *start, *end; 377 | jumpTableSection = getsectbynamefromheader( header, SEG_TEXT, "__symbol_stub" ); 378 | /* 379 | start = end = (char *) header + jumpTableSection->offset; 380 | end += jumpTableSection->size; 381 | 382 | fprintf(stderr, "start: %p\n", start); 383 | for (; start < end; start += 6) { 384 | fprintf(stderr, "%p: %p: %p\n", 385 | start, 386 | *(void **)(start+2), 387 | **(void ***)(start+2)); 388 | } 389 | */ 390 | } 391 | 392 | if (jumpTableSection) { 393 | *jumpTableOffset = jumpTableSection->offset; 394 | *jumpTableSize = jumpTableSection->size; 395 | } 396 | } 397 | #endif 398 | return err_none; 399 | } 400 | } 401 | 402 | return err_threadEntry_image_not_found; 403 | } 404 | 405 | #if defined(__i386__) 406 | void* fixedUpImageFromImage ( 407 | const void *image, 408 | unsigned long imageSize, 409 | unsigned int jumpTableOffset, 410 | unsigned int jumpTableSize, 411 | ptrdiff_t fixUpOffset) 412 | { 413 | // first copy the full image 414 | void *fixedUpImage = (void *) malloc ((size_t)imageSize); 415 | bcopy(image, fixedUpImage, imageSize); 416 | 417 | // address of jump table in copied image 418 | void *jumpTable = fixedUpImage + jumpTableOffset; 419 | 420 | 421 | /* indirect jump table */ 422 | if (*(unsigned char *) jumpTable == 0xff) { 423 | // each indirect JMP instruction is 6 bytes (FF xx xx xx xx xx) where FF is the opcode for JMP 424 | int jumpTableCount = jumpTableSize / 6; 425 | 426 | // skip first "ff xx" 427 | jumpTable += 2; 428 | 429 | int entry=0; 430 | for (entry = 0; entry < jumpTableCount; entry++) { 431 | void *jmpValue = *((void **)jumpTable); 432 | /* 433 | fprintf(stderr, "at %p correcting %p to %p\n", 434 | (char *)jumpTable -2, 435 | jmpValue, jmpValue + fixUpOffset); 436 | */ 437 | jmpValue -= fixUpOffset; 438 | *((void **)jumpTable) = jmpValue; 439 | jumpTable+=6; 440 | } 441 | } 442 | else { 443 | // each JMP instruction is 5 bytes (E9 xx xx xx xx) where E9 is the opcode for JMP 444 | int jumpTableCount = jumpTableSize / 5; 445 | 446 | // skip first "E9" 447 | jumpTable++; 448 | 449 | int entry=0; 450 | for (entry = 0; entry < jumpTableCount; entry++) { 451 | unsigned int jmpValue = *((unsigned int *)jumpTable); 452 | jmpValue += fixUpOffset; 453 | *((unsigned int *)jumpTable) = jmpValue; 454 | jumpTable+=5; 455 | } 456 | } 457 | 458 | return fixedUpImage; 459 | } 460 | #endif /* __i386__ */ 461 | -------------------------------------------------------------------------------- /mach_inject/mach_inject/mach_inject.h: -------------------------------------------------------------------------------- 1 | // mach_inject.h semver:1.2.0 2 | // Copyright (c) 2003-2012 Jonathan 'Wolf' Rentzsch: http://rentzsch.com 3 | // Some rights reserved: http://opensource.org/licenses/mit 4 | // https://github.com/rentzsch/mach_inject 5 | 6 | #ifndef _mach_inject_ 7 | #define _mach_inject_ 8 | 9 | #include 10 | #include 11 | #include 12 | #include // for ptrdiff_t 13 | 14 | #define err_threadEntry_image_not_found (err_local|1) 15 | 16 | #define INJECT_ENTRY injectEntry 17 | #define INJECT_ENTRY_SYMBOL "injectEntry" 18 | 19 | typedef void (*mach_inject_entry)( ptrdiff_t codeOffset, void *paramBlock, 20 | size_t paramSize, void* dummy_pthread_data ); 21 | 22 | __BEGIN_DECLS 23 | 24 | /******************************************************************************* 25 | Starts executing threadEntry in a new thread in the process specified by 26 | targetProcess. 27 | 28 | @param threadEntry -> Required pointer to injected thread's entry 29 | point. 30 | @param paramBlock -> Optional pointer to block of memory to pass to 31 | the injected thread. 32 | @param paramSize -> Optional size of paramBlock. 33 | @param targetProcess -> Required target process ID. 34 | @param stackSize -> Optional stack size of threadEntry's thread. Set 35 | to zero for default (currently 8K usable). 36 | @result <- mach_error_t 37 | 38 | ***************************************************************************/ 39 | 40 | mach_error_t 41 | mach_inject( 42 | const mach_inject_entry threadEntry, 43 | const void *paramBlock, 44 | size_t paramSize, 45 | pid_t targetProcess, 46 | vm_size_t stackSize ); 47 | 48 | /******************************************************************************* 49 | Given a pointer, returns its Mach-O image and image size. 50 | 51 | @param pointer -> Required pointer. 52 | @param image <- Optional returned pointer to image (really a 53 | mach_header). 54 | @param size <- Optional returned size of the image. 55 | @param jumpTableOffset <- Optional returned offset of jump table within image (useful on intel) 56 | @param jumpTableSize <- Optional returned size of jump table (useful on intel) 57 | @result <- mach_error_t 58 | 59 | ***************************************************************************/ 60 | 61 | mach_error_t 62 | machImageForPointer( 63 | const void *pointer, 64 | const void **image, 65 | unsigned long *size, 66 | unsigned int *jumpTableOffset, 67 | unsigned int *jumpTableSize ); 68 | 69 | __END_DECLS 70 | #endif // _mach_inject_ -------------------------------------------------------------------------------- /mach_inject/mach_inject/mach_inject.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 45; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 79797DFA07F62C5F00E7262E /* mach_inject.c in Sources */ = {isa = PBXBuildFile; fileRef = 79797DF807F62C5E00E7262E /* mach_inject.c */; }; 11 | 79797DFB07F62C5F00E7262E /* mach_inject.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 79797DF907F62C5F00E7262E /* mach_inject.h */; }; 12 | 8DD76F870486A9BA00D96B5E /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = 08FB7796FE84155DC02AAC07 /* main.c */; settings = {ATTRIBUTES = (); }; }; 13 | 8DD76F890486A9BA00D96B5E /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 097DBE83FE8419DDC02AAC07 /* CoreServices.framework */; }; 14 | /* End PBXBuildFile section */ 15 | 16 | /* Begin PBXCopyFilesBuildPhase section */ 17 | 8DD76F8B0486A9BA00D96B5E /* CopyFiles */ = { 18 | isa = PBXCopyFilesBuildPhase; 19 | buildActionMask = 8; 20 | dstPath = /usr/share/man/man1/; 21 | dstSubfolderSpec = 0; 22 | files = ( 23 | 79797DFB07F62C5F00E7262E /* mach_inject.h in CopyFiles */, 24 | ); 25 | runOnlyForDeploymentPostprocessing = 1; 26 | }; 27 | /* End PBXCopyFilesBuildPhase section */ 28 | 29 | /* Begin PBXFileReference section */ 30 | 08FB7796FE84155DC02AAC07 /* main.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = main.c; sourceTree = ""; }; 31 | 097DBE83FE8419DDC02AAC07 /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = /System/Library/Frameworks/CoreServices.framework; sourceTree = ""; }; 32 | 79797DF807F62C5E00E7262E /* mach_inject.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = mach_inject.c; sourceTree = ""; }; 33 | 79797DF907F62C5F00E7262E /* mach_inject.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = mach_inject.h; sourceTree = ""; }; 34 | 8DD76F8E0486A9BA00D96B5E /* mach_inject */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = mach_inject; sourceTree = BUILT_PRODUCTS_DIR; }; 35 | /* End PBXFileReference section */ 36 | 37 | /* Begin PBXFrameworksBuildPhase section */ 38 | 8DD76F880486A9BA00D96B5E /* Frameworks */ = { 39 | isa = PBXFrameworksBuildPhase; 40 | buildActionMask = 2147483647; 41 | files = ( 42 | 8DD76F890486A9BA00D96B5E /* CoreServices.framework in Frameworks */, 43 | ); 44 | runOnlyForDeploymentPostprocessing = 0; 45 | }; 46 | /* End PBXFrameworksBuildPhase section */ 47 | 48 | /* Begin PBXGroup section */ 49 | 08FB7794FE84155DC02AAC07 /* mach_inject */ = { 50 | isa = PBXGroup; 51 | children = ( 52 | 08FB7795FE84155DC02AAC07 /* Source */, 53 | 08FB779DFE84155DC02AAC07 /* External Frameworks and Libraries */, 54 | 1A8B4A8EFE9D542A11CA2CBB /* Products */, 55 | ); 56 | name = mach_inject; 57 | sourceTree = ""; 58 | }; 59 | 08FB7795FE84155DC02AAC07 /* Source */ = { 60 | isa = PBXGroup; 61 | children = ( 62 | 79797DF807F62C5E00E7262E /* mach_inject.c */, 63 | 79797DF907F62C5F00E7262E /* mach_inject.h */, 64 | 08FB7796FE84155DC02AAC07 /* main.c */, 65 | ); 66 | name = Source; 67 | sourceTree = ""; 68 | }; 69 | 08FB779DFE84155DC02AAC07 /* External Frameworks and Libraries */ = { 70 | isa = PBXGroup; 71 | children = ( 72 | 097DBE83FE8419DDC02AAC07 /* CoreServices.framework */, 73 | ); 74 | name = "External Frameworks and Libraries"; 75 | sourceTree = ""; 76 | }; 77 | 1A8B4A8EFE9D542A11CA2CBB /* Products */ = { 78 | isa = PBXGroup; 79 | children = ( 80 | 8DD76F8E0486A9BA00D96B5E /* mach_inject */, 81 | ); 82 | name = Products; 83 | sourceTree = ""; 84 | }; 85 | /* End PBXGroup section */ 86 | 87 | /* Begin PBXNativeTarget section */ 88 | 8DD76F840486A9BA00D96B5E /* mach_inject */ = { 89 | isa = PBXNativeTarget; 90 | buildConfigurationList = 33B2AC34092854CE004B1632 /* Build configuration list for PBXNativeTarget "mach_inject" */; 91 | buildPhases = ( 92 | 8DD76F860486A9BA00D96B5E /* Sources */, 93 | 8DD76F880486A9BA00D96B5E /* Frameworks */, 94 | 8DD76F8B0486A9BA00D96B5E /* CopyFiles */, 95 | ); 96 | buildRules = ( 97 | ); 98 | dependencies = ( 99 | ); 100 | name = mach_inject; 101 | productInstallPath = "$(HOME)/bin"; 102 | productName = mach_inject; 103 | productReference = 8DD76F8E0486A9BA00D96B5E /* mach_inject */; 104 | productType = "com.apple.product-type.tool"; 105 | }; 106 | /* End PBXNativeTarget section */ 107 | 108 | /* Begin PBXProject section */ 109 | 08FB7793FE84155DC02AAC07 /* Project object */ = { 110 | isa = PBXProject; 111 | buildConfigurationList = 33B2AC38092854CE004B1632 /* Build configuration list for PBXProject "mach_inject" */; 112 | compatibilityVersion = "Xcode 3.1"; 113 | hasScannedForEncodings = 1; 114 | mainGroup = 08FB7794FE84155DC02AAC07 /* mach_inject */; 115 | projectDirPath = ""; 116 | projectRoot = ""; 117 | targets = ( 118 | 8DD76F840486A9BA00D96B5E /* mach_inject */, 119 | ); 120 | }; 121 | /* End PBXProject section */ 122 | 123 | /* Begin PBXSourcesBuildPhase section */ 124 | 8DD76F860486A9BA00D96B5E /* Sources */ = { 125 | isa = PBXSourcesBuildPhase; 126 | buildActionMask = 2147483647; 127 | files = ( 128 | 8DD76F870486A9BA00D96B5E /* main.c in Sources */, 129 | 79797DFA07F62C5F00E7262E /* mach_inject.c in Sources */, 130 | ); 131 | runOnlyForDeploymentPostprocessing = 0; 132 | }; 133 | /* End PBXSourcesBuildPhase section */ 134 | 135 | /* Begin XCBuildConfiguration section */ 136 | 33B2AC35092854CE004B1632 /* Development */ = { 137 | isa = XCBuildConfiguration; 138 | buildSettings = { 139 | ARCHS = ( 140 | ppc, 141 | i386, 142 | x86_64, 143 | ); 144 | COPY_PHASE_STRIP = NO; 145 | GCC_DYNAMIC_NO_PIC = NO; 146 | GCC_ENABLE_FIX_AND_CONTINUE = YES; 147 | GCC_GENERATE_DEBUGGING_SYMBOLS = YES; 148 | GCC_OPTIMIZATION_LEVEL = 0; 149 | INSTALL_PATH = "$(HOME)/bin"; 150 | PRODUCT_NAME = mach_inject; 151 | ZERO_LINK = YES; 152 | }; 153 | name = Development; 154 | }; 155 | 33B2AC36092854CE004B1632 /* Deployment */ = { 156 | isa = XCBuildConfiguration; 157 | buildSettings = { 158 | COPY_PHASE_STRIP = YES; 159 | GCC_ENABLE_FIX_AND_CONTINUE = NO; 160 | GCC_GENERATE_DEBUGGING_SYMBOLS = NO; 161 | INSTALL_PATH = "$(HOME)/bin"; 162 | PRODUCT_NAME = mach_inject; 163 | ZERO_LINK = NO; 164 | }; 165 | name = Deployment; 166 | }; 167 | 33B2AC37092854CE004B1632 /* Default */ = { 168 | isa = XCBuildConfiguration; 169 | buildSettings = { 170 | GCC_GENERATE_DEBUGGING_SYMBOLS = NO; 171 | INSTALL_PATH = "$(HOME)/bin"; 172 | PRODUCT_NAME = mach_inject; 173 | }; 174 | name = Default; 175 | }; 176 | 33B2AC39092854CE004B1632 /* Development */ = { 177 | isa = XCBuildConfiguration; 178 | buildSettings = { 179 | }; 180 | name = Development; 181 | }; 182 | 33B2AC3A092854CE004B1632 /* Deployment */ = { 183 | isa = XCBuildConfiguration; 184 | buildSettings = { 185 | }; 186 | name = Deployment; 187 | }; 188 | 33B2AC3B092854CE004B1632 /* Default */ = { 189 | isa = XCBuildConfiguration; 190 | buildSettings = { 191 | }; 192 | name = Default; 193 | }; 194 | /* End XCBuildConfiguration section */ 195 | 196 | /* Begin XCConfigurationList section */ 197 | 33B2AC34092854CE004B1632 /* Build configuration list for PBXNativeTarget "mach_inject" */ = { 198 | isa = XCConfigurationList; 199 | buildConfigurations = ( 200 | 33B2AC35092854CE004B1632 /* Development */, 201 | 33B2AC36092854CE004B1632 /* Deployment */, 202 | 33B2AC37092854CE004B1632 /* Default */, 203 | ); 204 | defaultConfigurationIsVisible = 0; 205 | defaultConfigurationName = Default; 206 | }; 207 | 33B2AC38092854CE004B1632 /* Build configuration list for PBXProject "mach_inject" */ = { 208 | isa = XCConfigurationList; 209 | buildConfigurations = ( 210 | 33B2AC39092854CE004B1632 /* Development */, 211 | 33B2AC3A092854CE004B1632 /* Deployment */, 212 | 33B2AC3B092854CE004B1632 /* Default */, 213 | ); 214 | defaultConfigurationIsVisible = 0; 215 | defaultConfigurationName = Default; 216 | }; 217 | /* End XCConfigurationList section */ 218 | }; 219 | rootObject = 08FB7793FE84155DC02AAC07 /* Project object */; 220 | } 221 | -------------------------------------------------------------------------------- /mach_inject/mach_inject/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main (int argc, const char * argv[]) { 4 | // insert code here... 5 | printf("Hello, World!\n"); 6 | return 0; 7 | } 8 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_bundle/English.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zerodivisi0n/FinderMenu/d65aac3e98e75924c9efa0fae48b02bbc0928e53/mach_inject/mach_inject_bundle/English.lproj/InfoPlist.strings -------------------------------------------------------------------------------- /mach_inject/mach_inject_bundle/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | mach_inject_bundle 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | com.rentzsch.mach_inject_bundle 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1.0 21 | NSPrincipalClass 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_bundle/mach_inject_bundle.c: -------------------------------------------------------------------------------- 1 | // mach_inject_bundle.c semver:1.2.0 2 | // Copyright (c) 2003-2012 Jonathan 'Wolf' Rentzsch: http://rentzsch.com 3 | // Some rights reserved: http://opensource.org/licenses/mit 4 | // https://github.com/rentzsch/mach_inject 5 | 6 | #include "mach_inject_bundle.h" 7 | #include "mach_inject.h" 8 | #include "mach_inject_bundle_stub.h" 9 | #include 10 | 11 | mach_error_t 12 | mach_inject_bundle_pid( 13 | const char *bundlePackageFileSystemRepresentation, 14 | pid_t pid ) 15 | { 16 | assert( bundlePackageFileSystemRepresentation ); 17 | assert( pid > 0 ); 18 | 19 | mach_error_t err = err_none; 20 | 21 | // Get the framework's bundle. 22 | CFBundleRef frameworkBundle = NULL; 23 | if( !err ) { 24 | frameworkBundle = CFBundleGetBundleWithIdentifier( 25 | CFSTR("com.rentzsch.mach_inject_bundle")); 26 | if( frameworkBundle == NULL ) 27 | err = err_mach_inject_bundle_couldnt_load_framework_bundle; 28 | } 29 | 30 | // Find the injection bundle by name. 31 | CFURLRef injectionURL = NULL; 32 | if( !err ) { 33 | /*injectionURL = CFURLCreateWithFileSystemPath( kCFAllocatorDefault, CFSTR("mach_inject_bundle_stub.bundle"), 34 | kCFURLPOSIXPathStyle, true );*/ 35 | injectionURL = CFBundleCopyResourceURL( frameworkBundle, 36 | CFSTR("mach_inject_bundle_stub.bundle"), NULL, NULL ); 37 | 38 | /*char url[1024]; 39 | CFURLGetFileSystemRepresentation(injectionURL, true, url, 1024); 40 | printf("got a URL %s\n", url);*/ 41 | if( !injectionURL ) 42 | err = err_mach_inject_bundle_couldnt_find_injection_bundle; 43 | } 44 | 45 | // Create injection bundle instance. 46 | CFBundleRef injectionBundle = NULL; 47 | if( !err ) { 48 | injectionBundle = CFBundleCreate( kCFAllocatorDefault, injectionURL ); 49 | if( !injectionBundle ) 50 | err = err_mach_inject_bundle_couldnt_load_injection_bundle; 51 | } 52 | 53 | // Load the thread code injection. 54 | void *injectionCode = NULL; 55 | if( !err ) { 56 | injectionCode = CFBundleGetFunctionPointerForName( injectionBundle, 57 | CFSTR( INJECT_ENTRY_SYMBOL )); 58 | if( injectionCode == NULL ) 59 | err = err_mach_inject_bundle_couldnt_find_inject_entry_symbol; 60 | } 61 | 62 | // Allocate and populate the parameter block. 63 | mach_inject_bundle_stub_param *param = NULL; 64 | size_t paramSize; 65 | if( !err ) { 66 | size_t bundlePathSize = strlen( bundlePackageFileSystemRepresentation ) 67 | + 1; 68 | paramSize = sizeof( ptrdiff_t ) + bundlePathSize; 69 | param = malloc( paramSize ); 70 | bcopy( bundlePackageFileSystemRepresentation, 71 | param->bundlePackageFileSystemRepresentation, 72 | bundlePathSize ); 73 | } 74 | 75 | // Inject the code. 76 | if( !err ) { 77 | err = mach_inject( injectionCode, param, paramSize, pid, 0 ); 78 | } 79 | 80 | // Clean up. 81 | if( param ) 82 | free( param ); 83 | /*if( injectionBundle ) 84 | CFRelease( injectionBundle );*/ 85 | if( injectionURL ) 86 | CFRelease( injectionURL ); 87 | 88 | return err; 89 | } -------------------------------------------------------------------------------- /mach_inject/mach_inject_bundle/mach_inject_bundle.h: -------------------------------------------------------------------------------- 1 | // mach_inject_bundle.h semver:1.2.0 2 | // Copyright (c) 2003-2012 Jonathan 'Wolf' Rentzsch: http://rentzsch.com 3 | // Some rights reserved: http://opensource.org/licenses/mit 4 | // https://github.com/rentzsch/mach_inject 5 | 6 | /******************************************************************************* 7 | Higher-level interface for mach_inject. This framework, intended to be 8 | embedded into your application, allows you to "inject and forget" an 9 | arbitrary bundle into an arbitrary process. It supplies the primitive code 10 | block that gets squirted across the address spaces 11 | (mach_inject_bundle_stub), which was the trickiest thing to write. 12 | 13 | @todo Supply a higher-level interface to specifying processes than just a 14 | process ID. I'm thinking offering lookup via application ID 15 | ("com.apple.Finder"). 16 | 17 | ***************************************************************************/ 18 | 19 | #ifndef _mach_inject_bundle_ 20 | #define _mach_inject_bundle_ 21 | 22 | #include 23 | #include 24 | 25 | #define err_mach_inject_bundle_couldnt_load_framework_bundle (err_local|1) 26 | #define err_mach_inject_bundle_couldnt_find_injection_bundle (err_local|2) 27 | #define err_mach_inject_bundle_couldnt_load_injection_bundle (err_local|3) 28 | #define err_mach_inject_bundle_couldnt_find_inject_entry_symbol (err_local|4) 29 | 30 | __BEGIN_DECLS 31 | 32 | /******************************************************************************* 33 | @param bundlePackageFileSystemRepresentation -> Required pointer 34 | @param pid -> 35 | @result <- mach_error_t 36 | 37 | ***************************************************************************/ 38 | 39 | mach_error_t 40 | mach_inject_bundle_pid( 41 | const char *bundlePackageFileSystemRepresentation, 42 | pid_t pid ); 43 | 44 | __END_DECLS 45 | #endif // _mach_inject_bundle_ -------------------------------------------------------------------------------- /mach_inject/mach_inject_bundle/mach_inject_bundle.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 23A92516141586E900EE4B17 /* mach_inject_bundle_stub.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 33B2AC8809285572004B1632 /* mach_inject_bundle_stub.bundle */; }; 11 | 79ACC85907FD3EBD00D4147B /* mach_inject_bundle.h in Headers */ = {isa = PBXBuildFile; fileRef = 79ACC85707FD3EBD00D4147B /* mach_inject_bundle.h */; settings = {ATTRIBUTES = (Public, ); }; }; 12 | 79ACC85A07FD3EBD00D4147B /* mach_inject_bundle.c in Sources */ = {isa = PBXBuildFile; fileRef = 79ACC85807FD3EBD00D4147B /* mach_inject_bundle.c */; }; 13 | 79ACC88707FD40D700D4147B /* mach_inject.c in Sources */ = {isa = PBXBuildFile; fileRef = 79ACC88507FD40D700D4147B /* mach_inject.c */; }; 14 | 79ACC88807FD40D700D4147B /* mach_inject.h in Headers */ = {isa = PBXBuildFile; fileRef = 79ACC88607FD40D700D4147B /* mach_inject.h */; }; 15 | 79ACC8DC07FD452E00D4147B /* mach_inject_bundle_stub.h in Headers */ = {isa = PBXBuildFile; fileRef = 79ACC8DB07FD452E00D4147B /* mach_inject_bundle_stub.h */; }; 16 | 8DC2EF530486A6940098B216 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C1666FE841158C02AAC07 /* InfoPlist.strings */; }; 17 | 8DC2EF570486A6940098B216 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */; }; 18 | /* End PBXBuildFile section */ 19 | 20 | /* Begin PBXContainerItemProxy section */ 21 | 33B2AC8709285572004B1632 /* PBXContainerItemProxy */ = { 22 | isa = PBXContainerItemProxy; 23 | containerPortal = 33B2AC8109285572004B1632 /* mach_inject_bundle_stub.xcodeproj */; 24 | proxyType = 2; 25 | remoteGlobalIDString = 8D01CCD20486CAD60068D4B7; 26 | remoteInfo = mach_inject_bundle_stub; 27 | }; 28 | 33B2AC8909285578004B1632 /* PBXContainerItemProxy */ = { 29 | isa = PBXContainerItemProxy; 30 | containerPortal = 33B2AC8109285572004B1632 /* mach_inject_bundle_stub.xcodeproj */; 31 | proxyType = 1; 32 | remoteGlobalIDString = 8D01CCC60486CAD60068D4B7; 33 | remoteInfo = mach_inject_bundle_stub; 34 | }; 35 | /* End PBXContainerItemProxy section */ 36 | 37 | /* Begin PBXCopyFilesBuildPhase section */ 38 | 33B2ACA2092856E1004B1632 /* CopyFiles */ = { 39 | isa = PBXCopyFilesBuildPhase; 40 | buildActionMask = 2147483647; 41 | dstPath = ""; 42 | dstSubfolderSpec = 16; 43 | files = ( 44 | ); 45 | runOnlyForDeploymentPostprocessing = 0; 46 | }; 47 | /* End PBXCopyFilesBuildPhase section */ 48 | 49 | /* Begin PBXFileReference section */ 50 | 0867D69BFE84028FC02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; 51 | 0867D6A5FE840307C02AAC07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; 52 | 089C1667FE841158C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = ""; }; 53 | 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; 54 | 32DBCF5E0370ADEE00C91783 /* mach_inject_bundle_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mach_inject_bundle_Prefix.pch; sourceTree = ""; }; 55 | 33B2AC8109285572004B1632 /* mach_inject_bundle_stub.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = mach_inject_bundle_stub.xcodeproj; path = ../mach_inject_bundle_stub/mach_inject_bundle_stub.xcodeproj; sourceTree = SOURCE_ROOT; }; 56 | 79ACC85707FD3EBD00D4147B /* mach_inject_bundle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mach_inject_bundle.h; sourceTree = ""; }; 57 | 79ACC85807FD3EBD00D4147B /* mach_inject_bundle.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mach_inject_bundle.c; sourceTree = ""; }; 58 | 79ACC88507FD40D700D4147B /* mach_inject.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = mach_inject.c; path = ../mach_inject/mach_inject.c; sourceTree = SOURCE_ROOT; }; 59 | 79ACC88607FD40D700D4147B /* mach_inject.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = mach_inject.h; path = ../mach_inject/mach_inject.h; sourceTree = SOURCE_ROOT; }; 60 | 79ACC8DB07FD452E00D4147B /* mach_inject_bundle_stub.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = mach_inject_bundle_stub.h; path = ../mach_inject_bundle_stub/mach_inject_bundle_stub.h; sourceTree = SOURCE_ROOT; }; 61 | 8DC2EF5A0486A6940098B216 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; 62 | 8DC2EF5B0486A6940098B216 /* mach_inject_bundle.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = mach_inject_bundle.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 63 | /* End PBXFileReference section */ 64 | 65 | /* Begin PBXFrameworksBuildPhase section */ 66 | 8DC2EF560486A6940098B216 /* Frameworks */ = { 67 | isa = PBXFrameworksBuildPhase; 68 | buildActionMask = 2147483647; 69 | files = ( 70 | 8DC2EF570486A6940098B216 /* Cocoa.framework in Frameworks */, 71 | ); 72 | runOnlyForDeploymentPostprocessing = 0; 73 | }; 74 | /* End PBXFrameworksBuildPhase section */ 75 | 76 | /* Begin PBXGroup section */ 77 | 034768DFFF38A50411DB9C8B /* Products */ = { 78 | isa = PBXGroup; 79 | children = ( 80 | 8DC2EF5B0486A6940098B216 /* mach_inject_bundle.framework */, 81 | ); 82 | name = Products; 83 | sourceTree = ""; 84 | }; 85 | 0867D691FE84028FC02AAC07 /* mach_inject_bundle */ = { 86 | isa = PBXGroup; 87 | children = ( 88 | 33B2AC8109285572004B1632 /* mach_inject_bundle_stub.xcodeproj */, 89 | 32C88DFF0371C24200C91783 /* Other Sources */, 90 | 089C1665FE841158C02AAC07 /* Resources */, 91 | 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */, 92 | 034768DFFF38A50411DB9C8B /* Products */, 93 | ); 94 | name = mach_inject_bundle; 95 | sourceTree = ""; 96 | }; 97 | 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */ = { 98 | isa = PBXGroup; 99 | children = ( 100 | 1058C7B0FEA5585E11CA2CBB /* Linked Frameworks */, 101 | 1058C7B2FEA5585E11CA2CBB /* Other Frameworks */, 102 | ); 103 | name = "External Frameworks and Libraries"; 104 | sourceTree = ""; 105 | }; 106 | 089C1665FE841158C02AAC07 /* Resources */ = { 107 | isa = PBXGroup; 108 | children = ( 109 | 8DC2EF5A0486A6940098B216 /* Info.plist */, 110 | 089C1666FE841158C02AAC07 /* InfoPlist.strings */, 111 | ); 112 | name = Resources; 113 | sourceTree = ""; 114 | }; 115 | 1058C7B0FEA5585E11CA2CBB /* Linked Frameworks */ = { 116 | isa = PBXGroup; 117 | children = ( 118 | 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */, 119 | ); 120 | name = "Linked Frameworks"; 121 | sourceTree = ""; 122 | }; 123 | 1058C7B2FEA5585E11CA2CBB /* Other Frameworks */ = { 124 | isa = PBXGroup; 125 | children = ( 126 | 0867D69BFE84028FC02AAC07 /* Foundation.framework */, 127 | 0867D6A5FE840307C02AAC07 /* AppKit.framework */, 128 | ); 129 | name = "Other Frameworks"; 130 | sourceTree = ""; 131 | }; 132 | 32C88DFF0371C24200C91783 /* Other Sources */ = { 133 | isa = PBXGroup; 134 | children = ( 135 | 79ACC85707FD3EBD00D4147B /* mach_inject_bundle.h */, 136 | 79ACC85807FD3EBD00D4147B /* mach_inject_bundle.c */, 137 | 79ACC88507FD40D700D4147B /* mach_inject.c */, 138 | 79ACC88607FD40D700D4147B /* mach_inject.h */, 139 | 79ACC8DB07FD452E00D4147B /* mach_inject_bundle_stub.h */, 140 | 32DBCF5E0370ADEE00C91783 /* mach_inject_bundle_Prefix.pch */, 141 | ); 142 | name = "Other Sources"; 143 | sourceTree = ""; 144 | }; 145 | 33B2AC8409285572004B1632 /* Products */ = { 146 | isa = PBXGroup; 147 | children = ( 148 | 33B2AC8809285572004B1632 /* mach_inject_bundle_stub.bundle */, 149 | ); 150 | name = Products; 151 | sourceTree = ""; 152 | }; 153 | /* End PBXGroup section */ 154 | 155 | /* Begin PBXHeadersBuildPhase section */ 156 | 8DC2EF500486A6940098B216 /* Headers */ = { 157 | isa = PBXHeadersBuildPhase; 158 | buildActionMask = 2147483647; 159 | files = ( 160 | 79ACC85907FD3EBD00D4147B /* mach_inject_bundle.h in Headers */, 161 | 79ACC88807FD40D700D4147B /* mach_inject.h in Headers */, 162 | 79ACC8DC07FD452E00D4147B /* mach_inject_bundle_stub.h in Headers */, 163 | ); 164 | runOnlyForDeploymentPostprocessing = 0; 165 | }; 166 | /* End PBXHeadersBuildPhase section */ 167 | 168 | /* Begin PBXNativeTarget section */ 169 | 8DC2EF4F0486A6940098B216 /* mach_inject_bundle */ = { 170 | isa = PBXNativeTarget; 171 | buildConfigurationList = 33B2AC7709285567004B1632 /* Build configuration list for PBXNativeTarget "mach_inject_bundle" */; 172 | buildPhases = ( 173 | 8DC2EF500486A6940098B216 /* Headers */, 174 | 33B2ACA2092856E1004B1632 /* CopyFiles */, 175 | 8DC2EF520486A6940098B216 /* Resources */, 176 | 8DC2EF540486A6940098B216 /* Sources */, 177 | 8DC2EF560486A6940098B216 /* Frameworks */, 178 | ); 179 | buildRules = ( 180 | ); 181 | dependencies = ( 182 | 33B2AC8A09285578004B1632 /* PBXTargetDependency */, 183 | ); 184 | name = mach_inject_bundle; 185 | productInstallPath = "$(HOME)/Library/Frameworks"; 186 | productName = mach_inject_bundle; 187 | productReference = 8DC2EF5B0486A6940098B216 /* mach_inject_bundle.framework */; 188 | productType = "com.apple.product-type.framework"; 189 | }; 190 | /* End PBXNativeTarget section */ 191 | 192 | /* Begin PBXProject section */ 193 | 0867D690FE84028FC02AAC07 /* Project object */ = { 194 | isa = PBXProject; 195 | attributes = { 196 | LastUpgradeCheck = 0410; 197 | }; 198 | buildConfigurationList = 33B2AC7B09285567004B1632 /* Build configuration list for PBXProject "mach_inject_bundle" */; 199 | compatibilityVersion = "Xcode 3.2"; 200 | developmentRegion = English; 201 | hasScannedForEncodings = 1; 202 | knownRegions = ( 203 | en, 204 | ); 205 | mainGroup = 0867D691FE84028FC02AAC07 /* mach_inject_bundle */; 206 | productRefGroup = 034768DFFF38A50411DB9C8B /* Products */; 207 | projectDirPath = ""; 208 | projectReferences = ( 209 | { 210 | ProductGroup = 33B2AC8409285572004B1632 /* Products */; 211 | ProjectRef = 33B2AC8109285572004B1632 /* mach_inject_bundle_stub.xcodeproj */; 212 | }, 213 | ); 214 | projectRoot = ""; 215 | targets = ( 216 | 8DC2EF4F0486A6940098B216 /* mach_inject_bundle */, 217 | ); 218 | }; 219 | /* End PBXProject section */ 220 | 221 | /* Begin PBXReferenceProxy section */ 222 | 33B2AC8809285572004B1632 /* mach_inject_bundle_stub.bundle */ = { 223 | isa = PBXReferenceProxy; 224 | fileType = wrapper.cfbundle; 225 | path = mach_inject_bundle_stub.bundle; 226 | remoteRef = 33B2AC8709285572004B1632 /* PBXContainerItemProxy */; 227 | sourceTree = BUILT_PRODUCTS_DIR; 228 | }; 229 | /* End PBXReferenceProxy section */ 230 | 231 | /* Begin PBXResourcesBuildPhase section */ 232 | 8DC2EF520486A6940098B216 /* Resources */ = { 233 | isa = PBXResourcesBuildPhase; 234 | buildActionMask = 2147483647; 235 | files = ( 236 | 8DC2EF530486A6940098B216 /* InfoPlist.strings in Resources */, 237 | 23A92516141586E900EE4B17 /* mach_inject_bundle_stub.bundle in Resources */, 238 | ); 239 | runOnlyForDeploymentPostprocessing = 0; 240 | }; 241 | /* End PBXResourcesBuildPhase section */ 242 | 243 | /* Begin PBXSourcesBuildPhase section */ 244 | 8DC2EF540486A6940098B216 /* Sources */ = { 245 | isa = PBXSourcesBuildPhase; 246 | buildActionMask = 2147483647; 247 | files = ( 248 | 79ACC85A07FD3EBD00D4147B /* mach_inject_bundle.c in Sources */, 249 | 79ACC88707FD40D700D4147B /* mach_inject.c in Sources */, 250 | ); 251 | runOnlyForDeploymentPostprocessing = 0; 252 | }; 253 | /* End PBXSourcesBuildPhase section */ 254 | 255 | /* Begin PBXTargetDependency section */ 256 | 33B2AC8A09285578004B1632 /* PBXTargetDependency */ = { 257 | isa = PBXTargetDependency; 258 | name = mach_inject_bundle_stub; 259 | targetProxy = 33B2AC8909285578004B1632 /* PBXContainerItemProxy */; 260 | }; 261 | /* End PBXTargetDependency section */ 262 | 263 | /* Begin PBXVariantGroup section */ 264 | 089C1666FE841158C02AAC07 /* InfoPlist.strings */ = { 265 | isa = PBXVariantGroup; 266 | children = ( 267 | 089C1667FE841158C02AAC07 /* English */, 268 | ); 269 | name = InfoPlist.strings; 270 | sourceTree = ""; 271 | }; 272 | /* End PBXVariantGroup section */ 273 | 274 | /* Begin XCBuildConfiguration section */ 275 | 33B2AC7809285567004B1632 /* Development */ = { 276 | isa = XCBuildConfiguration; 277 | buildSettings = { 278 | COPY_PHASE_STRIP = NO; 279 | DYLIB_COMPATIBILITY_VERSION = 1; 280 | DYLIB_CURRENT_VERSION = 1; 281 | FRAMEWORK_VERSION = A; 282 | GCC_DYNAMIC_NO_PIC = NO; 283 | GCC_GENERATE_DEBUGGING_SYMBOLS = YES; 284 | GCC_OPTIMIZATION_LEVEL = 0; 285 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 286 | GCC_PREFIX_HEADER = mach_inject_bundle_Prefix.pch; 287 | INFOPLIST_FILE = Info.plist; 288 | INSTALL_PATH = "@executable_path/../Frameworks"; 289 | LD_DYLIB_INSTALL_NAME = "@rpath/Frameworks/$(EXECUTABLE_PATH)"; 290 | LIBRARY_STYLE = DYNAMIC; 291 | MACH_O_TYPE = mh_dylib; 292 | OTHER_LDFLAGS = ( 293 | "-seg1addr", 294 | 0xc0000000, 295 | ); 296 | PRODUCT_NAME = mach_inject_bundle; 297 | WRAPPER_EXTENSION = framework; 298 | ZERO_LINK = YES; 299 | }; 300 | name = Development; 301 | }; 302 | 33B2AC7909285567004B1632 /* Deployment */ = { 303 | isa = XCBuildConfiguration; 304 | buildSettings = { 305 | COPY_PHASE_STRIP = YES; 306 | DYLIB_COMPATIBILITY_VERSION = 1; 307 | DYLIB_CURRENT_VERSION = 1; 308 | FRAMEWORK_VERSION = A; 309 | GCC_GENERATE_DEBUGGING_SYMBOLS = NO; 310 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 311 | GCC_PREFIX_HEADER = mach_inject_bundle_Prefix.pch; 312 | INFOPLIST_FILE = Info.plist; 313 | INSTALL_PATH = "@executable_path/../Frameworks"; 314 | LD_DYLIB_INSTALL_NAME = "@rpath/Frameworks/$(EXECUTABLE_PATH)"; 315 | LIBRARY_STYLE = DYNAMIC; 316 | MACH_O_TYPE = mh_dylib; 317 | OTHER_LDFLAGS = ( 318 | "-seg1addr", 319 | 0xc0000000, 320 | ); 321 | PRODUCT_NAME = mach_inject_bundle; 322 | WRAPPER_EXTENSION = framework; 323 | ZERO_LINK = NO; 324 | }; 325 | name = Deployment; 326 | }; 327 | 33B2AC7A09285567004B1632 /* Default */ = { 328 | isa = XCBuildConfiguration; 329 | buildSettings = { 330 | DYLIB_COMPATIBILITY_VERSION = 1; 331 | DYLIB_CURRENT_VERSION = 1; 332 | FRAMEWORK_VERSION = A; 333 | GCC_GENERATE_DEBUGGING_SYMBOLS = NO; 334 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 335 | GCC_PREFIX_HEADER = mach_inject_bundle_Prefix.pch; 336 | INFOPLIST_FILE = Info.plist; 337 | INSTALL_PATH = "@executable_path/../Frameworks"; 338 | LD_DYLIB_INSTALL_NAME = "@rpath/Frameworks/$(EXECUTABLE_PATH)"; 339 | LIBRARY_STYLE = DYNAMIC; 340 | MACH_O_TYPE = mh_dylib; 341 | OTHER_LDFLAGS = ( 342 | "-seg1addr", 343 | 0xc0000000, 344 | ); 345 | PRODUCT_NAME = mach_inject_bundle; 346 | WRAPPER_EXTENSION = framework; 347 | }; 348 | name = Default; 349 | }; 350 | 33B2AC7C09285567004B1632 /* Development */ = { 351 | isa = XCBuildConfiguration; 352 | buildSettings = { 353 | ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; 354 | }; 355 | name = Development; 356 | }; 357 | 33B2AC7D09285567004B1632 /* Deployment */ = { 358 | isa = XCBuildConfiguration; 359 | buildSettings = { 360 | ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; 361 | }; 362 | name = Deployment; 363 | }; 364 | 33B2AC7E09285567004B1632 /* Default */ = { 365 | isa = XCBuildConfiguration; 366 | buildSettings = { 367 | ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; 368 | }; 369 | name = Default; 370 | }; 371 | /* End XCBuildConfiguration section */ 372 | 373 | /* Begin XCConfigurationList section */ 374 | 33B2AC7709285567004B1632 /* Build configuration list for PBXNativeTarget "mach_inject_bundle" */ = { 375 | isa = XCConfigurationList; 376 | buildConfigurations = ( 377 | 33B2AC7809285567004B1632 /* Development */, 378 | 33B2AC7909285567004B1632 /* Deployment */, 379 | 33B2AC7A09285567004B1632 /* Default */, 380 | ); 381 | defaultConfigurationIsVisible = 0; 382 | defaultConfigurationName = Default; 383 | }; 384 | 33B2AC7B09285567004B1632 /* Build configuration list for PBXProject "mach_inject_bundle" */ = { 385 | isa = XCConfigurationList; 386 | buildConfigurations = ( 387 | 33B2AC7C09285567004B1632 /* Development */, 388 | 33B2AC7D09285567004B1632 /* Deployment */, 389 | 33B2AC7E09285567004B1632 /* Default */, 390 | ); 391 | defaultConfigurationIsVisible = 0; 392 | defaultConfigurationName = Default; 393 | }; 394 | /* End XCConfigurationList section */ 395 | }; 396 | rootObject = 0867D690FE84028FC02AAC07 /* Project object */; 397 | } 398 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_bundle/mach_inject_bundle_Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'mach_inject_bundle' target in the 'mach_inject_bundle' project. 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_bundle/main.c: -------------------------------------------------------------------------------- 1 | /* This is the default source file for new frameworks. */ 2 | 3 | /* You can either fill in code here or remove this and create or add new files. */ 4 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_bundle/version.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildVersion 6 | 12 7 | CFBundleVersion 8 | 1.0 9 | ProductBuildVersion 10 | 7K571 11 | ProjectName 12 | DevToolsWizardTemplates 13 | SourceVersion 14 | 3870000 15 | 16 | 17 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_bundle_stub/English.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zerodivisi0n/FinderMenu/d65aac3e98e75924c9efa0fae48b02bbc0928e53/mach_inject/mach_inject_bundle_stub/English.lproj/InfoPlist.strings -------------------------------------------------------------------------------- /mach_inject/mach_inject_bundle_stub/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | mach_inject_bundle_stub 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | com.apple.carbonbundletemplate 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1.0 21 | CSResourcesFileMapped 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_bundle_stub/load_bundle.c: -------------------------------------------------------------------------------- 1 | // load_bundle.c semver:1.2.0 2 | // Copyright (c) 2003-2012 Jonathan 'Wolf' Rentzsch: http://rentzsch.com 3 | // Some rights reserved: http://opensource.org/licenses/mit 4 | // https://github.com/rentzsch/mach_inject 5 | 6 | #include "load_bundle.h" 7 | #include 8 | #include // for PATH_MAX. 9 | #include 10 | #include 11 | 12 | #include 13 | #define MACH_ERROR(msg, err) { if(err != err_none) mach_error(msg, err); } 14 | 15 | mach_error_t 16 | load_bundle_package( 17 | const char *bundlePackageFileSystemRepresentation ) 18 | { 19 | fprintf(stderr, "mach_inject_bundle load_bundle_package: %s\n", bundlePackageFileSystemRepresentation); 20 | assert( bundlePackageFileSystemRepresentation ); 21 | assert( strlen( bundlePackageFileSystemRepresentation ) ); 22 | 23 | mach_error_t err = err_none; 24 | MACH_ERROR("mach error on bundle load", err); 25 | 26 | // Morph the FSR into a URL. 27 | CFURLRef bundlePackageURL = NULL; 28 | if( !err ) { 29 | bundlePackageURL = CFURLCreateFromFileSystemRepresentation( 30 | kCFAllocatorDefault, 31 | (const UInt8*)bundlePackageFileSystemRepresentation, 32 | strlen(bundlePackageFileSystemRepresentation), 33 | true ); 34 | if( bundlePackageURL == NULL ) 35 | err = err_load_bundle_url_from_path; 36 | } 37 | MACH_ERROR("mach error on bundle load", err); 38 | 39 | // Create bundle. 40 | CFBundleRef bundle = NULL; 41 | if( !err ) { 42 | bundle = CFBundleCreate( kCFAllocatorDefault, bundlePackageURL ); 43 | if( bundle == NULL ) 44 | err = err_load_bundle_create_bundle; 45 | } 46 | MACH_ERROR("mach error on bundle load", err); 47 | 48 | // Discover the bundle's executable file. 49 | CFURLRef bundleExecutableURL = NULL; 50 | if( !err ) { 51 | assert( bundle ); 52 | bundleExecutableURL = CFBundleCopyExecutableURL( bundle ); 53 | if( bundleExecutableURL == NULL ) 54 | err = err_load_bundle_package_executable_url; 55 | } 56 | MACH_ERROR("mach error on bundle load", err); 57 | 58 | // Morph the executable's URL into an FSR. 59 | char bundleExecutableFileSystemRepresentation[PATH_MAX]; 60 | if( !err ) { 61 | assert( bundleExecutableURL ); 62 | if( !CFURLGetFileSystemRepresentation( 63 | bundleExecutableURL, 64 | true, 65 | (UInt8*)bundleExecutableFileSystemRepresentation, 66 | sizeof(bundleExecutableFileSystemRepresentation) ) ) 67 | { 68 | err = err_load_bundle_path_from_url; 69 | } 70 | } 71 | MACH_ERROR("mach error on bundle load", err); 72 | 73 | // Do the real work. 74 | if( !err ) { 75 | assert( strlen(bundleExecutableFileSystemRepresentation) ); 76 | err = load_bundle_executable( bundleExecutableFileSystemRepresentation); 77 | } 78 | 79 | // Clean up. 80 | if( bundleExecutableURL ) 81 | CFRelease( bundleExecutableURL ); 82 | /*if( bundle ) 83 | CFRelease( bundle );*/ 84 | if( bundlePackageURL ) 85 | CFRelease( bundlePackageURL ); 86 | 87 | MACH_ERROR("mach error on bundle load", err); 88 | return err; 89 | } 90 | 91 | mach_error_t 92 | load_bundle_executable( 93 | const char *bundleExecutableFileSystemRepresentation ) 94 | { 95 | assert( bundleExecutableFileSystemRepresentation ); 96 | 97 | /* 98 | NSBundle* bundle = [NSBundle bundleWithPath:[NSString stringWithUTF8String:bundleExecutableFileSystemRepresentation]]; 99 | 100 | if(![bundle load]) { 101 | fprintf(stderr, "mach_inject: failed to load %s\n", bundleExecutableFileSystemRepresentation); 102 | return err_load_bundle_NSObjectFileImageFailure; 103 | } 104 | else 105 | fprintf(stderr, "mach_inject: loaded succesfull: %s\n", bundleExecutableFileSystemRepresentation); 106 | */ 107 | 108 | //fprintf(stderr, "FS rep %s\n", bundleExecutableFileSystemRepresentation); 109 | void *image = dlopen(bundleExecutableFileSystemRepresentation, RTLD_NOW); 110 | //fprintf(stderr, "OH shit load? %p\n", image); 111 | if (!image) { 112 | dlerror(); 113 | return err_load_bundle_NSObjectFileImageFailure; 114 | } 115 | 116 | return 0; 117 | } -------------------------------------------------------------------------------- /mach_inject/mach_inject_bundle_stub/load_bundle.h: -------------------------------------------------------------------------------- 1 | // load_bundle.h semver:1.2.0 2 | // Copyright (c) 2003-2012 Jonathan 'Wolf' Rentzsch: http://rentzsch.com 3 | // Some rights reserved: http://opensource.org/licenses/mit 4 | // https://github.com/rentzsch/mach_inject 5 | 6 | #ifndef _loader_ 7 | #define _loader_ 8 | 9 | #include 10 | 11 | #define err_load_bundle_undefined_symbol (err_local|1) 12 | #define err_load_bundle_link_failed (err_local|2) 13 | #define err_load_bundle_url_from_path (err_local|3) 14 | #define err_load_bundle_create_bundle (err_local|4) 15 | #define err_load_bundle_package_executable_url (err_local|5) 16 | #define err_load_bundle_path_from_url (err_local|6) 17 | #define err_load_bundle_NSObjectFileImageFailure \ 18 | (err_local|7+NSObjectFileImageFailure) 19 | #define err_load_bundle_NSObjectFileImageInappropriateFile \ 20 | (err_local|7+NSObjectFileImageInappropriateFile) 21 | #define err_load_bundle_NSObjectFileImageArch \ 22 | (err_local|7+NSObjectFileImageArch) 23 | #define err_load_bundle_NSObjectFileImageFormat \ 24 | (err_local|7+NSObjectFileImageFormat) 25 | #define err_load_bundle_NSObjectFileImageAccess \ 26 | (err_local|7+NSObjectFileImageAccess) 27 | 28 | __BEGIN_DECLS 29 | 30 | // High-level: For loading 'MyBundle.bundle'. Calls load_bundle_executable(). 31 | mach_error_t 32 | load_bundle_package( 33 | const char *bundlePackageFileSystemRepresentation ); 34 | 35 | // Low-level: For loading 'MyBundle.bundle/Contents/MacOS/MyBundle'. 36 | mach_error_t 37 | load_bundle_executable( 38 | const char *bundleExecutableFileSystemRepresentation ); 39 | 40 | __END_DECLS 41 | #endif // _loader_ -------------------------------------------------------------------------------- /mach_inject/mach_inject_bundle_stub/mach_inject_bundle_stub.c: -------------------------------------------------------------------------------- 1 | // mach_inject_bundle_stub.c semver:1.2.0 2 | // Copyright (c) 2003-2012 Jonathan 'Wolf' Rentzsch: http://rentzsch.com 3 | // Some rights reserved: http://opensource.org/licenses/mit 4 | // https://github.com/rentzsch/mach_inject 5 | // 6 | // Design inspired by SCPatchLoader by Jon Gotow of St. Clair Software: 7 | // http://www.stclairsoft.com 8 | 9 | #include "mach_inject_bundle_stub.h" 10 | #include "load_bundle.h" 11 | #include "mach_inject.h" // for INJECT_ENTRY 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | /************************** 20 | * 21 | * Funky Protos 22 | * 23 | **************************/ 24 | #pragma mark (Funky Protos) 25 | 26 | void 27 | INJECT_ENTRY( 28 | ptrdiff_t codeOffset, 29 | mach_inject_bundle_stub_param *param, 30 | size_t paramSize, 31 | char *dummy_pthread_struc ); 32 | 33 | void* 34 | pthread_entry( 35 | mach_inject_bundle_stub_param *param ); 36 | 37 | pascal 38 | void 39 | EventLoopTimerEntry( 40 | EventLoopTimerRef inTimer, 41 | mach_inject_bundle_stub_param *param ); 42 | 43 | /******************************************************************************* 44 | * 45 | * Implementation 46 | * 47 | *******************************************************************************/ 48 | #pragma mark - 49 | #pragma mark (Implementation) 50 | 51 | void 52 | INJECT_ENTRY( 53 | ptrdiff_t codeOffset, 54 | mach_inject_bundle_stub_param *param, 55 | size_t paramSize, 56 | char *dummy_pthread_struct ) 57 | { 58 | assert( param ); 59 | 60 | param->codeOffset = codeOffset; 61 | 62 | #if defined (__i386__) || defined(__x86_64__) 63 | // On intel, per-pthread data is a zone of data that must be allocated. 64 | // if not, all function trying to access per-pthread data (all mig functions for instance) 65 | // will crash. 66 | extern void __pthread_set_self(char*); 67 | __pthread_set_self(dummy_pthread_struct); 68 | #endif 69 | 70 | fprintf(stderr, "mach_inject_bundle: entered in %s, codeOffset: %td, param: %p, paramSize: %lu\n", 71 | INJECT_ENTRY_SYMBOL, codeOffset, param, paramSize); 72 | 73 | pthread_attr_t attr; 74 | pthread_attr_init(&attr); 75 | 76 | int policy; 77 | pthread_attr_getschedpolicy( &attr, &policy ); 78 | pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_DETACHED ); 79 | pthread_attr_setinheritsched( &attr, PTHREAD_EXPLICIT_SCHED ); 80 | 81 | struct sched_param sched; 82 | sched.sched_priority = sched_get_priority_max( policy ); 83 | pthread_attr_setschedparam( &attr, &sched ); 84 | 85 | pthread_t thread; 86 | pthread_create( &thread, 87 | &attr, 88 | (void* (*)(void*))((long)pthread_entry + codeOffset), 89 | (void*) param ); 90 | pthread_attr_destroy(&attr); 91 | 92 | thread_suspend(mach_thread_self()); 93 | } 94 | 95 | void* 96 | pthread_entry( 97 | mach_inject_bundle_stub_param *param ) 98 | { 99 | fprintf(stderr, "mach_inject_bundle: entered in pthread_entry, param: %p\n", param); 100 | assert( param ); 101 | 102 | EventLoopTimerProcPtr proc = (EventLoopTimerProcPtr) EventLoopTimerEntry; 103 | proc += param->codeOffset; 104 | EventLoopTimerUPP upp = NewEventLoopTimerUPP( proc ); 105 | 106 | InstallEventLoopTimer( GetMainEventLoop(), 0, 0, upp, (void*)param, NULL ); 107 | return NULL; 108 | } 109 | 110 | pascal 111 | void 112 | EventLoopTimerEntry( 113 | EventLoopTimerRef inTimer, 114 | mach_inject_bundle_stub_param *param ) 115 | { 116 | fprintf(stderr, "mach_inject_bundle: entered in EventLoopTimerEntry, inTimer: %p, param: %p\n", inTimer, param); 117 | assert( inTimer ); 118 | assert( param ); 119 | load_bundle_package( param->bundlePackageFileSystemRepresentation ); 120 | } 121 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_bundle_stub/mach_inject_bundle_stub.h: -------------------------------------------------------------------------------- 1 | // mach_inject_bundle_stub.h semver:1.2.0 2 | // Copyright (c) 2003-2012 Jonathan 'Wolf' Rentzsch: http://rentzsch.com 3 | // Some rights reserved: http://opensource.org/licenses/mit 4 | // https://github.com/rentzsch/mach_inject 5 | // 6 | // Design inspired by SCPatchLoader by Jon Gotow of St. Clair Software: 7 | // http://www.stclairsoft.com 8 | 9 | #ifndef _mach_inject_bundle_stub_ 10 | #define _mach_inject_bundle_stub_ 11 | 12 | #include // for ptrdiff_t 13 | 14 | typedef struct { 15 | ptrdiff_t codeOffset; 16 | char bundlePackageFileSystemRepresentation[1]; 17 | } mach_inject_bundle_stub_param; 18 | 19 | #endif // _mach_inject_bundle_stub_ -------------------------------------------------------------------------------- /mach_inject/mach_inject_bundle_stub/mach_inject_bundle_stub.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 79ACC4F507FD370C00D4147B /* load_bundle.c in Sources */ = {isa = PBXBuildFile; fileRef = 79ACC4F307FD370C00D4147B /* load_bundle.c */; }; 11 | 79ACC4F607FD370C00D4147B /* load_bundle.h in Headers */ = {isa = PBXBuildFile; fileRef = 79ACC4F407FD370C00D4147B /* load_bundle.h */; settings = {ATTRIBUTES = (Public, ); }; }; 12 | 79ACC4FC07FD376D00D4147B /* mach_inject_bundle_stub.h in Headers */ = {isa = PBXBuildFile; fileRef = 79ACC4FB07FD376D00D4147B /* mach_inject_bundle_stub.h */; settings = {ATTRIBUTES = (Public, ); }; }; 13 | 79ACC50B07FD3CE100D4147B /* mach_inject.h in Headers */ = {isa = PBXBuildFile; fileRef = 79ACC50A07FD3CE100D4147B /* mach_inject.h */; settings = {ATTRIBUTES = (Public, ); }; }; 14 | 79ACC83D07FD3DA800D4147B /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 79ACC83C07FD3DA800D4147B /* Carbon.framework */; }; 15 | 8D01CCC80486CAD60068D4B7 /* mach_inject_bundle_stub_Prefix.pch in Headers */ = {isa = PBXBuildFile; fileRef = 32BAE0B30371A71500C91783 /* mach_inject_bundle_stub_Prefix.pch */; settings = {ATTRIBUTES = (Public, ); }; }; 16 | 8D01CCCA0486CAD60068D4B7 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C167DFE841241C02AAC07 /* InfoPlist.strings */; }; 17 | 8D01CCCC0486CAD60068D4B7 /* mach_inject_bundle_stub.c in Sources */ = {isa = PBXBuildFile; fileRef = 08FB77B2FE8417CDC02AAC07 /* mach_inject_bundle_stub.c */; settings = {ATTRIBUTES = (); }; }; 18 | /* End PBXBuildFile section */ 19 | 20 | /* Begin PBXFileReference section */ 21 | 089C167EFE841241C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = ""; }; 22 | 08FB77B2FE8417CDC02AAC07 /* mach_inject_bundle_stub.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = mach_inject_bundle_stub.c; sourceTree = ""; }; 23 | 23A925321415A34F00EE4B17 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = ../../../../../../System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; 24 | 23A925341415A35900EE4B17 /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = ../../../../../../System/Library/Frameworks/CoreServices.framework; sourceTree = ""; }; 25 | 23A925361415A36B00EE4B17 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = ../../../../../../System/Library/Frameworks/CoreFoundation.framework; sourceTree = ""; }; 26 | 23A925381415A37800EE4B17 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = ../../../../../../System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; 27 | 32BAE0B30371A71500C91783 /* mach_inject_bundle_stub_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mach_inject_bundle_stub_Prefix.pch; sourceTree = ""; }; 28 | 79ACC4F307FD370C00D4147B /* load_bundle.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = load_bundle.c; sourceTree = ""; }; 29 | 79ACC4F407FD370C00D4147B /* load_bundle.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = load_bundle.h; sourceTree = ""; }; 30 | 79ACC4FB07FD376D00D4147B /* mach_inject_bundle_stub.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = mach_inject_bundle_stub.h; sourceTree = ""; }; 31 | 79ACC50A07FD3CE100D4147B /* mach_inject.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = mach_inject.h; path = ../mach_inject/mach_inject.h; sourceTree = SOURCE_ROOT; }; 32 | 79ACC83C07FD3DA800D4147B /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = ""; }; 33 | 8D01CCD10486CAD60068D4B7 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; 34 | 8D01CCD20486CAD60068D4B7 /* mach_inject_bundle_stub.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = mach_inject_bundle_stub.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; 35 | /* End PBXFileReference section */ 36 | 37 | /* Begin PBXFrameworksBuildPhase section */ 38 | 8D01CCCD0486CAD60068D4B7 /* Frameworks */ = { 39 | isa = PBXFrameworksBuildPhase; 40 | buildActionMask = 2147483647; 41 | files = ( 42 | 79ACC83D07FD3DA800D4147B /* Carbon.framework in Frameworks */, 43 | ); 44 | runOnlyForDeploymentPostprocessing = 0; 45 | }; 46 | /* End PBXFrameworksBuildPhase section */ 47 | 48 | /* Begin PBXGroup section */ 49 | 089C166AFE841209C02AAC07 /* mach_inject_bundle_stub */ = { 50 | isa = PBXGroup; 51 | children = ( 52 | 23A925381415A37800EE4B17 /* Cocoa.framework */, 53 | 23A925361415A36B00EE4B17 /* CoreFoundation.framework */, 54 | 23A925341415A35900EE4B17 /* CoreServices.framework */, 55 | 23A925321415A34F00EE4B17 /* Cocoa.framework */, 56 | 08FB77ADFE841716C02AAC07 /* Source */, 57 | 089C167CFE841241C02AAC07 /* Resources */, 58 | 089C1671FE841209C02AAC07 /* External Frameworks and Libraries */, 59 | 19C28FB4FE9D528D11CA2CBB /* Products */, 60 | ); 61 | name = mach_inject_bundle_stub; 62 | sourceTree = ""; 63 | }; 64 | 089C1671FE841209C02AAC07 /* External Frameworks and Libraries */ = { 65 | isa = PBXGroup; 66 | children = ( 67 | 79ACC83C07FD3DA800D4147B /* Carbon.framework */, 68 | ); 69 | name = "External Frameworks and Libraries"; 70 | sourceTree = ""; 71 | }; 72 | 089C167CFE841241C02AAC07 /* Resources */ = { 73 | isa = PBXGroup; 74 | children = ( 75 | 8D01CCD10486CAD60068D4B7 /* Info.plist */, 76 | 089C167DFE841241C02AAC07 /* InfoPlist.strings */, 77 | ); 78 | name = Resources; 79 | sourceTree = ""; 80 | }; 81 | 08FB77ADFE841716C02AAC07 /* Source */ = { 82 | isa = PBXGroup; 83 | children = ( 84 | 08FB77B2FE8417CDC02AAC07 /* mach_inject_bundle_stub.c */, 85 | 79ACC4FB07FD376D00D4147B /* mach_inject_bundle_stub.h */, 86 | 79ACC4F307FD370C00D4147B /* load_bundle.c */, 87 | 79ACC4F407FD370C00D4147B /* load_bundle.h */, 88 | 79ACC50A07FD3CE100D4147B /* mach_inject.h */, 89 | 32BAE0B30371A71500C91783 /* mach_inject_bundle_stub_Prefix.pch */, 90 | ); 91 | name = Source; 92 | sourceTree = ""; 93 | }; 94 | 19C28FB4FE9D528D11CA2CBB /* Products */ = { 95 | isa = PBXGroup; 96 | children = ( 97 | 8D01CCD20486CAD60068D4B7 /* mach_inject_bundle_stub.bundle */, 98 | ); 99 | name = Products; 100 | sourceTree = ""; 101 | }; 102 | /* End PBXGroup section */ 103 | 104 | /* Begin PBXHeadersBuildPhase section */ 105 | 8D01CCC70486CAD60068D4B7 /* Headers */ = { 106 | isa = PBXHeadersBuildPhase; 107 | buildActionMask = 2147483647; 108 | files = ( 109 | 8D01CCC80486CAD60068D4B7 /* mach_inject_bundle_stub_Prefix.pch in Headers */, 110 | 79ACC4F607FD370C00D4147B /* load_bundle.h in Headers */, 111 | 79ACC4FC07FD376D00D4147B /* mach_inject_bundle_stub.h in Headers */, 112 | 79ACC50B07FD3CE100D4147B /* mach_inject.h in Headers */, 113 | ); 114 | runOnlyForDeploymentPostprocessing = 0; 115 | }; 116 | /* End PBXHeadersBuildPhase section */ 117 | 118 | /* Begin PBXNativeTarget section */ 119 | 8D01CCC60486CAD60068D4B7 /* mach_inject_bundle_stub */ = { 120 | isa = PBXNativeTarget; 121 | buildConfigurationList = 33B2AC4A092854FB004B1632 /* Build configuration list for PBXNativeTarget "mach_inject_bundle_stub" */; 122 | buildPhases = ( 123 | 8D01CCC70486CAD60068D4B7 /* Headers */, 124 | 8D01CCC90486CAD60068D4B7 /* Resources */, 125 | 8D01CCCB0486CAD60068D4B7 /* Sources */, 126 | 8D01CCCD0486CAD60068D4B7 /* Frameworks */, 127 | 8D01CCCF0486CAD60068D4B7 /* Rez */, 128 | ); 129 | buildRules = ( 130 | ); 131 | dependencies = ( 132 | ); 133 | name = mach_inject_bundle_stub; 134 | productInstallPath = "$(HOME)/Library/Bundles"; 135 | productName = mach_inject_bundle_stub; 136 | productReference = 8D01CCD20486CAD60068D4B7 /* mach_inject_bundle_stub.bundle */; 137 | productType = "com.apple.product-type.bundle"; 138 | }; 139 | /* End PBXNativeTarget section */ 140 | 141 | /* Begin PBXProject section */ 142 | 089C1669FE841209C02AAC07 /* Project object */ = { 143 | isa = PBXProject; 144 | attributes = { 145 | LastUpgradeCheck = 0410; 146 | }; 147 | buildConfigurationList = 33B2AC4E092854FB004B1632 /* Build configuration list for PBXProject "mach_inject_bundle_stub" */; 148 | compatibilityVersion = "Xcode 3.2"; 149 | developmentRegion = English; 150 | hasScannedForEncodings = 1; 151 | knownRegions = ( 152 | en, 153 | ); 154 | mainGroup = 089C166AFE841209C02AAC07 /* mach_inject_bundle_stub */; 155 | projectDirPath = ""; 156 | projectRoot = ""; 157 | targets = ( 158 | 8D01CCC60486CAD60068D4B7 /* mach_inject_bundle_stub */, 159 | ); 160 | }; 161 | /* End PBXProject section */ 162 | 163 | /* Begin PBXResourcesBuildPhase section */ 164 | 8D01CCC90486CAD60068D4B7 /* Resources */ = { 165 | isa = PBXResourcesBuildPhase; 166 | buildActionMask = 2147483647; 167 | files = ( 168 | 8D01CCCA0486CAD60068D4B7 /* InfoPlist.strings in Resources */, 169 | ); 170 | runOnlyForDeploymentPostprocessing = 0; 171 | }; 172 | /* End PBXResourcesBuildPhase section */ 173 | 174 | /* Begin PBXRezBuildPhase section */ 175 | 8D01CCCF0486CAD60068D4B7 /* Rez */ = { 176 | isa = PBXRezBuildPhase; 177 | buildActionMask = 2147483647; 178 | files = ( 179 | ); 180 | runOnlyForDeploymentPostprocessing = 0; 181 | }; 182 | /* End PBXRezBuildPhase section */ 183 | 184 | /* Begin PBXSourcesBuildPhase section */ 185 | 8D01CCCB0486CAD60068D4B7 /* Sources */ = { 186 | isa = PBXSourcesBuildPhase; 187 | buildActionMask = 2147483647; 188 | files = ( 189 | 8D01CCCC0486CAD60068D4B7 /* mach_inject_bundle_stub.c in Sources */, 190 | 79ACC4F507FD370C00D4147B /* load_bundle.c in Sources */, 191 | ); 192 | runOnlyForDeploymentPostprocessing = 0; 193 | }; 194 | /* End PBXSourcesBuildPhase section */ 195 | 196 | /* Begin PBXVariantGroup section */ 197 | 089C167DFE841241C02AAC07 /* InfoPlist.strings */ = { 198 | isa = PBXVariantGroup; 199 | children = ( 200 | 089C167EFE841241C02AAC07 /* English */, 201 | ); 202 | name = InfoPlist.strings; 203 | sourceTree = ""; 204 | }; 205 | /* End PBXVariantGroup section */ 206 | 207 | /* Begin XCBuildConfiguration section */ 208 | 33B2AC4B092854FB004B1632 /* Development */ = { 209 | isa = XCBuildConfiguration; 210 | buildSettings = { 211 | COPY_PHASE_STRIP = NO; 212 | DEBUGGING_SYMBOLS = YES; 213 | FRAMEWORK_SEARCH_PATHS = ""; 214 | GCC_DYNAMIC_NO_PIC = NO; 215 | GCC_ENABLE_TRIGRAPHS = NO; 216 | GCC_GENERATE_DEBUGGING_SYMBOLS = YES; 217 | GCC_OPTIMIZATION_LEVEL = 0; 218 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 219 | GCC_PREFIX_HEADER = mach_inject_bundle_stub_Prefix.pch; 220 | GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO; 221 | GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; 222 | GCC_WARN_UNKNOWN_PRAGMAS = NO; 223 | HEADER_SEARCH_PATHS = ""; 224 | INFOPLIST_FILE = Info.plist; 225 | INSTALL_PATH = "$(HOME)/Library/Bundles"; 226 | LIBRARY_SEARCH_PATHS = ""; 227 | LIBRARY_STYLE = Bundle; 228 | OTHER_CFLAGS = ""; 229 | OTHER_LDFLAGS = ""; 230 | OTHER_REZFLAGS = ""; 231 | PRODUCT_NAME = mach_inject_bundle_stub; 232 | SECTORDER_FLAGS = ""; 233 | WARNING_CFLAGS = ( 234 | "-Wmost", 235 | "-Wno-four-char-constants", 236 | "-Wno-unknown-pragmas", 237 | ); 238 | WRAPPER_EXTENSION = bundle; 239 | ZERO_LINK = YES; 240 | }; 241 | name = Development; 242 | }; 243 | 33B2AC4C092854FB004B1632 /* Deployment */ = { 244 | isa = XCBuildConfiguration; 245 | buildSettings = { 246 | COPY_PHASE_STRIP = YES; 247 | FRAMEWORK_SEARCH_PATHS = ""; 248 | GCC_ENABLE_TRIGRAPHS = NO; 249 | GCC_GENERATE_DEBUGGING_SYMBOLS = NO; 250 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 251 | GCC_PREFIX_HEADER = mach_inject_bundle_stub_Prefix.pch; 252 | GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO; 253 | GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; 254 | GCC_WARN_UNKNOWN_PRAGMAS = NO; 255 | HEADER_SEARCH_PATHS = ""; 256 | INFOPLIST_FILE = Info.plist; 257 | INSTALL_PATH = "$(HOME)/Library/Bundles"; 258 | LIBRARY_SEARCH_PATHS = ""; 259 | LIBRARY_STYLE = Bundle; 260 | OTHER_CFLAGS = ""; 261 | OTHER_LDFLAGS = ""; 262 | OTHER_REZFLAGS = ""; 263 | PRODUCT_NAME = mach_inject_bundle_stub; 264 | SECTORDER_FLAGS = ""; 265 | WARNING_CFLAGS = ( 266 | "-Wmost", 267 | "-Wno-four-char-constants", 268 | "-Wno-unknown-pragmas", 269 | ); 270 | WRAPPER_EXTENSION = bundle; 271 | ZERO_LINK = NO; 272 | }; 273 | name = Deployment; 274 | }; 275 | 33B2AC4D092854FB004B1632 /* Default */ = { 276 | isa = XCBuildConfiguration; 277 | buildSettings = { 278 | FRAMEWORK_SEARCH_PATHS = ""; 279 | GCC_ENABLE_TRIGRAPHS = NO; 280 | GCC_GENERATE_DEBUGGING_SYMBOLS = NO; 281 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 282 | GCC_PREFIX_HEADER = mach_inject_bundle_stub_Prefix.pch; 283 | GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO; 284 | GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; 285 | GCC_WARN_UNKNOWN_PRAGMAS = NO; 286 | HEADER_SEARCH_PATHS = ""; 287 | INFOPLIST_FILE = Info.plist; 288 | INSTALL_PATH = "$(HOME)/Library/Bundles"; 289 | LIBRARY_SEARCH_PATHS = ""; 290 | LIBRARY_STYLE = Bundle; 291 | OTHER_CFLAGS = ""; 292 | OTHER_LDFLAGS = ""; 293 | OTHER_REZFLAGS = ""; 294 | PRODUCT_NAME = mach_inject_bundle_stub; 295 | SECTORDER_FLAGS = ""; 296 | WARNING_CFLAGS = ( 297 | "-Wmost", 298 | "-Wno-four-char-constants", 299 | "-Wno-unknown-pragmas", 300 | ); 301 | WRAPPER_EXTENSION = bundle; 302 | }; 303 | name = Default; 304 | }; 305 | 33B2AC4F092854FB004B1632 /* Development */ = { 306 | isa = XCBuildConfiguration; 307 | buildSettings = { 308 | ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; 309 | }; 310 | name = Development; 311 | }; 312 | 33B2AC50092854FB004B1632 /* Deployment */ = { 313 | isa = XCBuildConfiguration; 314 | buildSettings = { 315 | ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; 316 | }; 317 | name = Deployment; 318 | }; 319 | 33B2AC51092854FB004B1632 /* Default */ = { 320 | isa = XCBuildConfiguration; 321 | buildSettings = { 322 | ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; 323 | }; 324 | name = Default; 325 | }; 326 | /* End XCBuildConfiguration section */ 327 | 328 | /* Begin XCConfigurationList section */ 329 | 33B2AC4A092854FB004B1632 /* Build configuration list for PBXNativeTarget "mach_inject_bundle_stub" */ = { 330 | isa = XCConfigurationList; 331 | buildConfigurations = ( 332 | 33B2AC4B092854FB004B1632 /* Development */, 333 | 33B2AC4C092854FB004B1632 /* Deployment */, 334 | 33B2AC4D092854FB004B1632 /* Default */, 335 | ); 336 | defaultConfigurationIsVisible = 0; 337 | defaultConfigurationName = Default; 338 | }; 339 | 33B2AC4E092854FB004B1632 /* Build configuration list for PBXProject "mach_inject_bundle_stub" */ = { 340 | isa = XCConfigurationList; 341 | buildConfigurations = ( 342 | 33B2AC4F092854FB004B1632 /* Development */, 343 | 33B2AC50092854FB004B1632 /* Deployment */, 344 | 33B2AC51092854FB004B1632 /* Default */, 345 | ); 346 | defaultConfigurationIsVisible = 0; 347 | defaultConfigurationName = Default; 348 | }; 349 | /* End XCConfigurationList section */ 350 | }; 351 | rootObject = 089C1669FE841209C02AAC07 /* Project object */; 352 | } 353 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_bundle_stub/mach_inject_bundle_stub_Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'mach_inject_bundle_stub' target in the 'mach_inject_bundle_stub' project. 3 | // 4 | 5 | #include 6 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_bundle_stub/version.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildVersion 6 | 317 7 | CFBundleShortVersionString 8 | 1.0 9 | CFBundleVersion 10 | 1.0 11 | ProductBuildVersion 12 | 7K571 13 | ProjectName 14 | CarbonProjectTemplates 15 | SourceVersion 16 | 140000 17 | 18 | 19 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_example/Injector/DKInjector.h: -------------------------------------------------------------------------------- 1 | // 2 | // Injector.h 3 | // Dark 4 | // 5 | // Created by Erwan Barrier on 8/8/12. 6 | // Copyright (c) 2012 Erwan Barrier. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | extern dispatch_source_t g_timer_source; 12 | 13 | @interface DKInjector : NSObject 14 | 15 | - (mach_error_t)inject:(pid_t)pid withBundle:(const char *)bundlePackageFileSystemRepresentation; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_example/Injector/DKInjector.m: -------------------------------------------------------------------------------- 1 | // 2 | // Injector.m 3 | // Dark 4 | // 5 | // Created by Erwan Barrier on 8/8/12. 6 | // Copyright (c) 2012 Erwan Barrier. All rights reserved. 7 | // 8 | 9 | #import "mach_inject_bundle.h" 10 | #import 11 | 12 | #import "DKInjector.h" 13 | 14 | @implementation DKInjector 15 | 16 | - (mach_error_t)inject:(pid_t)pid withBundle:(const char *)bundlePackageFileSystemRepresentation { 17 | // Disarm timer while installing framework 18 | dispatch_source_set_timer(g_timer_source, DISPATCH_TIME_FOREVER, 0llu, 0llu); 19 | 20 | mach_error_t error = mach_inject_bundle_pid(bundlePackageFileSystemRepresentation, pid); 21 | 22 | // Rearm timer 23 | dispatch_time_t t0 = dispatch_time(DISPATCH_TIME_NOW, 5llu * NSEC_PER_SEC); 24 | dispatch_source_set_timer(g_timer_source, t0, 0llu, 0llu); 25 | 26 | return (error); 27 | } 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_example/Injector/Injector-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleIdentifier 6 | com.erwanb.MachInjectSample.Injector 7 | CFBundleInfoDictionaryVersion 8 | 6.0 9 | CFBundleName 10 | Injector 11 | CFBundleVersion 12 | 0.1 13 | SMAuthorizedClients 14 | 15 | identifier com.erwanb.MachInjectSample 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_example/Injector/Injector-Launchd.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Label 6 | com.erwanb.MachInjectSample.Injector 7 | MachServices 8 | 9 | com.erwanb.MachInjectSample.Injector.mach 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_example/Injector/Injector-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'Injector' target in the 'Injector' project 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_example/Injector/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // Injector 4 | // 5 | // Created by Erwan Barrier on 8/7/12. 6 | // Copyright (c) 2012 Erwan Barrier. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "DKInjector.h" 12 | 13 | dispatch_source_t g_timer_source = NULL; 14 | 15 | int main(int argc, char *argv[]) 16 | { 17 | // Init idle-exit timer 18 | dispatch_queue_t mq = dispatch_get_main_queue(); 19 | g_timer_source = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, mq); 20 | assert(g_timer_source != NULL); 21 | 22 | /* When the idle-exit timer fires, we just call exit(2) with status 0. */ 23 | dispatch_set_context(g_timer_source, NULL); 24 | dispatch_source_set_event_handler_f(g_timer_source, (void (*)(void *))exit); 25 | /* We start off with our timer armed. This is for the simple reason that, 26 | * upon kicking off the GCD state engine, the first thing we'll get to is 27 | * a connection on our socket which will disarm the timer. Remember, handling 28 | * new connections and the firing of the idle-exit timer are synchronized. 29 | */ 30 | dispatch_time_t t0 = dispatch_time(DISPATCH_TIME_NOW, 5llu * NSEC_PER_SEC); 31 | dispatch_source_set_timer(g_timer_source, t0, 0llu, 0llu); 32 | dispatch_resume(g_timer_source); 33 | 34 | 35 | // Check in mach service 36 | launch_data_t req = launch_data_new_string(LAUNCH_KEY_CHECKIN); 37 | assert(req != NULL); 38 | 39 | launch_data_t resp = launch_msg(req); 40 | assert(resp != NULL); 41 | assert(launch_data_get_type(resp) == LAUNCH_DATA_DICTIONARY); 42 | 43 | launch_data_t machs = launch_data_dict_lookup(resp, LAUNCH_JOBKEY_MACHSERVICES); 44 | assert(machs != NULL); 45 | assert(launch_data_get_type(machs) == LAUNCH_DATA_DICTIONARY); 46 | 47 | launch_data_t machPortData = launch_data_dict_lookup(machs, "com.erwanb.MachInjectSample.Injector.mach"); 48 | 49 | mach_port_t mp = launch_data_get_machport(machPortData); 50 | launch_data_free(req); 51 | launch_data_free(resp); 52 | 53 | NSMachPort *rp = [[NSMachPort alloc] initWithMachPort:mp]; 54 | NSConnection *c = [NSConnection connectionWithReceivePort:rp sendPort:nil]; 55 | 56 | DKInjector *injector = [DKInjector new]; 57 | [c setRootObject:injector]; 58 | 59 | [[NSRunLoop currentRunLoop] run]; 60 | 61 | return (0); 62 | } 63 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_example/Installer/DKFrameworkInstaller.h: -------------------------------------------------------------------------------- 1 | // 2 | // DKInstaller.h 3 | // Dark 4 | // 5 | // Created by Erwan Barrier on 8/11/12. 6 | // Copyright (c) 2012 Erwan Barrier. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | FOUNDATION_EXPORT NSString *const DKFrameworkDstPath; 12 | 13 | extern dispatch_source_t g_timer_source; 14 | 15 | @interface DKFrameworkInstaller : NSObject 16 | 17 | @property (nonatomic, strong) NSError *error; 18 | 19 | - (BOOL)installFramework:(NSString *)frameworkPath; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_example/Installer/DKFrameworkInstaller.m: -------------------------------------------------------------------------------- 1 | // 2 | // DKInstaller.m 3 | // Dark 4 | // 5 | // Created by Erwan Barrier on 8/11/12. 6 | // Copyright (c) 2012 Erwan Barrier. All rights reserved. 7 | // 8 | 9 | #import "DKFrameworkInstaller.h" 10 | 11 | NSString *const DKFrameworkDstPath = @"/Library/Frameworks/mach_inject_bundle.framework"; 12 | 13 | @implementation DKFrameworkInstaller 14 | 15 | @synthesize error = _error; 16 | 17 | - (BOOL)installFramework:(NSString *)frameworkPath { 18 | // Disarm timer while installing framework 19 | dispatch_source_set_timer(g_timer_source, DISPATCH_TIME_FOREVER, 0llu, 0llu); 20 | 21 | NSError *fileError; 22 | BOOL result = YES; 23 | 24 | if ([[NSFileManager defaultManager] fileExistsAtPath:DKFrameworkDstPath] == YES) { 25 | result = [[NSFileManager defaultManager] removeItemAtPath:DKFrameworkDstPath error:&fileError]; 26 | } 27 | 28 | if (result == YES) { 29 | result = [[NSFileManager defaultManager] copyItemAtPath:frameworkPath toPath:DKFrameworkDstPath error:&fileError]; 30 | } 31 | 32 | if (result == NO) { 33 | _error = fileError; 34 | } 35 | 36 | // Rearm timer 37 | dispatch_time_t t0 = dispatch_time(DISPATCH_TIME_NOW, 5llu * NSEC_PER_SEC); 38 | dispatch_source_set_timer(g_timer_source, t0, 0llu, 0llu); 39 | 40 | return result; 41 | } 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_example/Installer/Installer-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleIdentifier 6 | com.erwanb.MachInjectSample.Installer 7 | CFBundleInfoDictionaryVersion 8 | 6.0 9 | CFBundleName 10 | Installer 11 | CFBundleVersion 12 | 0.1 13 | SMAuthorizedClients 14 | 15 | identifier com.erwanb.MachInjectSample 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_example/Installer/Installer-Launchd.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Label 6 | com.erwanb.MachInjectSample.Installer 7 | MachServices 8 | 9 | com.erwanb.MachInjectSample.Installer.mach 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_example/Installer/Installer-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'Installer' target in the 'Installer' project 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_example/Installer/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // Installer 4 | // 5 | // Created by Erwan Barrier on 8/11/12. 6 | // Copyright (c) 2012 Erwan Barrier. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | #import "DKFrameworkInstaller.h" 13 | 14 | dispatch_source_t g_timer_source = NULL; 15 | 16 | int main(int argc, const char * argv[]) 17 | { 18 | @autoreleasepool { 19 | // Init idle-exit timer 20 | dispatch_queue_t mq = dispatch_get_main_queue(); 21 | g_timer_source = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, mq); 22 | assert(g_timer_source != NULL); 23 | 24 | /* When the idle-exit timer fires, we just call exit(2) with status 0. */ 25 | dispatch_set_context(g_timer_source, NULL); 26 | dispatch_source_set_event_handler_f(g_timer_source, (void (*)(void *))exit); 27 | /* We start off with our timer armed. This is for the simple reason that, 28 | * upon kicking off the GCD state engine, the first thing we'll get to is 29 | * a connection on our socket which will disarm the timer. Remember, handling 30 | * new connections and the firing of the idle-exit timer are synchronized. 31 | */ 32 | dispatch_time_t t0 = dispatch_time(DISPATCH_TIME_NOW, 5llu * NSEC_PER_SEC); 33 | dispatch_source_set_timer(g_timer_source, t0, 0llu, 0llu); 34 | dispatch_resume(g_timer_source); 35 | 36 | 37 | // Check in mach service 38 | launch_data_t req = launch_data_new_string(LAUNCH_KEY_CHECKIN); 39 | assert(req != NULL); 40 | 41 | launch_data_t resp = launch_msg(req); 42 | assert(resp != NULL); 43 | assert(launch_data_get_type(resp) == LAUNCH_DATA_DICTIONARY); 44 | 45 | launch_data_t machs = launch_data_dict_lookup(resp, LAUNCH_JOBKEY_MACHSERVICES); 46 | assert(machs != NULL); 47 | assert(launch_data_get_type(machs) == LAUNCH_DATA_DICTIONARY); 48 | 49 | launch_data_t machPortData = launch_data_dict_lookup(machs, "com.erwanb.MachInjectSample.Installer.mach"); 50 | 51 | mach_port_t mp = launch_data_get_machport(machPortData); 52 | launch_data_free(req); 53 | launch_data_free(resp); 54 | 55 | NSMachPort *rp = [[NSMachPort alloc] initWithMachPort:mp]; 56 | NSConnection *c = [NSConnection connectionWithReceivePort:rp sendPort:nil]; 57 | 58 | DKFrameworkInstaller *installer = [DKFrameworkInstaller new]; 59 | [c setRootObject:installer]; 60 | 61 | [[NSRunLoop currentRunLoop] run]; 62 | 63 | return (0); 64 | } 65 | } 66 | 67 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_example/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2012 Erwan Barrier 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_example/MachInjectSample/DKAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // DKAppDelegate.h 3 | // MachInjectSample 4 | // 5 | // Created by Erwan Barrier on 04/12/12. 6 | // Copyright (c) 2012 Erwan Barrier. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface DKAppDelegate : NSObject 12 | 13 | @property (assign) IBOutlet NSWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_example/MachInjectSample/DKAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // DKAppDelegate.m 3 | // MachInjectSample 4 | // 5 | // Created by Erwan Barrier on 04/12/12. 6 | // Copyright (c) 2012 Erwan Barrier. All rights reserved. 7 | // 8 | 9 | #import "DKAppDelegate.h" 10 | #import "DKInstaller.h" 11 | #import "DKInjectorProxy.h" 12 | 13 | #include 14 | 15 | @implementation DKAppDelegate 16 | 17 | - (void)applicationDidFinishLaunching:(NSNotification *)aNotification 18 | { 19 | NSError *error; 20 | 21 | // Install helper tools 22 | if ([DKInstaller isInstalled] == NO && [DKInstaller install:&error] == NO) { 23 | assert(error != nil); 24 | 25 | NSLog(@"Couldn't install MachInjectSample (domain: %@ code: %@)", error.domain, [NSNumber numberWithInteger:error.code]); 26 | NSAlert *alert = [NSAlert alertWithError:error]; 27 | [alert runModal]; 28 | [NSApp terminate:self]; 29 | } 30 | 31 | // Inject Finder process 32 | if ([DKInjectorProxy inject:&error] == FALSE) { 33 | assert(error != nil); 34 | 35 | NSLog(@"Couldn't inject Finder (domain: %@ code: %@)", error.domain, [NSNumber numberWithInteger:error.code]); 36 | NSAlert *alert = [NSAlert alertWithError:error]; 37 | [alert runModal]; 38 | [NSApp terminate:self]; 39 | } 40 | } 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_example/MachInjectSample/DKConstant.h: -------------------------------------------------------------------------------- 1 | // 2 | // DKError.h 3 | // Dark 4 | // 5 | // Created by Erwan Barrier on 8/11/12. 6 | // Copyright (c) 2012 Erwan Barrier. All rights reserved. 7 | // 8 | 9 | FOUNDATION_EXPORT NSString *const DKUserDefaultsInstalledVersionKey; 10 | 11 | FOUNDATION_EXPORT NSString *const DKErrorDomain; 12 | 13 | enum { 14 | DKErrPermissionDenied = 0, 15 | DKErrInstallHelperTool = 1, 16 | DKErrInstallFramework = 2, 17 | DKErrInjection = 3, 18 | }; 19 | 20 | FOUNDATION_EXPORT NSString *const DKErrPermissionDeniedDescription; 21 | FOUNDATION_EXPORT NSString *const DKErrInstallDescription; 22 | FOUNDATION_EXPORT NSString *const DKErrInjectionDescription; 23 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_example/MachInjectSample/DKConstant.m: -------------------------------------------------------------------------------- 1 | // 2 | // DKError.m 3 | // Dark 4 | // 5 | // Created by Erwan Barrier on 8/11/12. 6 | // Copyright (c) 2012 Erwan Barrier. All rights reserved. 7 | // 8 | 9 | #import "DKConstant.h" 10 | 11 | NSString *const DKUserDefaultsInstalledVersionKey = @"InstalledVersion"; 12 | 13 | NSString *const DKErrorDomain = @"com.erwanb.MachInjectSample.ErrorDomain"; 14 | 15 | NSString *const DKErrPermissionDeniedDescription = @"MachInjectSample couldn't complete installation without an administrator's permission."; 16 | NSString *const DKErrInstallDescription = @"An error occurred while installing MachInjectSample. Please report this to the author."; 17 | NSString *const DKErrInjectionDescription = @"An error occurred while injecting Finder. Please report this to the author."; -------------------------------------------------------------------------------- /mach_inject/mach_inject_example/MachInjectSample/DKInjectorProxy.h: -------------------------------------------------------------------------------- 1 | // 2 | // InjectorWrapper.h 3 | // Dark 4 | // 5 | // Created by Erwan Barrier on 8/6/12. 6 | // Copyright (c) 2012 Erwan Barrier. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface DKInjectorProxy : NSObject 12 | 13 | + (BOOL)inject:(NSError **)error; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_example/MachInjectSample/DKInjectorProxy.m: -------------------------------------------------------------------------------- 1 | // 2 | // InjectorWrapper.m 3 | // Dark 4 | // 5 | // Created by Erwan Barrier on 8/6/12. 6 | // Copyright (c) 2012 Erwan Barrier. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | #import "DKInjector.h" 13 | #import "DKInjectorProxy.h" 14 | 15 | @implementation DKInjectorProxy 16 | 17 | + (BOOL)inject:(NSError **)error { 18 | NSConnection *c = [NSConnection connectionWithRegisteredName:@"com.erwanb.MachInjectSample.Injector.mach" host:nil]; 19 | assert(c != nil); 20 | 21 | DKInjector *injector = (DKInjector *)[c rootProxy]; 22 | assert(injector != nil); 23 | 24 | pid_t pid = [[[NSRunningApplication runningApplicationsWithBundleIdentifier:@"com.apple.finder"] 25 | lastObject] processIdentifier]; 26 | 27 | NSString *bundlePath = [[NSBundle mainBundle] pathForResource:@"Payload" ofType:@"bundle"]; 28 | 29 | NSLog(@"Injecting Finder (%@) with %@", [NSNumber numberWithInt:pid], bundlePath); 30 | 31 | mach_error_t err = [injector inject:pid withBundle:[bundlePath fileSystemRepresentation]]; 32 | 33 | if (err == 0) { 34 | NSLog(@"Injected Finder"); 35 | return YES; 36 | } else { 37 | NSLog(@"an error occurred while injecting Finder: %@ (error code: %@)", [NSString stringWithCString:mach_error_string(err) encoding:NSASCIIStringEncoding], [NSNumber numberWithInt:err]); 38 | 39 | *error = [[NSError alloc] initWithDomain:DKErrorDomain 40 | code:DKErrInjection 41 | userInfo:@{NSLocalizedDescriptionKey: DKErrInjectionDescription}]; 42 | 43 | return NO; 44 | } 45 | } 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_example/MachInjectSample/DKInstaller.h: -------------------------------------------------------------------------------- 1 | // 2 | // DKInstaller.h 3 | // Dark 4 | // 5 | // Created by Erwan Barrier on 8/11/12. 6 | // Copyright (c) 2012 Erwan Barrier. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | FOUNDATION_EXPORT NSString *const DKInjectorExecutablLabel; 12 | FOUNDATION_EXPORT NSString *const DKInstallerExecutablLabel; 13 | 14 | @interface DKInstaller : NSObject 15 | 16 | + (BOOL)isInstalled; 17 | + (BOOL)install:(NSError **)error; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_example/MachInjectSample/DKInstaller.m: -------------------------------------------------------------------------------- 1 | // 2 | // DKInstaller.m 3 | // Dark 4 | // 5 | // Created by Erwan Barrier on 8/11/12. 6 | // Copyright (c) 2012 Erwan Barrier. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "DKInstaller.h" 12 | #import "DKFrameworkInstaller.h" 13 | 14 | NSString *const DKInjectorExecutablLabel = @"com.erwanb.MachInjectSample.Injector"; 15 | NSString *const DKInstallerExecutablLabel = @"com.erwanb.MachInjectSample.Installer"; 16 | 17 | @interface DKInstaller () 18 | + (BOOL)askPermission:(AuthorizationRef *)authRef error:(NSError **)error; 19 | + (BOOL)installHelperTool:(NSString *)executableLabel authorizationRef:(AuthorizationRef)authRef error:(NSError **)error; 20 | + (BOOL)installMachInjectBundleFramework:(NSError **)error; 21 | @end 22 | 23 | @implementation DKInstaller 24 | 25 | + (BOOL)isInstalled { 26 | NSString *versionInstalled = [[NSUserDefaults standardUserDefaults] stringForKey:DKUserDefaultsInstalledVersionKey]; 27 | NSString *currentVersion = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"]; 28 | 29 | return ([currentVersion compare:versionInstalled] == NSOrderedSame); 30 | } 31 | 32 | + (BOOL)install:(NSError **)error { 33 | AuthorizationRef authRef = NULL; 34 | BOOL result = YES; 35 | 36 | result = [self askPermission:&authRef error:error]; 37 | 38 | if (result == YES) { 39 | result = [self installHelperTool:DKInstallerExecutablLabel authorizationRef:authRef error:error]; 40 | } 41 | 42 | if (result == YES) { 43 | result = [self installMachInjectBundleFramework:error]; 44 | } 45 | 46 | if (result == YES) { 47 | result = [self installHelperTool:DKInjectorExecutablLabel authorizationRef:authRef error:error]; 48 | } 49 | 50 | if (result == YES) { 51 | NSString *currentVersion = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"]; 52 | [[NSUserDefaults standardUserDefaults] setObject:currentVersion forKey:DKUserDefaultsInstalledVersionKey]; 53 | 54 | NSLog(@"Installed v%@", currentVersion); 55 | } 56 | 57 | return result; 58 | } 59 | 60 | + (BOOL)askPermission:(AuthorizationRef *)authRef error:(NSError **)error { 61 | // Creating auth item to bless helper tool and install framework 62 | AuthorizationItem authItem = {kSMRightBlessPrivilegedHelper, 0, NULL, 0}; 63 | 64 | // Creating a set of authorization rights 65 | AuthorizationRights authRights = {1, &authItem}; 66 | 67 | // Specifying authorization options for authorization 68 | AuthorizationFlags flags = kAuthorizationFlagDefaults | kAuthorizationFlagInteractionAllowed | kAuthorizationFlagExtendRights; 69 | 70 | // Open dialog and prompt user for password 71 | OSStatus status = AuthorizationCreate(&authRights, kAuthorizationEmptyEnvironment, flags, authRef); 72 | 73 | if (status == errAuthorizationSuccess) { 74 | return YES; 75 | } else { 76 | NSLog(@"%@ (error code: %@)", DKErrPermissionDeniedDescription, [NSNumber numberWithInt:status]); 77 | 78 | *error = [[NSError alloc] initWithDomain:DKErrorDomain 79 | code:DKErrPermissionDenied 80 | userInfo:@{NSLocalizedDescriptionKey: DKErrPermissionDeniedDescription}]; 81 | 82 | return NO; 83 | } 84 | } 85 | 86 | + (BOOL)installHelperTool:(NSString *)executableLabel authorizationRef:(AuthorizationRef)authRef error:(NSError **)error { 87 | CFErrorRef blessError = NULL; 88 | BOOL result; 89 | 90 | result = SMJobBless(kSMDomainSystemLaunchd, (__bridge CFStringRef)executableLabel, authRef, &blessError); 91 | 92 | if (result == NO) { 93 | CFIndex errorCode = CFErrorGetCode(blessError); 94 | CFStringRef errorDomain = CFErrorGetDomain(blessError); 95 | 96 | NSLog(@"an error occurred while installing %@ (domain: %@ (%@))", executableLabel, errorDomain, [NSNumber numberWithLong:errorCode]); 97 | 98 | *error = [[NSError alloc] initWithDomain:DKErrorDomain 99 | code:DKErrInstallHelperTool 100 | userInfo:@{NSLocalizedDescriptionKey: DKErrInstallDescription}]; 101 | } else { 102 | NSLog(@"Installed %@ successfully", executableLabel); 103 | } 104 | 105 | return result; 106 | } 107 | 108 | + (BOOL)installMachInjectBundleFramework:(NSError **)error { 109 | NSString *frameworkPath = [[NSBundle mainBundle] pathForResource:@"mach_inject_bundle" ofType:@"framework"]; 110 | BOOL result = YES; 111 | 112 | NSConnection *c = [NSConnection connectionWithRegisteredName:@"com.erwanb.MachInjectSample.Installer.mach" host:nil]; 113 | assert(c != nil); 114 | 115 | DKFrameworkInstaller *installer = (DKFrameworkInstaller *)[c rootProxy]; 116 | assert(installer != nil); 117 | 118 | result = [installer installFramework:frameworkPath]; 119 | 120 | if (result == YES) { 121 | NSLog(@"Installed mach_inject_bundle.framework successfully"); 122 | } else { 123 | NSLog(@"an error occurred while installing mach_inject_bundle.framework (domain: %@ code: %@)", installer.error.domain, [NSNumber numberWithInteger:installer.error.code]); 124 | 125 | *error = [[NSError alloc] initWithDomain:DKErrorDomain 126 | code:DKErrInstallFramework 127 | userInfo:@{NSLocalizedDescriptionKey: DKErrInstallDescription}]; 128 | } 129 | 130 | return result; 131 | } 132 | 133 | @end 134 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_example/MachInjectSample/MachInjectSample-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | com.erwanb.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.1 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSMinimumSystemVersion 26 | ${MACOSX_DEPLOYMENT_TARGET} 27 | NSHumanReadableCopyright 28 | Copyright © 2012 Erwan Barrier. All rights reserved. 29 | NSMainNibFile 30 | MainMenu 31 | NSPrincipalClass 32 | NSApplication 33 | SMPrivilegedExecutables 34 | 35 | com.erwanb.MachInjectSample.Injector 36 | identifier com.erwanb.MachInjectSample.Injector 37 | com.erwanb.MachInjectSample.Installer 38 | identifier com.erwanb.MachInjectSample.Installer 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_example/MachInjectSample/MachInjectSample-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'MachInjectSample' target in the 'MachInjectSample' project 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #import "DKConstant.h" 8 | #endif 9 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_example/MachInjectSample/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_example/MachInjectSample/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // MachInjectSample 4 | // 5 | // Created by Erwan Barrier on 04/12/12. 6 | // Copyright (c) 2012 Erwan Barrier. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, char *argv[]) 12 | { 13 | return NSApplicationMain(argc, (const char **)argv); 14 | } 15 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_example/Payload/Payload-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | com.erwanb.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | BNDL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | NSHumanReadableCopyright 26 | Copyright © 2012 Erwan Barrier. All rights reserved. 27 | NSPrincipalClass 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_example/Payload/Payload-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'Payload' target in the 'Payload' project 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_example/Payload/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_example/Payload/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.c 3 | // Dark 4 | // 5 | // Created by Erwan Barrier on 8/8/12. 6 | // Copyright (c) 2012 Erwan Barrier. All rights reserved. 7 | // 8 | 9 | #include 10 | 11 | __attribute__((constructor)) 12 | void load() 13 | { 14 | syslog(LOG_NOTICE, "MachInjectSample PAYLOAD: My pid is %d\n", getpid()); 15 | } -------------------------------------------------------------------------------- /mach_inject/mach_inject_example/README.md: -------------------------------------------------------------------------------- 1 | # Welcome To MachInjectSample 2 | 3 | MachInjectSample demonstrate the use of mach inject with the new SMJobBless API. By creating a privileged helper tool with the SMJobBless API, we can avoid asking an admin password each time we need to inject code into a process. 4 | 5 | ## Description of contents 6 | 7 | * MachInjectSample: The app. 8 | * Installer: a helper tool (launch-on-demand) for installing mach_inject_bundle.framework (needed by the injector). This avoid the need to create a pkg installer, as the injector need to know the path to mach_inject_bundle at compile time. 9 | * Injector: a helper tool (launch-on-demand daemon) for injecting code in a process. 10 | * Payload: a bundle running inside the process. For demonstration purpose, it just write a message in /var/log/system.log upon loading. 11 | 12 | Before testing, you need to code-sign the app, injector and installer with the same certificate. 13 | 14 | For more info about the SMJobBless API, [see here](https://developer.apple.com/library/mac/#documentation/ServiceManagement/Reference/ServiceManagement_header_reference/Reference/reference.html#//apple_ref/doc/uid/TP40012447). 15 | For more info on mach_inject, [see here](https://github.com/rentzsch/mach_inject). 16 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_sandbox/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface AppDelegate : NSObject {} 4 | @end 5 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_sandbox/AppDelegate.m: -------------------------------------------------------------------------------- 1 | #import "AppDelegate.h" 2 | #include "mach_inject_bundle/mach_inject_bundle.h" 3 | 4 | @implementation AppDelegate 5 | 6 | - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { 7 | printf("lol\n"); 8 | mach_error_t err = mach_inject_bundle_pid( [[[NSBundle mainBundle] pathForResource:@"mach_inject_sandbox_bundle" 9 | ofType:@"bundle"] fileSystemRepresentation], 10 | getpid() ); 11 | assert( !err ); 12 | } 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_sandbox/English.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zerodivisi0n/FinderMenu/d65aac3e98e75924c9efa0fae48b02bbc0928e53/mach_inject/mach_inject_sandbox/English.lproj/InfoPlist.strings -------------------------------------------------------------------------------- /mach_inject/mach_inject_sandbox/English.lproj/MainMenu.nib/classes.nib: -------------------------------------------------------------------------------- 1 | { 2 | IBClasses = ( 3 | {CLASS = AppDelegate; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, 4 | {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; } 5 | ); 6 | IBVersion = 1; 7 | } -------------------------------------------------------------------------------- /mach_inject/mach_inject_sandbox/English.lproj/MainMenu.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBDocumentLocation 6 | 224 181 356 240 0 0 2560 1578 7 | IBEditorPositions 8 | 9 | 29 10 | 219 549 338 44 0 0 2560 1578 11 | 12 | IBFramework Version 13 | 443.0 14 | IBOpenObjects 15 | 16 | 29 17 | 18 | IBSystem Version 19 | 8F46 20 | 21 | 22 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_sandbox/English.lproj/MainMenu.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zerodivisi0n/FinderMenu/d65aac3e98e75924c9efa0fae48b02bbc0928e53/mach_inject/mach_inject_sandbox/English.lproj/MainMenu.nib/keyedobjects.nib -------------------------------------------------------------------------------- /mach_inject/mach_inject_sandbox/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | com.yourcompany.mach_inject_sandbox 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | NSMainNibFile 24 | MainMenu 25 | NSPrincipalClass 26 | NSApplication 27 | 28 | 29 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_sandbox/InjectedBundleClass.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface InjectedBundleClass : NSObject {} 4 | @end 5 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_sandbox/InjectedBundleClass.m: -------------------------------------------------------------------------------- 1 | #import "InjectedBundleClass.h" 2 | 3 | @implementation InjectedBundleClass 4 | 5 | + (void)load { 6 | NSLog( @"+[InjectedBundleClass load]" ); 7 | } 8 | 9 | @end 10 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_sandbox/Japanese.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zerodivisi0n/FinderMenu/d65aac3e98e75924c9efa0fae48b02bbc0928e53/mach_inject/mach_inject_sandbox/Japanese.lproj/InfoPlist.strings -------------------------------------------------------------------------------- /mach_inject/mach_inject_sandbox/Japanese.lproj/MainMenu.nib/classes.nib: -------------------------------------------------------------------------------- 1 | { 2 | IBClasses = ({CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }); 3 | IBVersion = 1; 4 | } -------------------------------------------------------------------------------- /mach_inject/mach_inject_sandbox/Japanese.lproj/MainMenu.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBDocumentLocation 6 | 94 103 356 240 0 0 1280 1002 7 | IBEditorPositions 8 | 9 | 29 10 | 93 343 318 44 0 0 1280 1002 11 | 12 | IBFramework Version 13 | 403.0 14 | IBSystem Version 15 | 8A278 16 | 17 | 18 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_sandbox/Japanese.lproj/MainMenu.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zerodivisi0n/FinderMenu/d65aac3e98e75924c9efa0fae48b02bbc0928e53/mach_inject/mach_inject_sandbox/Japanese.lproj/MainMenu.nib/keyedobjects.nib -------------------------------------------------------------------------------- /mach_inject/mach_inject_sandbox/mach_inject_sandbox_Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'mach_inject_sandbox' target in the 'mach_inject_sandbox' project 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_sandbox/mach_inject_sandbox_bundle-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | com.rentzsch.mach_inject_sandbox_bundle 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleSignature 16 | ???? 17 | CFBundleVersion 18 | 1.0 19 | 20 | 21 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_sandbox/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // mach_inject_sandbox 4 | // 5 | // Created by wolf on 1/1/06. 6 | // Copyright __MyCompanyName__ 2006. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, char *argv[]) 12 | { 13 | return NSApplicationMain(argc, (const char **) argv); 14 | } 15 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_test/English.lproj/injectee-InfoPlist.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zerodivisi0n/FinderMenu/d65aac3e98e75924c9efa0fae48b02bbc0928e53/mach_inject/mach_inject_test/English.lproj/injectee-InfoPlist.strings -------------------------------------------------------------------------------- /mach_inject/mach_inject_test/English.lproj/injectee-MainMenu.nib/classes.nib: -------------------------------------------------------------------------------- 1 | { 2 | IBClasses = ( 3 | {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, 4 | {CLASS = "injectee_AppDelegate"; LANGUAGE = ObjC; SUPERCLASS = NSObject; } 5 | ); 6 | IBVersion = 1; 7 | } -------------------------------------------------------------------------------- /mach_inject/mach_inject_test/English.lproj/injectee-MainMenu.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBDocumentLocation 6 | 383 188 356 240 0 0 2560 1578 7 | IBEditorPositions 8 | 9 | 29 10 | 219 549 338 44 0 0 2560 1578 11 | 12 | IBFramework Version 13 | 443.0 14 | IBOpenObjects 15 | 16 | 29 17 | 21 18 | 19 | IBSystem Version 20 | 8F46 21 | 22 | 23 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_test/English.lproj/injectee-MainMenu.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zerodivisi0n/FinderMenu/d65aac3e98e75924c9efa0fae48b02bbc0928e53/mach_inject/mach_inject_test/English.lproj/injectee-MainMenu.nib/keyedobjects.nib -------------------------------------------------------------------------------- /mach_inject/mach_inject_test/English.lproj/injector-InfoPlist.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zerodivisi0n/FinderMenu/d65aac3e98e75924c9efa0fae48b02bbc0928e53/mach_inject/mach_inject_test/English.lproj/injector-InfoPlist.strings -------------------------------------------------------------------------------- /mach_inject/mach_inject_test/English.lproj/injector-MainMenu.nib/classes.nib: -------------------------------------------------------------------------------- 1 | { 2 | IBClasses = ( 3 | {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, 4 | {CLASS = "injector_AppDelegate"; LANGUAGE = ObjC; SUPERCLASS = NSObject; } 5 | ); 6 | IBVersion = 1; 7 | } -------------------------------------------------------------------------------- /mach_inject/mach_inject_test/English.lproj/injector-MainMenu.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBDocumentLocation 6 | 11 183 356 240 0 0 2560 1578 7 | IBEditorPositions 8 | 9 | 29 10 | 219 549 338 44 0 0 2560 1578 11 | 12 | IBFramework Version 13 | 443.0 14 | IBOpenObjects 15 | 16 | 29 17 | 21 18 | 19 | IBSystem Version 20 | 8F46 21 | 22 | 23 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_test/English.lproj/injector-MainMenu.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zerodivisi0n/FinderMenu/d65aac3e98e75924c9efa0fae48b02bbc0928e53/mach_inject/mach_inject_test/English.lproj/injector-MainMenu.nib/keyedobjects.nib -------------------------------------------------------------------------------- /mach_inject/mach_inject_test/injected-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | com.rentzsch.mach_inject_test_injected_bundle 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleSignature 16 | ???? 17 | CFBundleVersion 18 | 1.0 19 | NSPrincipalClass 20 | injected_PrincipalClass 21 | 22 | 23 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_test/injected-PrincipalClass.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface injected_PrincipalClass : NSObject {} 4 | @end 5 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_test/injected-PrincipalClass.m: -------------------------------------------------------------------------------- 1 | #import "injected-PrincipalClass.h" 2 | 3 | @interface NSObject (mach_inject_test_injectee_app) 4 | - (void)notifyInjecteeSuccessfullyInjected; 5 | @end 6 | 7 | @interface mach_inject_test_injected_bundle : NSObject {} 8 | - (unsigned)testInjectedBundle; 9 | @end 10 | @implementation mach_inject_test_injected_bundle 11 | - (unsigned)testInjectedBundle { 12 | return 42; 13 | } 14 | @end 15 | 16 | @implementation injected_PrincipalClass 17 | 18 | + (void)load { 19 | printf("LOADDDDDDDDDD!\n"); 20 | NSConnection *connection = [[NSConnection defaultConnection] retain]; 21 | [connection setRootObject:[[[mach_inject_test_injected_bundle alloc] init] autorelease]]; 22 | [connection registerName:[[connection rootObject] className]]; 23 | 24 | [[NSApp delegate] notifyInjecteeSuccessfullyInjected]; 25 | assert(0); 26 | } 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_test/injectee-AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface injectee_AppDelegate : NSObject {} 4 | @end 5 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_test/injectee-AppDelegate.m: -------------------------------------------------------------------------------- 1 | #import "injectee-AppDelegate.h" 2 | 3 | @interface NSObject (mach_inject_test_injector_app) 4 | - (void)notifyInjectorReadyForInjection; 5 | - (void)notifyInjectorSuccessfullyInjected; 6 | @end 7 | 8 | @implementation injectee_AppDelegate 9 | 10 | - (void)applicationDidFinishLaunching:(NSNotification*)notification_ { 11 | return; 12 | id injector = [NSConnection rootProxyForConnectionWithRegisteredName:@"mach_inject_test_injector_app" host:nil]; 13 | printf("hi!!!\n"); 14 | assert( injector ); 15 | [injector notifyInjectorReadyForInjection]; 16 | } 17 | 18 | - (void)notifyInjecteeSuccessfullyInjected { 19 | return; 20 | printf("OMG injected!!!\n"); 21 | id injector = [NSConnection rootProxyForConnectionWithRegisteredName:@"mach_inject_test_injector_app" host:nil]; 22 | assert( injector ); 23 | [injector notifyInjectorSuccessfullyInjected]; 24 | } 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_test/injectee-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | com.rentzsch.mach_inject_test_injectee_app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | APPL 15 | CFBundleSignature 16 | ???? 17 | CFBundleVersion 18 | 1.0 19 | NSMainNibFile 20 | injectee-MainMenu 21 | NSPrincipalClass 22 | NSApplication 23 | 24 | 25 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_test/injector-AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface injector_AppDelegate : NSObject 4 | { 5 | id pid; 6 | } 7 | @end 8 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_test/injector-AppDelegate.m: -------------------------------------------------------------------------------- 1 | #import "injector-AppDelegate.h" 2 | #import 3 | 4 | NSTask *gInjecteeTask; 5 | 6 | @interface NSObject (mach_inject_test_injected_bundle) 7 | - (unsigned)testInjectedBundle; 8 | @end 9 | 10 | @interface mach_inject_test_injector_app : NSObject {} 11 | - (void)notifyInjectorReadyForInjection; 12 | @end 13 | @implementation mach_inject_test_injector_app 14 | - (void)notifyInjectorReadyForInjection { 15 | NSString *injectedBundlePath = [[NSBundle mainBundle] pathForResource:@"mach_inject_test_injected" 16 | ofType:@"bundle"]; 17 | assert( injectedBundlePath ); 18 | 19 | printf("injecting pid\n"); 20 | mach_error_t err = mach_inject_bundle_pid( [injectedBundlePath fileSystemRepresentation], 21 | [gInjecteeTask processIdentifier] ); 22 | printf("hi\n"); 23 | assert( !err ); 24 | } 25 | - (void)notifyInjectorSuccessfullyInjected { 26 | printf("successfully!\n"); 27 | id injectedBundle = [NSConnection rootProxyForConnectionWithRegisteredName:@"mach_inject_test_injected_bundle" host:nil]; 28 | assert( injectedBundle ); 29 | assert( 42 == [injectedBundle testInjectedBundle] ); 30 | 31 | [gInjecteeTask terminate]; 32 | [NSApp terminate:nil]; 33 | } 34 | @end 35 | 36 | @implementation injector_AppDelegate 37 | 38 | - (void)inject:(IBOutlet)sender 39 | { 40 | pid_t process_id = [pid intValue]; 41 | printf("injecting into pid %d\n", process_id); 42 | NSString *injectedBundlePath = [[NSBundle mainBundle] pathForResource:@"mach_inject_test_injected" 43 | ofType:@"bundle"]; 44 | assert( injectedBundlePath ); 45 | 46 | printf("injecting pid\n"); 47 | mach_error_t err = mach_inject_bundle_pid( [injectedBundlePath fileSystemRepresentation], 48 | process_id ); 49 | printf("hi\n"); 50 | assert( !err ); 51 | } 52 | 53 | - (void)applicationDidFinishLaunching:(NSNotification*)notification_ { 54 | return; 55 | NSConnection *connection = [[NSConnection defaultConnection] retain]; 56 | [connection setRootObject:[[[mach_inject_test_injector_app alloc] init] autorelease]]; 57 | [connection registerName:[[connection rootObject] className]]; 58 | 59 | assert( ![NSConnection rootProxyForConnectionWithRegisteredName:@"mach_inject_test_injected_bundle" host:nil] ); 60 | 61 | NSString *injecteeAppPath = [[NSBundle mainBundle] pathForResource:@"mach_inject_test_injectee" 62 | ofType:@"app"]; 63 | assert( injecteeAppPath ); 64 | gInjecteeTask = [NSTask launchedTaskWithLaunchPath:[injecteeAppPath stringByAppendingString:@"/Contents/MacOS/mach_inject_test_injectee"] 65 | arguments:[NSArray array]]; 66 | assert( gInjecteeTask ); 67 | } 68 | 69 | @end 70 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_test/injector-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | com.rentzsch.mach_inject_test_injector_app 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | NSMainNibFile 24 | injector-MainMenu 25 | NSPrincipalClass 26 | NSApplication 27 | 28 | 29 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_test/mach_inject_test_Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'mach_inject_test' target in the 'mach_inject_test' project 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | -------------------------------------------------------------------------------- /mach_inject/mach_inject_test/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // mach_inject_test 4 | // 5 | // Created by wolf on 1/1/06. 6 | // Copyright __MyCompanyName__ 2006. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, char *argv[]) 12 | { 13 | return NSApplicationMain(argc, (const char **) argv); 14 | } 15 | -------------------------------------------------------------------------------- /run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Helper script to start FinderMenu 3 | xcodebuild clean && \ 4 | xcodebuild && \ 5 | killall Finder && \ 6 | rm -f ~/FinderExt.log && \ 7 | sleep 1 && \ 8 | sudo build/Release/FinderMenu && \ 9 | sleep 1 && \ 10 | tail -f ~/FinderExt.log --------------------------------------------------------------------------------