android 代码注入 崩溃 解决方法

.registers 定义了方法中总共使用了几个寄存器;

.locals定义了方法中有几个非参数寄存器;

如果一个方法有5个寄存器,即.registers==5,v0-v4,而且该方法有两个参数,那么这两个参数将使用最后的两个寄存器,即v3和v4。

对于非static方法,那么第一个寄存器肯定是this,比如方法 LMyObject;->callMe(II)V有两个整形参数,那么它就会用三个寄存器。


为了动态调试android代码,有时候需要动态的注入代码,但是,代码注入时候,有几次发现会崩溃,后来,经过研究,发现是寄存器用错。一个方法可能本身就用了5个寄存器,v0-v4,而你用v5,那肯定要崩溃,是吧!或者你用了后面会用到的寄存器,把值给改了,那肯定也要崩溃。具体大家可以看看下面的文章:

见 http://code.google.com/p/smali/wiki/Registers:

There are two naming schemes for registers - the normalv naming scheme and thep naming scheme for parameter registers. The first register in thep naming scheme is the first parameter register in the method. So let's go back to the previous example of a method with 3 arguments and 5 total registers. The following table shows the normalv name for each register, followed by the p name for the parameter registers 


有点像stdcall的压栈形式。说白了就是,比如有个方法:

void method(arg1, arg2)

{

     int i;

    i = arg1+arg2;

}

那么method函数就要用三个寄存器,如果采用V模式来使用寄存器,那么就是:

i == v0;

arg1 == v1;

arg2 == v2;

如果是p模式使用寄存器,那么就是:

i == v0;

arg1 == p0;

arg2 == p1;

下面两个重载函数:

public int Add(int i,int j)
    {
        int k = 0;
        k = i+j;
        return k;
    }
    public int Add(int i,int j,int k )
    {
        int m = 0,n = 0;
        m = i+j;
        n = m+k;
        return n;
    }

对应的smali码:

# virtual methods
.method public Add(II)I
    .locals 1
    .parameter "i"
    .parameter "j"

    .prologue
    .line 44
    const/4 v0, 0x0
    

    .line 45
    .local v0, k:I
    add-int v0, p1, p2
    .line 46
    return v0
.end method

.method public Add(III)I
    .locals 2
    .parameter "i"
    .parameter "j"
    .parameter "k"

    .prologue
    .line 50
    const/4 v0, 0x0

    .local v0, m:I
    const/4 v1, 0x0

    .line 51
    .local v1, n:I
    add-int v0, p1, p2

    .line 52
    add-int v1, v0, p3

    .line 53
    return v1
.end method


你可能感兴趣的:(Android)