17

我有一个工作的 android 应用程序。其中我没有源代码。我想调试这个应用程序的功能。我可以使用 apktool 成功地对这个应用程序 apk 文件进行逆向工程 - https://code.google.com/p/android-apktool/ 这个工具生成 smali 格式的类文件。

我的要求是:

  1. 能够通过添加调试日志来调试方法。
  2. 能够通过打印堆栈跟踪来调试方法调用。

为此,我需要注入/插入与调试日志或堆栈跟踪等效的 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 调试日志。提前谢谢。

4

6 回答 6

31

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.堆栈跟踪

这是 smali 打印方法堆栈跟踪的代码

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

希望这可以帮助 .....

于 2014-01-02T10:01:47.200 回答
5

如果你喜欢 IntellijIdea,就给smalidea一个机会吧!

于 2017-01-09T14:09:12.160 回答
2

我建议使用来自索尼的 apkanalyzer:

https://github.com/sonyxperiadev/ApkAnalyser

它允许您反编译 apk-s 并读取 smali 代码,将打印语句插入到各个位置。有菜单选项:“打印自定义日志”,您还可以打印堆栈跟踪,并做很多其他事情。完成所有更改后,您只需按 Device->Install 并启动 apk。全部来自 GUI。

于 2014-01-02T10:09:33.593 回答
2

嘿,我在想你可能会发现这个工具很有帮助

它将任何 apk 文件反编译为 java 编写的代码类

检查此链接并尝试一下

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

于 2014-01-02T10:20:25.523 回答
1

抱歉指出 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
于 2014-03-24T14:10:48.213 回答
0

我尝试使用 smalidea 插件,但无法使其正常工作,因此尝试了以下不同的方法。

Android Studio 3.1.2 中有一个选项,转到文件 -> 选择配置文件或分析 Apk 选项。然后它将在 classes.dex 文件和包含 smali 文件的 out 文件中反编译 Apk。然后您可以 Rus As-> Debug 选项并将断点放在任何 smali 文件中,它将在指定的断点处停止。这仅在您的应用程序中有单个 dex 文件时才有效。然而,对于多 dex 应用程序有一个解决方法,您需要按照以下步骤操作 -

1) 从这里下载 Apktool 工具

2) 使用 -> apktool d 反编译 Apk

3) 将上面生成的所有smali文件复制到多个文件夹-smali, smali_classess2, smali_classes3等到前面Android Studio->Analyze Apk方法创建的out文件夹中,这样所有smali文件都在一个文件夹中

4)这一步我不确定是否需要,但我已经遵循了这个,请随时验证这一步。在这里,您再次使用 apktool 使用在步骤 2 中使用 command -> apktool b 创建的文件夹来构建 Apk。这将生成所有 .dex 文件并将所有文件复制到之前使用分析 Apk 方法生成单个 classes.dex 文件的同一位置。

5) 现在使用使用分析 Apk 方法创建的相同项目,您可以调试了。

PS - Android Studio 会抱怨使用 Java 代码进行调试,但这种方法会起作用。此方法仅在您正在编辑任何 smali 文件并且想要调试它时才有用。

于 2018-08-08T06:22:36.337 回答