For writing hacks and unofficial extensions for Mac OS X apps, there seem to be two choices today: SIMBL and mach_star
. I'm starting a project that will require injecting into another process, and I need to decide between these libraries.
What are the differences in approach and functionality between SIMBL and mach_star
? Why would I use one over the other?
SIMBL was built from mach_star... it contains mach_star in it's code...
SIMBL is the SIMple BundleLoader... note the caps.... it was designed to allow plugin modules to be stored in ~/Library/Application Support/SIMBL/Plugins and be injected into the finder automatically..
There is a startup script in /Library/Scripting Additions/SIMBL.osax... this script is responsible for installing the mach_inject_bundle.framework into /Library/Frameworks (i think) and inject the code into the target programs specified by the plist.
mach_star has several examples of performing mach_inject_bundle_pid commands and other nefarious mach method swapping magic.
To use SIMBL and have plugins you develop is one thing... you can make the plugin and you don't need to worry about injecting the finder every time finder wakes up or installing the mach_inject_bundle.framework.
YOU CAN USE THOSE PLUGINS IN YOU APP AUTOMATICALLY: you just have to have them installed and injected in your code each time finder restarts/starts up and/or when your app starts up
(the only way to eliminate your injections is to use an applescript like the following:
tell application "Finder" to quit
delay 2.5
tell application "Finder" activate
or we would need to complete the mach_star code and implement the uninject mach stuff... :(
To be professional and make an app that auto installs your plugin, we must do the following: there is code that can use SMJobBless to bless a program to do the installation of the mach_inject_bundle.framework file if its not already installed, as well as inject the finder each time your application loads and/or when the finder restarts.
zerodivisi0n:Alexey Zhuchkov has done a wonderful job as well as Erwan Barrier to illustrate how to embed some code in your app that does the following:
(pseudo code)
AppDelegate ApplicaitonDidFinishLaunching:
SMJobBlessGetPermission() //keeps us with permission to inject the finder each launch once the user has approved one time
{
//with executive permissions
if (framework is not installed)
install the mach_inject_bundle.framework into /Library/Frameworks
inject the finder with your bundle code
}
https://github.com/twotreeszf/FinderMenu
https://github.com/erwanb/MachInjectSample
Cited from MachInjectSample:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
NSError *error;
// Install helper tools
if ([DKInstaller isInstalled] == NO && [DKInstaller install:&error] == NO) {
assert(error != nil);
NSLog(@"Couldn't install MachInjectSample (domain: %@ code: %@)", error.domain, [NSNumber numberWithInteger:error.code]);
NSAlert *alert = [NSAlert alertWithError:error];
[alert runModal];
[NSApp terminate:self];
}
// Inject Finder process
if ([DKInjectorProxy inject:&error] == FALSE) {
assert(error != nil);
NSLog(@"Couldn't inject Finder (domain: %@ code: %@)", error.domain, [NSNumber numberWithInteger:error.code]);
NSAlert *alert = [NSAlert alertWithError:error];
[alert runModal];
[NSApp terminate:self];
}
}