This is probably the last technical year post, consider it my Chrismast gift yo you. Happy holidays,
A little bit of history you can Check Reto 14: Android crackme #2, it is an intersting publication where they challenge you to bypass LVL security on a developed APK; that was the perfect excuse for me to get to learn about decompile code in Android with practice, I mean I knew "How" but i theory never done it for myself, so thanks again to Hackerplayers for the challenge.
Clarifications
This post is not intended to be a profound explanation about how Android compile clases and package into an APK. I'm not going to explain deeply about Smali/Backsmali (Decompile code), there are already excelent places that you can check them out like Dissasembling Dex File or Android Cracking, personally I liked the last better because it's a whole blog intended to cracking, tells you a lot about tips and tricks in this subject, totally worth it to check it out.
This post is a pragmatic example on how you can bypass a security licencing solving ofcourse Reto 14: Android crackme #2. So lets start with the fun, here is the answer I gave and was approve by Hackerplayer author:
Download the APKTool
Apktool is a wonderful tool, when it comes to cracking more like when it comes to decompiling, it becomes your bestfriend allows you to do several stuff like:
- Decoding resources to nearly original form (including resources.arsc, XMLs and 9.png files) and rebuilding them
- Smali debugging: SmaliDebugging
- Helping with some repetitive tasks
After following the APKTool instalation you can proceed to execut the folowing command:
$apktool d cracme2hpys.apk out
*out is the target folder where the apk it's decompressed.
Checking the extracted folder out
First I though I could bypass the application by changing the start up ACtivity on the Manifest, but that was unsucessful.
So No way, I had to check out the decompile code. The AndroidManifest.xml it's always a good place to start, gives you many hint where to look like the Start up Activity, probably there is where the ALVL process start.
So No way, I had to check out the decompile code. The AndroidManifest.xml it's always a good place to start, gives you many hint where to look like the Start up Activity, probably there is where the ALVL process start.
So you now we know we have to check LicenseCheck.smali. When you open this file, you'll se a lot of code similar to Assembly language if you are not confortable with this, get used to it's the only way.
Search for the #onCreate method on LicenseCheck, this is where the licesence que check and invoke the method doCheck on the same class.
invoke-direct {v1, p0, v2, v3}, Lcom/android/vending/licensing/LicenseChecker;->(Landroid/content/Context;Lcom/android/vending/licensing/Policy;Ljava/lang/String;)V
.line 120
iput-object v1, p0, Lcom/hpys/crackmes/LicenseCheck;->mChecker:Lcom/android/vending/licensing/LicenseChecker;
.line 123
invoke-direct {p0}, Lcom/hpys/crackmes/LicenseCheck;->doCheck()V
.line 125
return-void
If you look at the line 123. you'll se there is a doCheck method invocation of the current class so lets dig out to see what does this method actually do:
.method private doCheck()V
.locals 2
.prologue
.line 106
iget-object v0, p0, Lcom/hpys/crackmes/LicenseCheck;->mChecker:Lcom/android/vending/licensing/LicenseChecker;
iget-object v1, p0, Lcom/hpys/crackmes/LicenseCheck;->mLicenseCheckerCallback:Lcom/android/vending/licensing/LicenseCheckerCallback;
invoke-virtual {v0, v1}, Lcom/android/vending/licensing/LicenseChecker;->checkAccess(Lcom/android/vending/licensing/LicenseCheckerCallback;)V
.line 107
return-void
.end method
Now is clear the method doCheck does the License check through a class named LicenseCecker aparently there is also a callback instance passed to this object probably to inform that the checking was successfuly, so now we have to into:com/android/vending/licensing/LicenseChecker
Before we start to read all the LicenseChecker and $ classes, we should go straight to the checkAccess method that was invoke previusly in LicenseCheck class remember? I'll help you out here:
invoke-virtual {v0, v1}, Lcom/android/vending/licensing/LicenseChecker;->checkAccess(Lcom/android/vending/licensing/LicenseCheckerCallback;)V
Probably this method gives us better clues than any other, this method is quite extensive, so I'll narrow it do to the important stuff:
# virtual methods
.method public declared-synchronized checkAccess(Lcom/android/vending/licensing/LicenseCheckerCallback;)V
.locals 9
.parameter "callback"
.prologue
.line 133
monitor-enter p0
:try_start_0
iget-object v1, p0, Lcom/android/vending/licensing/LicenseChecker;->mPolicy:Lcom/android/vending/licensing/Policy;
invoke-interface {v1}, Lcom/android/vending/licensing/Policy;->allowAccess()Z
move-result v1
if-eqz v1, :cond_0
.line 134
const-string v1, "LicenseChecker"
Did you see if-eqz v1, :cond_0 operation? well this it's a very important one if this it's not true then It will send you lower to instantiate the License Validator, and we don;t want that do we?, so lets negate that condition with another operation if-nez vx,target so now it should work right? welll
Are you kidding It ain't working.... ¬¬
Yes, yes I know we change the license execution and recompile and repacked (I'll explained the process later) but still does not work, well turns out the challenge gives you another problem. The MyAndroidAppActivity does not seem to be invoking the onCreate method and generate the following trace on logcat:
So?, What's going on?, The answer is plain simple the MyAndroidActivity does not invoke onCreate, we need to add that into the backsmali. Look:
.class public Lcom/hpys/crackmes/MyAndroidAppActivity; .super Lcom/hpys/crackmes/LicenseCheck; .source "MyAndroidAppActivity.java" # direct methods .method public constructor()V .locals 0 .prologue .line 6 invoke-direct {p0}, Lcom/hpys/crackmes/LicenseCheck;->()V return-void .end method # virtual methods .method public onCreate(Landroid/os/Bundle;)V .locals 0 .parameter "savedInstanceState" .prologue .line 11 invoke-super {p0, p1}, Lcom/hpys/crackmes/LicenseCheck;->onCreate(Landroid/os/Bundle;)V .line 15 return-void .end method
The code above show a lots of lacks in the MyAndroidAppActivity, being a simple and small code we can aknowledge the following problems:
- The onCreate method does not call the super.onCreate(savedInstanceState)
- The onCreate method does not have any assign layout
- The MyAndroidAppActivity inherit the LicenseCheck instead of the Activity, and also does not make the proper code on the init invocation.
Here is the right code:
.class public Lcom/hpys/crackmes/MyAndroidAppActivity; .super Landroid/app/Activity; .source "MyAndroidAppActivity.java" # direct methods .method public constructor()V .locals 0 .prologue .line 6 invoke-direct {p0}, Landroid/app/Activity;-> ()V return-void .end method # virtual methods .method public onCreate(Landroid/os/Bundle;)V .locals 1 .parameter "savedInstanceState" .prologue .line 15 invoke-super {p0, p1}, Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)V .line 17 const/high16 v0, 0x7f03 invoke-virtual {p0, v0}, Lcom/hpys/crackmes/MyAndroidAppActivity;->setContentView(I)V .line 20 return-void .end method
We can take the following notes like the onCreate and setContentView invocation, and the variable v0 was added, when adding variable you have to be careful to declare how many are you using in the block scope in this case we add locals 1 on the method declaration.
Are we done? kind of, we now need to recompile and repackaged this into an APK, as I promised this is how you do it
Back to an APK
Rembember apktool? well the same tool that allows you to decompile, help you into recompile and recreate an APK, but you probably going to need a little bit more to get it back into the phone. "But you'll se I'll show you" (Joker quote)
First build and create the apk with the following command
$ apktool b out crackemecracked.apkYou will also need to sign this out, and you are going to need a keystore, you can easly created with keytool
$ keytool -genkey -v -keystore keystore.keystore
Now that you have a keystore, use it to signed your app
jarsigner -verbose -keystore keystore.keystore crackemecracked.apk crackmecracked
If you wish to learn more about how to sign Android application don't forget to pass by the oficial documenation.
$ adb uninstall com.hpys.crackmes $ adb install crackemecracked-za.apk
If everything it's correct you should be seeing this:
And READY!!
¿Some aditional tips ?
Particulary I've never done this before, the information on how to modify backsmali is not that wide, but it is not that hard (at least not the basic to do this)
- I suggest you learn a bit about Assembler because it is really similar the operator and the register changes.
- I suggest you learn a bit about Assembler because it is really similar the operator and the register changes.
- Whenever I get lost with a specific operation I went to Dalvik OpCode it was like the Larouse for me
- I did some small and simple classes to check out what does the decompile code looks like.
- No need to check everything like LicenseChecker$ResultListener$1 this classes are either anonymous or declare internal classes on the file so you can skip them.
- For the recompilation and reepackaging procedure I did small shellscript feel free to use it.
- No need to check everything like LicenseChecker$ResultListener$1 this classes are either anonymous or declare internal classes on the file so you can skip them.
- For the recompilation and reepackaging procedure I did small shellscript feel free to use it.
- I suggest you two excelent I/O presentations.
Google I/O 2008 - Dalvik Virtual Machine Internals
Google I/O 2010 - A JIT Compiler for Android's Dalvik VM






No hay comentarios:
Publicar un comentario en la entrada