Sunday, August 8, 2010

Android Trial Patching - Android App Cracking Tutorial #2

Collins English/French Dictionary Trial Crack

Requisites:
apktool - contains baksmali/smali, generally awesome. (http://code.google.com/p/android-apktool/)
Android SDK installed. (http://developer.android.com/sdk/index.html)
ADB Access.
An Android Device

Collins audio english french dictionary is a translation dictionary with audio capability. It was
chosen due to its method of protection and listing in the "demo" section of the market as a featured
application.

7 day trial

I downloaded the apk from: http://android.mobisystems.com/product.html?p=16&l=1&pid=370&i=1&c=1&sc=9

getting CollinsAudioMltEnFr.apk


Then I use apktool to decompress and disassemble the package:
    apktool d CollinsAudioMltEnFr.apk enfr_dict

Then I go into the newly created directory:
    cd enfr_dict

Searching the directory structure, I see:
  msdict/viewer/engine/LicenseManager.smali

This looks promising!

In this directory, we find enough information to determine that they store registration information in .reginfo in the files directory
sure enough:
    ben@ben-laptop:~/Downloads$ adb shell busybox ls -Al /data/data/com.mobisystems.msdict.embedded.wireless.collins.audiomltenfr/files
    -rw-rw----    1 10106    10106          25 Aug  8 07:52 .reginfo

Deleting this file will start your trial anew, but we're still going to crack this app!

Well, let's stop and look at this file a bit

hexdump -C .reginfo on my linux host results in this:

00000000  00 00 00 01 00 00 00 01  00 00 00 0a 00 00 00 92  |................|
00000010  00 00 00 01 2a 74 bb f9  dd                       |....*t...|


Looking at: /smali/com/mobisystems/msdict/viewer/engine/LicenseManagerBase.smali

search for the following "public load", this is where the filestream for the .reginfo file is read, this will provide good smali reading
practice.

###

.method public load(Ljava/io/InputStream;)V
    .locals 7
    iget-object v0, p0, Lcom/mobisystems/msdict/viewer/engine/LicenseManagerBase;->_items:Ljava/util/Vector;
    invoke-virtual {v0}, Ljava/util/Vector;->removeAllElements()V
    new-instance v0, Ljava/io/DataInputStream;
    invoke-direct {v0, p1}, Ljava/io/DataInputStream;->(Ljava/io/InputStream;)V
    :try_start_0
    invoke-virtual {v0}, Ljava/io/DataInputStream;->readInt()I
    invoke-virtual {v0}, Ljava/io/DataInputStream;->readInt()I
    move-result v1
    :goto_0
    const/4 v2, 0x1
    sub-int v2, v1, v2
    if-lez v1, :cond_0
    invoke-virtual {v0}, Ljava/io/DataInputStream;->readInt()I
    move-result v1
    invoke-virtual {v0}, Ljava/io/DataInputStream;->readInt()I
    move-result v3
    new-instance v4, Lcom/mobisystems/msdict/viewer/engine/LicenseManagerBase$Item;
    invoke-direct {v4, v1, v3}, Lcom/mobisystems/msdict/viewer/engine/LicenseManagerBase$Item;->(II)V
    invoke-virtual {v0}, Ljava/io/DataInputStream;->readBoolean()Z
    move-result v1
    iput-boolean v1, v4, Lcom/mobisystems/msdict/viewer/engine/LicenseManagerBase$Item;->registered:Z
    invoke-virtual {v0}, Ljava/io/DataInputStream;->readLong()J
    move-result-wide v5
    iput-wide v5, v4, Lcom/mobisystems/msdict/viewer/engine/LicenseManagerBase$Item;->expire_time:J

###


From looking at that file, I can tell the following:
 * It reads 4 ints (4 bytes each), 1 boolean (1 byte, although this is not guaranteed I don't think), and 1 long (8 bytes) 4x4=16 + 1x1=17 + 1x8 = 25 == MY FILESIZE
 * The last parameter is a member named "expire_time"
 * The boolean value says whether or not the application is registered.

So back to the hexdump:

00000000  00 00 00 01 00 00 00 01  00 00 00 0a 00 00 00 92  |................|
00000010  00 00 00 01 2a 74 bb f9  dd                       |....*t...|

int1 = 00 00 00 01
int2 = 00 00 00 01
int3 = 00 00 00 0a
int4 = 00 00 00 92
bool = 00
long = 00 00 01 2a 74 bb f9 dd

So for shits and giggles, I wondered what making the last parameters all F's would do:

Upon starting the app back up, I was greeted with the fact I had 3,242,983 days left on my
trail period. So I think I can make it to the rapture before my trial runs out, but I still have that annoying nag screen, so let's find a different route.





in smali/com/mobisystems/msdict/viewer/engine/LicenseManagerBase.smali I find:

###

.method public isRegistered(II)Z
    .locals 1
    if-nez p1, :cond_0
    const/4 v0, 0x1
    :goto_0
    return v0
    :cond_0
    invoke-virtual {p0, p1, p2}, Lcom/mobisystems/msdict/viewer/engine/LicenseManagerBase;->getItem(II)Lcom/mobisystems/msdict/viewer/engine/LicenseManagerBase$Item;
    move-result-object v0
    iget-boolean v0, v0, Lcom/mobisystems/msdict/viewer/engine/LicenseManagerBase$Item;->registered:Z
    goto :goto_0
.end method

###

This is simple, if the passed parameter is NULL, it returns 0 right away. If not, it gets the base item (this piece of software) license
and checks its 'registered' member. This is too damn complex, I'm going to simplify things a bit.

###

.method public isRegistered(II)Z
    .locals 1
    const/4 v0, 0x1
    return v0
.end method

###

It now makes a variable, assigns it '1', and then returns that variable.

OK I think I'm done, let's package everything back up, I go to the directory I originally ran apktool in, and do the following:
    apktool b enfr_dict enfr_dict.apk

we need to sign this to put on most android devices, if you have the SDK installed, you should have a debug key
    jarsigner -keystore ~/.android/debug.keystore enfr_dict.apk androiddebugkey

and enter "android" as the password.

NOTE: You won't be able to "upgrade" the app on the device, you MUST uninstall it either on the device, or by typing the following:
    adb uninstall com.mobisystems.msdict.embedded.wireless.collins.audiomltenfr

You now have an installable cracked apk, which you can install by typing:
    adb install enfr_dict.apk

6 comments:

  1. Hi Exellent article. Very useful! But I have a question. Where i can fing that .reginfo file. I searched a lot but could not find it. Can you please tell me how & where to find it. That would be a great help!
    Thanx in advance!

    ReplyDelete
  2. Prasenjit, the file should be in

    /data/data/com.mobisystems.msdict.embedded.wireless.collins.audiomltenfr/files/.reginfo

    if you have busybox, try

    busybox find /data/data -name .reginfo

    ReplyDelete
  3. Hi Android Reversing :). Hey thanx a lot man because of you I was able to crack 9 apps from Mob!systms. Thanx man. The only thing different in my method of cracking was instead of using .reginfo file for extending the trial period. I edited the trial period line in the same license manager...smali you used. The line had trial:0x7 so I just replaced it with 0x5f5e100. & then continued to do the final editing. after signing & installing viola!!! the app were registered products. Thanx buddy your article helped me a lot!:)

    ReplyDelete
  4. Android Reversing, you are awesome. Thanks for the article. Now I can use Duden german dict.
    Thanks a lot

    ReplyDelete
  5. Hi,
    i tried installing above files but i got an error .. "Could not load Java virtual machine "
    I m using Win Xp SP3
    1 GB Ram
    Celeron 1.8 Ghz
    i have downloaded all the latest files but still i got this error.. Pls help me

    ReplyDelete
  6. cant find anything like this... trying 2 crack solid explorer 1.42

    ReplyDelete