Introduction
Since I started doing Android development, I have looked at many licensing options, from simple forward locking (/data/app-private), which was a complete failure, to KeyesLab’s AAL which I really liked, to a custom one I was privy to, written by my friend Colin O’Dell. I even went as far as writing two different ones myself.
By far the best looking, and nicest option I have seen is Google’s own Android Licensing Service. However, even Goliath can fall to a pebble.
A few days ago, after asking the AndroidPolice editors to write an article on piracy, I found a problem with Google’sAndroid License Verification Library. A minor patch to an application employing this official, Google-recommended protection system will render it completely worthless.
Implications
Our findings show that most (any?) apps can be easily patched and stripped of licensing protection, making them an easy target for off-Market, pirated distribution. By corollary, this means that sites dedicated to pirating apps can continue to do so, using a few automated scripts mixed with some smarts.
Demo
Watch this demonstration video of my patch method tricking both the protected version of the game StarHunt and the Google LVL demo app into thinking they have been purchased legitimately
Breaking The Library (aka The Technical Mumbo Jumbo)
A little back-story on Java, which most Android applications are written in. Java applications are compiled into bytecode, that runs on top of a Virtual Machine, generally independent of platform. Due to the need for cross compatibility, the bytecode is fairly readable. Many software suites exist to decompile/disassemble it, making it an easy target for reverse engineering.
For Android, the main disassembly suite is smali/baksmali. The bytecode output from baksmali can be edited in any text editor, and reassembled using smali.
[*]please note, theres more ways to decompiling/compiling apks such as apktool which is in .jar(jave) it has no GUI, unlike apk manager thats has somewhat of a GUI
Because the License Verification Library is not part of the Android OS (i.e. it doesn’t ship with phones – it’s an optional SDK download), an app developer needs to package it with the app that uses it, making it an easier patch target, without requiring root access.
The first step in reproducing this is to dissemble the apk using baksmali and find the LicenseValidator class. In custom implementations and pro-guarded apps like Tasker, this filename will differ, and so will the code, but not enough to stop a pirate from patching it.
When disassembling the basic implementation of the licensing service, you will find this file out/com/android/vending/licensing/LicenseValidator.smali. This class responds back to the application, telling it the results of the verification attempt. Opening this file in a text editor will show you the bytecode, and at the beginning you will see these constants.
LicenseValidator.smalli constants
- CODE: SELECT ALL
.field private static final ERROR_CONTACTING_SERVER:I = 0x101
.field private static final ERROR_INVALID_PACKAGE_NAME:I = 0x102
.field private static final ERROR_NON_MATCHING_UID:I = 0x103
.field private static final ERROR_NOT_MARKET_MANAGED:I = 0x3
.field private static final ERROR_OVER_QUOTA:I = 0x5
.field private static final ERROR_SERVER_FAILURE:I = 0x4
.field private static final LICENSED:I = 0x0
.field private static final LICENSED_OLD_KEY:I = 0x2
.field private static final NOT_LICENSED:I = 0x1
This code itself is unimportant, and may not show up in custom implementations, but it will help you understand the next step.
Scrolling to the bottom of LicenseValidator.smali, you will see this block of code in the “verify” method:
LicenseValidator.smali verify
- CODE: SELECT ALL
.sparse-switch
0x0 -> :sswitch_d3
0x1 -> :sswitch_de
0x2 -> :sswitch_d3
0x3 -> :sswitch_11d
0x4 -> :sswitch_f3
0x5 -> :sswitch_101
0x101 -> :sswitch_e5
0x102 -> :sswitch_10f
0x103 -> :sswitch_116
.end sparse-switch
This is a switch block, which essentially tells the licensing library what to do next, depending on the results of the verification query. Each possible result is “mapped” to a different function.
Notice how the values on the left correspond to the constants at the beginning of the file. 0X0 and 0×3 are both positive results, which will tell the application that your device has a valid license. The others are various forms of negative results, and depending on how the application is coded, will result in different things.
The important one here is 0×1, or NOT_LICENSED. By changing “0×1 -> :sswitch_de ” to “0×1 -> :sswitch_d3” we basically point it to a positive outcome instead, so the library tells your app the license is actually valid.
The final step is to reassemble with smali, placing the new dex file in the apk, and re-sign it with any valid key (even test-keys).
Even though the library knows the status is NOT_LICENSED, the described tweak ensures the application will receive a LICENSED result instead and believe that it is, in fact, licensed. This method is so simple, even a novice programmer could write a script to automatically patch most apps.
Credits:.blackdroid
No comments:
Post a Comment