APK Piracy: Using private code & resources in Android

Jan. 24, 2010, 7:31 p.m.

Did you know that the Android SDK makes it relatively easy to load code and resources from other apks into your own application? One way is to use a PathClassLoader and point it to an arbitrary APK:

new PathClassLoader("/system/app/Mms.apk", getClassLoader());

Another way is to use createPackageContext and use that context's ClassLoader to instantiate objects and load referenced resources.

Example

Let's suppose we want to use the standard messaging application's (Mms.apk) SmileyParser class that annotates CharSequences with spans to convert textual emoticons to graphical ones. Even though this functionality is not exposed, we can write a wrapper like the following to use it:

public class SmileyParserWrapper {

    private Method addSmileySpansMethod;
    private Object smileyParser;

    public SmileyParserWrapper(Context context) {

        try {

            Context mmsCtx = context.createPackageContext("com.android.mms",
                Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);

            Class<?> cl = Class.forName(
                "com.android.mms.util.SmileyParser", true, mmsCtx.getClassLoader());

            cl.getMethod("init", Context.class).invoke(null, mmsCtx);
            smileyParser = cl.getMethod("getInstance").invoke(null);
            addSmileySpansMethod = cl.getMethod("addSmileySpans", CharSequence.class);

        } catch(Exception ex) {
            // trouble
        }
    }

    public CharSequence addSmileySpans(CharSequence text) {

        try {

            return (CharSequence) addSmileySpansMethod.invoke(smileyParser, text);

        } catch (Exception ex) {

            // trouble
            return text;
        }
    }
}

Now we can use our wrapper to annotate arbitrary text with graphical emoticons:

SmileyParserWrapper smileyParser = new SmileyParserWrapper(this);
textBox.setText(smileyParser.addSmileySpans("B-) helo emoticon world ;-)"));

And here is the result: Screenshot

Disclaimer :)

Reaching past the SDK is obviously a very bad idea but there are a lot of useful things (e.g. SMS API) in the Android code base that are (not yet) public and I think it is okay to use the aforementioned methods for personal (experimental) applications.

about

subscribe