Monday, November 05, 2007

Leopard Hacking : Front Row

Thanks to my coffee, i can't seem to sleep. So to pass the time i decided to do some more work on a new brain wave i just had this evening.

It centers around front row. Well actually it had nothing to do with front row, however building on top of front row makes more sense, than starting out from scratch.

Now as you may or may not know, like most of the cool gui stuff on osx front row is a closed environment. Which means it's hacking time. Something i always wanted to play with is a decompiler. Now i'm no Dmitry Grinberg, so assembly doesn't wash with me. Instead i found this little gem.

After a a brief compile it gave me this wonderful output



struct _NSZone;

/*
* File: Movies
* Arch: Intel 80x86 (i386)
*/

@protocol BRMenuListItemProvider
- (long)itemCount;
- (float)heightForRow:(long)fp8;
- (BOOL)rowSelectable:(long)fp8;
- (id)titleForRow:(long)fp8;
- (id)itemForRow:(long)fp8;
@end

@protocol NSObject
- (BOOL)isEqual:(id)fp8;
- (unsigned int)hash;
- (Class)superclass;
- (Class)class;
- (id)self;
- (struct _NSZone *)zone;
- (id)performSelector:(SEL)fp8;
- (id)performSelector:(SEL)fp8 withObject:(id)fp12;
- (id)performSelector:(SEL)fp8 withObject:(id)fp12 withObject:(id)fp16;
- (BOOL)isProxy;
- (BOOL)isKindOfClass:(Class)fp8;
- (BOOL)isMemberOfClass:(Class)fp8;
- (BOOL)conformsToProtocol:(id)fp8;
- (BOOL)respondsToSelector:(SEL)fp8;
- (id)retain;
- (oneway void)release;
- (id)autorelease;
- (unsigned int)retainCount;
- (id)description;
@end

@interface RUIMoviesAppliance : BRAppliance
{
}

+ (id)moduleKey;
- (id)init;
- (void)dealloc;
- (id)moduleIconName;
- (float)moduleIconReflectionOffset;
- (id)moduleName;
- (id)moduleKey;
- (id)applianceController;

@end

@interface RUIMoviesApplianceController : BRMediaMenuController
{
NSArray *_headerRows;
NSMutableArray *_titlesWithUnplayedContent;
RUIMovieFolderCollection *_movieFolderCollection;
BRMovieTrailersProvider *_trailersProvider;
unsigned int _hasLocalMovies:1;
unsigned int _movieTrailersPreviewRequested:1;
unsigned int _movieTrailersSelected:1;
BRDataStore *_dataStore;
Class _msClass;
}

- (id)init;
- (void)dealloc;
- (id)musicStoreBaseType;
- (BOOL)menuDisplaysLeftIcon;
- (void)networkStatusChanged:(id)fp8;
- (BOOL)isVolatile;
- (id)loadModelData;
- (void)refreshControllerForModelUpdate;
- (BOOL)shouldRefreshForUpdateToObject:(id)fp8;
- (long)defaultIndex;
- (void)itemSelected:(long)fp8;
- (void)wasExhumedByPoppingController:(id)fp8;
- (void)wasPushed;
- (void)willBePopped;
- (void)wasPopped;
- (id)previewControlForItem:(long)fp8;
- (BOOL)brEventAction:(id)fp8;

@end

@interface RUIMoviesApplianceController (AsyncNotifications)
- (void)_movieTrailersLoaded:(id)fp8;
- (void)_swapNewController:(id)fp8;
@end

@interface RUIMoviesApplianceController (DataSourceAccess)
- (id)_movieTrailers:(id *)fp8;
@end

@interface RUIMoviesApplianceController (MediaParadeBuilders)
- (id)_moviesFolderParade;
- (id)_movieTrailersParade;
- (id)_stingrayMediaPreview;
@end

@interface RUIMoviesApplianceController (MovieLoading)
- (void)_cacheUnplayedTitles;
- (BOOL)_hasUnplayedMovies;
@end

@interface RUIMoviesApplianceController (MovieSelection)
- (id)_movieSelectedAtIndex:(long)fp8;
@end

@interface RUIMoviesApplianceController (MenuBuilding)
- (id)_buildMovieTrailersMenu;
- (id)_movieTrailersController:(id)fp8;
- (id)_buildMyMoviesMenu;
- (id)_stingrayFrontPageController;
- (id)_headerRows;
@end

@interface RUIMoviesApplianceController (DataProviders)
- (id)itemForRow:(long)fp8;
- (long)itemCount;
- (id)titleForRow:(long)fp8;
- (float)heightForRow:(long)fp8;
- (BOOL)rowSelectable:(long)fp8;
@end

@interface RUISDMovieTrailersController : RUIMovieTrailersController
{
}

- (id)initWithTrailers:(id)fp8;
- (id)previewControlForItem:(long)fp8;
- (id)titleForRow:(long)fp8;
- (long)defaultIndex;
- (id)itemForRow:(long)fp8;
- (long)itemCount;
- (void)itemSelected:(long)fp8;

