+# ShareKitTest: Research into injecting custom sharing services for OS X
+OS X 10.8 Mountain Lion has introduced a share button as a concept. This was
+integrated into various applications shipping with the OS, and was exposed as
+a public API for application developers.
+It's a very handy way to share content for users, and easy to implement for
+The trouble is, some of us don't use just the "proscribed" services such as
+Twitter or Facebook. OS X 10.9 Mavericks has introduced LinkedIn and more,
+but some services are sorely missing.
+**Note:** The code was developed under OS X 10.8, which is why I am
+releasing it. I am uninterested in further exploration on how to write sharing
+plugins, since I have never went into working on the Google+ plugin that was
+the motivation behind the search (aside from the fact that Apple actively
+blocked something so trivial).
+I am not a security researcher nor do I ordinarily play with defeating systems.
+This has piqued my interest because I was being blocked from using trivial
+services on *my own machine*. And having upgraded to 10.9, and this method
+still working, but me no longer being motivated to continue exploration of the
+APIs, I release this in hope someone else will play with it.
+Hopefully, Apple will not be inspired to block people completely off. I really
+like the deep integration of something that works more elegantly than
+NeXT-style Services. Please, Apple, open ShareKit up.
+OS X 10.8 has a helper process that actually provides the sharing service
+to applications. Access to this helper process is provided solely through
+a simple API. This is alright. What's even better is that there are bundles
+with extension `.sharingservice` implementing individual services.
+Surely we could just implement a plugin and have it loaded by `ShareKit`,
+as this entire framework is fondly named by Apple?
+Of course not. If you try that, first you find out that the plugin is not
+even looked for in the expected location such as `/Library/ShareKit/PlugIns`,
+which would be analogous to where these are looked for in the System domain's
+`Library` folder. Not wanting to dig into `/System` (which is a big no-no),
+you figure out that you can put the framework in
+Hurray? Of course not! You get informed that:
+ com.apple.ShareKitHelper: --error: [ShareKit-Plugin] ShareKit plugin is not signed by Apple: file:///AppleInternal/Library/ShareKit/PlugIns/ShareKitTest.sharingservice/
+ com.apple.ShareKitHelper: ShareKit plugin is not signed by Apple: file:///AppleInternal/Library/ShareKit/PlugIns/ShareKitTest.sharingservice/
+Thanks so much, for first not documenting this and then blocking enterprising
+developers and hackers from even trying to figure out how to load their
+own plugins. Oh well -- there must be reasons for not disclosing a way
+You can use a debugger such as `gdb` or `lldb` to attach to the
+`com.apple.ShareKitHelper` process as soon as it launches. When it launches,
+you tell the process to break as soon as it enters `NSApplicationMain()`;
+you want some setup to be done and some essential frameworks to be loaded
+before loading your own code.
+Then you load your plugin. Inside this code, we abuse the fact that Objective-C
+categories override the base class methods. That is, if we extend an
+Objective-C class with a category (those not familiar with the language:
+a category is not a subclass), we actually replace the implementation of the
+ShareKit has an interesting class `SHKServicesManager` with an even more
+interesting method: `- (BOOL)isFileSignedByAppleAtURL:(id)arg1`. Accepting an
+`NSURL`, we can trivially return `YES` and every single plugin will be loaded
+by ShareKitHelper. (Our plugin is already loaded, so no problem there.)
+Next we have to implement a `SHKShareWindowServiceProvider`. Our subclass
+will return services in appropriate contexts, window controller class,
+We also need to implement a `SHKShareWindowController` subclass, which will
+contain our actual user interface.
+The Xcode project contains a custom 'Run Script' build step which deploys
+the plugin into `/AppleInternal` path. It also contains a 'shared schema'
+which is configured to, before running, `killall -9 com.apple.ShareKitHelper`.
+Then it waits for 'something' (your click on a Share button) to run
+Service should then be loaded and the Share button should show two new
+options, the second of which actually has some user interface.
+(Looking back, I don't know why my original instructions include breaking
+at `NSApplicationMain()`. Obviously because otherwise the plugin didn't work.
+However, looking at the Xcode project's configuration, obviously this is not
+My research into injecting an extra service has stopped once I succeeded in
+injecting custom dummy services into ShareKit.
+When today I was researching whether the project still works under OS X 10.9,
+initially it didn't work. I didn't know why; fiddling around, it started to
+work as if nothing happened.
+Everything is an experiment created during 10.8. Apple might block off
+attaching a debugger from `ShareKitHelper` in the future, which is why I
+still would advise people not to create finished products based on this
+knowledge. You may want to keep your plugin and application and what-not
+for other hackers. It's your choice, of course.
+-- Ivan Vucica <email@example.com> - Oct 5 2013