Question

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.

Was it helpful?

Solution

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 .....

OTHER TIPS

If you like IntellijIdea, give smalidea a chance!

I suggest using apkanalyzer from sony:

https://github.com/sonyxperiadev/ApkAnalyser

it allows you to decompile apk-s and read smali code, insert print statements into various places. There is menu option: "Print custom log", you can also print stacktrace, and do lots of other things. After all the changes you just press Device->Install and start apk. All from GUI.

hey I was thinking that You might find this tool helpful

it decompiles any apk file to a java written code classes

check this link and give it a try

http://forum.xda-developers.com/showthread.php?t=2430413

Sorry to point out that apkanalyzer is a ststic analyser For understanding and editing smali code, try the following

http://themasterofmagik.wordpress.com/2014/03/08/decompilerecompile-an-apk-basic-editing/

It explains editing in various scenarios. What tool to use and when.

Different approaches to Decompile/Recompile an apk

a. apk
    1. apktool + Notepad++
    2. Virtuous Ten Studio
    3. AndroChef Java Decompiler
b. classes.dex
    1. smali/baksmali
    2. dex2jar + JD-GUI

I tried using smalidea plugin but could not get it working so tried with different approach stated below.

There is an option in Android Studio 3.1.2, Go to File -> Select Profile or Analyze Apk option. It will then decompile the Apk in classes.dex file and out file which will have smali files. You can then Rus As-> Debug option and put breakpoint in any smali files an it will stop at specified breakpoint. This works only if you have single dex file in your application. There is however an work around for multi dex application in which you need to follow below steps -

1) Download Apktool tool from here

2) Decompile the Apk using -> apktool d

3) Copy all the smali files generated above in multiple folders - smali, smali_classess2, smali_classes3 and so on into the out folder created from Android Studio -> Analyze Apk method earlier, so that all the smali files are in single folder

4) This step I am not sure if it is required, but I had followed this, feel free to verify this step. Here you again build the Apk using apktool using folder created in step 2 using command -> apktool b . This will generate all the .dex files and copy all the files in the same location where single classes.dex file was generated using Analyze Apk method earlier.

5) Now use the same Project created using Analyze Apk method and you are good to debug.

P.S. - Android studio will complain of debugging using Java code but this method will work. This method is only helpful if you are editing any smali file and you want to debug it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top