@end

@interface RUIMovieTrailersController : BRMediaMenuController
{
NSArray *_trailers;
}

- (id)initWithTrailers:(id)fp8;
- (void)dealloc;
- (BOOL)isNetworkDependent;
- (void)itemSelected:(long)fp8;
- (long)itemCount;
- (id)itemForRow:(long)fp8;
- (id)titleForRow:(long)fp8;
- (float)heightForRow:(long)fp8;
- (BOOL)rowSelectable:(long)fp8;
- (id)previewControlForItem:(long)fp8;

@end

@interface RUISDMovieTrailersController (Private)
- (id)_HDMovieTrailers:(id *)fp8;
@end

@interface RUIMovieTrailersController (Private)
- (id)_movieTrailersTitle;
@end

@interface RUIMovieDirectoryController : BRMediaMenuController
{
RUIMovieFolderCollection *_collection;
NSString *_path;
}

- (id)initWithMovieFolderCollection:(id)fp8;
- (void)dealloc;
- (id)moviesForParade;
- (void)itemSelected:(long)fp8;
- (id)previewControlForItem:(long)fp8;
- (id)mediaPreviewMissingMediaType;
- (BOOL)mediaPreviewShouldShowMetadata;
- (BOOL)mediaPreviewShouldShowMetadataImmediately;
- (long)itemCount;
- (id)itemForRow:(long)fp8;
- (id)titleForRow:(long)fp8;
- (float)heightForRow:(long)fp8;
- (BOOL)rowSelectable:(long)fp8;

@end

@interface RUIMovieFolderAsset : BRBaseMediaAsset
{
NSString *_displayName;
NSURL *_mediaURL;
NSString *_folderPath;
BRImage *_posterImage;
BOOL _requestedImage;
}

+ (id)assetForName:(id)fp8 folderPath:(id)fp12 andMediaURL:(id)fp16;
- (void)dealloc;
- (void)setDisplayName:(id)fp8;
- (void)setMediaURL:(id)fp8;
- (void)setMovieFolderPath:(id)fp8;
- (id)assetID;
- (id)title;
- (id)mediaURL;
- (BOOL)hasCoverArt;
- (id)coverArt;
- (id)dateAcquired;
- (id)mediaType;

@end

@interface RUIMovieFolderAsset (ArtLoading)
- (void)_loadImage:(id)fp8;
- (void)_imageLoaded:(id)fp8;
@end

@interface RUIMovieFolderCollection : BRBaseMediaCollection
{
RUIMovieFolderCollection *_parent;
NSString *_displayName;
NSString *_folderPath;
NSArray *_childCollections;
NSArray *_childAssets;
}

+ (id)collectionForName:(id)fp8 folderPath:(id)fp12 andParent:(id)fp16;
- (void)dealloc;
- (void)setParent:(id)fp8;
- (void)setDisplayName:(id)fp8;
- (void)setMovieFolderPath:(id)fp8;
- (id)childCollections;
- (id)parentCollection;
- (id)collectionType;
- (id)collectionID;
- (int)count;
- (id)mediaAssets;
- (id)title;
- (id)titleForSorting;
- (BOOL)hasCoverArt;
- (id)coverArt;
- (BOOL)isLocal;

@end

@interface RUIMovieFolderCollection (Private)
- (void)_generateCollectionChildren;
@end

@interface BRMediaCollectionType (FolderCollectionExtension)
+ (id)folderCollection;
@end

What you see here is the headers/interface & protocol files for all the different classes located within Front rows movies appliance.

If you want to see your own front row app, it's located @ /system/library/coreservices/front row.app

Now i had heard that some good folks over at Awkward TV forums have hacked appliances for the Apple TV which is basically what the new front row on leopard is, however these don't seem to work 'out of the box', and apparently Apple updated this version before the roll out.

Coupled with all the above, i have reason to believe that the new appliances are digitally signed by [chinese] ni cai, Apple.

By reasoning for this, is a did a hex dump (using 0xED) of the appliance executables, and found the following string(s) @ 135535

"Apple Certification Authority1301U*Apple Code Signing Certification Authority"

Now just after typing the above sentence, it dawned on me that this might be for the transactions with the ITMS, for movie trailers, however i checked the settings appliance and found the same thing.

Also i tried deleting the various applications from a running front row, and it handles them gracefully, and also doesn't mind having new ones dropped in. I tried droping in the rss apple tv plugin, however it didn't like it very much.

I'm a programmer, not a hacker so this is about the limit of my skill, especially if it envolves digitally signed apps. I can barely deal with the symbian signed apps, never mind about these ones. If got some ideas or feel like getting dirty and dodging some DMCA takedown notices let me know.

UPDATE

i found this URL above the previous string, http://www.apple.com/appleca/

turns out that the certificate may be freely available, which might make life a tad bit easier.

PS. to any one wanting to warn me for breaking the law, i'm not a US resident ^_^

No comments: