Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Programmatically expanding iOS dictionary app lexicons

Tags:

dictionary

ios

There is an app in the Apple App Store that downloads custom dictionaries and programmatically adds them to the iOS's built-in Dictionary.app without user intervention. It works normally with the stock ROM, i.e. no jailbreak or anything of that sort is required.

I wonder how this is possible since Apple has never documented such a "feature." There is no API or hints in the iOS and Dictionary.app documents to explain how this is done.

How could this be implemented?

like image 398
user3524743 Avatar asked Apr 11 '14 17:04

user3524743


1 Answers

Dictionary.appender app uses private framework MobileAsset.framework. There are several selectors that the app use:

  • setQueriesLocalAssetInformationOnly:

  • runQueryAndReturnError:

  • initWithAssetType:attributes:. Asset types are com.apple.MobileAsset.DictionaryServices.dictionary for iOS < 7 and com.apple.MobileAsset.DictionaryServices.dictionary2 for iOS >= 7. They are saved in /var/mobile/Library/Assets/.

And here's class-dump of the framework https://github.com/nst/iOS-Runtime-Headers/tree/master/PrivateFrameworks/MobileAsset.framework where you can find methods with those selectors.

In order to call them the app uses very simple technique - NSClassFromString to obtain class object in runtime. In our case, ASAsset and ASAssetQuery classes. I don't know how this got approved in App Store but that's how it works. Very simple technique , selectors and class names are not even encrypted.

UPDATE

The app doesn't explicitly link private MobileAsset.framework. It doesn't use any of the usual techniques to dynamically load a framework - no dlopen or NSBundle calls. Import table doesn't contain private MobileAsset.framework either. But it linked by UIKit.framework which obviously is linked by the app. I did a simple test. Wrote a stripped out console application that links only needed frameworks by turning off all the project settings that may automatically link the frameworks. Without UIKit.framework executing NSClassFromString(@"ASAsset") returns nil. With UIKit.framework it returns ASAsset class object.

like image 182
creker Avatar answered Oct 06 '22 01:10

creker