在smali中插入log

image-20210130190952786

1
2
3
4
5
const-string v3, "Hello"

const-string v4, "\u6211\u662f\u6dfb\u52a0\u7684smali\u4ee3\u7801"

invoke-static {v3, v4}, Landroid/util/Log;->i(Ljava/lang/String;Ljava/lang/String;)I

在smali中插入log时,插入的位置,以及变量的值似乎是有要求的。随意插入会导致逻辑运行出错,程序原有的log无法打印。使用除了v和p之外的变量名,编译不通过。在此例使用p作为变量名,程序运行闪退。

打印变量的值

1
2
3
4
5
6
7
8
9
10
11
12
13
invoke-virtual {p0}, Lcom/luckyfuture/logtosmali/MainActivity;->fun1()I
# 调用fun1()方法,无参数,返回值类型为int
move-result p1
# 将上一步函数调用的返回值赋值给p1
invoke-static {p1}, Ljava/lang/String;->valueOf(I)Ljava/lang/String;
# 调用valueof(I)方法,一个参数为Int类型,返回值为String
move-result-object p1
# 将上一步方法调用对象引用返回值到p1,对于返回值为String要这么写,因为String不是基本数据类型

const-string v0, "\u8fd9\u4e2a\u503c\u662f"

invoke-static {v0, p1}, Landroid/util/Log;->i(Ljava/lang/String;Ljava/lang/String;)I
# 调用log.i方法,两个参数都为String,返回值为int

image-20210130191025828

插入log时要注意寄存器变量的名称,插入log更改寄存器中的值时,可能会影响到程序原本的运行。

不仅如此,使用寄存器时名称也有限制,本例中必须使用v2才能正确运行,使用其它名称闪退,可能是与smali性质有关。

提出问题

插入log时,寄存器变量名使用有无限制;对于不同数据类型,寄存器使用有无限制;寄存器的数量有多少,名称分别是什么?

  • 两种不同的寄存器表示方法,v命名法和p命名法

v命名法:寄存器命名从v0开始,表示函数中用到的局部变量与参数

p命名法:对函数的局部变量寄存器命名没有影响,函数中引用的参数的命名从p0开始,局部变量寄存器仍然用v表示。

使用p命名法更容易判断寄存器到底是局部变量寄存器还是参数寄存器,优势更明显。smali语法使用p命名法。

  • Dalvik寄存器

Dalvik虚拟机基于寄存器架构,在ARM架构的CPU上运行,Dalvik将部分寄存器映射到ARM处理器的寄存器上,还有一部分通过调用栈进行虚拟。最多有16位,2的16次方,65536个寄存器。v0——v65535

  • 不同数据类型和寄存器的关系

image-20210130191043704

参考资料

https://www.52pojie.cn/thread-665362-1-1.html

《Android软件安全与逆向分析》