如何记录方法中引用的字符串 - Smali

逆向工程 安卓 爪哇
2021-06-18 03:22:16

我一直在尝试对 Android 应用程序进行逆向工程,并想知道如何记录某个字符串。这是我尝试从以下位置记录字符串的方法:

.method private getValue(Ljava/lang/String;)[B
.locals 2
.param p1, "parameter"    # Ljava/lang/String;

.prologue
.line 216
new-instance v0, Ljava/lang/StringBuilder;

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

iget-object v1, p0, Lcom/directory/theseSettings;->newSettings:Lcom/directory/NewSettings;

iget-object v1, v1, Lcom/directory/NewSettings;->newValue:Ljava/lang/String;

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

move-result-object v0

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

move-result-object v0

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

move-result-object v0

const-string v1, "UTF-8"

invoke-static {v0, v1}, Lorg/apache/http/util/EncodingUtils;->getBytes(Ljava/lang/String;Ljava/lang/String;)[B

move-result-object v0

return-object v0
.end method

作为参考,这里是用jadx反编译时的那个方法。

private byte[] getValue(String parameter) {
    return EncodingUtils.getBytes(this.newSettings.newValue + parameter, "UTF-8");
}

我希望记录在 jadx 方法中看到的“this.newSettings.newValue”,我猜它会是:

iget-object v1, v1, Lcom/directory/NewSettings;->newValue:Ljava/lang/String;

在斯马里。

唯一的问题是我不知道如何记录它,我可以通过使用记录“参数”

const-string v0, “PARAMETER:” 
invoke-static {v0, p1}, Landroid/util/Log;->e(Ljava/lang/String;Ljava/lang/String;)I 

但是如果在方法中引用它而不是“传递”给它,我不确定如何处理它。

1个回答

在 Dalvik 中,中间值存储在“寄存器”中,您可以将其视为类似于局部变量,只是它们被编号而不是命名,并且它们在方法的不同点可以具有不同的类型。

当你写

const-string v0, “PARAMETER:” 
invoke-static {v0, p1}, Landroid/util/Log;->e(Ljava/lang/String;Ljava/lang/String;)I

代码做了两件事。第一它存储文本字符串“PARAMETER:”在寄存器0(简称v0),然后通过在寄存器中的值v0p1作为参数Log.e()。

在字节码级别,寄存器只是一个平面数组,但最后几个寄存器是特殊的,因为这是在进入方法时传递参数的地方。因此,Smali 提供了处理参数的语法糖。在这种情况下,有两个局部变量,这样的参数在开始寄存器2p0仅仅是一个别名v2p1只是一个别名v3

注意:按照惯例,参数寄存器保持不变,但它们和其他寄存器一样,如果需要,您可以在其中存储不同的内容。您的代码工作的原因是因为p1在方法的开头包含第二个参数(第一个参数 ,this存储在 中p0),并且没有存储任何内容,因此当控制到达您的日志语句时,它仍然包含您想要的值。

无论如何,如果您想将值记录在不同的寄存器中并没有什么不同,您只需将不同的寄存器命名为 Log.e() 的参数即可。在这种情况下,您想要的值存储在寄存器 1 中,因此您应该这样做

invoke-static {v0, v1}, Landroid/util/Log;->e(Ljava/lang/String;Ljava/lang/String;)I