Как отладить smali-код приложения Android?

У меня есть работающее приложение для Android. из которых у меня нет исходного кода. Я хотел бы отладить функциональность этого приложения. Я мог бы успешно перепроектировать этот файл apk приложения, используя apktool - https://code.google.com/p/android-apktool/ Этот инструмент генерирует файлы классов в формате smali.

Мое требование:

  • Чтобы иметь возможность отлаживать метод, добавляя журналы отладки.
  • Возможность отладки вызовов методов путем печати трассировки стека.

Для этого мне нужно ввести/вставить smali-эквивалент журнала отладки или трассировки стека. Я попытался добавить некоторую инструкцию smali в начале одного из методов, но он разбился с ClassVerifyError.

Пример smali-кода -

.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

               :
               :

Может ли кто-нибудь помочь мне в добавлении журналов отладки smali. Thnx заранее.

Ответ 1

1. Отладочный журнал smali

Отладить журнал smali. Скажем, например, внутри метода test() вы хотите распечатать журнал отладки "Inside Test()". В начале метода в smali добавьте следующие инструкции:

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

Примечание.. Вы должны быть осторожны при использовании регистров v0, v1 здесь. В потоке выполнения кода вы должны проверить, что вы не используете один из регистров, который используется позже в потоке. Или вы можете получить исключение.

2. StackTrace

Вот код smali для печати stacktrace метода

Код Java

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

И эквивалентный smali-код

.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

Добавьте этот метод в любой файл smali. И назовите

(Предполагая, что вы добавили код smali в com.example.pakagename.ClassName)

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

Надеюсь, это поможет.....

Ответ 2

Теперь вы можете использовать отличный плагин для Android Studio или Intellij IDEA - Smalidea. Кроме того, я описал процесс установки и отладки в своем сообщении .

Ответ 3

Если вам нравится IntellijIdea, дайте smalidea шанс!

Ответ 4

Я предлагаю использовать apkanalyzer из sony:

https://github.com/sonyxperiadev/ApkAnalyser

он позволяет декомпилировать apk-s и читать smali-код, вставлять инструкции печати в разные места. Существует опция меню: "Распечатайте собственный журнал", вы также можете распечатать stacktrace и сделать много других вещей. После всех изменений вы просто нажимаете Device- > Install and start apk. Все из графического интерфейса.

Ответ 5

Эй, я думал, что вы можете найти этот инструмент полезным

он декомпилирует любой файл apk в классы кода, написанные java

проверьте эту ссылку и попробуйте

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

Ответ 6

Извините, что apkanalyzer - это ststic-анализатор Для понимания и редактирования smali-кода попробуйте выполнить

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

Он объясняет редактирование в различных сценариях. Какой инструмент использовать и когда.

Различные подходы к декомпиляции/перекомпиляции apk

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