Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to debug smali code of an android application?

I have a working android application. of which i dont have a source code. I would like to debug a functionality of this application. I could successfully reverse engineer this application apk file using apktool - https://code.google.com/p/android-apktool/ This tool generates class files in smali format.

My requirement is :

  1. To be able to debug a method by adding debug logs.
  2. To be able to debug method calls by printing a stack trace.

To achieve this I need to inject/insert smali equivalent of a debug log or stack trace. I tried adding some smali instruction at the start of one of the method but it crashed with ClassVerifyError.

Example smali code -

.method public declared-synchronized b()V
    .locals 2

    .prologue

    .line 87
    monitor-enter p0

    :try_start_0
    iget-object v0, p0, Lcom/example/viewerlib/t/d;->a:Ljava/lang/Thread;

    invoke-virtual {v0}, Ljava/lang/Thread;->isAlive()Z

               :
               :

Could someone help me out in adding smali debug logs. Thnx in advance.

like image 583
Dheeraj Kumar Chaudhary Avatar asked Jan 02 '14 09:01

Dheeraj Kumar Chaudhary


People also ask

How do I read Smali files on Android?

For reading SMALI files, there is a Smali syntax highlighting addon for Notepad++ distributed by the Android Cracking blog. NOTE: "Smali" stands for assembler in Icelandic. Iceland has a village named Dalvik from which the Dalvik Virtual machine was named. Similarly, "Baksmali" stands for disassembler.

What is Smali code in Android?

From the official git¹, “smali/baksmali is an assembler/disassembler for the dex format used by dalvik, Android's Java VM implementation”. The smali code, which is what we wish to modify, can be thought of as an equivalent of assembly code of a C program.

How do I debug an apk file?

To start debugging an APK, click Profile or debug APK from the Android Studio Welcome screen. Or, if you already have a project open, click File > Profile or Debug APK from the menu bar. In the next dialog window, select the APK you want to import into Android Studio and click OK.


2 Answers

1. Debug log in smali

Debug log in smali. Say for example inside method test() you want to print "Inside Test()" debug log. At the start of method in smali add following instructions :

sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;

const-string v1, "Inside Test()"

invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V

Note - You need to be careful while using registers v0,v1 here. In code execution flow, you have to check that you are not using one of the register which is used later in the flow. Or you may get Exception.

2. StackTrace

Here is the code of smali to print stacktrace of a method

Java code

public static void printStackTraces() {
    StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace(); 
    for (StackTraceElement element : stackTraceElements) {
        System.out.println("Class name :: " + element.getClassName() + "  || method name :: " + element.getMethodName());
    }
}

And equivalent smali code is

.method public static printStackTraces()V
    .locals 7

    .prologue
    .line 74
    invoke-static {}, Ljava/lang/Thread;->currentThread()Ljava/lang/Thread;

    move-result-object v2

    invoke-virtual {v2}, Ljava/lang/Thread;->getStackTrace()[Ljava/lang/StackTraceElement;

    move-result-object v1

    .line 75
    .local v1, stackTraceElements:[Ljava/lang/StackTraceElement;
    array-length v3, v1

    const/4 v2, 0x0

    :goto_0
    if-lt v2, v3, :cond_0

    .line 78
    return-void

    .line 75
    :cond_0
    aget-object v0, v1, v2

    .line 76
    .local v0, element:Ljava/lang/StackTraceElement;
    sget-object v4, Ljava/lang/System;->out:Ljava/io/PrintStream;

    new-instance v5, Ljava/lang/StringBuilder;

    const-string v6, "Class name :: " 

    invoke-direct {v5, v6}, Ljava/lang/StringBuilder;-><init>(Ljava/lang/String;)V

    invoke-virtual {v0}, Ljava/lang/StackTraceElement;->getClassName()Ljava/lang/String;

    move-result-object v6

    invoke-virtual {v5, v6}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    move-result-object v5

    const-string v6, "  || method name :: " 

    invoke-virtual {v5, v6}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    move-result-object v5

    invoke-virtual {v0}, Ljava/lang/StackTraceElement;->getMethodName()Ljava/lang/String;

    move-result-object v6

    invoke-virtual {v5, v6}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    move-result-object v5

    invoke-virtual {v5}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;

    move-result-object v5

    invoke-virtual {v4, v5}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V

    .line 75
    add-int/lit8 v2, v2, 0x1

    goto :goto_0
.end method

Add this method into any smali file. And call as

(Assuming you added above smali code into com.example.pakagename.ClassName)

invoke-static {}, Lcom/example/packagename/ClassName;->printStackTraces()V

Hope this helps .....

like image 110
rajan goswami Avatar answered Oct 03 '22 08:10

rajan goswami


If you like IntellijIdea, give smalidea a chance!

like image 31
packmad Avatar answered Oct 03 '22 08:10

packmad