Android中反编译Smali文件解读

  1. 寄存器

    修改Smali时有一件很重要的事情就是要注意寄存器。如果乱用寄存器的话可能会导致程序崩溃。每个方法开头声明了registers的数量,这个数量是参数和本地变量总和。参数统一用P表示。如果是非静态方法p0代表this,p1-pN代表各个参数。如果是静态方法的话,p0-pN代表各个参数。本地变量统一用v表示。如果想要增加的新的本地变量,需要在方法开头的registers数量上增加相应的数值。

    比如下面这个方法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     # direct methods
    .method public constructor <init>()V
    .registers 1

    .prologue
    .line 7
    invoke-direct {p0}, Ljava/lang/Object;-><init>()V

    return-void
    .end method

    因为这不是静态方法,所以p0代表this。如果想要增加一个新的本地变量,比如v0。就需要把.registers 1改为.registers 2。

    有两种方式指定一个方法中有多少寄存器是可用的

    1. .registers 使用这个指令指定方法中寄存器的总数
    1. .locals 使用这个指定表明方法中非参寄存器的总数,放在方法的第一行。

    https://github.com/JesusFreke/smali/wiki/Registers

    寄存器的命名方式

    有两种方式——V命名方式和P命名方式。P命名方式中的第一个寄存器就是方法中的第一个参数寄存器。在下表中我们用这两种命名方式来表示上一个例子中有5个寄存器和3个参数的方法。

    1
    2
    3
    4
    5
    v0    第一个local register  
    v1 第二个local register
    v2 p0 第一个parameter register
    v3 p1 第二个parameter register
    v4 p2 第三个parameter register

    你可以用任何一种方式来引用参数寄存器——他们没有任何差别。
    注意:baksmali(apktool)默认对参数寄存器使用P命名方式。如果想使用V命名方式,可以使用-pl—no-parameter-registers选项。但是有的工具反编译的出来的都是v命名的方式。比如(smaliviewer),使用P命名的方式可读性比较好。

    使用P命名方式是为了防止以后如果要在方法中增加寄存器,需要对参数寄存器重新进行编号的缺点。

  1. 给原程序增加大量逻辑的办法

    我非常不建议在程序原有的方法上增加大量逻辑,这样可能会出现很多寄存器方面的错误导致编译失败。比较好的方法是:把想要增加的逻辑先用java写成一个apk,然后把这个apk反编译成smali文件,随后把反编译后的这部分逻辑的smali文件插入到目标程序的smali文件夹中,然后再在原来的方法上采用invoke的方式调用新加入的逻辑。这样的话不管加入再多的逻辑,也只是修改了原程序的几行代码而已。这个思路也是很多重打包病毒惯用的伎俩,确实非常方便好用。

  2. 方法中出现的关键字

    1
    2
    3
    4
    5
    6
    7
     .method <访问权限>[修饰关键字]<方法原型>
    <.locals> # 指定了使用的局部变量个数
    [.parameter] # 指定了方法的参数,如果有三个参数就有三个.parameter
    [.prologue] # 指定了代码开始段,混淆过的代码可能去掉了改段落
    [.line] # 指定了该处指令在源代码中的行数,混淆过的代码可能会去掉,主要用于调试。
    <代码体>
    .end method
    1
    2
    3
    4
    5
    6
    7
    8
    invoke-super  调用父函数
    const/high16 v0, 0x7fo3  把0x7fo3赋值给v0
    invoke-direct  调用函数
    return-void  函数返回void
    new-instance  创建实例
    iput-object  对象赋值
    iget-object  调用对象
    invoke-static  调用静态函数

【参考文章】

Smali 语法:

http://www.cnblogs.com/lee0oo0/p/3728271.html

http://dalufan.com/2015/01/14/android-Smail-learn/

官网文档:
转载官网Android官网,科学上网

Dalvik字节码